[wasm] Add support to tier down/up Wasm NativeModule
This is the first part of switching between Liftoff and Turbofan in debugging Wasm. In this CL, we implemented the logic to tier down/up all functions in module. Bug: v8:9654 Change-Id: Ia25103ca29963afa103c124ff5f159f197c2b2b0 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1970470 Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com> Reviewed-by: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#65529}
This commit is contained in:
parent
2e7eb2f108
commit
6ce3046e2b
@ -1377,6 +1377,26 @@ RUNTIME_FUNCTION(Runtime_WasmTierUpFunction) {
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_WasmTierDownModule) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
|
||||
auto* native_module = instance->module_object().native_module();
|
||||
native_module->TierDown(isolate);
|
||||
CHECK(!native_module->compilation_state()->failed());
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_WasmTierUpModule) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0);
|
||||
auto* native_module = instance->module_object().native_module();
|
||||
native_module->TierUp(isolate);
|
||||
CHECK(!native_module->compilation_state()->failed());
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_IsLiftoffFunction) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
|
@ -536,7 +536,9 @@ namespace internal {
|
||||
F(WasmGetNumberOfInstances, 1, 1) \
|
||||
F(WasmNumInterpretedCalls, 1, 1) \
|
||||
F(WasmNumCodeSpaces, 1, 1) \
|
||||
F(WasmTierDownModule, 1, 1) \
|
||||
F(WasmTierUpFunction, 2, 1) \
|
||||
F(WasmTierUpModule, 1, 1) \
|
||||
F(WasmTraceMemory, 1, 1) \
|
||||
I(DeoptimizeNow, 0, 1)
|
||||
|
||||
|
@ -1046,11 +1046,14 @@ WasmCode* NativeModule::PublishCodeLocked(std::unique_ptr<WasmCode> code) {
|
||||
ExecutionTier::kLiftoff < ExecutionTier::kTurbofan,
|
||||
"Assume an order on execution tiers");
|
||||
|
||||
// Update code table but avoid to fall back to less optimized code. We use
|
||||
// the new code if it was compiled with a higher tier.
|
||||
// Unless tier down to Liftoff: update code table but avoid to fall back to
|
||||
// less optimized code. We use the new code if it was compiled with a higher
|
||||
// tier.
|
||||
uint32_t slot_idx = code->index() - module_->num_imported_functions;
|
||||
WasmCode* prior_code = code_table_[slot_idx];
|
||||
bool update_code_table = !prior_code || prior_code->tier() < code->tier();
|
||||
bool update_code_table =
|
||||
tier_down_ ? !prior_code || code->tier() == ExecutionTier::kLiftoff
|
||||
: !prior_code || prior_code->tier() < code->tier();
|
||||
if (update_code_table) {
|
||||
code_table_[slot_idx] = code.get();
|
||||
if (prior_code) {
|
||||
@ -1807,6 +1810,34 @@ bool NativeModule::IsRedirectedToInterpreter(uint32_t func_index) {
|
||||
return has_interpreter_redirection(func_index);
|
||||
}
|
||||
|
||||
void NativeModule::TierDown(Isolate* isolate) {
|
||||
// Set the flag.
|
||||
tier_down_ = true;
|
||||
|
||||
// Tier down all functions.
|
||||
// TODO(duongn): parallelize this eventually.
|
||||
for (uint32_t index = module_->num_imported_functions;
|
||||
index < num_functions(); index++) {
|
||||
isolate->wasm_engine()->CompileFunction(isolate, this, index,
|
||||
ExecutionTier::kLiftoff);
|
||||
DCHECK(!compilation_state()->failed());
|
||||
}
|
||||
}
|
||||
|
||||
void NativeModule::TierUp(Isolate* isolate) {
|
||||
// Set the flag.
|
||||
tier_down_ = false;
|
||||
|
||||
// Tier up all functions.
|
||||
// TODO(duongn): parallelize this eventually.
|
||||
for (uint32_t index = module_->num_imported_functions;
|
||||
index < num_functions(); index++) {
|
||||
isolate->wasm_engine()->CompileFunction(isolate, this, index,
|
||||
ExecutionTier::kTurbofan);
|
||||
DCHECK(!compilation_state()->failed());
|
||||
}
|
||||
}
|
||||
|
||||
void NativeModule::FreeCode(Vector<WasmCode* const> codes) {
|
||||
// Free the code space.
|
||||
code_allocator_.FreeCode(codes);
|
||||
|
@ -551,6 +551,11 @@ class V8_EXPORT_PRIVATE NativeModule final {
|
||||
// by publishing an entry stub with the {Kind::kInterpreterEntry} code kind.
|
||||
bool IsRedirectedToInterpreter(uint32_t func_index);
|
||||
|
||||
// Sets the flag, triggers recompilation of all methods to tier down or up,
|
||||
// waits for that to complete.
|
||||
void TierDown(Isolate* isolate);
|
||||
void TierUp(Isolate* isolate);
|
||||
|
||||
// Free a set of functions of this module. Uncommits whole pages if possible.
|
||||
// The given vector must be ordered by the instruction start address, and all
|
||||
// {WasmCode} objects must not be used any more.
|
||||
@ -686,6 +691,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
|
||||
// Data (especially jump table) per code space.
|
||||
std::vector<CodeSpaceData> code_space_data_;
|
||||
|
||||
bool tier_down_ = false;
|
||||
// End of fields protected by {allocation_mutex_}.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -1096,6 +1096,7 @@
|
||||
['arch != x64 and arch != ia32 and arch != arm64 and arch != arm', {
|
||||
'wasm/liftoff': [SKIP],
|
||||
'wasm/tier-up-testing-flag': [SKIP],
|
||||
'wasm/tier-down-to-liftoff': [SKIP],
|
||||
}], # arch != x64 and arch != ia32 and arch != arm64 and arch != arm
|
||||
|
||||
##############################################################################
|
||||
|
56
test/mjsunit/wasm/tier-down-to-liftoff.js
Normal file
56
test/mjsunit/wasm/tier-down-to-liftoff.js
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright 2019 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax --wasm-tier-up
|
||||
|
||||
load('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
|
||||
const num_functions = 2;
|
||||
|
||||
function create_builder() {
|
||||
const builder = new WasmModuleBuilder();
|
||||
for (let i = 0; i < num_functions; ++i) {
|
||||
builder.addFunction('f' + i, kSig_i_v)
|
||||
.addBody(wasmI32Const(i))
|
||||
.exportFunc();
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
function check(instance) {
|
||||
for (let i = 0; i < num_functions; ++i) {
|
||||
%WasmTierUpFunction(instance, i);
|
||||
assertFalse(%IsLiftoffFunction(instance.exports['f' + i]));
|
||||
}
|
||||
|
||||
%WasmTierDownModule(instance);
|
||||
for (let i = 0; i < num_functions; ++i) {
|
||||
assertTrue(%IsLiftoffFunction(instance.exports['f' + i]));
|
||||
}
|
||||
|
||||
for (let i = 0; i < num_functions; ++i) {
|
||||
%WasmTierUpFunction(instance, i);
|
||||
assertTrue(%IsLiftoffFunction(instance.exports['f' + i]));
|
||||
}
|
||||
|
||||
%WasmTierUpModule(instance);
|
||||
for (let i = 0; i < num_functions; ++i) {
|
||||
assertFalse(%IsLiftoffFunction(instance.exports['f' + i]));
|
||||
}
|
||||
}
|
||||
|
||||
(function testTierDownToLiftoff() {
|
||||
print(arguments.callee.name);
|
||||
const instance = create_builder().instantiate();
|
||||
check(instance);
|
||||
})();
|
||||
|
||||
|
||||
async function testTierDownToLiftoffAsync() {
|
||||
print(arguments.callee.name);
|
||||
const instance = await create_builder().asyncInstantiate();
|
||||
check(instance);
|
||||
}
|
||||
|
||||
assertPromiseResult(testTierDownToLiftoffAsync());
|
Loading…
Reference in New Issue
Block a user