[wasm][debug] Generate debug sidetable from code alone
Instead of passing a bunch of objects and pointers to {GenerateLiftoffDebugSideTable}, just pass the WasmCode pointer for which the debug sidetable should be created. This requires changing the corresponding cctests to actually compile code, such that we can get a WasmCode pointer. R=thibaudm@chromium.org Bug: chromium:1172299 Change-Id: If42f06a545feb590f9c2377ce95e6214bbc6f566 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2674006 Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#72526}
This commit is contained in:
parent
a9eff909e9
commit
8aadf7c5cb
@ -5364,22 +5364,32 @@ WasmCompilationResult ExecuteLiftoffCompilation(
|
||||
}
|
||||
|
||||
std::unique_ptr<DebugSideTable> GenerateLiftoffDebugSideTable(
|
||||
AccountingAllocator* allocator, CompilationEnv* env,
|
||||
const FunctionBody& func_body, int func_index, ForDebugging for_debugging) {
|
||||
const WasmCode* code) {
|
||||
auto* native_module = code->native_module();
|
||||
auto* function = &native_module->module()->functions[code->index()];
|
||||
ModuleWireBytes wire_bytes{native_module->wire_bytes()};
|
||||
Vector<const byte> function_bytes = wire_bytes.GetFunctionBytes(function);
|
||||
CompilationEnv env = native_module->CreateCompilationEnv();
|
||||
FunctionBody func_body{function->sig, 0, function_bytes.begin(),
|
||||
function_bytes.end()};
|
||||
|
||||
AccountingAllocator* allocator = native_module->engine()->allocator();
|
||||
Zone zone(allocator, "LiftoffDebugSideTableZone");
|
||||
auto call_descriptor = compiler::GetWasmCallDescriptor(&zone, func_body.sig);
|
||||
auto call_descriptor = compiler::GetWasmCallDescriptor(&zone, function->sig);
|
||||
DebugSideTableBuilder debug_sidetable_builder;
|
||||
WasmFeatures detected;
|
||||
constexpr int kSteppingBreakpoints[] = {0};
|
||||
DCHECK(for_debugging == kForDebugging || for_debugging == kForStepping);
|
||||
Vector<const int> breakpoints = for_debugging == kForStepping
|
||||
DCHECK(code->for_debugging() == kForDebugging ||
|
||||
code->for_debugging() == kForStepping);
|
||||
Vector<const int> breakpoints = code->for_debugging() == kForStepping
|
||||
? ArrayVector(kSteppingBreakpoints)
|
||||
: Vector<const int>{};
|
||||
WasmFullDecoder<Decoder::kBooleanValidation, LiftoffCompiler> decoder(
|
||||
&zone, env->module, env->enabled_features, &detected, func_body,
|
||||
call_descriptor, env, &zone,
|
||||
&zone, native_module->module(), env.enabled_features, &detected,
|
||||
func_body, call_descriptor, &env, &zone,
|
||||
NewAssemblerBuffer(AssemblerBase::kDefaultBufferSize),
|
||||
&debug_sidetable_builder, for_debugging, func_index, breakpoints);
|
||||
&debug_sidetable_builder, code->for_debugging(), code->index(),
|
||||
breakpoints);
|
||||
decoder.Decode();
|
||||
DCHECK(decoder.ok());
|
||||
DCHECK(!decoder.interface().did_bailout());
|
||||
|
@ -60,8 +60,7 @@ V8_EXPORT_PRIVATE WasmCompilationResult ExecuteLiftoffCompilation(
|
||||
std::unique_ptr<DebugSideTable>* = nullptr, int dead_breakpoint = 0);
|
||||
|
||||
V8_EXPORT_PRIVATE std::unique_ptr<DebugSideTable> GenerateLiftoffDebugSideTable(
|
||||
AccountingAllocator*, CompilationEnv*, const FunctionBody&, int func_index,
|
||||
ForDebugging);
|
||||
const WasmCode*);
|
||||
|
||||
} // namespace wasm
|
||||
} // namespace internal
|
||||
|
@ -481,17 +481,8 @@ class DebugInfoImpl {
|
||||
}
|
||||
|
||||
// Otherwise create the debug side table now.
|
||||
auto* module = native_module_->module();
|
||||
auto* allocator = native_module_->engine()->allocator();
|
||||
auto* function = &module->functions[code->index()];
|
||||
ModuleWireBytes wire_bytes{native_module_->wire_bytes()};
|
||||
Vector<const byte> function_bytes = wire_bytes.GetFunctionBytes(function);
|
||||
CompilationEnv env = native_module_->CreateCompilationEnv();
|
||||
FunctionBody func_body{function->sig, 0, function_bytes.begin(),
|
||||
function_bytes.end()};
|
||||
std::unique_ptr<DebugSideTable> debug_side_table =
|
||||
GenerateLiftoffDebugSideTable(allocator, &env, func_body, code->index(),
|
||||
code->for_debugging());
|
||||
GenerateLiftoffDebugSideTable(code);
|
||||
DebugSideTable* ret = debug_side_table.get();
|
||||
|
||||
// Check cache again, maybe another thread concurrently generated a debug
|
||||
|
@ -20,15 +20,16 @@ class LiftoffCompileEnvironment {
|
||||
: isolate_(CcTest::InitIsolateOnce()),
|
||||
handle_scope_(isolate_),
|
||||
zone_(isolate_->allocator(), ZONE_NAME),
|
||||
module_builder_(&zone_, nullptr, TestExecutionTier::kLiftoff,
|
||||
kRuntimeExceptionSupport, kNoLowerSimd) {
|
||||
wasm_runner_(nullptr, TestExecutionTier::kLiftoff, 0,
|
||||
kRuntimeExceptionSupport, kNoLowerSimd) {
|
||||
// Add a table of length 1, for indirect calls.
|
||||
module_builder_.AddIndirectFunctionTable(nullptr, 1);
|
||||
wasm_runner_.builder().AddIndirectFunctionTable(nullptr, 1);
|
||||
// Set tiered down such that we generate debugging code.
|
||||
wasm_runner_.builder().SetTieredDown();
|
||||
}
|
||||
|
||||
struct TestFunction {
|
||||
OwnedVector<uint8_t> body_bytes;
|
||||
WasmFunction* function;
|
||||
WasmCode* code;
|
||||
FunctionBody body;
|
||||
};
|
||||
|
||||
@ -39,17 +40,15 @@ class LiftoffCompileEnvironment {
|
||||
auto test_func = AddFunction(return_types, param_types, raw_function_bytes);
|
||||
|
||||
// Now compile the function with Liftoff two times.
|
||||
CompilationEnv env = module_builder_.CreateCompilationEnv();
|
||||
CompilationEnv env = wasm_runner_.builder().CreateCompilationEnv();
|
||||
WasmFeatures detected1;
|
||||
WasmFeatures detected2;
|
||||
WasmCompilationResult result1 =
|
||||
ExecuteLiftoffCompilation(isolate_->allocator(), &env, test_func.body,
|
||||
test_func.function->func_index, kNoDebugging,
|
||||
isolate_->counters(), &detected1);
|
||||
WasmCompilationResult result2 =
|
||||
ExecuteLiftoffCompilation(isolate_->allocator(), &env, test_func.body,
|
||||
test_func.function->func_index, kNoDebugging,
|
||||
isolate_->counters(), &detected2);
|
||||
WasmCompilationResult result1 = ExecuteLiftoffCompilation(
|
||||
isolate_->allocator(), &env, test_func.body, test_func.code->index(),
|
||||
kNoDebugging, isolate_->counters(), &detected1);
|
||||
WasmCompilationResult result2 = ExecuteLiftoffCompilation(
|
||||
isolate_->allocator(), &env, test_func.body, test_func.code->index(),
|
||||
kNoDebugging, isolate_->counters(), &detected2);
|
||||
|
||||
CHECK(result1.succeeded());
|
||||
CHECK(result2.succeeded());
|
||||
@ -70,20 +69,20 @@ class LiftoffCompileEnvironment {
|
||||
std::vector<int> breakpoints = {}) {
|
||||
auto test_func = AddFunction(return_types, param_types, raw_function_bytes);
|
||||
|
||||
CompilationEnv env = module_builder_.CreateCompilationEnv();
|
||||
CompilationEnv env = wasm_runner_.builder().CreateCompilationEnv();
|
||||
WasmFeatures detected;
|
||||
std::unique_ptr<DebugSideTable> debug_side_table_via_compilation;
|
||||
ExecuteLiftoffCompilation(CcTest::i_isolate()->allocator(), &env,
|
||||
test_func.body, 0, kForDebugging, nullptr,
|
||||
&detected, VectorOf(breakpoints),
|
||||
&debug_side_table_via_compilation);
|
||||
auto result = ExecuteLiftoffCompilation(
|
||||
CcTest::i_isolate()->allocator(), &env, test_func.body, 0,
|
||||
kForDebugging, nullptr, &detected, VectorOf(breakpoints),
|
||||
&debug_side_table_via_compilation);
|
||||
CHECK(result.succeeded());
|
||||
|
||||
// If there are no breakpoint, then {ExecuteLiftoffCompilation} should
|
||||
// provide the same debug side table.
|
||||
if (breakpoints.empty()) {
|
||||
std::unique_ptr<DebugSideTable> debug_side_table =
|
||||
GenerateLiftoffDebugSideTable(CcTest::i_isolate()->allocator(), &env,
|
||||
test_func.body, 0, kForDebugging);
|
||||
GenerateLiftoffDebugSideTable(test_func.code);
|
||||
CheckTableEquals(*debug_side_table, *debug_side_table_via_compilation);
|
||||
}
|
||||
|
||||
@ -94,6 +93,7 @@ class LiftoffCompileEnvironment {
|
||||
static void CheckTableEquals(const DebugSideTable& a,
|
||||
const DebugSideTable& b) {
|
||||
CHECK_EQ(a.num_locals(), b.num_locals());
|
||||
CHECK_EQ(a.entries().size(), b.entries().size());
|
||||
CHECK(std::equal(a.entries().begin(), a.entries().end(),
|
||||
b.entries().begin(), b.entries().end(),
|
||||
&CheckEntryEquals));
|
||||
@ -125,19 +125,6 @@ class LiftoffCompileEnvironment {
|
||||
return true;
|
||||
}
|
||||
|
||||
OwnedVector<uint8_t> GenerateFunctionBody(
|
||||
std::initializer_list<uint8_t> raw_function_bytes) {
|
||||
// Build the function bytes by prepending the locals decl and appending an
|
||||
// "end" opcode.
|
||||
OwnedVector<uint8_t> function_bytes =
|
||||
OwnedVector<uint8_t>::New(raw_function_bytes.size() + 2);
|
||||
function_bytes[0] = WASM_NO_LOCALS;
|
||||
std::copy(raw_function_bytes.begin(), raw_function_bytes.end(),
|
||||
&function_bytes[1]);
|
||||
function_bytes[raw_function_bytes.size() + 1] = WASM_END;
|
||||
return function_bytes;
|
||||
}
|
||||
|
||||
FunctionSig* AddSig(std::initializer_list<ValueType> return_types,
|
||||
std::initializer_list<ValueType> param_types) {
|
||||
ValueType* storage =
|
||||
@ -147,30 +134,41 @@ class LiftoffCompileEnvironment {
|
||||
storage + return_types.size());
|
||||
FunctionSig* sig = zone_.New<FunctionSig>(return_types.size(),
|
||||
param_types.size(), storage);
|
||||
module_builder_.AddSignature(sig);
|
||||
return sig;
|
||||
}
|
||||
|
||||
TestFunction AddFunction(std::initializer_list<ValueType> return_types,
|
||||
std::initializer_list<ValueType> param_types,
|
||||
std::initializer_list<uint8_t> raw_function_bytes) {
|
||||
OwnedVector<uint8_t> function_bytes =
|
||||
GenerateFunctionBody(raw_function_bytes);
|
||||
std::initializer_list<uint8_t> function_bytes) {
|
||||
FunctionSig* sig = AddSig(return_types, param_types);
|
||||
int func_index =
|
||||
module_builder_.AddFunction(sig, "f", TestingModuleBuilder::kWasm);
|
||||
WasmFunction* function = module_builder_.GetFunctionAt(func_index);
|
||||
function->code = {module_builder_.AddBytes(function_bytes.as_vector()),
|
||||
static_cast<uint32_t>(function_bytes.size())};
|
||||
FunctionBody body{function->sig, 0, function_bytes.begin(),
|
||||
function_bytes.end()};
|
||||
return {std::move(function_bytes), function, body};
|
||||
// Compile the function so we can get the WasmCode* which is later used to
|
||||
// generate the debug side table lazily.
|
||||
auto& func_compiler = wasm_runner_.NewFunction(sig, "f");
|
||||
func_compiler.Build(function_bytes.begin(), function_bytes.end());
|
||||
|
||||
WasmCode* code =
|
||||
wasm_runner_.builder().GetFunctionCode(func_compiler.function_index());
|
||||
|
||||
// Get the wire bytes created by the function compiler (including locals
|
||||
// declaration and the trailing "end" opcode).
|
||||
NativeModule* native_module = code->native_module();
|
||||
auto* function = &native_module->module()->functions[code->index()];
|
||||
Vector<const uint8_t> function_wire_bytes =
|
||||
native_module->wire_bytes().SubVector(function->code.offset(),
|
||||
function->code.end_offset());
|
||||
|
||||
FunctionBody body{sig, 0, function_wire_bytes.begin(),
|
||||
function_wire_bytes.end()};
|
||||
return {code, body};
|
||||
}
|
||||
|
||||
Isolate* isolate_;
|
||||
HandleScope handle_scope_;
|
||||
Zone zone_;
|
||||
TestingModuleBuilder module_builder_;
|
||||
// wasm_runner_ is used to build actual code objects needed to request lazy
|
||||
// generation of debug side tables.
|
||||
WasmRunnerBase wasm_runner_;
|
||||
WasmCodeRefScope code_ref_scope_;
|
||||
};
|
||||
|
||||
struct DebugSideTableEntry {
|
||||
|
@ -233,12 +233,16 @@ class TestingModuleBuilder {
|
||||
|
||||
void SetExecutable() { native_module_->SetExecutable(true); }
|
||||
|
||||
void TierDown() {
|
||||
void SetTieredDown() {
|
||||
native_module_->SetTieringState(kTieredDown);
|
||||
native_module_->RecompileForTiering();
|
||||
execution_tier_ = TestExecutionTier::kLiftoff;
|
||||
}
|
||||
|
||||
void TierDown() {
|
||||
SetTieredDown();
|
||||
native_module_->RecompileForTiering();
|
||||
}
|
||||
|
||||
CompilationEnv CreateCompilationEnv();
|
||||
|
||||
ExecutionTier execution_tier() const {
|
||||
|
Loading…
Reference in New Issue
Block a user