From 9716f689b8bc21f1ecd62358fdf259c0a8f067d9 Mon Sep 17 00:00:00 2001 From: Clemens Hammacher Date: Tue, 23 Oct 2018 13:43:07 +0200 Subject: [PATCH] [wasm] Do not store ModuleEnv Instead, create it when needed and pass it down to the actual compilation. This saves memory by making the WasmCompilationUnit smaller and will eventually allow us to implement the trap handler fallback correctly by using an updated ModuleEnv in background compilation and tier up. R=mstarzinger@chromium.org Bug: v8:5277, v8:8343 Change-Id: I0dc3a37fb88e54eb4822dc99d58ff024f4b2a367 Reviewed-on: https://chromium-review.googlesource.com/c/1293953 Commit-Queue: Clemens Hammacher Reviewed-by: Michael Starzinger Cr-Commit-Position: refs/heads/master@{#56896} --- src/compiler/wasm-compiler.cc | 28 +++--- src/compiler/wasm-compiler.h | 5 +- src/wasm/baseline/liftoff-compiler.cc | 8 +- src/wasm/baseline/liftoff-compiler.h | 7 +- src/wasm/compilation-environment.h | 4 +- src/wasm/function-compiler.cc | 34 +++---- src/wasm/function-compiler.h | 10 +- src/wasm/module-compiler.cc | 97 ++++++++----------- src/wasm/wasm-code-manager.cc | 21 ++-- src/wasm/wasm-code-manager.h | 8 +- src/wasm/wasm-engine.cc | 1 - src/wasm/wasm-objects.cc | 9 +- src/wasm/wasm-objects.h | 2 +- src/wasm/wasm-serialization.cc | 12 +-- test/cctest/compiler/test-multiple-return.cc | 6 +- .../wasm/test-wasm-import-wrapper-cache.cc | 7 +- test/cctest/wasm/test-wasm-shared-engine.cc | 1 - test/cctest/wasm/wasm-run-utils.cc | 12 +-- test/fuzzer/multi-return.cc | 6 +- .../wasm/wasm-code-manager-unittest.cc | 4 +- 20 files changed, 122 insertions(+), 160 deletions(-) diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc index c5924f61ec..030cefe9f1 100644 --- a/src/compiler/wasm-compiler.cc +++ b/src/compiler/wasm-compiler.cc @@ -5144,8 +5144,8 @@ TurbofanWasmCompilationUnit::TurbofanWasmCompilationUnit( TurbofanWasmCompilationUnit::~TurbofanWasmCompilationUnit() = default; SourcePositionTable* TurbofanWasmCompilationUnit::BuildGraphForWasmFunction( - wasm::WasmFeatures* detected, double* decode_ms, MachineGraph* mcgraph, - NodeOriginTable* node_origins) { + wasm::ModuleEnv* env, wasm::WasmFeatures* detected, double* decode_ms, + MachineGraph* mcgraph, NodeOriginTable* node_origins) { base::ElapsedTimer decode_timer; if (FLAG_trace_wasm_decode_time) { decode_timer.Start(); @@ -5154,12 +5154,12 @@ SourcePositionTable* TurbofanWasmCompilationUnit::BuildGraphForWasmFunction( // Create a TF graph during decoding. SourcePositionTable* source_position_table = new (mcgraph->zone()) SourcePositionTable(mcgraph->graph()); - WasmGraphBuilder builder(wasm_unit_->env_, mcgraph->zone(), mcgraph, + WasmGraphBuilder builder(env, mcgraph->zone(), mcgraph, wasm_unit_->func_body_.sig, source_position_table); wasm::VoidResult graph_construction_result = wasm::BuildTFGraph( wasm_unit_->wasm_engine_->allocator(), - wasm_unit_->native_module_->enabled_features(), wasm_unit_->env_->module, - &builder, detected, wasm_unit_->func_body_, node_origins); + wasm_unit_->native_module_->enabled_features(), env->module, &builder, + detected, wasm_unit_->func_body_, node_origins); if (graph_construction_result.failed()) { if (FLAG_trace_wasm_compiler) { StdoutStream{} << "Compilation failed: " @@ -5172,7 +5172,7 @@ SourcePositionTable* TurbofanWasmCompilationUnit::BuildGraphForWasmFunction( builder.LowerInt64(); if (builder.has_simd() && - (!CpuFeatures::SupportsWasmSimd128() || wasm_unit_->env_->lower_simd)) { + (!CpuFeatures::SupportsWasmSimd128() || env->lower_simd)) { SimdScalarLowering( mcgraph, CreateMachineSignature(mcgraph->zone(), wasm_unit_->func_body_.sig)) @@ -5182,8 +5182,7 @@ SourcePositionTable* TurbofanWasmCompilationUnit::BuildGraphForWasmFunction( if (wasm_unit_->func_index_ >= FLAG_trace_wasm_ast_start && wasm_unit_->func_index_ < FLAG_trace_wasm_ast_end) { PrintRawWasmCode(wasm_unit_->wasm_engine_->allocator(), - wasm_unit_->func_body_, wasm_unit_->env_->module, - wasm::kPrintLocals); + wasm_unit_->func_body_, env->module, wasm::kPrintLocals); } if (FLAG_trace_wasm_decode_time) { *decode_ms = decode_timer.Elapsed().InMillisecondsF(); @@ -5207,7 +5206,7 @@ Vector GetDebugName(Zone* zone, int index) { } // namespace void TurbofanWasmCompilationUnit::ExecuteCompilation( - wasm::WasmFeatures* detected) { + wasm::ModuleEnv* env, wasm::WasmFeatures* detected) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "ExecuteTurbofanCompilation"); double decode_ms = 0; @@ -5223,7 +5222,7 @@ void TurbofanWasmCompilationUnit::ExecuteCompilation( OptimizedCompilationInfo info(GetDebugName(&zone, wasm_unit_->func_index_), &zone, Code::WASM_FUNCTION); - if (wasm_unit_->env_->runtime_exception_support) { + if (env->runtime_exception_support) { info.SetWasmRuntimeExceptionSupport(); } @@ -5236,8 +5235,8 @@ void TurbofanWasmCompilationUnit::ExecuteCompilation( ? new (&zone) NodeOriginTable(mcgraph->graph()) : nullptr; - SourcePositionTable* source_positions = - BuildGraphForWasmFunction(detected, &decode_ms, mcgraph, node_origins); + SourcePositionTable* source_positions = BuildGraphForWasmFunction( + env, detected, &decode_ms, mcgraph, node_origins); if (wasm_unit_->failed()) return; @@ -5261,9 +5260,8 @@ void TurbofanWasmCompilationUnit::ExecuteCompilation( std::unique_ptr job(Pipeline::NewWasmCompilationJob( &info, wasm_unit_->wasm_engine_, mcgraph, call_descriptor, source_positions, node_origins, wasm_unit_->func_body_, - const_cast(wasm_unit_->env_->module), - wasm_unit_->native_module_, wasm_unit_->func_index_, - wasm_unit_->env_->module->origin)); + const_cast(env->module), wasm_unit_->native_module_, + wasm_unit_->func_index_, env->module->origin)); if (job->ExecuteJob() == CompilationJob::SUCCEEDED) { wasm_unit_->SetResult(info.wasm_code()); } diff --git a/src/compiler/wasm-compiler.h b/src/compiler/wasm-compiler.h index a52086d339..b5a448d606 100644 --- a/src/compiler/wasm-compiler.h +++ b/src/compiler/wasm-compiler.h @@ -50,12 +50,13 @@ class TurbofanWasmCompilationUnit { explicit TurbofanWasmCompilationUnit(wasm::WasmCompilationUnit* wasm_unit); ~TurbofanWasmCompilationUnit(); - SourcePositionTable* BuildGraphForWasmFunction(wasm::WasmFeatures* detected, + SourcePositionTable* BuildGraphForWasmFunction(wasm::ModuleEnv* env, + wasm::WasmFeatures* detected, double* decode_ms, MachineGraph* mcgraph, NodeOriginTable* node_origins); - void ExecuteCompilation(wasm::WasmFeatures* detected); + void ExecuteCompilation(wasm::ModuleEnv* env, wasm::WasmFeatures* detected); private: wasm::WasmCompilationUnit* const wasm_unit_; diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc index 2719a90382..8089ca04d1 100644 --- a/src/wasm/baseline/liftoff-compiler.cc +++ b/src/wasm/baseline/liftoff-compiler.cc @@ -1872,7 +1872,8 @@ class LiftoffCompiler { } // namespace -bool LiftoffCompilationUnit::ExecuteCompilation(WasmFeatures* detected) { +bool LiftoffCompilationUnit::ExecuteCompilation(ModuleEnv* env, + WasmFeatures* detected) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "ExecuteLiftoffCompilation"); base::ElapsedTimer compile_timer; @@ -1881,15 +1882,14 @@ bool LiftoffCompilationUnit::ExecuteCompilation(WasmFeatures* detected) { } Zone zone(wasm_unit_->wasm_engine_->allocator(), "LiftoffCompilationZone"); - const WasmModule* module = - wasm_unit_->env_ ? wasm_unit_->env_->module : nullptr; + const WasmModule* module = env ? env->module : nullptr; auto call_descriptor = compiler::GetWasmCallDescriptor(&zone, wasm_unit_->func_body_.sig); base::Optional liftoff_compile_time_scope( base::in_place, wasm_unit_->counters_->liftoff_compile_time()); WasmFullDecoder decoder( &zone, module, wasm_unit_->native_module_->enabled_features(), detected, - wasm_unit_->func_body_, call_descriptor, wasm_unit_->env_, &zone); + wasm_unit_->func_body_, call_descriptor, env, &zone); decoder.Decode(); liftoff_compile_time_scope.reset(); LiftoffCompiler* compiler = &decoder.interface(); diff --git a/src/wasm/baseline/liftoff-compiler.h b/src/wasm/baseline/liftoff-compiler.h index 1330633f60..da019fc773 100644 --- a/src/wasm/baseline/liftoff-compiler.h +++ b/src/wasm/baseline/liftoff-compiler.h @@ -11,17 +11,16 @@ namespace v8 { namespace internal { namespace wasm { -struct WasmFeatures; -class ErrorThrower; -class WasmCode; +struct ModuleEnv; class WasmCompilationUnit; +struct WasmFeatures; class LiftoffCompilationUnit final { public: explicit LiftoffCompilationUnit(WasmCompilationUnit* wasm_unit) : wasm_unit_(wasm_unit) {} - bool ExecuteCompilation(WasmFeatures* detected); + bool ExecuteCompilation(ModuleEnv*, WasmFeatures* detected); private: WasmCompilationUnit* const wasm_unit_; diff --git a/src/wasm/compilation-environment.h b/src/wasm/compilation-environment.h index 7ea4c3210c..bc0a139003 100644 --- a/src/wasm/compilation-environment.h +++ b/src/wasm/compilation-environment.h @@ -80,9 +80,7 @@ struct CompilationStateDeleter { // Wrapper to create a CompilationState exists in order to avoid having // the CompilationState in the header file. std::unique_ptr NewCompilationState( - Isolate*, const ModuleEnv&); - -ModuleEnv* GetModuleEnv(CompilationState* compilation_state); + Isolate*, NativeModule*); } // namespace wasm } // namespace internal diff --git a/src/wasm/function-compiler.cc b/src/wasm/function-compiler.cc index fc5cc817fe..531f14d01f 100644 --- a/src/wasm/function-compiler.cc +++ b/src/wasm/function-compiler.cc @@ -36,23 +36,22 @@ ExecutionTier WasmCompilationUnit::GetDefaultExecutionTier() { } WasmCompilationUnit::WasmCompilationUnit(WasmEngine* wasm_engine, - ModuleEnv* env, NativeModule* native_module, FunctionBody body, int index, Counters* counters, ExecutionTier mode) - : env_(env), - wasm_engine_(wasm_engine), + : wasm_engine_(wasm_engine), func_body_(body), counters_(counters), func_index_(index), native_module_(native_module), mode_(mode) { - DCHECK_GE(index, env->module->num_imported_functions); - DCHECK_LT(index, env->module->functions.size()); + const WasmModule* module = native_module->module(); + DCHECK_GE(index, module->num_imported_functions); + DCHECK_LT(index, module->functions.size()); // Always disable Liftoff for asm.js, for two reasons: // 1) asm-specific opcodes are not implemented, and // 2) tier-up does not work with lazy compilation. - if (env->module->origin == kAsmJsOrigin) mode = ExecutionTier::kOptimized; + if (module->origin == kAsmJsOrigin) mode = ExecutionTier::kOptimized; if (V8_UNLIKELY(FLAG_wasm_tier_mask_for_testing) && index < 32 && (FLAG_wasm_tier_mask_for_testing & (1 << index))) { mode = ExecutionTier::kOptimized; @@ -64,12 +63,14 @@ WasmCompilationUnit::WasmCompilationUnit(WasmEngine* wasm_engine, // {TurbofanWasmCompilationUnit} can be opaque in the header file. WasmCompilationUnit::~WasmCompilationUnit() = default; -void WasmCompilationUnit::ExecuteCompilation(WasmFeatures* detected) { - auto size_histogram = SELECT_WASM_COUNTER(counters_, env_->module->origin, - wasm, function_size_bytes); +void WasmCompilationUnit::ExecuteCompilation(ModuleEnv* env, + WasmFeatures* detected) { + const WasmModule* module = native_module_->module(); + auto size_histogram = + SELECT_WASM_COUNTER(counters_, module->origin, wasm, function_size_bytes); size_histogram->AddSample( static_cast(func_body_.end - func_body_.start)); - auto timed_histogram = SELECT_WASM_COUNTER(counters_, env_->module->origin, + auto timed_histogram = SELECT_WASM_COUNTER(counters_, module->origin, wasm_compile, function_time); TimedHistogramScope wasm_compile_function_time_scope(timed_histogram); @@ -80,12 +81,12 @@ void WasmCompilationUnit::ExecuteCompilation(WasmFeatures* detected) { switch (mode_) { case ExecutionTier::kBaseline: - if (liftoff_unit_->ExecuteCompilation(detected)) break; + if (liftoff_unit_->ExecuteCompilation(env, detected)) break; // Otherwise, fall back to turbofan. SwitchMode(ExecutionTier::kOptimized); V8_FALLTHROUGH; case ExecutionTier::kOptimized: - turbofan_unit_->ExecuteCompilation(detected); + turbofan_unit_->ExecuteCompilation(env, detected); break; case ExecutionTier::kInterpreter: UNREACHABLE(); // TODO(titzer): compile interpreter entry stub. @@ -136,17 +137,16 @@ void WasmCompilationUnit::SwitchMode(ExecutionTier new_mode) { // static WasmCode* WasmCompilationUnit::CompileWasmFunction( Isolate* isolate, NativeModule* native_module, WasmFeatures* detected, - ErrorThrower* thrower, ModuleEnv* env, const WasmFunction* function, - ExecutionTier mode) { + ErrorThrower* thrower, const WasmFunction* function, ExecutionTier mode) { ModuleWireBytes wire_bytes(native_module->wire_bytes()); FunctionBody function_body{function->sig, function->code.offset(), wire_bytes.start() + function->code.offset(), wire_bytes.start() + function->code.end_offset()}; - WasmCompilationUnit unit(isolate->wasm_engine(), env, native_module, - function_body, + WasmCompilationUnit unit(isolate->wasm_engine(), native_module, function_body, function->func_index, isolate->counters(), mode); - unit.ExecuteCompilation(detected); + ModuleEnv env = native_module->CreateModuleEnv(); + unit.ExecuteCompilation(&env, detected); if (unit.failed()) { unit.ReportError(thrower); return nullptr; diff --git a/src/wasm/function-compiler.h b/src/wasm/function-compiler.h index 8f13bc2d3e..fe04440881 100644 --- a/src/wasm/function-compiler.h +++ b/src/wasm/function-compiler.h @@ -37,13 +37,12 @@ class WasmCompilationUnit final { // typically means to hold a std::shared_ptr). // If used exclusively from a foreground thread, Isolate::counters() may be // used by callers to pass Counters. - WasmCompilationUnit(WasmEngine* wasm_engine, ModuleEnv*, NativeModule*, - FunctionBody, int index, Counters*, - ExecutionTier = GetDefaultExecutionTier()); + WasmCompilationUnit(WasmEngine*, NativeModule*, FunctionBody, int index, + Counters*, ExecutionTier = GetDefaultExecutionTier()); ~WasmCompilationUnit(); - void ExecuteCompilation(WasmFeatures* detected); + void ExecuteCompilation(ModuleEnv*, WasmFeatures* detected); NativeModule* native_module() const { return native_module_; } ExecutionTier mode() const { return mode_; } @@ -58,14 +57,13 @@ class WasmCompilationUnit final { static WasmCode* CompileWasmFunction( Isolate* isolate, NativeModule* native_module, WasmFeatures* detected, - ErrorThrower* thrower, ModuleEnv* env, const WasmFunction* function, + ErrorThrower* thrower, const WasmFunction* function, ExecutionTier = GetDefaultExecutionTier()); private: friend class LiftoffCompilationUnit; friend class compiler::TurbofanWasmCompilationUnit; - ModuleEnv* env_; WasmEngine* wasm_engine_; FunctionBody func_body_; Counters* counters_; diff --git a/src/wasm/module-compiler.cc b/src/wasm/module-compiler.cc index 36b86298a8..730215997a 100644 --- a/src/wasm/module-compiler.cc +++ b/src/wasm/module-compiler.cc @@ -65,7 +65,7 @@ enum class CompileMode : uint8_t { kRegular, kTiering }; // compilation of functions. class CompilationState { public: - CompilationState(internal::Isolate*, const ModuleEnv&); + CompilationState(internal::Isolate*, NativeModule*); ~CompilationState(); // Set the number of compilations unit expected to be executed. Needs to be @@ -115,7 +115,6 @@ class CompilationState { WasmEngine* wasm_engine() const { return wasm_engine_; } CompileMode compile_mode() const { return compile_mode_; } - ModuleEnv* module_env() { return &module_env_; } WasmFeatures* detected_features() { return &detected_features_; } private: @@ -130,8 +129,7 @@ class CompilationState { // can be shared across multiple Isolates. Isolate* const isolate_; WasmEngine* const wasm_engine_; - // TODO(clemensh): Remove ModuleEnv, generate it when needed. - ModuleEnv module_env_; + NativeModule* const native_module_; const CompileMode compile_mode_; bool baseline_compilation_finished_ = false; @@ -347,21 +345,20 @@ WasmCode* LazyCompileFunction(Isolate* isolate, NativeModule* native_module, compilation_timer.Start(); - ModuleEnv* module_env = native_module->compilation_state()->module_env(); - TRACE_LAZY("Compiling wasm-function#%d.\n", func_index); const uint8_t* module_start = native_module->wire_bytes().start(); - const WasmFunction* func = &module_env->module->functions[func_index]; + const WasmFunction* func = &native_module->module()->functions[func_index]; FunctionBody body{func->sig, func->code.offset(), module_start + func->code.offset(), module_start + func->code.end_offset()}; - WasmCompilationUnit unit(isolate->wasm_engine(), module_env, native_module, - body, func_index, isolate->counters()); + WasmCompilationUnit unit(isolate->wasm_engine(), native_module, body, + func_index, isolate->counters()); + ModuleEnv env = native_module->CreateModuleEnv(); unit.ExecuteCompilation( - native_module->compilation_state()->detected_features()); + &env, native_module->compilation_state()->detected_features()); // If there is a pending error, something really went wrong. The module was // verified before starting execution with lazy compilation. @@ -449,8 +446,7 @@ class CompilationUnitBuilder { Vector bytes, ExecutionTier mode) { return base::make_unique( - compilation_state_->wasm_engine(), compilation_state_->module_env(), - native_module_, + compilation_state_->wasm_engine(), native_module_, FunctionBody{function->sig, buffer_offset, bytes.begin(), bytes.end()}, function->func_index, compilation_state_->isolate()->async_counters().get(), mode); @@ -489,20 +485,12 @@ double MonotonicallyIncreasingTimeInMs() { base::Time::kMillisecondsPerSecond; } -ModuleEnv CreateDefaultModuleEnv(const WasmModule* module, - bool allow_trap_handler = true) { - UseTrapHandler use_trap_handler = - trap_handler::IsTrapHandlerEnabled() && allow_trap_handler - ? kUseTrapHandler - : kNoTrapHandler; - return ModuleEnv(module, use_trap_handler, kRuntimeExceptionSupport); -} - // Run by each compilation task and by the main thread (i.e. in both // foreground and background threads). The no_finisher_callback is called // within the result_mutex_ lock when no finishing task is running, i.e. when // the finisher_is_running_ flag is not set. -bool FetchAndExecuteCompilationUnit(CompilationState* compilation_state, +bool FetchAndExecuteCompilationUnit(ModuleEnv* env, + CompilationState* compilation_state, WasmFeatures* detected) { DisallowHeapAccess no_heap_access; @@ -516,7 +504,7 @@ bool FetchAndExecuteCompilationUnit(CompilationState* compilation_state, // later as soon as Liftoff can compile any function. Then, we can directly // access {unit->mode()} within {ScheduleUnitForFinishing()}. ExecutionTier mode = unit->mode(); - unit->ExecuteCompilation(detected); + unit->ExecuteCompilation(env, detected); compilation_state->ScheduleUnitForFinishing(std::move(unit), mode); return true; @@ -615,9 +603,10 @@ void CompileInParallel(Isolate* isolate, NativeModule* native_module, // The foreground task bypasses waiting on memory threshold, because // its results will immediately be converted to code (below). WasmFeatures detected_features; - while ( - FetchAndExecuteCompilationUnit(compilation_state, &detected_features) && - !compilation_state->baseline_compilation_finished()) { + ModuleEnv env = native_module->CreateModuleEnv(); + while (FetchAndExecuteCompilationUnit(&env, compilation_state, + &detected_features) && + !compilation_state->baseline_compilation_finished()) { // 2.b) If {baseline_finish_units_} contains a compilation unit, the main // thread dequeues it and finishes the compilation unit. Compilation // units are finished concurrently to the background threads to save @@ -652,11 +641,11 @@ void CompileInParallel(Isolate* isolate, NativeModule* native_module, } void CompileSequentially(Isolate* isolate, NativeModule* native_module, - ModuleEnv* module_env, ErrorThrower* thrower) { + ErrorThrower* thrower) { DCHECK(!thrower->error()); ModuleWireBytes wire_bytes(native_module->wire_bytes()); - const WasmModule* module = module_env->module; + const WasmModule* module = native_module->module(); WasmFeatures detected = kNoWasmFeatures; for (uint32_t i = 0; i < module->functions.size(); ++i) { const WasmFunction& func = module->functions[i]; @@ -664,7 +653,7 @@ void CompileSequentially(Isolate* isolate, NativeModule* native_module, // Compile the function. WasmCode* code = WasmCompilationUnit::CompileWasmFunction( - isolate, native_module, &detected, thrower, module_env, &func); + isolate, native_module, &detected, thrower, &func); if (code == nullptr) { TruncatedUserString<> name(wire_bytes.GetNameOrNull(&func, module)); thrower->CompileError("Compilation of #%d:%.*s failed.", i, name.length(), @@ -713,7 +702,7 @@ void ValidateSequentially(Isolate* isolate, NativeModule* native_module, void CompileNativeModule(Isolate* isolate, ErrorThrower* thrower, Handle module_object, - const WasmModule* wasm_module, ModuleEnv* env) { + const WasmModule* wasm_module) { NativeModule* const native_module = module_object->native_module(); ModuleWireBytes wire_bytes(native_module->wire_bytes()); @@ -741,7 +730,7 @@ void CompileNativeModule(Isolate* isolate, ErrorThrower* thrower, if (compile_parallel) { CompileInParallel(isolate, native_module, module_object, thrower); } else { - CompileSequentially(isolate, native_module, env, thrower); + CompileSequentially(isolate, native_module, thrower); } if (thrower->error()) return; } @@ -829,25 +818,27 @@ class FinishCompileTask : public CancelableTask { // The runnable task that performs compilations in the background. class BackgroundCompileTask : public CancelableTask { public: - explicit BackgroundCompileTask(CompilationState* compilation_state, + explicit BackgroundCompileTask(NativeModule* native_module, CancelableTaskManager* task_manager) - : CancelableTask(task_manager), compilation_state_(compilation_state) {} + : CancelableTask(task_manager), native_module_(native_module) {} void RunInternal() override { TRACE_COMPILE("(3b) Compiling...\n"); // The number of currently running background tasks is reduced in // {OnBackgroundTaskStopped}. - while (!compilation_state_->failed()) { - if (!FetchAndExecuteCompilationUnit(compilation_state_, + ModuleEnv env = native_module_->CreateModuleEnv(); + auto* compilation_state = native_module_->compilation_state(); + while (!compilation_state->failed()) { + if (!FetchAndExecuteCompilationUnit(&env, compilation_state, &detected_features_)) { break; } } - compilation_state_->OnBackgroundTaskStopped(detected_features_); + compilation_state->OnBackgroundTaskStopped(detected_features_); } private: - CompilationState* compilation_state_; + NativeModule* const native_module_; WasmFeatures detected_features_ = kNoWasmFeatures; }; } // namespace @@ -893,16 +884,15 @@ MaybeHandle CompileToModuleObject( // 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. - ModuleEnv env = CreateDefaultModuleEnv(wasm_module); // 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 module_object = WasmModuleObject::New( - isolate, enabled, std::move(module), env, std::move(wire_bytes_copy), - script, asm_js_offset_table); - CompileNativeModule(isolate, thrower, module_object, wasm_module, &env); + isolate, enabled, std::move(module), std::move(wire_bytes_copy), script, + asm_js_offset_table); + CompileNativeModule(isolate, thrower, module_object, wasm_module); if (thrower->error()) return {}; // Compile JS->wasm wrappers for exported functions. @@ -1013,14 +1003,15 @@ MaybeHandle InstanceBuilder::Build() { TRACE("Recompiling module without bounds checks\n"); constexpr bool allow_trap_handler = false; - ModuleEnv env = CreateDefaultModuleEnv(module_, allow_trap_handler); + // TODO(wasm): Fix this before enabling the trap handler fallback. + USE(allow_trap_handler); // Disable trap handlers on this native module. NativeModule* native_module = module_object_->native_module(); native_module->DisableTrapHandler(); // Recompile all functions in this native module. ErrorThrower thrower(isolate_, "recompile"); - CompileNativeModule(isolate_, &thrower, module_object_, module_, &env); + CompileNativeModule(isolate_, &thrower, module_object_, module_); if (thrower.error()) { return {}; } @@ -2483,7 +2474,6 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep { module->source_map_url); Handle asm_js_offset_table; - ModuleEnv env = CreateDefaultModuleEnv(module); // TODO(wasm): Improve efficiency of storing module wire bytes. Only store // relevant sections, not function bodies @@ -2494,7 +2484,7 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep { // breakpoints on a (potentially empty) subset of the instances. // Create the module object. job_->module_object_ = WasmModuleObject::New( - job_->isolate_, job_->enabled_features_, module_, env, + job_->isolate_, job_->enabled_features_, module_, {std::move(job_->bytes_copy_), job_->wire_bytes_.length()}, script, asm_js_offset_table); job_->native_module_ = job_->module_object_->native_module(); @@ -2850,21 +2840,18 @@ void CompilationStateDeleter::operator()( } std::unique_ptr NewCompilationState( - Isolate* isolate, const ModuleEnv& env) { + Isolate* isolate, NativeModule* native_module) { return std::unique_ptr( - new CompilationState(isolate, env)); -} - -ModuleEnv* GetModuleEnv(CompilationState* compilation_state) { - return compilation_state->module_env(); + new CompilationState(isolate, native_module)); } CompilationState::CompilationState(internal::Isolate* isolate, - const ModuleEnv& env) + NativeModule* native_module) : isolate_(isolate), wasm_engine_(isolate->wasm_engine()), - module_env_(env), - compile_mode_(FLAG_wasm_tier_up && env.module->origin == kWasmOrigin + native_module_(native_module), + compile_mode_(FLAG_wasm_tier_up && + native_module->module()->origin == kWasmOrigin ? CompileMode::kTiering : CompileMode::kRegular), max_background_tasks_(std::max( @@ -3042,7 +3029,7 @@ void CompilationState::RestartBackgroundTasks(size_t max) { for (; num_restart > 0; --num_restart) { auto task = base::make_unique( - this, &background_task_manager_); + native_module_, &background_task_manager_); // If --wasm-num-compilation-tasks=0 is passed, do only spawn foreground // tasks. This is used to make timing deterministic. diff --git a/src/wasm/wasm-code-manager.cc b/src/wasm/wasm-code-manager.cc index 4790512274..529caec737 100644 --- a/src/wasm/wasm-code-manager.cc +++ b/src/wasm/wasm-code-manager.cc @@ -150,9 +150,8 @@ void WasmCode::LogCode(Isolate* isolate) const { ModuleWireBytes wire_bytes(native_module()->wire_bytes()); // TODO(herhut): Allow to log code without on-heap round-trip of the name. - ModuleEnv* module_env = GetModuleEnv(native_module()->compilation_state()); WireBytesRef name_ref = - module_env->module->LookupFunctionName(wire_bytes, index()); + native_module()->module()->LookupFunctionName(wire_bytes, index()); WasmName name_vec = wire_bytes.GetNameOrNull(name_ref); if (!name_vec.is_empty()) { MaybeHandle maybe_name = isolate->factory()->NewStringFromUtf8( @@ -339,18 +338,17 @@ WasmCode::~WasmCode() { NativeModule::NativeModule(Isolate* isolate, const WasmFeatures& enabled, bool can_request_more, VirtualMemory code_space, WasmCodeManager* code_manager, - std::shared_ptr module, - const ModuleEnv& env) + std::shared_ptr module) : enabled_features_(enabled), module_(std::move(module)), - compilation_state_(NewCompilationState(isolate, env)), + compilation_state_(NewCompilationState(isolate, this)), import_wrapper_cache_(std::unique_ptr( new WasmImportWrapperCache(this))), free_code_space_(code_space.region()), wasm_code_manager_(code_manager), can_request_more_memory_(can_request_more), - use_trap_handler_(env.use_trap_handler) { - DCHECK_EQ(module_.get(), env.module); + use_trap_handler_(trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler + : kNoTrapHandler) { DCHECK_NOT_NULL(module_); owned_code_space_.emplace_back(std::move(code_space)); owned_code_.reserve(num_functions()); @@ -386,6 +384,10 @@ void NativeModule::LogWasmCodes(Isolate* isolate) { } } +ModuleEnv NativeModule::CreateModuleEnv() const { + return {module(), use_trap_handler_, kRuntimeExceptionSupport}; +} + WasmCode* NativeModule::AddOwnedCode( uint32_t index, Vector instructions, uint32_t stack_slots, size_t safepoint_table_offset, size_t handler_table_offset, @@ -932,8 +934,7 @@ bool WasmCodeManager::ShouldForceCriticalMemoryPressureNotification() { std::unique_ptr WasmCodeManager::NewNativeModule( Isolate* isolate, const WasmFeatures& enabled, size_t memory_estimate, - bool can_request_more, std::shared_ptr module, - const ModuleEnv& env) { + bool can_request_more, std::shared_ptr module) { if (ShouldForceCriticalMemoryPressureNotification()) { (reinterpret_cast(isolate)) ->MemoryPressureNotification(MemoryPressureLevel::kCritical); @@ -963,7 +964,7 @@ std::unique_ptr WasmCodeManager::NewNativeModule( Address end = mem.end(); std::unique_ptr ret( new NativeModule(isolate, enabled, can_request_more, std::move(mem), this, - std::move(module), env)); + std::move(module))); TRACE_HEAP("New NativeModule %p: Mem: %" PRIuPTR ",+%zu\n", this, start, size); AssignRangesAndAddModule(start, end, ret.get()); diff --git a/src/wasm/wasm-code-manager.h b/src/wasm/wasm-code-manager.h index 9e552eea8c..205d1f46ac 100644 --- a/src/wasm/wasm-code-manager.h +++ b/src/wasm/wasm-code-manager.h @@ -314,6 +314,10 @@ class V8_EXPORT_PRIVATE NativeModule final { CompilationState* compilation_state() { return compilation_state_.get(); } + // Create a {ModuleEnv} object for compilation. Only valid as long as this + // {NativeModule} is alive. + ModuleEnv CreateModuleEnv() const; + uint32_t num_functions() const { return module_->num_declared_functions + module_->num_imported_functions; } @@ -349,7 +353,7 @@ class V8_EXPORT_PRIVATE NativeModule final { NativeModule(Isolate* isolate, const WasmFeatures& enabled_features, bool can_request_more, VirtualMemory code_space, WasmCodeManager* code_manager, - std::shared_ptr module, const ModuleEnv& env); + std::shared_ptr module); WasmCode* AddAnonymousCode(Handle, WasmCode::Kind kind, const char* name = nullptr); @@ -473,7 +477,7 @@ class V8_EXPORT_PRIVATE WasmCodeManager final { std::unique_ptr NewNativeModule( Isolate* isolate, const WasmFeatures& enabled_features, size_t memory_estimate, bool can_request_more, - std::shared_ptr module, const ModuleEnv& env); + std::shared_ptr module); NativeModule* LookupNativeModule(Address pc) const; WasmCode* LookupCode(Address pc) const; diff --git a/src/wasm/wasm-engine.cc b/src/wasm/wasm-engine.cc index 93676636c0..1a4dea34e3 100644 --- a/src/wasm/wasm-engine.cc +++ b/src/wasm/wasm-engine.cc @@ -178,7 +178,6 @@ bool WasmEngine::CompileFunction(Isolate* isolate, NativeModule* native_module, WasmFeatures detected = kNoWasmFeatures; WasmCode* ret = WasmCompilationUnit::CompileWasmFunction( isolate, native_module, &detected, &thrower, - GetModuleEnv(native_module->compilation_state()), &native_module->module()->functions[function_index], tier); return ret != nullptr; } diff --git a/src/wasm/wasm-objects.cc b/src/wasm/wasm-objects.cc index 3fd34933f4..a5e711def6 100644 --- a/src/wasm/wasm-objects.cc +++ b/src/wasm/wasm-objects.cc @@ -175,19 +175,16 @@ enum DispatchTableElements : int { // static Handle WasmModuleObject::New( Isolate* isolate, const wasm::WasmFeatures& enabled, - std::shared_ptr shared_module, wasm::ModuleEnv& env, + std::shared_ptr shared_module, OwnedVector wire_bytes, Handle