[wasm-gc] Add cache lookup to wrapper compilation

Bug: v8:7748
Change-Id: I3599be973b8f20d6fe3a9a7a25f18c06e1bc2a87
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4177096
Reviewed-by: Manos Koukoutos <manoskouk@chromium.org>
Commit-Queue: Matthias Liedtke <mliedtke@chromium.org>
Auto-Submit: Matthias Liedtke <mliedtke@chromium.org>
Cr-Commit-Position: refs/heads/main@{#85431}
This commit is contained in:
Matthias Liedtke 2023-01-23 12:23:56 +01:00 committed by V8 LUCI CQ
parent 21ab8287a6
commit 3e64021c7e
5 changed files with 70 additions and 5 deletions

View File

@ -343,7 +343,8 @@ namespace internal {
SC(lo_space_bytes_used, V8.MemoryLoSpaceBytesUsed) \
SC(wasm_generated_code_size, V8.WasmGeneratedCodeBytes) \
SC(wasm_reloc_size, V8.WasmRelocBytes) \
SC(wasm_lazily_compiled_functions, V8.WasmLazilyCompiledFunctions)
SC(wasm_lazily_compiled_functions, V8.WasmLazilyCompiledFunctions) \
SC(wasm_compiled_export_wrapper, V8.WasmCompiledExportWrappers)
// List of counters that can be incremented from generated code. We need them in
// a separate list to be able to relocate them.

View File

@ -528,5 +528,13 @@ RUNTIME_FUNCTION(Runtime_FlushWasmCode) {
return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_WasmCompiledExportWrappersCount) {
int count = isolate->counters()
->wasm_compiled_export_wrapper()
->GetInternalPointer()
->load();
return Smi::FromInt(count);
}
} // namespace internal
} // namespace v8

View File

@ -673,6 +673,7 @@ namespace internal {
F(SetWasmCompileControls, 2, 1) \
F(SetWasmInstantiateControls, 0, 1) \
F(SetWasmGCEnabled, 1, 1) \
F(WasmCompiledExportWrappersCount, 0, 1) \
F(WasmGetNumberOfInstances, 1, 1) \
F(WasmNumCodeSpaces, 1, 1) \
F(WasmEnterDebugging, 0, 1) \

View File

@ -1628,6 +1628,19 @@ int AddExportWrapperUnits(Isolate* isolate, NativeModule* native_module,
uint32_t canonical_type_index =
native_module->module()
->isorecursive_canonical_type_ids[function.sig_index];
int wrapper_index =
GetExportWrapperIndex(canonical_type_index, function.imported);
if (wrapper_index < isolate->heap()->js_to_wasm_wrappers().length()) {
MaybeObject existing_wrapper =
isolate->heap()->js_to_wasm_wrappers().Get(wrapper_index);
if (existing_wrapper.IsStrongOrWeak() &&
!existing_wrapper.GetHeapObject().IsUndefined()) {
// Skip wrapper compilation as the wrapper is already cached.
// Note that this does not guarantee that the wrapper is still cached
// at the moment at which the WasmInternalFunction is instantiated.
continue;
}
}
JSToWasmWrapperKey key(function.imported, canonical_type_index);
if (keys.insert(key).second) {
auto unit = std::make_shared<JSToWasmWrapperCompilationUnit>(
@ -1943,7 +1956,6 @@ std::shared_ptr<NativeModule> CompileToNativeModule(
// {cached_native_module} instead.
module.reset();
native_module.reset();
CompileJsToWasmWrappers(isolate, cached_native_module->module());
return cached_native_module;
}
@ -3343,12 +3355,18 @@ void CompilationStateImpl::FinalizeJSToWasmWrappers(Isolate* isolate,
CodePageCollectionMemoryModificationScope modification_scope(isolate->heap());
for (auto& unit : js_to_wasm_wrapper_units_) {
DCHECK_EQ(isolate, unit->isolate());
// Note: The code is either the compiled signature-specific wrapper or the
// generic wrapper built-in.
Handle<Code> code = unit->Finalize();
uint32_t index =
GetExportWrapperIndex(unit->canonical_sig_index(), unit->is_import());
isolate->heap()->js_to_wasm_wrappers().Set(index,
MaybeObject::FromObject(*code));
RecordStats(*code, isolate->counters());
if (!code->is_builtin()) {
// Do not increase code stats for non-jitted wrappers.
RecordStats(*code, isolate->counters());
isolate->counters()->wasm_compiled_export_wrapper()->Increment(1);
}
}
}
@ -3760,7 +3778,7 @@ void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module) {
module->isorecursive_canonical_type_ids[function.sig_index];
int wrapper_index =
GetExportWrapperIndex(canonical_type_index, function.imported);
auto existing_wrapper =
MaybeObject existing_wrapper =
isolate->heap()->js_to_wasm_wrappers().Get(wrapper_index);
if (existing_wrapper.IsStrongOrWeak() &&
!existing_wrapper.GetHeapObject().IsUndefined()) {
@ -3809,7 +3827,11 @@ void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module) {
int wrapper_index = GetExportWrapperIndex(key.second, key.first);
isolate->heap()->js_to_wasm_wrappers().Set(
wrapper_index, HeapObjectReference::Strong(*code));
RecordStats(*code, isolate->counters());
if (!code->is_builtin()) {
// Do not increase code stats for non-jitted wrappers.
RecordStats(*code, isolate->counters());
isolate->counters()->wasm_compiled_export_wrapper()->Increment(1);
}
}
}

View File

@ -0,0 +1,33 @@
// Copyright 2023 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: --experimental-wasm-gc --allow-natives-syntax --dump-counters
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
function compileAdd(val) {
var builder = new WasmModuleBuilder();
let struct = builder.addStruct([makeField(kWasmI32, true)]);
let sig = makeSig([kWasmI32], [wasmRefType(struct)])
builder.addFunction(`fct`, sig)
.addBody([
kExprLocalGet, 0,
kExprI32Const, val,
kExprI32Add,
kGCPrefix, kExprStructNew, struct,
])
.exportFunc();
return builder.instantiate();
}
assertEquals(0, %WasmCompiledExportWrappersCount());
let a = compileAdd(1);
a.exports.fct(1);
assertEquals(1, %WasmCompiledExportWrappersCount());
let b = compileAdd(2);
b.exports.fct(1);
assertEquals(1, %WasmCompiledExportWrappersCount());
let c = compileAdd(2);
c.exports.fct(1);
assertEquals(1, %WasmCompiledExportWrappersCount());