[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 <ahaas@chromium.org>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77256}
This commit is contained in:
Andreas Haas 2021-10-06 13:18:10 +02:00 committed by V8 LUCI CQ
parent 2a68b88401
commit 5578195db3
12 changed files with 97 additions and 36 deletions

View File

@ -308,6 +308,9 @@ using WasmSimdEnabledCallback = bool (*)(Local<Context> context);
// --- Callback for checking if WebAssembly exceptions are enabled ---
using WasmExceptionsEnabledCallback = bool (*)(Local<Context> context);
// --- Callback for checking if WebAssembly dynamic tiering is enabled ---
using WasmDynamicTieringEnabledCallback = bool (*)(Local<Context> context);
// --- Callback for checking if the SharedArrayBuffer constructor is enabled ---
using SharedArrayBufferConstructorEnabledCallback =
bool (*)(Local<Context> context);

View File

@ -1482,6 +1482,9 @@ class V8_EXPORT Isolate {
void SetWasmExceptionsEnabledCallback(WasmExceptionsEnabledCallback callback);
void SetWasmDynamicTieringEnabledCallback(
WasmDynamicTieringEnabledCallback callback);
void SetSharedArrayBufferConstructorEnabledCallback(
SharedArrayBufferConstructorEnabledCallback callback);

View File

@ -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)

View File

@ -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);

View File

@ -2636,6 +2636,20 @@ bool Isolate::AreWasmExceptionsEnabled(Handle<Context> context) {
#endif // V8_ENABLE_WEBASSEMBLY
}
bool Isolate::IsWasmDynamicTieringEnabled() {
#if V8_ENABLE_WEBASSEMBLY
if (wasm_dynamic_tiering_enabled_callback()) {
HandleScope handle_scope(this);
v8::Local<v8::Context> 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<Context> Isolate::GetIncumbentContext() {
JavaScriptFrameIterator it(this);

View File

@ -447,6 +447,8 @@ using DebugObjectCache = std::vector<Handle<HeapObject>>;
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> context);
bool AreWasmExceptionsEnabled(Handle<Context> context);
bool IsWasmDynamicTieringEnabled();
THREAD_LOCAL_TOP_ADDRESS(Context, pending_handler_context)
THREAD_LOCAL_TOP_ADDRESS(Address, pending_handler_entrypoint)

View File

@ -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");

View File

@ -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<CompilationState> New(
const std::shared_ptr<NativeModule>&, std::shared_ptr<Counters>);
const std::shared_ptr<NativeModule>&, std::shared_ptr<Counters>,
DynamicTiering dynamic_tiering);
};
} // namespace wasm

View File

@ -529,7 +529,8 @@ bool CompilationUnitQueues::Queue::ShouldPublish(
class CompilationStateImpl {
public:
CompilationStateImpl(const std::shared_ptr<NativeModule>& native_module,
std::shared_ptr<Counters> async_counters);
std::shared_ptr<Counters> 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<std::shared_ptr<JSToWasmWrapperCompilationUnit>>
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> CompilationState::New(
const std::shared_ptr<NativeModule>& native_module,
std::shared_ptr<Counters> async_counters) {
return std::unique_ptr<CompilationState>(
reinterpret_cast<CompilationState*>(new CompilationStateImpl(
std::move(native_module), std::move(async_counters))));
std::shared_ptr<Counters> async_counters, DynamicTiering dynamic_tiering) {
return std::unique_ptr<CompilationState>(reinterpret_cast<CompilationState*>(
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<WasmModuleObject> 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<NativeModule>& native_module,
std::shared_ptr<Counters> async_counters)
std::shared_ptr<Counters> 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.

View File

@ -970,6 +970,7 @@ BoundsCheckStrategy GetBoundsChecks(const WasmModule* module) {
} // namespace
NativeModule::NativeModule(const WasmFeatures& enabled,
DynamicTiering dynamic_tiering,
VirtualMemory code_space,
std::shared_ptr<const WasmModule> module,
std::shared_ptr<Counters> 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> code) {
@ -2201,8 +2202,11 @@ std::shared_ptr<NativeModule> WasmCodeManager::NewNativeModule(
size_t size = code_space.size();
Address end = code_space.end();
std::shared_ptr<NativeModule> 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(),

View File

@ -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<const WasmModule> module,
std::shared_ptr<Counters> async_counters,
std::shared_ptr<NativeModule>* shared_this);

View File

@ -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) {