diff options
Diffstat (limited to 'deps/v8/src/wasm/wasm-engine.cc')
-rw-r--r-- | deps/v8/src/wasm/wasm-engine.cc | 155 |
1 files changed, 101 insertions, 54 deletions
diff --git a/deps/v8/src/wasm/wasm-engine.cc b/deps/v8/src/wasm/wasm-engine.cc index dc78797365..d948157a12 100644 --- a/deps/v8/src/wasm/wasm-engine.cc +++ b/deps/v8/src/wasm/wasm-engine.cc @@ -7,10 +7,13 @@ #include "src/code-tracer.h" #include "src/compilation-statistics.h" #include "src/objects-inl.h" +#include "src/objects/heap-number.h" #include "src/objects/js-promise.h" +#include "src/ostreams.h" #include "src/wasm/function-compiler.h" #include "src/wasm/module-compiler.h" #include "src/wasm/module-decoder.h" +#include "src/wasm/module-instantiate.h" #include "src/wasm/streaming-decoder.h" #include "src/wasm/wasm-objects-inl.h" @@ -19,7 +22,7 @@ namespace internal { namespace wasm { WasmEngine::WasmEngine() - : code_manager_(&memory_tracker_, kMaxWasmCodeMemory) {} + : code_manager_(&memory_tracker_, FLAG_wasm_max_code_space * MB) {} WasmEngine::~WasmEngine() { // All AsyncCompileJobs have been canceled. @@ -38,20 +41,50 @@ bool WasmEngine::SyncValidate(Isolate* isolate, const WasmFeatures& enabled, return result.ok(); } -MaybeHandle<WasmModuleObject> WasmEngine::SyncCompileTranslatedAsmJs( +MaybeHandle<AsmWasmData> WasmEngine::SyncCompileTranslatedAsmJs( Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes, - Handle<Script> asm_js_script, - Vector<const byte> asm_js_offset_table_bytes) { + Vector<const byte> asm_js_offset_table_bytes, + Handle<HeapNumber> uses_bitset) { ModuleResult result = DecodeWasmModule(kAsmjsWasmFeatures, bytes.start(), bytes.end(), false, kAsmJsOrigin, isolate->counters(), allocator()); CHECK(!result.failed()); // Transfer ownership of the WasmModule to the {Managed<WasmModule>} generated - // in {CompileToModuleObject}. - return CompileToModuleObject(isolate, kAsmjsWasmFeatures, thrower, - std::move(result.val), bytes, asm_js_script, - asm_js_offset_table_bytes); + // in {CompileToNativeModule}. + Handle<FixedArray> export_wrappers; + std::unique_ptr<NativeModule> native_module = + CompileToNativeModule(isolate, kAsmjsWasmFeatures, thrower, + std::move(result).value(), bytes, &export_wrappers); + if (!native_module) return {}; + + // Create heap objects for asm.js offset table to be stored in the module + // object. + Handle<ByteArray> asm_js_offset_table = + isolate->factory()->NewByteArray(asm_js_offset_table_bytes.length()); + asm_js_offset_table->copy_in(0, asm_js_offset_table_bytes.start(), + asm_js_offset_table_bytes.length()); + + return AsmWasmData::New(isolate, std::move(native_module), export_wrappers, + asm_js_offset_table, uses_bitset); +} + +Handle<WasmModuleObject> WasmEngine::FinalizeTranslatedAsmJs( + Isolate* isolate, Handle<AsmWasmData> asm_wasm_data, + Handle<Script> script) { + std::shared_ptr<NativeModule> native_module = + asm_wasm_data->managed_native_module()->get(); + Handle<FixedArray> export_wrappers = + handle(asm_wasm_data->export_wrappers(), isolate); + size_t code_size_estimate = + wasm::WasmCodeManager::EstimateNativeModuleCodeSize( + native_module->module()); + + Handle<WasmModuleObject> module_object = + WasmModuleObject::New(isolate, std::move(native_module), script, + export_wrappers, code_size_estimate); + module_object->set_asm_js_offset_table(asm_wasm_data->asm_js_offset_table()); + return module_object; } MaybeHandle<WasmModuleObject> WasmEngine::SyncCompile( @@ -61,14 +94,40 @@ MaybeHandle<WasmModuleObject> WasmEngine::SyncCompile( DecodeWasmModule(enabled, bytes.start(), bytes.end(), false, kWasmOrigin, isolate->counters(), allocator()); if (result.failed()) { - thrower->CompileFailed("Wasm decoding failed", result); + thrower->CompileFailed("Wasm decoding failed", result.error()); return {}; } // Transfer ownership of the WasmModule to the {Managed<WasmModule>} generated // in {CompileToModuleObject}. - return CompileToModuleObject(isolate, enabled, thrower, std::move(result.val), - bytes, Handle<Script>(), Vector<const byte>()); + Handle<FixedArray> export_wrappers; + std::unique_ptr<NativeModule> native_module = + CompileToNativeModule(isolate, enabled, thrower, + std::move(result).value(), bytes, &export_wrappers); + if (!native_module) return {}; + + Handle<Script> script = + CreateWasmScript(isolate, bytes, native_module->module()->source_map_url); + size_t code_size_estimate = + wasm::WasmCodeManager::EstimateNativeModuleCodeSize( + native_module->module()); + + // Create the module object. + // TODO(clemensh): For the same module (same bytes / same hash), we should + // only have one WasmModuleObject. Otherwise, we might only set + // breakpoints on a (potentially empty) subset of the instances. + + // Create the compiled module object and populate with compiled functions + // and information needed at instantiation time. This object needs to be + // serializable. Instantiation may occur off a deserialized version of this + // object. + Handle<WasmModuleObject> module_object = + WasmModuleObject::New(isolate, std::move(native_module), script, + export_wrappers, code_size_estimate); + + // Finish the Wasm script now and make it public to the debugger. + isolate->debug()->OnAfterCompile(script); + return module_object; } MaybeHandle<WasmInstanceObject> WasmEngine::SyncInstantiate( @@ -170,43 +229,36 @@ std::shared_ptr<StreamingDecoder> WasmEngine::StartStreamingCompilation( return job->CreateStreamingDecoder(); } -bool WasmEngine::CompileFunction(Isolate* isolate, NativeModule* native_module, +void WasmEngine::CompileFunction(Isolate* isolate, NativeModule* native_module, uint32_t function_index, ExecutionTier tier) { - ErrorThrower thrower(isolate, "Manually requested tier up"); // Note we assume that "one-off" compilations can discard detected features. WasmFeatures detected = kNoWasmFeatures; - WasmCode* ret = WasmCompilationUnit::CompileWasmFunction( - isolate, native_module, &detected, &thrower, - GetModuleEnv(native_module->compilation_state()), + WasmCompilationUnit::CompileWasmFunction( + isolate, native_module, &detected, &native_module->module()->functions[function_index], tier); - return ret != nullptr; } std::shared_ptr<NativeModule> WasmEngine::ExportNativeModule( Handle<WasmModuleObject> module_object) { - return module_object->managed_native_module()->get(); + return module_object->shared_native_module(); } Handle<WasmModuleObject> WasmEngine::ImportNativeModule( Isolate* isolate, std::shared_ptr<NativeModule> shared_module) { - CHECK_EQ(code_manager(), shared_module->code_manager()); - Vector<const byte> wire_bytes = shared_module->wire_bytes(); + ModuleWireBytes wire_bytes(shared_module->wire_bytes()); const WasmModule* module = shared_module->module(); Handle<Script> script = CreateWasmScript(isolate, wire_bytes, module->source_map_url); - Handle<WasmModuleObject> module_object = - WasmModuleObject::New(isolate, std::move(shared_module), script); - - // TODO(6792): Wrappers below might be cloned using {Factory::CopyCode}. - // This requires unlocking the code space here. This should eventually be - // moved into the allocator. - CodeSpaceMemoryModificationScope modification_scope(isolate->heap()); - CompileJsToWasmWrappers(isolate, module_object); + size_t code_size = shared_module->committed_code_space(); + Handle<WasmModuleObject> module_object = WasmModuleObject::New( + isolate, std::move(shared_module), script, code_size); + CompileJsToWasmWrappers(isolate, module_object->native_module()->module(), + handle(module_object->export_wrappers(), isolate)); return module_object; } CompilationStatistics* WasmEngine::GetOrCreateTurboStatistics() { - base::LockGuard<base::Mutex> guard(&mutex_); + base::MutexGuard guard(&mutex_); if (compilation_stats_ == nullptr) { compilation_stats_.reset(new CompilationStatistics()); } @@ -214,7 +266,7 @@ CompilationStatistics* WasmEngine::GetOrCreateTurboStatistics() { } void WasmEngine::DumpAndResetTurboStatistics() { - base::LockGuard<base::Mutex> guard(&mutex_); + base::MutexGuard guard(&mutex_); if (compilation_stats_ != nullptr) { StdoutStream os; os << AsPrintableStatistics{*compilation_stats_.get(), false} << std::endl; @@ -223,7 +275,7 @@ void WasmEngine::DumpAndResetTurboStatistics() { } CodeTracer* WasmEngine::GetCodeTracer() { - base::LockGuard<base::Mutex> guard(&mutex_); + base::MutexGuard guard(&mutex_); if (code_tracer_ == nullptr) code_tracer_.reset(new CodeTracer(-1)); return code_tracer_.get(); } @@ -236,14 +288,14 @@ AsyncCompileJob* WasmEngine::CreateAsyncCompileJob( new AsyncCompileJob(isolate, enabled, std::move(bytes_copy), length, context, std::move(resolver)); // Pass ownership to the unique_ptr in {jobs_}. - base::LockGuard<base::Mutex> guard(&mutex_); + base::MutexGuard guard(&mutex_); jobs_[job] = std::unique_ptr<AsyncCompileJob>(job); return job; } std::unique_ptr<AsyncCompileJob> WasmEngine::RemoveCompileJob( AsyncCompileJob* job) { - base::LockGuard<base::Mutex> guard(&mutex_); + base::MutexGuard guard(&mutex_); auto item = jobs_.find(job); DCHECK(item != jobs_.end()); std::unique_ptr<AsyncCompileJob> result = std::move(item->second); @@ -252,7 +304,7 @@ std::unique_ptr<AsyncCompileJob> WasmEngine::RemoveCompileJob( } bool WasmEngine::HasRunningCompileJob(Isolate* isolate) { - base::LockGuard<base::Mutex> guard(&mutex_); + base::MutexGuard guard(&mutex_); DCHECK_EQ(1, isolates_.count(isolate)); for (auto& entry : jobs_) { if (entry.first->isolate() == isolate) return true; @@ -261,7 +313,7 @@ bool WasmEngine::HasRunningCompileJob(Isolate* isolate) { } void WasmEngine::DeleteCompileJobsOnIsolate(Isolate* isolate) { - base::LockGuard<base::Mutex> guard(&mutex_); + base::MutexGuard guard(&mutex_); DCHECK_EQ(1, isolates_.count(isolate)); for (auto it = jobs_.begin(); it != jobs_.end();) { if (it->first->isolate() == isolate) { @@ -273,51 +325,46 @@ void WasmEngine::DeleteCompileJobsOnIsolate(Isolate* isolate) { } void WasmEngine::AddIsolate(Isolate* isolate) { - base::LockGuard<base::Mutex> guard(&mutex_); + base::MutexGuard guard(&mutex_); DCHECK_EQ(0, isolates_.count(isolate)); isolates_.insert(isolate); } void WasmEngine::RemoveIsolate(Isolate* isolate) { - base::LockGuard<base::Mutex> guard(&mutex_); + base::MutexGuard guard(&mutex_); DCHECK_EQ(1, isolates_.count(isolate)); isolates_.erase(isolate); } namespace { -struct WasmEnginePointerConstructTrait final { - static void Construct(void* raw_ptr) { - auto engine_ptr = reinterpret_cast<std::shared_ptr<WasmEngine>*>(raw_ptr); - *engine_ptr = std::shared_ptr<WasmEngine>(); - } -}; - -// Holds the global shared pointer to the single {WasmEngine} that is intended -// to be shared among Isolates within the same process. The {LazyStaticInstance} -// here is required because {std::shared_ptr} has a non-trivial initializer. -base::LazyStaticInstance<std::shared_ptr<WasmEngine>, - WasmEnginePointerConstructTrait>::type - global_wasm_engine; +DEFINE_LAZY_LEAKY_OBJECT_GETTER(std::shared_ptr<WasmEngine>, + GetSharedWasmEngine); } // namespace // static void WasmEngine::InitializeOncePerProcess() { if (!FLAG_wasm_shared_engine) return; - global_wasm_engine.Pointer()->reset(new WasmEngine()); + *GetSharedWasmEngine() = std::make_shared<WasmEngine>(); } // static void WasmEngine::GlobalTearDown() { if (!FLAG_wasm_shared_engine) return; - global_wasm_engine.Pointer()->reset(); + GetSharedWasmEngine()->reset(); } // static std::shared_ptr<WasmEngine> WasmEngine::GetWasmEngine() { - if (FLAG_wasm_shared_engine) return global_wasm_engine.Get(); - return std::shared_ptr<WasmEngine>(new WasmEngine()); + if (FLAG_wasm_shared_engine) return *GetSharedWasmEngine(); + return std::make_shared<WasmEngine>(); +} + +// {max_mem_pages} is declared in wasm-limits.h. +uint32_t max_mem_pages() { + STATIC_ASSERT(kV8MaxWasmMemoryPages <= kMaxUInt32); + return std::min(uint32_t{kV8MaxWasmMemoryPages}, FLAG_wasm_max_mem_pages); } } // namespace wasm |