[wasm] Create runtime objects later
For compilation we only need the NativeModule. Thus only create this before compilation, create other runtime objects later. This is a first step towards removing the deferred handles and clustering all foreground work in one chunk after compilation. R=ahaas@chromium.org Bug: v8:7921, v8:8423 Change-Id: If62387d68ddf0f5e067adbaef5fbeca7178958a4 Reviewed-on: https://chromium-review.googlesource.com/c/1402544 Reviewed-by: Andreas Haas <ahaas@chromium.org> Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#58656}
This commit is contained in:
parent
b0dc60f6b3
commit
c26b4977d6
@ -2476,19 +2476,13 @@ AsyncCompileJob::~AsyncCompileJob() {
|
||||
for (auto d : deferred_handles_) delete d;
|
||||
}
|
||||
|
||||
void AsyncCompileJob::PrepareRuntimeObjects(
|
||||
void AsyncCompileJob::CreateNativeModule(
|
||||
std::shared_ptr<const WasmModule> module) {
|
||||
// Embedder usage count for declared shared memories.
|
||||
if (module->has_shared_memory) {
|
||||
isolate_->CountUsage(v8::Isolate::UseCounterFeature::kWasmSharedMemory);
|
||||
}
|
||||
|
||||
// Create heap objects for script and module bytes to be stored in the
|
||||
// module object. Asm.js is not compiled asynchronously.
|
||||
Handle<Script> script =
|
||||
CreateWasmScript(isolate_, wire_bytes_, module->source_map_url);
|
||||
Handle<ByteArray> asm_js_offset_table;
|
||||
|
||||
// TODO(wasm): Improve efficiency of storing module wire bytes. Only store
|
||||
// relevant sections, not function bodies
|
||||
|
||||
@ -2498,11 +2492,27 @@ void AsyncCompileJob::PrepareRuntimeObjects(
|
||||
// only have one {WasmModuleObject}. Otherwise, we might only set
|
||||
// breakpoints on a (potentially empty) subset of the instances.
|
||||
// Create the module object.
|
||||
module_object_ =
|
||||
WasmModuleObject::New(isolate_, enabled_features_, std::move(module),
|
||||
{std::move(bytes_copy_), wire_bytes_.length()},
|
||||
script, asm_js_offset_table);
|
||||
native_module_ = module_object_->native_module();
|
||||
|
||||
size_t code_size_estimate =
|
||||
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(module.get());
|
||||
native_module_ = isolate_->wasm_engine()->code_manager()->NewNativeModule(
|
||||
isolate_, enabled_features_, code_size_estimate,
|
||||
wasm::NativeModule::kCanAllocateMoreMemory, std::move(module));
|
||||
native_module_->SetWireBytes({std::move(bytes_copy_), wire_bytes_.length()});
|
||||
native_module_->SetRuntimeStubs(isolate_);
|
||||
}
|
||||
|
||||
void AsyncCompileJob::PrepareRuntimeObjects() {
|
||||
// Create heap objects for script and module bytes to be stored in the
|
||||
// module object. Asm.js is not compiled asynchronously.
|
||||
const WasmModule* module = native_module_->module();
|
||||
Handle<Script> script =
|
||||
CreateWasmScript(isolate_, wire_bytes_, module->source_map_url);
|
||||
|
||||
size_t code_size_estimate =
|
||||
wasm::WasmCodeManager::EstimateNativeModuleCodeSize(module);
|
||||
module_object_ = WasmModuleObject::New(isolate_, native_module_, script,
|
||||
code_size_estimate);
|
||||
|
||||
{
|
||||
DeferredHandleScope deferred(isolate_);
|
||||
@ -2515,7 +2525,11 @@ void AsyncCompileJob::PrepareRuntimeObjects(
|
||||
|
||||
// This function assumes that it is executed in a HandleScope, and that a
|
||||
// context is set on the isolate.
|
||||
void AsyncCompileJob::FinishCompile(bool compile_wrappers) {
|
||||
void AsyncCompileJob::FinishCompile() {
|
||||
bool is_after_deserialization = !module_object_.is_null();
|
||||
if (!is_after_deserialization) {
|
||||
PrepareRuntimeObjects();
|
||||
}
|
||||
DCHECK(!isolate_->context().is_null());
|
||||
// Finish the wasm script now and make it public to the debugger.
|
||||
Handle<Script> script(module_object_->script(), isolate_);
|
||||
@ -2528,17 +2542,18 @@ void AsyncCompileJob::FinishCompile(bool compile_wrappers) {
|
||||
isolate_->debug()->OnAfterCompile(script);
|
||||
|
||||
// We can only update the feature counts once the entire compile is done.
|
||||
auto compilation_state = Impl(native_module_->compilation_state());
|
||||
auto compilation_state =
|
||||
Impl(module_object_->native_module()->compilation_state());
|
||||
compilation_state->PublishDetectedFeatures(
|
||||
isolate_, *compilation_state->detected_features());
|
||||
|
||||
// TODO(bbudge) Allow deserialization without wrapper compilation, so we can
|
||||
// just compile wrappers here.
|
||||
if (compile_wrappers) {
|
||||
DoSync<CompileWrappers>();
|
||||
if (is_after_deserialization) {
|
||||
DoSync<AsyncCompileJob::FinishModule>();
|
||||
} else {
|
||||
// TODO(wasm): compiling wrappers should be made async as well.
|
||||
DoSync<AsyncCompileJob::FinishModule>();
|
||||
DoSync<CompileWrappers>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2565,7 +2580,7 @@ class AsyncCompileJob::CompilationStateCallback {
|
||||
if (job_->DecrementAndCheckFinisherCount()) {
|
||||
SaveContext saved_context(job_->isolate());
|
||||
job_->isolate()->set_context(*job_->native_context_);
|
||||
job_->FinishCompile(true);
|
||||
job_->FinishCompile();
|
||||
}
|
||||
break;
|
||||
case CompilationEvent::kFinishedTopTierCompilation:
|
||||
@ -2809,14 +2824,14 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep {
|
||||
// is done.
|
||||
job->background_task_manager_.CancelAndWait();
|
||||
|
||||
job->PrepareRuntimeObjects(module_);
|
||||
job->CreateNativeModule(module_);
|
||||
|
||||
size_t num_functions =
|
||||
module_->functions.size() - module_->num_imported_functions;
|
||||
|
||||
if (num_functions == 0) {
|
||||
// Degenerate case of an empty module.
|
||||
job->FinishCompile(true);
|
||||
job->FinishCompile();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2832,7 +2847,7 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep {
|
||||
compilation_state->SetNumberOfFunctionsToCompile(
|
||||
module_->num_declared_functions);
|
||||
// Add compilation units and kick off compilation.
|
||||
InitializeCompilationUnits(job->native_module_,
|
||||
InitializeCompilationUnits(job->native_module_.get(),
|
||||
job->isolate()->wasm_engine());
|
||||
}
|
||||
}
|
||||
@ -3000,7 +3015,7 @@ bool AsyncStreamingProcessor::ProcessCodeSectionHeader(
|
||||
// AsyncStreamingProcessor have to finish.
|
||||
job_->outstanding_finishers_.store(2);
|
||||
compilation_unit_builder_.reset(new CompilationUnitBuilder(
|
||||
job_->native_module_, job_->isolate()->wasm_engine()));
|
||||
job_->native_module_.get(), job_->isolate()->wasm_engine()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3039,8 +3054,8 @@ void AsyncStreamingProcessor::OnFinishedStream(OwnedVector<uint8_t> bytes) {
|
||||
return;
|
||||
}
|
||||
// We have to open a HandleScope and prepare the Context for
|
||||
// PrepareRuntimeObjects and FinishCompile as this is a callback from the
|
||||
// embedder.
|
||||
// CreateNativeModule, PrepareRuntimeObjects and FinishCompile as this is a
|
||||
// callback from the embedder.
|
||||
HandleScope scope(job_->isolate_);
|
||||
SaveContext saved_context(job_->isolate_);
|
||||
job_->isolate_->set_context(*job_->native_context_);
|
||||
@ -3049,13 +3064,13 @@ void AsyncStreamingProcessor::OnFinishedStream(OwnedVector<uint8_t> bytes) {
|
||||
if (job_->native_module_ == nullptr) {
|
||||
// We are processing a WebAssembly module without code section. Create the
|
||||
// runtime objects now (would otherwise happen in {PrepareAndStartCompile}).
|
||||
job_->PrepareRuntimeObjects(std::move(result).value());
|
||||
job_->CreateNativeModule(std::move(result).value());
|
||||
DCHECK(needs_finish);
|
||||
}
|
||||
job_->wire_bytes_ = ModuleWireBytes(bytes.as_vector());
|
||||
job_->native_module_->SetWireBytes(std::move(bytes));
|
||||
if (needs_finish) {
|
||||
job_->FinishCompile(true);
|
||||
job_->FinishCompile();
|
||||
}
|
||||
}
|
||||
|
||||
@ -3088,11 +3103,11 @@ bool AsyncStreamingProcessor::Deserialize(Vector<const uint8_t> module_bytes,
|
||||
job_->module_object_ = handle(*job_->module_object_, job_->isolate_);
|
||||
job_->deferred_handles_.push_back(deferred.Detach());
|
||||
}
|
||||
job_->native_module_ = job_->module_object_->native_module();
|
||||
job_->native_module_ = job_->module_object_->shared_native_module();
|
||||
auto owned_wire_bytes = OwnedVector<uint8_t>::Of(wire_bytes);
|
||||
job_->wire_bytes_ = ModuleWireBytes(owned_wire_bytes.as_vector());
|
||||
job_->native_module_->SetWireBytes(std::move(owned_wire_bytes));
|
||||
job_->FinishCompile(false);
|
||||
job_->FinishCompile();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -105,9 +105,10 @@ class AsyncCompileJob {
|
||||
return outstanding_finishers_.fetch_sub(1) == 1;
|
||||
}
|
||||
|
||||
void PrepareRuntimeObjects(std::shared_ptr<const WasmModule>);
|
||||
void CreateNativeModule(std::shared_ptr<const WasmModule> module);
|
||||
void PrepareRuntimeObjects();
|
||||
|
||||
void FinishCompile(bool compile_wrappers);
|
||||
void FinishCompile();
|
||||
|
||||
void AsyncCompileFailed(Handle<Object> error_reason);
|
||||
|
||||
@ -158,7 +159,7 @@ class AsyncCompileJob {
|
||||
|
||||
std::vector<DeferredHandles*> deferred_handles_;
|
||||
Handle<WasmModuleObject> module_object_;
|
||||
NativeModule* native_module_ = nullptr;
|
||||
std::shared_ptr<NativeModule> native_module_;
|
||||
|
||||
std::unique_ptr<CompileStep> step_;
|
||||
CancelableTaskManager background_task_manager_;
|
||||
|
Loading…
Reference in New Issue
Block a user