[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:
parent
63c95e6197
commit
078f7c4fca
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user