Index: src/wasm/wasm-module.cc |
diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc |
index f075b1e40903a54f3527bf9eb5f53f40cbc32252..5cd89f52be12f4dc51d9bf93f0440be3be8e72e0 100644 |
--- a/src/wasm/wasm-module.cc |
+++ b/src/wasm/wasm-module.cc |
@@ -467,9 +467,18 @@ int AdvanceSourcePositionTableIterator(SourcePositionTableIterator& iterator, |
return byte_pos; |
} |
-void PatchDirectCalls(Handle<FixedArray> new_functions, |
- Handle<WasmCompiledModule> compiled_module, |
- WasmModule* module, int start) { |
+void PatchContext(RelocIterator& it, Context* context) { |
+ Object* old = it.rinfo()->target_object(); |
+ // The only context we use is the native context. |
+ DCHECK_IMPLIES(old->IsContext(), old->IsNativeContext()); |
+ if (!old->IsNativeContext()) return; |
+ it.rinfo()->set_target_object(context, UPDATE_WRITE_BARRIER, |
+ SKIP_ICACHE_FLUSH); |
+} |
+ |
+void PatchDirectCallsAndContext(Handle<FixedArray> new_functions, |
+ Handle<WasmCompiledModule> compiled_module, |
+ WasmModule* module, int start) { |
DisallowHeapAllocation no_gc; |
AllowDeferredHandleDereference embedding_raw_address; |
SeqOneByteString* module_bytes = compiled_module->module_bytes(); |
@@ -479,6 +488,9 @@ void PatchDirectCalls(Handle<FixedArray> new_functions, |
compiled_module->module()->num_exported_functions, |
new_functions->length()); |
DCHECK_EQ(start, compiled_module->module()->num_imported_functions); |
+ Context* context = compiled_module->ptr_to_native_context(); |
+ int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
+ RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
// Allocate decoder outside of the loop and reuse it to decode all function |
// indexes. |
@@ -499,8 +511,12 @@ void PatchDirectCalls(Handle<FixedArray> new_functions, |
const byte* func_bytes = |
module_bytes->GetChars() + |
compiled_module->module()->functions[func_index].code_start_offset; |
- for (RelocIterator it(wasm_function, RelocInfo::kCodeTargetMask); |
- !it.done(); it.next()) { |
+ for (RelocIterator it(wasm_function, mode_mask); !it.done(); it.next()) { |
+ if (RelocInfo::IsEmbeddedObject(it.rinfo()->rmode())) { |
+ PatchContext(it, context); |
+ continue; |
+ } |
+ DCHECK(RelocInfo::IsCodeTarget(it.rinfo()->rmode())); |
Code::Kind kind = |
Code::GetCodeFromTargetAddress(it.rinfo()->target_address())->kind(); |
if (kind != Code::WASM_FUNCTION && kind != Code::WASM_TO_JS_FUNCTION) |
@@ -522,8 +538,12 @@ void PatchDirectCalls(Handle<FixedArray> new_functions, |
DCHECK_EQ(Code::JS_TO_WASM_FUNCTION, export_wrapper->kind()); |
// There must be exactly one call to WASM_FUNCTION or WASM_TO_JS_FUNCTION. |
int num_wasm_calls = 0; |
- for (RelocIterator it(export_wrapper, RelocInfo::kCodeTargetMask); |
- !it.done(); it.next()) { |
+ for (RelocIterator it(export_wrapper, mode_mask); !it.done(); it.next()) { |
+ if (RelocInfo::IsEmbeddedObject(it.rinfo()->rmode())) { |
+ PatchContext(it, context); |
+ continue; |
+ } |
+ DCHECK(RelocInfo::IsCodeTarget(it.rinfo()->rmode())); |
Code::Kind kind = |
Code::GetCodeFromTargetAddress(it.rinfo()->target_address())->kind(); |
if (kind != Code::WASM_FUNCTION && kind != Code::WASM_TO_JS_FUNCTION) |
@@ -1237,6 +1257,7 @@ class WasmInstanceBuilder { |
compiled_module_->instance_id()); |
} |
compiled_module_->set_code_table(code_table); |
+ compiled_module_->set_native_context(isolate_->native_context()); |
} |
module_ = compiled_module_->module(); |
@@ -1366,11 +1387,9 @@ class WasmInstanceBuilder { |
//-------------------------------------------------------------------------- |
if (function_table_count > 0) InitializeTables(code_table, instance); |
- if (num_imported_functions > 0 || !owner.is_null()) { |
- // If the code was cloned, or new imports were compiled, patch. |
- PatchDirectCalls(code_table, compiled_module_, module_, |
- num_imported_functions); |
- } |
+ // Patch new call sites and the context. |
+ PatchDirectCallsAndContext(code_table, compiled_module_, module_, |
+ num_imported_functions); |
FlushICache(isolate_, code_table); |