Commit 410ca4c5 authored by Z Nguyen-Huu's avatar Z Nguyen-Huu Committed by Commit Bot

[wasm] Tierdown wasm module upon "Debugger.enable"

Put a logic in Wasm Engine to tier down all existing modules per isolate
when debugger is enabled. This CL does not handle new module added after
debugger is enabled yet.

Bug: v8:9654
Change-Id: I87060f5c416506543fcaf231bff9999d06ba4c0d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2013692
Commit-Queue: Z Nguyen-Huu <duongn@microsoft.com>
Reviewed-by: 's avatarSimon Zünd <szuend@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66017}
parent 7fa6c693
......@@ -9817,6 +9817,11 @@ MaybeLocal<UnboundScript> debug::CompileInspectorScript(Isolate* v8_isolate,
RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
}
void debug::TierDownAllModulesPerIsolate(Isolate* v8_isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
isolate->wasm_engine()->TierDownAllModulesPerIsolate(isolate);
}
void debug::SetDebugDelegate(Isolate* v8_isolate,
debug::DebugDelegate* delegate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
......
......@@ -212,6 +212,8 @@ class DebugDelegate {
V8_EXPORT_PRIVATE void SetDebugDelegate(Isolate* isolate,
DebugDelegate* listener);
V8_EXPORT_PRIVATE void TierDownAllModulesPerIsolate(Isolate* isolate);
class AsyncEventDelegate {
public:
virtual ~AsyncEventDelegate() = default;
......
......@@ -124,6 +124,7 @@ void V8Debugger::enable() {
m_isolate->AddNearHeapLimitCallback(&V8Debugger::nearHeapLimitCallback, this);
v8::debug::ChangeBreakOnException(m_isolate, v8::debug::NoBreakOnException);
m_pauseOnExceptionsState = v8::debug::NoBreakOnException;
v8::debug::TierDownAllModulesPerIsolate(m_isolate);
}
void V8Debugger::disable() {
......
......@@ -382,7 +382,9 @@ class CompilationStateImpl {
void InitializeCompilationProgress(bool lazy_module, int num_wrappers);
// Initialize compilation progress for recompilation of the whole module.
void InitializeRecompilationProgress(ExecutionTier tier);
// Return false if initial compilation hasn't started yet, otherwise return
// true.
bool InitializeRecompilationProgress(ExecutionTier tier);
// Add the callback function to be called on compilation events. Needs to be
// set before {AddCompilationUnits} is run to ensure that it receives all
......@@ -1434,8 +1436,9 @@ void RecompileNativeModule(Isolate* isolate, NativeModule* native_module,
});
// Initialize the compilation units and kick off background compile tasks.
compilation_state->InitializeRecompilationProgress(tier);
AddBaselineCompilationUnits(native_module);
if (compilation_state->InitializeRecompilationProgress(tier)) {
AddBaselineCompilationUnits(native_module);
}
// The main thread contributes to the compilation, except if we need
// deterministic compilation; in that case, the single background task will
......@@ -2422,7 +2425,7 @@ void CompilationStateImpl::InitializeCompilationProgress(bool lazy_module,
}
}
void CompilationStateImpl::InitializeRecompilationProgress(ExecutionTier tier) {
bool CompilationStateImpl::InitializeRecompilationProgress(ExecutionTier tier) {
DCHECK(!failed());
auto* module = native_module_->module();
......@@ -2432,25 +2435,32 @@ void CompilationStateImpl::InitializeRecompilationProgress(ExecutionTier tier) {
DCHECK_EQ(0, outstanding_recompilation_functions_);
int start = module->num_imported_functions;
int end = start + module->num_declared_functions;
for (int function_index = start; function_index < end; function_index++) {
int slot_index = function_index - start;
DCHECK_LT(slot_index, compilation_progress_.size());
ExecutionTier reached_tier =
ReachedTierField::decode(compilation_progress_[slot_index]);
if (reached_tier != tier) {
outstanding_recompilation_functions_++;
// If compilation hasn't started yet then code would be keep as tiered-down
// and don't need to recompile.
if (compilation_progress_.size() > 0) {
for (int function_index = start; function_index < end; function_index++) {
int slot_index = function_index - start;
DCHECK_LT(slot_index, compilation_progress_.size());
ExecutionTier reached_tier =
ReachedTierField::decode(compilation_progress_[slot_index]);
if (reached_tier != tier) {
outstanding_recompilation_functions_++;
}
}
DCHECK_LE(0, outstanding_recompilation_functions_);
DCHECK_LE(outstanding_recompilation_functions_,
module->num_declared_functions);
}
DCHECK_LE(0, outstanding_recompilation_functions_);
DCHECK_LE(outstanding_recompilation_functions_,
module->num_declared_functions);
// Trigger callbacks if module needs no recompilation.
if (outstanding_recompilation_functions_ == 0) {
for (auto& callback : callbacks_) {
callback(CompilationEvent::kFinishedRecompilation);
}
return false;
}
return true;
}
void CompilationStateImpl::AddCallback(CompilationState::callback_t callback) {
......
......@@ -1810,6 +1810,7 @@ void NativeModule::TierDown(Isolate* isolate) {
// Set the flag.
{
base::MutexGuard lock(&allocation_mutex_);
if (tier_down_) return;
tier_down_ = true;
}
// Tier down all functions.
......
......@@ -494,6 +494,19 @@ void WasmEngine::RecompileAllFunctions(Isolate* isolate,
RecompileNativeModule(isolate, native_module, tier);
}
void WasmEngine::TierDownAllModulesPerIsolate(Isolate* isolate) {
std::vector<NativeModule*> native_modules;
{
base::MutexGuard lock(&mutex_);
for (auto* native_module : isolates_[isolate]->native_modules) {
native_modules.push_back(native_module);
}
}
for (auto* native_module : native_modules) {
native_module->TierDown(isolate);
}
}
std::shared_ptr<NativeModule> WasmEngine::ExportNativeModule(
Handle<WasmModuleObject> module_object) {
return module_object->shared_native_module();
......
......@@ -152,6 +152,8 @@ class V8_EXPORT_PRIVATE WasmEngine {
void RecompileAllFunctions(Isolate* isolate, NativeModule* native_module,
ExecutionTier tier);
void TierDownAllModulesPerIsolate(Isolate* isolate);
// Exports the sharable parts of the given module object so that they can be
// transferred to a different Context/Isolate using the same engine.
std::shared_ptr<NativeModule> ExportNativeModule(
......
// Copyright 2020 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: --liftoff --wasm-tier-up --no-stress-opt
load("test/mjsunit/wasm/wasm-module-builder.js");
const num_functions = 2;
// Create a simple Wasm script.
function create_builder(delta = 0) {
const builder = new WasmModuleBuilder();
for (let i = 0; i < num_functions; ++i) {
builder.addFunction('f' + i, kSig_i_v)
.addBody(wasmI32Const(i + delta))
.exportFunc();
}
return builder;
}
function check(instance) {
for (let i = 0; i < num_functions; ++i) {
assertTrue(%IsLiftoffFunction(instance.exports['f' + i]));
}
}
const instance = create_builder().instantiate();
const Debug = new DebugWrapper();
Debug.enable();
check(instance);
// Async.
async function testTierDownToLiftoffAsync() {
Debug.disable();
const asyncInstance = await create_builder(num_functions).asyncInstantiate();
Debug.enable();
check(asyncInstance);
}
assertPromiseResult(testTierDownToLiftoffAsync());
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment