Commit 53d47216 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Avoid redundant code copy for interpreter entry.

This avoids creating an on-heap copy for interpreter entry wrappers by
directly adding the {WasmCode} into the native heap instead. It reduces
compilation time as well as useless GC pressure.

R=clemensh@chromium.org
BUG=v8:8423

Change-Id: I91a8f3fc9fe542233d8700a58585f4715eed695a
Reviewed-on: https://chromium-review.googlesource.com/c/1337570Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57527}
parent ea39a981
......@@ -2089,9 +2089,9 @@ MaybeHandle<Code> Pipeline::GenerateCodeForCodeStub(
// static
wasm::WasmCode* Pipeline::GenerateCodeForWasmNativeStub(
wasm::WasmEngine* wasm_engine, CallDescriptor* call_descriptor,
MachineGraph* mcgraph, Code::Kind kind, const char* debug_name,
const AssemblerOptions& options, wasm::NativeModule* native_module,
SourcePositionTable* source_positions) {
MachineGraph* mcgraph, Code::Kind kind, int wasm_kind,
const char* debug_name, const AssemblerOptions& options,
wasm::NativeModule* native_module, SourcePositionTable* source_positions) {
Graph* graph = mcgraph->graph();
OptimizedCompilationInfo info(CStrVector(debug_name), graph->zone(), kind);
// Construct a pipeline for scheduling and code generation.
......@@ -2139,8 +2139,6 @@ wasm::WasmCode* Pipeline::GenerateCodeForWasmNativeStub(
CodeDesc code_desc;
code_generator->tasm()->GetCode(nullptr, &code_desc);
// TODO(mstarzinger): This is specific to Wasm-to-JS wrappers, fix this before
// using it for other wrappers (like the interpreter entry wrapper).
wasm::WasmCode* code = native_module->AddCode(
data.wasm_function_index(), code_desc,
code_generator->frame()->GetTotalFrameSlotCount(),
......@@ -2148,7 +2146,7 @@ wasm::WasmCode* Pipeline::GenerateCodeForWasmNativeStub(
code_generator->GetHandlerTableOffset(),
code_generator->GetProtectedInstructions(),
code_generator->GetSourcePositionTable(),
wasm::WasmCode::kWasmToJsWrapper, wasm::WasmCode::kOther);
static_cast<wasm::WasmCode::Kind>(wasm_kind), wasm::WasmCode::kOther);
if (info.trace_turbo_json_enabled()) {
TurboJsonFile json_of(&info, std::ios_base::app);
......
......@@ -55,8 +55,8 @@ class Pipeline : public AllStatic {
// Run the pipeline on a machine graph and generate code.
static wasm::WasmCode* GenerateCodeForWasmNativeStub(
wasm::WasmEngine* wasm_engine, CallDescriptor* call_descriptor,
MachineGraph* mcgraph, Code::Kind kind, const char* debug_name,
const AssemblerOptions& assembler_options,
MachineGraph* mcgraph, Code::Kind kind, int wasm_kind,
const char* debug_name, const AssemblerOptions& assembler_options,
wasm::NativeModule* native_module,
SourcePositionTable* source_positions = nullptr);
......
......@@ -5079,8 +5079,8 @@ wasm::WasmCode* CompileWasmImportCallWrapper(Isolate* isolate,
}
wasm::WasmCode* wasm_code = Pipeline::GenerateCodeForWasmNativeStub(
isolate->wasm_engine(), incoming, &jsgraph, Code::WASM_TO_JS_FUNCTION,
func_name, AssemblerOptions::Default(isolate), native_module,
source_position_table);
wasm::WasmCode::kWasmToJsWrapper, func_name,
AssemblerOptions::Default(isolate), native_module, source_position_table);
CHECK_NOT_NULL(wasm_code);
return wasm_code;
......@@ -5121,26 +5121,11 @@ wasm::WasmCode* CompileWasmInterpreterEntry(Isolate* isolate,
func_name.Truncate(
SNPrintF(func_name, "wasm-interpreter-entry#%d", func_index));
MaybeHandle<Code> maybe_code = Pipeline::GenerateCodeForWasmHeapStub(
isolate, incoming, &graph, Code::WASM_INTERPRETER_ENTRY,
func_name.start(), AssemblerOptions::Default(isolate));
Handle<Code> code = maybe_code.ToHandleChecked();
#ifdef ENABLE_DISASSEMBLER
if (FLAG_print_opt_code) {
CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
OFStream os(tracing_scope.file());
code->Disassemble(func_name.start(), os);
}
#endif
if (must_record_function_compilation(isolate)) {
RecordFunctionCompilation(CodeEventListener::STUB_TAG, isolate, code,
"%.*s", func_name.length(), func_name.start());
}
// TODO(wasm): No need to compile the code onto the heap and copy back.
wasm::WasmCode* wasm_code =
native_module->AddInterpreterEntry(code, func_index);
wasm::WasmCode* wasm_code = Pipeline::GenerateCodeForWasmNativeStub(
isolate->wasm_engine(), incoming, &jsgraph, Code::WASM_INTERPRETER_ENTRY,
wasm::WasmCode::kInterpreterEntry, func_name.start(),
AssemblerOptions::Default(isolate), native_module);
CHECK_NOT_NULL(wasm_code);
return wasm_code;
}
......
......@@ -430,16 +430,6 @@ WasmCode* NativeModule::AddOwnedCode(
return code;
}
WasmCode* NativeModule::AddInterpreterEntry(Handle<Code> code,
uint32_t func_index) {
WasmCode* ret = AddAnonymousCode(code, WasmCode::kInterpreterEntry);
ret->index_ = func_index;
base::MutexGuard lock(&allocation_mutex_);
InstallCode(ret);
SetInterpreterRedirection(func_index);
return ret;
}
WasmCode* NativeModule::AddCodeForTesting(Handle<Code> code) {
WasmCode* ret = AddAnonymousCode(code, WasmCode::kFunction);
return ret;
......@@ -622,6 +612,14 @@ void NativeModule::PublishCode(WasmCode* code) {
InstallCode(code);
}
void NativeModule::PublishInterpreterEntry(WasmCode* code,
uint32_t func_index) {
code->index_ = func_index;
base::MutexGuard lock(&allocation_mutex_);
InstallCode(code);
SetInterpreterRedirection(func_index);
}
std::vector<WasmCode*> NativeModule::SnapshotCodeTable() const {
base::MutexGuard lock(&allocation_mutex_);
std::vector<WasmCode*> result;
......
......@@ -232,12 +232,6 @@ class V8_EXPORT_PRIVATE NativeModule final {
OwnedVector<const byte> reloc_info,
OwnedVector<const byte> source_position_table, WasmCode::Tier tier);
// Add an interpreter entry. We currently compile these using a different
// pipeline and we can't get a CodeDesc here. When adding interpreter
// wrappers, we do not insert them in the code_table, however, we let them
// self-identify as the {index} function.
WasmCode* AddInterpreterEntry(Handle<Code> code, uint32_t index);
// Adds anonymous code for testing purposes.
WasmCode* AddCodeForTesting(Handle<Code> code);
......@@ -257,6 +251,11 @@ class V8_EXPORT_PRIVATE NativeModule final {
// threads executing the old code.
void PublishCode(WasmCode* code);
// Switch a function to an interpreter entry wrapper. When adding interpreter
// wrappers, we do not insert them in the code_table, however, we let them
// self-identify as the {index} function.
void PublishInterpreterEntry(WasmCode* code, uint32_t index);
// Creates a snapshot of the current state of the code table. This is useful
// to get a consistent view of the table (e.g. used by the serializer).
std::vector<WasmCode*> SnapshotCodeTable() const;
......
......@@ -626,8 +626,9 @@ void WasmDebugInfo::RedirectToInterpreter(Handle<WasmDebugInfo> debug_info,
DCHECK_GT(module->functions.size(), func_index);
if (!interpreted_functions->get(func_index)->IsUndefined(isolate)) continue;
const wasm::WasmCode* wasm_new_code = compiler::CompileWasmInterpreterEntry(
wasm::WasmCode* wasm_new_code = compiler::CompileWasmInterpreterEntry(
isolate, native_module, func_index, module->functions[func_index].sig);
native_module->PublishInterpreterEntry(wasm_new_code, func_index);
Handle<Foreign> foreign_holder = isolate->factory()->NewForeign(
wasm_new_code->instruction_start(), TENURED);
interpreted_functions->set(func_index, *foreign_holder);
......
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