Commit 4dd0d712 authored by Mircea Trofin's avatar Mircea Trofin Committed by Commit Bot

[wasm] Correctly delete global handles to tables

We weren't deleting them correctly - the intention was to delete
them when an instance is finalized; the code was deleting them
only for the last instance in a chain of instances.

Bug: 
Change-Id: I177a64ac9f10a4993927d9654c032cb3f22eca51
Reviewed-on: https://chromium-review.googlesource.com/651238Reviewed-by: 's avatarBrad Nelson <bradnelson@chromium.org>
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47841}
parent 1902b5a9
...@@ -124,6 +124,9 @@ static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) { ...@@ -124,6 +124,9 @@ static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
WasmMemoryObject::RemoveInstance(isolate, memory, instance); WasmMemoryObject::RemoveInstance(isolate, memory, instance);
} }
// In all cases, release the global handles held to tables by this instance
WasmCompiledModule::DestroyGlobalHandles(isolate, compiled_module);
// weak_wasm_module may have been cleared, meaning the module object // weak_wasm_module may have been cleared, meaning the module object
// was GC-ed. In that case, there won't be any new instances created, // was GC-ed. In that case, there won't be any new instances created,
// and we don't need to maintain the links between instances. // and we don't need to maintain the links between instances.
......
...@@ -941,9 +941,31 @@ Address WasmCompiledModule::GetTableValue(FixedArray* table, int index) { ...@@ -941,9 +941,31 @@ Address WasmCompiledModule::GetTableValue(FixedArray* table, int index) {
return reinterpret_cast<Address>(static_cast<size_t>(value)); return reinterpret_cast<Address>(static_cast<size_t>(value));
} }
void WasmCompiledModule::DestroyGlobalHandles(
Isolate* isolate, WasmCompiledModule* compiled_module) {
DisallowHeapAllocation no_gc;
if (compiled_module->has_function_tables()) {
FixedArray* function_tables = compiled_module->ptr_to_function_tables();
FixedArray* signature_tables = compiled_module->ptr_to_signature_tables();
FixedArray* empty_function_tables =
compiled_module->ptr_to_empty_function_tables();
// We don't release the placeholder ("empty") handles here, we do so
// in {WasmModuleObject::Finalizer}.
if (function_tables != empty_function_tables) {
for (int i = 0, e = function_tables->length(); i < e; ++i) {
GlobalHandleAddress func_addr =
WasmCompiledModule::GetTableValue(function_tables, i);
GlobalHandleAddress sig_addr =
WasmCompiledModule::GetTableValue(signature_tables, i);
GlobalHandles::Destroy(reinterpret_cast<Object**>(func_addr));
GlobalHandles::Destroy(reinterpret_cast<Object**>(sig_addr));
}
}
}
}
void WasmCompiledModule::Reset(Isolate* isolate, void WasmCompiledModule::Reset(Isolate* isolate,
WasmCompiledModule* compiled_module, WasmCompiledModule* compiled_module) {
bool clear_global_handles) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
TRACE("Resetting %d\n", compiled_module->instance_id()); TRACE("Resetting %d\n", compiled_module->instance_id());
Object* undefined = *isolate->factory()->undefined_value(); Object* undefined = *isolate->factory()->undefined_value();
...@@ -971,7 +993,10 @@ void WasmCompiledModule::Reset(Isolate* isolate, ...@@ -971,7 +993,10 @@ void WasmCompiledModule::Reset(Isolate* isolate,
compiled_module->set_globals_start(0); compiled_module->set_globals_start(0);
} }
// Reset function tables. // Reset function tables. The global handles have been freed (see
// {DestroyGlobalHandles})
// The pointers are still embedded in code - so we want to reset
// them with the "empty" ones.
if (compiled_module->has_function_tables()) { if (compiled_module->has_function_tables()) {
FixedArray* function_tables = compiled_module->ptr_to_function_tables(); FixedArray* function_tables = compiled_module->ptr_to_function_tables();
FixedArray* signature_tables = compiled_module->ptr_to_signature_tables(); FixedArray* signature_tables = compiled_module->ptr_to_signature_tables();
...@@ -992,15 +1017,6 @@ void WasmCompiledModule::Reset(Isolate* isolate, ...@@ -992,15 +1017,6 @@ void WasmCompiledModule::Reset(Isolate* isolate,
code_specialization.RelocatePointer( code_specialization.RelocatePointer(
sig_addr, sig_addr,
WasmCompiledModule::GetTableValue(empty_signature_tables, i)); WasmCompiledModule::GetTableValue(empty_signature_tables, i));
// We create a global handle per table per instance. When sharing
// tables, to avoid accummulating global handles until the last
// instance sharing the table is GC-ed, destroy the handles here.
// Except if we call this post-deserialize - because maybe the
// instance that originated the {WasmCompiledModule} is still alive.
if (clear_global_handles) {
GlobalHandles::Destroy(reinterpret_cast<Object**>(func_addr));
GlobalHandles::Destroy(reinterpret_cast<Object**>(sig_addr));
}
} }
compiled_module->set_ptr_to_function_tables(empty_function_tables); compiled_module->set_ptr_to_function_tables(empty_function_tables);
compiled_module->set_ptr_to_signature_tables(empty_signature_tables); compiled_module->set_ptr_to_signature_tables(empty_signature_tables);
...@@ -1187,9 +1203,7 @@ void WasmCompiledModule::ReinitializeAfterDeserialization( ...@@ -1187,9 +1203,7 @@ void WasmCompiledModule::ReinitializeAfterDeserialization(
} }
} }
// Reset, but don't delete any global handles, because their owning instance WasmCompiledModule::Reset(isolate, *compiled_module);
// may still be active.
WasmCompiledModule::Reset(isolate, *compiled_module, false);
DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*shared)); DCHECK(WasmSharedModuleData::IsWasmSharedModuleData(*shared));
} }
......
...@@ -421,8 +421,9 @@ class WasmCompiledModule : public FixedArray { ...@@ -421,8 +421,9 @@ class WasmCompiledModule : public FixedArray {
static Handle<WasmCompiledModule> Clone(Isolate* isolate, static Handle<WasmCompiledModule> Clone(Isolate* isolate,
Handle<WasmCompiledModule> module); Handle<WasmCompiledModule> module);
static void Reset(Isolate* isolate, WasmCompiledModule* module, static void Reset(Isolate* isolate, WasmCompiledModule* module);
bool clear_global_handles = true); static void DestroyGlobalHandles(Isolate* isolate,
WasmCompiledModule* compiled_module);
inline Address GetEmbeddedMemStartOrNull() const; inline Address GetEmbeddedMemStartOrNull() const;
inline Address GetGlobalsStartOrNull() const; inline Address GetGlobalsStartOrNull() const;
......
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