[wasm] Unhandlify UpdateDispatchTables

UpdateDispatchTables is the hottest function during Wasm instantiation,
thus dehandlify it, as it does not allocate on the JS heap anyway. This
saves ~20% of instantiation time locally.

R=manoskouk@chromium.org

Bug: v8:12593
Cq-Include-Trybots: luci.v8.try:v8_linux_gc_stress_dbg_ng
Cq-Include-Trybots: luci.v8.try:v8_mac64_gc_stress_dbg_ng
Change-Id: Ifdd3f8fcd2e31950b591b179a62a0d397c41c339
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3429205
Reviewed-by: Manos Koukoutos <manoskouk@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78904}
This commit is contained in:
Clemens Backes 2022-02-02 12:55:01 +01:00 committed by V8 LUCI CQ
parent 63c95e6197
commit 078f7c4fca
3 changed files with 36 additions and 33 deletions

View File

@ -1908,8 +1908,8 @@ V8_INLINE void SetFunctionTablePlaceholder(Isolate* isolate,
table_object->entries().set(entry_index,
*wasm_internal_function.ToHandleChecked());
}
WasmTableObject::UpdateDispatchTables(isolate, table_object, entry_index,
function->sig, instance, func_index);
WasmTableObject::UpdateDispatchTables(isolate, *table_object, entry_index,
function->sig, *instance, func_index);
}
V8_INLINE void SetFunctionTableNullEntry(Isolate* isolate,

View File

@ -358,8 +358,8 @@ void WasmTableObject::SetFunctionTableEntry(Isolate* isolate,
auto* wasm_function = &target_instance->module()->functions[func_index];
DCHECK_NOT_NULL(wasm_function);
DCHECK_NOT_NULL(wasm_function->sig);
UpdateDispatchTables(isolate, table, entry_index, wasm_function->sig,
target_instance, func_index);
UpdateDispatchTables(isolate, *table, entry_index, wasm_function->sig,
*target_instance, func_index);
} else if (WasmJSFunction::IsWasmJSFunction(*external)) {
UpdateDispatchTables(isolate, table, entry_index,
Handle<WasmJSFunction>::cast(external));
@ -478,37 +478,41 @@ void WasmTableObject::Fill(Isolate* isolate, Handle<WasmTableObject> table,
}
}
void WasmTableObject::UpdateDispatchTables(
Isolate* isolate, Handle<WasmTableObject> table, int entry_index,
const wasm::FunctionSig* sig, Handle<WasmInstanceObject> target_instance,
void WasmTableObject::UpdateDispatchTables(Isolate* isolate,
WasmTableObject table,
int entry_index,
const wasm::FunctionSig* sig,
WasmInstanceObject target_instance,
int target_func_index) {
DisallowGarbageCollection no_gc;
// We simply need to update the IFTs for each instance that imports
// this table.
Handle<FixedArray> dispatch_tables(table->dispatch_tables(), isolate);
DCHECK_EQ(0, dispatch_tables->length() % kDispatchTableNumElements);
FunctionTargetAndRef entry(target_instance, target_func_index);
FixedArray dispatch_tables = table.dispatch_tables();
DCHECK_EQ(0, dispatch_tables.length() % kDispatchTableNumElements);
for (int i = 0; i < dispatch_tables->length();
Object call_ref =
target_func_index <
static_cast<int>(target_instance.module()->num_imported_functions)
// The function in the target instance was imported. Use its imports
// table, which contains a tuple needed by the import wrapper.
? target_instance.imported_function_refs().get(target_func_index)
// For wasm functions, just pass the target instance.
: target_instance;
Address call_target = target_instance.GetCallTarget(target_func_index);
for (int i = 0, len = dispatch_tables.length(); i < len;
i += kDispatchTableNumElements) {
int table_index =
Smi::cast(dispatch_tables->get(i + kDispatchTableIndexOffset)).value();
if (*target_instance ==
dispatch_tables->get(i + kDispatchTableInstanceOffset)) {
// Skip creating a handle if the IFT belongs to the {target_instance}.
auto sig_id = target_instance->module()->signature_map.Find(*sig);
target_instance->GetIndirectFunctionTable(isolate, table_index)
->Set(entry_index, sig_id, entry.call_target(), *entry.ref());
} else {
Handle<WasmInstanceObject> instance =
handle(WasmInstanceObject::cast(
dispatch_tables->get(i + kDispatchTableInstanceOffset)),
isolate);
Smi::cast(dispatch_tables.get(i + kDispatchTableIndexOffset)).value();
WasmInstanceObject instance = WasmInstanceObject::cast(
dispatch_tables.get(i + kDispatchTableInstanceOffset));
// Note that {SignatureMap::Find} may return {-1} if the signature is
// not found; it will simply never match any check.
auto sig_id = instance->module()->signature_map.Find(*sig);
instance->GetIndirectFunctionTable(isolate, table_index)
->Set(entry_index, sig_id, entry.call_target(), *entry.ref());
}
auto sig_id = instance.module()->signature_map.Find(*sig);
WasmIndirectFunctionTable ift = WasmIndirectFunctionTable::cast(
instance.indirect_function_tables().get(table_index));
ift.Set(entry_index, sig_id, call_target, call_ref);
}
}

View File

@ -202,11 +202,10 @@ class WasmTableObject
uint32_t count);
// TODO(wasm): Unify these three methods into one.
static void UpdateDispatchTables(Isolate* isolate,
Handle<WasmTableObject> table,
static void UpdateDispatchTables(Isolate* isolate, WasmTableObject table,
int entry_index,
const wasm::FunctionSig* sig,
Handle<WasmInstanceObject> target_instance,
WasmInstanceObject target_instance,
int target_func_index);
static void UpdateDispatchTables(Isolate* isolate,
Handle<WasmTableObject> table,