| Index: src/wasm/wasm-module.cc
|
| diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc
|
| index cee393b4cf6f12eb9c5c2b21cebd9c6abe922a6a..46f2814978344d4c0eab2660afa1fd2d942205ce 100644
|
| --- a/src/wasm/wasm-module.cc
|
| +++ b/src/wasm/wasm-module.cc
|
| @@ -758,6 +758,47 @@ Handle<Script> CreateWasmScript(Isolate* isolate,
|
|
|
| return script;
|
| }
|
| +
|
| +class JSToWasmWrapperCache {
|
| + public:
|
| + Handle<Code> CloneOrCompileJSToWasmWrapper(Isolate* isolate,
|
| + const wasm::WasmModule* module,
|
| + Handle<Code> wasm_code,
|
| + uint32_t index) {
|
| + const wasm::WasmFunction* func = &module->functions[index];
|
| + int cached_idx = sig_map_.Find(func->sig);
|
| + if (cached_idx >= 0) {
|
| + Handle<Code> code = isolate->factory()->CopyCode(code_cache_[cached_idx]);
|
| + // Now patch the call to wasm code.
|
| + for (RelocIterator it(*code, RelocInfo::kCodeTargetMask);; it.next()) {
|
| + DCHECK(!it.done());
|
| + Code* target =
|
| + Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
|
| + if (target->kind() == Code::WASM_FUNCTION ||
|
| + target->kind() == Code::WASM_TO_JS_FUNCTION ||
|
| + target->builtin_index() == Builtins::kIllegal) {
|
| + it.rinfo()->set_target_address(wasm_code->instruction_start());
|
| + break;
|
| + }
|
| + }
|
| + return code;
|
| + }
|
| +
|
| + Handle<Code> code =
|
| + compiler::CompileJSToWasmWrapper(isolate, module, wasm_code, index);
|
| + uint32_t new_cache_idx = sig_map_.FindOrInsert(func->sig);
|
| + DCHECK_EQ(code_cache_.size(), new_cache_idx);
|
| + USE(new_cache_idx);
|
| + code_cache_.push_back(code);
|
| + return code;
|
| + }
|
| +
|
| + private:
|
| + // sig_map_ maps signatures to an index in code_cache_.
|
| + wasm::SignatureMap sig_map_;
|
| + std::vector<Handle<Code>> code_cache_;
|
| +};
|
| +
|
| } // namespace
|
|
|
| Handle<JSArrayBuffer> SetupArrayBuffer(Isolate* isolate, void* backing_store,
|
| @@ -1022,13 +1063,13 @@ MaybeHandle<WasmModuleObject> CompileToModuleObject(
|
| }
|
|
|
| // Compile JS->WASM wrappers for exported functions.
|
| + JSToWasmWrapperCache js_to_wasm_cache;
|
| int func_index = 0;
|
| for (auto exp : m->export_table) {
|
| if (exp.kind != kExternalFunction) continue;
|
| - Handle<Code> wasm_code =
|
| - code_table->GetValueChecked<Code>(isolate, exp.index);
|
| - Handle<Code> wrapper_code =
|
| - compiler::CompileJSToWasmWrapper(isolate, m, wasm_code, exp.index);
|
| + Handle<Code> wasm_code(Code::cast(code_table->get(exp.index)), isolate);
|
| + Handle<Code> wrapper_code = js_to_wasm_cache.CloneOrCompileJSToWasmWrapper(
|
| + isolate, m, wasm_code, exp.index);
|
| int export_index = static_cast<int>(m->functions.size() + func_index);
|
| code_table->set(export_index, *wrapper_code);
|
| RecordStats(isolate, *wrapper_code);
|
| @@ -1489,8 +1530,9 @@ class InstantiationHelper {
|
| Handle<Code> startup_code =
|
| code_table->GetValueChecked<Code>(isolate_, start_index);
|
| FunctionSig* sig = module_->functions[start_index].sig;
|
| - Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper(
|
| - isolate_, module_, startup_code, start_index);
|
| + Handle<Code> wrapper_code =
|
| + js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper(
|
| + isolate_, module_, startup_code, start_index);
|
| Handle<WasmExportedFunction> startup_fct = WasmExportedFunction::New(
|
| isolate_, instance, MaybeHandle<String>(), start_index,
|
| static_cast<int>(sig->parameter_count()), wrapper_code);
|
| @@ -1536,6 +1578,7 @@ class InstantiationHelper {
|
| Handle<WasmCompiledModule> compiled_module_;
|
| std::vector<TableInstance> table_instances_;
|
| std::vector<Handle<JSFunction>> js_wrappers_;
|
| + JSToWasmWrapperCache js_to_wasm_cache_;
|
|
|
| // Helper routines to print out errors with imports.
|
| void ReportLinkError(const char* error, uint32_t index,
|
| @@ -2207,8 +2250,9 @@ class InstantiationHelper {
|
| temp_instance.mem_start = nullptr;
|
| temp_instance.globals_start = nullptr;
|
|
|
| - Handle<Code> wrapper_code = compiler::CompileJSToWasmWrapper(
|
| - isolate_, module_, wasm_code, func_index);
|
| + Handle<Code> wrapper_code =
|
| + js_to_wasm_cache_.CloneOrCompileJSToWasmWrapper(
|
| + isolate_, module_, wasm_code, func_index);
|
| MaybeHandle<String> func_name;
|
| if (module_->origin == kAsmJsOrigin) {
|
| // For modules arising from asm.js, honor the names section.
|
|
|