Index: src/wasm/wasm-module.cc |
diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc |
index 94bf998e538fc2b54ef9858f39e56393245f64b5..13773f21bedc2f4a4d0acef219e307012ba2d1f9 100644 |
--- a/src/wasm/wasm-module.cc |
+++ b/src/wasm/wasm-module.cc |
@@ -166,6 +166,8 @@ enum CompiledWasmObjectFields { |
kFunctions, // FixedArray of Code |
kImportData, // maybe FixedArray of FixedArray respecting the |
// WasmImportMetadata structure. |
+ kImportMap, // FixedArray. The i-th element is the Code object used for |
+ // import i |
kExports, // maybe FixedArray of FixedArray of WasmExportMetadata |
// structure |
kStartupFunction, // maybe FixedArray of WasmExportMetadata structure |
@@ -424,14 +426,6 @@ void LinkModuleFunctions(Isolate* isolate, |
} |
} |
-void LinkImports(Isolate* isolate, std::vector<Handle<Code>>& functions, |
- const std::vector<Handle<Code>>& imports) { |
- for (uint32_t i = 0; i < functions.size(); ++i) { |
- Handle<Code> code = functions[i]; |
- LinkFunction(code, imports, Code::WASM_TO_JS_FUNCTION); |
- } |
-} |
- |
void FlushAssemblyCache(Isolate* isolate, Handle<FixedArray> functions) { |
for (int i = 0; i < functions->length(); ++i) { |
Handle<Code> code = functions->GetValueChecked<Code>(isolate, i); |
@@ -966,17 +960,48 @@ bool SetupImports(Isolate* isolate, Handle<FixedArray> compiled_module, |
RecordStats(isolate, import_code); |
- Handle<FixedArray> code_table = Handle<FixedArray>( |
- FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); |
- // TODO(mtrofin): get the code off std::vector and on FixedArray, for |
- // consistency. |
- std::vector<Handle<Code>> function_code(code_table->length()); |
- for (int i = 0; i < code_table->length(); ++i) { |
- Handle<Code> code = Handle<Code>(Code::cast(code_table->get(i))); |
- function_code[i] = code; |
+ if (import_code.empty()) return true; |
+ |
+ { |
+ DisallowHeapAllocation no_gc; |
+ std::map<Code*, int> import_to_index; |
+ Handle<FixedArray> mapping = |
+ compiled_module->GetValueChecked<FixedArray>(isolate, kImportMap); |
+ for (int i = 0; i < mapping->length(); ++i) { |
+ import_to_index.insert(std::make_pair(Code::cast(mapping->get(i)), i)); |
+ } |
+ |
+ Handle<FixedArray> code_table = Handle<FixedArray>( |
+ FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable))); |
+ |
+ int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); |
+ AllowDeferredHandleDereference embedding_raw_address; |
+ for (int i = 0; i < code_table->length(); ++i) { |
+ Handle<Code> wasm_function = |
+ code_table->GetValueChecked<Code>(isolate, i); |
+ for (RelocIterator it(*wasm_function, mode_mask); !it.done(); it.next()) { |
+ Code* target = |
+ Code::GetCodeFromTargetAddress(it.rinfo()->target_address()); |
+ if (target->kind() == Code::WASM_TO_JS_FUNCTION) { |
+ auto found_index = import_to_index.find(target); |
+ CHECK(found_index != import_to_index.end()); |
+ int index = found_index->second; |
+ CHECK(index < static_cast<int>(import_code.size())); |
+ Handle<Code> new_target = import_code[index]; |
+ it.rinfo()->set_target_address(new_target->instruction_start(), |
+ UPDATE_WRITE_BARRIER, |
+ SKIP_ICACHE_FLUSH); |
+ } |
+ } |
+ } |
+ } |
+ Handle<FixedArray> new_mapping = |
+ isolate->factory()->NewFixedArray(static_cast<int>(import_code.size())); |
+ for (int i = 0; i < new_mapping->length(); ++i) { |
+ new_mapping->set(i, *import_code[i]); |
} |
+ compiled_module->set(kImportMap, *new_mapping); |
- LinkImports(isolate, function_code, import_code); |
return true; |
} |
@@ -1083,10 +1108,18 @@ MaybeHandle<FixedArray> WasmModule::CompileFunctions( |
Handle<FixedArray> compiled_functions = |
factory->NewFixedArray(static_cast<int>(functions.size()), TENURED); |
- temp_instance_for_compilation.import_code.resize(import_table.size()); |
- for (uint32_t i = 0; i < import_table.size(); ++i) { |
- temp_instance_for_compilation.import_code[i] = |
- CreatePlaceholder(factory, i, Code::WASM_TO_JS_FUNCTION); |
+ MaybeHandle<FixedArray> maybe_imports; |
+ if (import_table.size() > 0) { |
+ temp_instance_for_compilation.import_code.resize(import_table.size()); |
+ Handle<FixedArray> imports = |
+ factory->NewFixedArray(static_cast<int>(import_table.size())); |
+ for (uint32_t i = 0; i < import_table.size(); ++i) { |
+ Handle<Code> placeholder = |
+ CreatePlaceholder(factory, i, Code::WASM_TO_JS_FUNCTION); |
+ temp_instance_for_compilation.import_code[i] = placeholder; |
+ imports->set(i, *placeholder); |
+ } |
+ maybe_imports = imports; |
} |
isolate->counters()->wasm_functions_per_module()->AddSample( |
static_cast<int>(functions.size())); |
@@ -1118,6 +1151,9 @@ MaybeHandle<FixedArray> WasmModule::CompileFunctions( |
if (!indirect_table.is_null()) { |
ret->set(kTableOfIndirectFunctionTables, *indirect_table.ToHandleChecked()); |
} |
+ if (!maybe_imports.is_null()) { |
+ ret->set(kImportMap, *maybe_imports.ToHandleChecked()); |
+ } |
Handle<FixedArray> import_data = GetImportsMetadata(factory, this); |
ret->set(kImportData, *import_data); |