From 078f7c4fca3cf24add3e8debfc21824a21439083 Mon Sep 17 00:00:00 2001 From: Clemens Backes Date: Wed, 2 Feb 2022 12:55:01 +0100 Subject: [PATCH] [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 Commit-Queue: Clemens Backes Cr-Commit-Position: refs/heads/main@{#78904} --- src/wasm/module-instantiate.cc | 4 +-- src/wasm/wasm-objects.cc | 60 ++++++++++++++++++---------------- src/wasm/wasm-objects.h | 5 ++- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/src/wasm/module-instantiate.cc b/src/wasm/module-instantiate.cc index c0bb8591d6..3f8f5c7519 100644 --- a/src/wasm/module-instantiate.cc +++ b/src/wasm/module-instantiate.cc @@ -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, diff --git a/src/wasm/wasm-objects.cc b/src/wasm/wasm-objects.cc index 0025e924ce..a5dbe62603 100644 --- a/src/wasm/wasm-objects.cc +++ b/src/wasm/wasm-objects.cc @@ -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::cast(external)); @@ -478,37 +478,41 @@ void WasmTableObject::Fill(Isolate* isolate, Handle table, } } -void WasmTableObject::UpdateDispatchTables( - Isolate* isolate, Handle table, int entry_index, - const wasm::FunctionSig* sig, Handle target_instance, - int target_func_index) { +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 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(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 instance = - handle(WasmInstanceObject::cast( - dispatch_tables->get(i + kDispatchTableInstanceOffset)), - isolate); - // 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()); - } + 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); + WasmIndirectFunctionTable ift = WasmIndirectFunctionTable::cast( + instance.indirect_function_tables().get(table_index)); + ift.Set(entry_index, sig_id, call_target, call_ref); } } diff --git a/src/wasm/wasm-objects.h b/src/wasm/wasm-objects.h index 1cea466ec6..4d2f6b4f33 100644 --- a/src/wasm/wasm-objects.h +++ b/src/wasm/wasm-objects.h @@ -202,11 +202,10 @@ class WasmTableObject uint32_t count); // TODO(wasm): Unify these three methods into one. - static void UpdateDispatchTables(Isolate* isolate, - Handle table, + static void UpdateDispatchTables(Isolate* isolate, WasmTableObject table, int entry_index, const wasm::FunctionSig* sig, - Handle target_instance, + WasmInstanceObject target_instance, int target_func_index); static void UpdateDispatchTables(Isolate* isolate, Handle table,