From 5578195db3c1f66afcca53ec7c66845f7572f7ba Mon Sep 17 00:00:00 2001 From: Andreas Haas Date: Wed, 6 Oct 2021 13:18:10 +0200 Subject: [PATCH] [wasm] Load --wasm_dynamic_tiering from the context WebAssembly dynamic tiering should be tested with an origin trial. For the origin trial the feature flag value has to be loaded from blink. This CL stores the value of the --wasm-dynamic-tiering flag in the compilation state, from where it gets passed forward to all uses of the flag. The flag value gets loaded from blink when a new NativeModule is created. R=clemensb@chromium.org Bug: v8:12281 Change-Id: Ia26355a665b7dfcdb47144863c1bec296774abb2 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3204963 Commit-Queue: Andreas Haas Reviewed-by: Clemens Backes Reviewed-by: Adam Klein Cr-Commit-Position: refs/heads/main@{#77256} --- include/v8-callbacks.h | 3 ++ include/v8-isolate.h | 3 ++ src/api/api.cc | 4 ++ src/compiler/wasm-compiler.cc | 2 +- src/execution/isolate.cc | 14 ++++++ src/execution/isolate.h | 3 ++ src/wasm/baseline/liftoff-compiler.cc | 2 +- src/wasm/compilation-environment.h | 15 +++++-- src/wasm/module-compiler.cc | 61 +++++++++++++++++---------- src/wasm/wasm-code-manager.cc | 16 ++++--- src/wasm/wasm-code-manager.h | 7 ++- test/cctest/wasm/wasm-run-utils.cc | 3 +- 12 files changed, 97 insertions(+), 36 deletions(-) diff --git a/include/v8-callbacks.h b/include/v8-callbacks.h index f424a24d8b..870df6a821 100644 --- a/include/v8-callbacks.h +++ b/include/v8-callbacks.h @@ -308,6 +308,9 @@ using WasmSimdEnabledCallback = bool (*)(Local context); // --- Callback for checking if WebAssembly exceptions are enabled --- using WasmExceptionsEnabledCallback = bool (*)(Local context); +// --- Callback for checking if WebAssembly dynamic tiering is enabled --- +using WasmDynamicTieringEnabledCallback = bool (*)(Local context); + // --- Callback for checking if the SharedArrayBuffer constructor is enabled --- using SharedArrayBufferConstructorEnabledCallback = bool (*)(Local context); diff --git a/include/v8-isolate.h b/include/v8-isolate.h index dc4af456b5..39276b34a9 100644 --- a/include/v8-isolate.h +++ b/include/v8-isolate.h @@ -1482,6 +1482,9 @@ class V8_EXPORT Isolate { void SetWasmExceptionsEnabledCallback(WasmExceptionsEnabledCallback callback); + void SetWasmDynamicTieringEnabledCallback( + WasmDynamicTieringEnabledCallback callback); + void SetSharedArrayBufferConstructorEnabledCallback( SharedArrayBufferConstructorEnabledCallback callback); diff --git a/src/api/api.cc b/src/api/api.cc index 851c22cc73..f79d0482ed 100644 --- a/src/api/api.cc +++ b/src/api/api.cc @@ -9178,6 +9178,10 @@ CALLBACK_SETTER(WasmSimdEnabledCallback, WasmSimdEnabledCallback, CALLBACK_SETTER(WasmExceptionsEnabledCallback, WasmExceptionsEnabledCallback, wasm_exceptions_enabled_callback) +CALLBACK_SETTER(WasmDynamicTieringEnabledCallback, + WasmDynamicTieringEnabledCallback, + wasm_dynamic_tiering_enabled_callback) + CALLBACK_SETTER(SharedArrayBufferConstructorEnabledCallback, SharedArrayBufferConstructorEnabledCallback, sharedarraybuffer_constructor_enabled_callback) diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc index 2d0f72abd7..8446640bfc 100644 --- a/src/compiler/wasm-compiler.cc +++ b/src/compiler/wasm-compiler.cc @@ -7547,7 +7547,7 @@ wasm::WasmCompilationResult CompileWasmMathIntrinsic( wasm::CompilationEnv env( nullptr, wasm::kNoBoundsChecks, wasm::RuntimeExceptionSupport::kNoRuntimeExceptionSupport, - wasm::WasmFeatures::All()); + wasm::WasmFeatures::All(), wasm::DynamicTiering::kDisabled); WasmGraphBuilder builder(&env, mcgraph->zone(), mcgraph, sig, source_positions); diff --git a/src/execution/isolate.cc b/src/execution/isolate.cc index 6e630a08af..888b4efcb0 100644 --- a/src/execution/isolate.cc +++ b/src/execution/isolate.cc @@ -2636,6 +2636,20 @@ bool Isolate::AreWasmExceptionsEnabled(Handle context) { #endif // V8_ENABLE_WEBASSEMBLY } +bool Isolate::IsWasmDynamicTieringEnabled() { +#if V8_ENABLE_WEBASSEMBLY + if (wasm_dynamic_tiering_enabled_callback()) { + HandleScope handle_scope(this); + v8::Local api_context = + v8::Utils::ToLocal(handle(context(), this)); + return wasm_dynamic_tiering_enabled_callback()(api_context); + } + return FLAG_wasm_dynamic_tiering; +#else + return false; +#endif // V8_ENABLE_WEBASSEMBLY +} + Handle Isolate::GetIncumbentContext() { JavaScriptFrameIterator it(this); diff --git a/src/execution/isolate.h b/src/execution/isolate.h index 2262d06141..785dee202b 100644 --- a/src/execution/isolate.h +++ b/src/execution/isolate.h @@ -447,6 +447,8 @@ using DebugObjectCache = std::vector>; V(WasmLoadSourceMapCallback, wasm_load_source_map_callback, nullptr) \ V(WasmSimdEnabledCallback, wasm_simd_enabled_callback, nullptr) \ V(WasmExceptionsEnabledCallback, wasm_exceptions_enabled_callback, nullptr) \ + V(WasmDynamicTieringEnabledCallback, wasm_dynamic_tiering_enabled_callback, \ + nullptr) \ /* State for Relocatable. */ \ V(Relocatable*, relocatable_top, nullptr) \ V(DebugObjectCache*, string_stream_debug_object_cache, nullptr) \ @@ -715,6 +717,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { bool IsWasmSimdEnabled(Handle context); bool AreWasmExceptionsEnabled(Handle context); + bool IsWasmDynamicTieringEnabled(); THREAD_LOCAL_TOP_ADDRESS(Context, pending_handler_context) THREAD_LOCAL_TOP_ADDRESS(Address, pending_handler_entrypoint) diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc index f0c342db54..fc5684f427 100644 --- a/src/wasm/baseline/liftoff-compiler.cc +++ b/src/wasm/baseline/liftoff-compiler.cc @@ -810,7 +810,7 @@ class LiftoffCompiler { // is never a position of any instruction in the function. StackCheck(decoder, 0); - if (FLAG_wasm_dynamic_tiering) { + if (env_->dynamic_tiering == DynamicTiering::kEnabled) { // TODO(arobin): Avoid spilling registers unconditionally. __ SpillAllRegisters(); CODE_COMMENT("dynamic tiering"); diff --git a/src/wasm/compilation-environment.h b/src/wasm/compilation-environment.h index 4208f83d75..574fe25cca 100644 --- a/src/wasm/compilation-environment.h +++ b/src/wasm/compilation-environment.h @@ -45,6 +45,8 @@ enum BoundsCheckStrategy : int8_t { kNoBoundsChecks }; +enum class DynamicTiering { kEnabled, kDisabled }; + // The {CompilationEnv} encapsulates the module data that is used during // compilation. CompilationEnvs are shareable across multiple compilations. struct CompilationEnv { @@ -70,10 +72,13 @@ struct CompilationEnv { // Features enabled for this compilation. const WasmFeatures enabled_features; + const DynamicTiering dynamic_tiering; + constexpr CompilationEnv(const WasmModule* module, BoundsCheckStrategy bounds_checks, RuntimeExceptionSupport runtime_exception_support, - const WasmFeatures& enabled_features) + const WasmFeatures& enabled_features, + DynamicTiering dynamic_tiering) : module(module), bounds_checks(bounds_checks), runtime_exception_support(runtime_exception_support), @@ -88,7 +93,8 @@ struct CompilationEnv { uintptr_t{module->maximum_pages}) : kV8MaxWasmMemoryPages) * kWasmPageSize), - enabled_features(enabled_features) {} + enabled_features(enabled_features), + dynamic_tiering(dynamic_tiering) {} }; // The wire bytes are either owned by the StreamingDecoder, or (after streaming) @@ -149,6 +155,8 @@ class V8_EXPORT_PRIVATE CompilationState { void set_compilation_id(int compilation_id); + DynamicTiering dynamic_tiering() const; + // Override {operator delete} to avoid implicit instantiation of {operator // delete} with {size_t} argument. The {size_t} argument would be incorrect. void operator delete(void* ptr) { ::operator delete(ptr); } @@ -163,7 +171,8 @@ class V8_EXPORT_PRIVATE CompilationState { // such that it can keep it alive (by regaining a {std::shared_ptr}) in // certain scopes. static std::unique_ptr New( - const std::shared_ptr&, std::shared_ptr); + const std::shared_ptr&, std::shared_ptr, + DynamicTiering dynamic_tiering); }; } // namespace wasm diff --git a/src/wasm/module-compiler.cc b/src/wasm/module-compiler.cc index 5caaa2eee3..e6b42ea3ee 100644 --- a/src/wasm/module-compiler.cc +++ b/src/wasm/module-compiler.cc @@ -529,7 +529,8 @@ bool CompilationUnitQueues::Queue::ShouldPublish( class CompilationStateImpl { public: CompilationStateImpl(const std::shared_ptr& native_module, - std::shared_ptr async_counters); + std::shared_ptr async_counters, + DynamicTiering dynamic_tiering); ~CompilationStateImpl() { if (compile_job_->IsValid()) compile_job_->CancelAndDetach(); } @@ -638,6 +639,8 @@ class CompilationStateImpl { return outstanding_recompilation_functions_ == 0; } + DynamicTiering dynamic_tiering() const { return dynamic_tiering_; } + Counters* counters() const { return async_counters_.get(); } void SetWireBytesStorage( @@ -663,7 +666,7 @@ class CompilationStateImpl { private: uint8_t SetupCompilationProgressForFunction( - bool lazy_module, const WasmModule* module, + bool lazy_module, NativeModule* module, const WasmFeatures& enabled_features, int func_index); // Returns the potentially-updated {function_progress}. @@ -702,6 +705,10 @@ class CompilationStateImpl { std::vector> js_to_wasm_wrapper_units_; + // Cache the dynamic tiering configuration to be consistent for the whole + // compilation. + const DynamicTiering dynamic_tiering_; + // This mutex protects all information of this {CompilationStateImpl} which is // being accessed concurrently. mutable base::Mutex mutex_; @@ -864,13 +871,17 @@ void CompilationState::set_compilation_id(int compilation_id) { Impl(this)->set_compilation_id(compilation_id); } +DynamicTiering CompilationState::dynamic_tiering() const { + return Impl(this)->dynamic_tiering(); +} + // static std::unique_ptr CompilationState::New( const std::shared_ptr& native_module, - std::shared_ptr async_counters) { - return std::unique_ptr( - reinterpret_cast(new CompilationStateImpl( - std::move(native_module), std::move(async_counters)))); + std::shared_ptr async_counters, DynamicTiering dynamic_tiering) { + return std::unique_ptr(reinterpret_cast( + new CompilationStateImpl(std::move(native_module), + std::move(async_counters), dynamic_tiering))); } // End of PIMPL implementation of {CompilationState}. @@ -930,13 +941,18 @@ struct ExecutionTierPair { }; ExecutionTierPair GetRequestedExecutionTiers( - const WasmModule* module, const WasmFeatures& enabled_features, + NativeModule* native_module, const WasmFeatures& enabled_features, uint32_t func_index) { + const WasmModule* module = native_module->module(); ExecutionTierPair result; result.baseline_tier = WasmCompilationUnit::GetBaselineExecutionTier(module); - if (module->origin != kWasmOrigin || !FLAG_wasm_tier_up) { + bool dynamic_tiering = + Impl(native_module->compilation_state())->dynamic_tiering() == + DynamicTiering::kEnabled; + bool tier_up_enabled = !dynamic_tiering && FLAG_wasm_tier_up; + if (module->origin != kWasmOrigin || !tier_up_enabled) { result.top_tier = result.baseline_tier; return result; } @@ -979,8 +995,7 @@ class CompilationUnitBuilder { return; } ExecutionTierPair tiers = GetRequestedExecutionTiers( - native_module_->module(), native_module_->enabled_features(), - func_index); + native_module_, native_module_->enabled_features(), func_index); // Compile everything for non-debugging initially. If needed, we will tier // down when the module is fully compiled. Synchronization would be pretty // difficult otherwise. @@ -1145,7 +1160,7 @@ bool CompileLazy(Isolate* isolate, Handle module_object, CompilationStateImpl* compilation_state = Impl(native_module->compilation_state()); ExecutionTierPair tiers = - GetRequestedExecutionTiers(module, enabled_features, func_index); + GetRequestedExecutionTiers(native_module, enabled_features, func_index); DCHECK_LE(native_module->num_imported_functions(), func_index); DCHECK_LT(func_index, native_module->num_functions()); @@ -2829,11 +2844,12 @@ bool AsyncStreamingProcessor::Deserialize( CompilationStateImpl::CompilationStateImpl( const std::shared_ptr& native_module, - std::shared_ptr async_counters) + std::shared_ptr async_counters, DynamicTiering dynamic_tiering) : native_module_(native_module.get()), native_module_weak_(std::move(native_module)), async_counters_(std::move(async_counters)), - compilation_unit_queues_(native_module->num_functions()) {} + compilation_unit_queues_(native_module->num_functions()), + dynamic_tiering_(dynamic_tiering) {} void CompilationStateImpl::InitCompileJob() { DCHECK_NULL(compile_job_); @@ -2866,12 +2882,12 @@ bool CompilationStateImpl::cancelled() const { } uint8_t CompilationStateImpl::SetupCompilationProgressForFunction( - bool lazy_module, const WasmModule* module, + bool lazy_module, NativeModule* native_module, const WasmFeatures& enabled_features, int func_index) { ExecutionTierPair requested_tiers = - GetRequestedExecutionTiers(module, enabled_features, func_index); - CompileStrategy strategy = - GetCompileStrategy(module, enabled_features, func_index, lazy_module); + GetRequestedExecutionTiers(native_module, enabled_features, func_index); + CompileStrategy strategy = GetCompileStrategy( + native_module->module(), enabled_features, func_index, lazy_module); bool required_for_baseline = strategy == CompileStrategy::kEager; bool required_for_top_tier = strategy != CompileStrategy::kLazy; @@ -2924,7 +2940,7 @@ void CompilationStateImpl::InitializeCompilationProgress( continue; } uint8_t function_progress = SetupCompilationProgressForFunction( - lazy_module, module, enabled_features, func_index); + lazy_module, native_module_, enabled_features, func_index); compilation_progress_.push_back(function_progress); } DCHECK_IMPLIES(lazy_module, outstanding_baseline_units_ == 0); @@ -3058,7 +3074,7 @@ void CompilationStateImpl::InitializeCompilationProgressAfterDeserialization( native_module_->UseLazyStub(func_index); } compilation_progress_[declared_function_index(module, func_index)] = - SetupCompilationProgressForFunction(lazy_module, module, + SetupCompilationProgressForFunction(lazy_module, native_module_, enabled_features, func_index); } } @@ -3370,7 +3386,8 @@ void CompilationStateImpl::TriggerCallbacks( triggered_events.Add(CompilationEvent::kFinishedExportWrappers); if (outstanding_baseline_units_ == 0) { triggered_events.Add(CompilationEvent::kFinishedBaselineCompilation); - if (!FLAG_wasm_dynamic_tiering && outstanding_top_tier_functions_ == 0) { + if (dynamic_tiering_ == DynamicTiering::kDisabled && + outstanding_top_tier_functions_ == 0) { triggered_events.Add(CompilationEvent::kFinishedTopTierCompilation); } } @@ -3421,8 +3438,8 @@ void CompilationStateImpl::TriggerCallbacks( // With dynamic tiering, we don't know if we can ever delete the callback. // TODO(https://crbug.com/v8/12289): Release some callbacks also when dynamic // tiering is enabled. - if (!FLAG_wasm_dynamic_tiering && outstanding_baseline_units_ == 0 && - outstanding_export_wrappers_ == 0 && + if (dynamic_tiering_ == DynamicTiering::kDisabled && + outstanding_baseline_units_ == 0 && outstanding_export_wrappers_ == 0 && outstanding_top_tier_functions_ == 0 && outstanding_recompilation_functions_ == 0) { // Clear the callbacks because no more events will be delivered. diff --git a/src/wasm/wasm-code-manager.cc b/src/wasm/wasm-code-manager.cc index bd5fec6da6..27687f6e1d 100644 --- a/src/wasm/wasm-code-manager.cc +++ b/src/wasm/wasm-code-manager.cc @@ -970,6 +970,7 @@ BoundsCheckStrategy GetBoundsChecks(const WasmModule* module) { } // namespace NativeModule::NativeModule(const WasmFeatures& enabled, + DynamicTiering dynamic_tiering, VirtualMemory code_space, std::shared_ptr module, std::shared_ptr async_counters, @@ -988,8 +989,8 @@ NativeModule::NativeModule(const WasmFeatures& enabled, DCHECK_NOT_NULL(shared_this); DCHECK_NULL(*shared_this); shared_this->reset(this); - compilation_state_ = - CompilationState::New(*shared_this, std::move(async_counters)); + compilation_state_ = CompilationState::New( + *shared_this, std::move(async_counters), dynamic_tiering); compilation_state_->InitCompileJob(); DCHECK_NOT_NULL(module_); if (module_->num_declared_functions > 0) { @@ -1055,8 +1056,8 @@ void NativeModule::LogWasmCodes(Isolate* isolate, Script script) { } CompilationEnv NativeModule::CreateCompilationEnv() const { - return {module(), bounds_checks_, kRuntimeExceptionSupport, - enabled_features_}; + return {module(), bounds_checks_, kRuntimeExceptionSupport, enabled_features_, + compilation_state()->dynamic_tiering()}; } WasmCode* NativeModule::AddCodeForTesting(Handle code) { @@ -2201,8 +2202,11 @@ std::shared_ptr WasmCodeManager::NewNativeModule( size_t size = code_space.size(); Address end = code_space.end(); std::shared_ptr ret; - new NativeModule(enabled, std::move(code_space), std::move(module), - isolate->async_counters(), &ret); + DynamicTiering dynamic_tiering = isolate->IsWasmDynamicTieringEnabled() + ? DynamicTiering::kEnabled + : DynamicTiering::kDisabled; + new NativeModule(enabled, dynamic_tiering, std::move(code_space), + std::move(module), isolate->async_counters(), &ret); // The constructor initialized the shared_ptr. DCHECK_NOT_NULL(ret); TRACE_HEAP("New NativeModule %p: Mem: 0x%" PRIxPTR ",+%zu\n", ret.get(), diff --git a/src/wasm/wasm-code-manager.h b/src/wasm/wasm-code-manager.h index e1a0dfb71b..ad7e4ab26b 100644 --- a/src/wasm/wasm-code-manager.h +++ b/src/wasm/wasm-code-manager.h @@ -728,7 +728,9 @@ class V8_EXPORT_PRIVATE NativeModule final { void LogWasmCodes(Isolate*, Script); - CompilationState* compilation_state() { return compilation_state_.get(); } + CompilationState* compilation_state() const { + return compilation_state_.get(); + } // Create a {CompilationEnv} object for compilation. The caller has to ensure // that the {WasmModule} pointer stays valid while the {CompilationEnv} is @@ -848,7 +850,8 @@ class V8_EXPORT_PRIVATE NativeModule final { }; // Private constructor, called via {WasmCodeManager::NewNativeModule()}. - NativeModule(const WasmFeatures& enabled_features, VirtualMemory code_space, + NativeModule(const WasmFeatures& enabled_features, + DynamicTiering dynamic_tiering, VirtualMemory code_space, std::shared_ptr module, std::shared_ptr async_counters, std::shared_ptr* shared_this); diff --git a/test/cctest/wasm/wasm-run-utils.cc b/test/cctest/wasm/wasm-run-utils.cc index 8c0192d01d..1bbb2d1ac2 100644 --- a/test/cctest/wasm/wasm-run-utils.cc +++ b/test/cctest/wasm/wasm-run-utils.cc @@ -336,7 +336,8 @@ uint32_t TestingModuleBuilder::AddPassiveElementSegment( CompilationEnv TestingModuleBuilder::CreateCompilationEnv() { return {test_module_.get(), native_module_->bounds_checks(), - runtime_exception_support_, enabled_features_}; + runtime_exception_support_, enabled_features_, + DynamicTiering::kDisabled}; } const WasmGlobal* TestingModuleBuilder::AddGlobal(ValueType type) {