[wasm] Lazy-compilation: Support exporting an import
When exporting an imported wasm function, we generate a js-to-wasm wrapper which calls the wasm-to-wasm wrapper (which then tail-calls the WasmCompileLazy stub). This wasm-to-wasm wrapper also needs to be patched. R=titzer@chromium.org Bug: chromium:788441, v8:5991 Change-Id: Ibf27618a0511851cb55714b720fe7299a21c2959 Reviewed-on: https://chromium-review.googlesource.com/795990 Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Ben Titzer <titzer@chromium.org> Cr-Commit-Position: refs/heads/master@{#49715}
This commit is contained in:
parent
0d5b0d7365
commit
690ac5760c
@ -1041,9 +1041,9 @@ Handle<Code> LazyCompilationOrchestrator::CompileLazyOnGCHeap(
|
|||||||
// remember that code object.
|
// remember that code object.
|
||||||
Handle<Code> wasm_to_wasm_callee;
|
Handle<Code> wasm_to_wasm_callee;
|
||||||
|
|
||||||
if (is_js_to_wasm) {
|
// For js-to-wasm wrappers, don't iterate the reloc info. There is just one
|
||||||
non_compiled_functions.push_back({0, exported_func_index});
|
// call site in there anyway.
|
||||||
} else if (patch_caller) {
|
if (patch_caller && !is_js_to_wasm) {
|
||||||
DisallowHeapAllocation no_gc;
|
DisallowHeapAllocation no_gc;
|
||||||
SourcePositionTableIterator source_pos_iterator(
|
SourcePositionTableIterator source_pos_iterator(
|
||||||
caller->SourcePositionTable());
|
caller->SourcePositionTable());
|
||||||
@ -1111,7 +1111,7 @@ Handle<Code> LazyCompilationOrchestrator::CompileLazyOnGCHeap(
|
|||||||
isolate);
|
isolate);
|
||||||
DCHECK_EQ(Code::WASM_FUNCTION, compiled_function->kind());
|
DCHECK_EQ(Code::WASM_FUNCTION, compiled_function->kind());
|
||||||
|
|
||||||
if (is_js_to_wasm || patch_caller) {
|
if (patch_caller || is_js_to_wasm) {
|
||||||
DisallowHeapAllocation no_gc;
|
DisallowHeapAllocation no_gc;
|
||||||
// TODO(6792): No longer needed once WebAssembly code is off heap.
|
// TODO(6792): No longer needed once WebAssembly code is off heap.
|
||||||
CodeSpaceMemoryModificationScope modification_scope(isolate->heap());
|
CodeSpaceMemoryModificationScope modification_scope(isolate->heap());
|
||||||
@ -1124,27 +1124,30 @@ Handle<Code> LazyCompilationOrchestrator::CompileLazyOnGCHeap(
|
|||||||
Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
|
Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
|
||||||
if (callee->builtin_index() != Builtins::kWasmCompileLazy) {
|
if (callee->builtin_index() != Builtins::kWasmCompileLazy) {
|
||||||
// If the callee is the wasm-to-wasm wrapper triggering this lazy
|
// If the callee is the wasm-to-wasm wrapper triggering this lazy
|
||||||
// compilation, patch it.
|
// compilation, patch it. If is_js_to_wasm is set, we did not set the
|
||||||
if (!wasm_to_wasm_callee.is_null() && callee == *wasm_to_wasm_callee) {
|
// wasm_to_wasm_callee, so just check the code kind (this is the only
|
||||||
|
// call in that wrapper anyway).
|
||||||
|
if ((is_js_to_wasm && callee->kind() == Code::WASM_TO_WASM_FUNCTION) ||
|
||||||
|
(!wasm_to_wasm_callee.is_null() &&
|
||||||
|
callee == *wasm_to_wasm_callee)) {
|
||||||
TRACE_LAZY("Patching wasm-to-wasm wrapper.\n");
|
TRACE_LAZY("Patching wasm-to-wasm wrapper.\n");
|
||||||
PatchWasmToWasmWrapper(isolate, callee, *compiled_function);
|
PatchWasmToWasmWrapper(isolate, callee, *compiled_function);
|
||||||
++patched;
|
++patched;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DCHECK_GT(non_compiled_functions.size(), idx);
|
int called_func_index = func_to_return_idx;
|
||||||
int called_func_index = non_compiled_functions[idx].func_index;
|
if (!is_js_to_wasm) {
|
||||||
|
DCHECK_GT(non_compiled_functions.size(), idx);
|
||||||
|
called_func_index = non_compiled_functions[idx].func_index;
|
||||||
|
DCHECK_EQ(non_compiled_functions[idx].offset,
|
||||||
|
it.rinfo()->pc() - caller->instruction_start());
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
// Check that the callee agrees with our assumed called_func_index.
|
// Check that the callee agrees with our assumed called_func_index.
|
||||||
DCHECK_IMPLIES(callee->deoptimization_data()->length() > 0,
|
DCHECK_IMPLIES(callee->deoptimization_data()->length() > 0,
|
||||||
Smi::ToInt(callee->deoptimization_data()->get(1)) ==
|
Smi::ToInt(callee->deoptimization_data()->get(1)) ==
|
||||||
called_func_index);
|
called_func_index);
|
||||||
if (is_js_to_wasm) {
|
|
||||||
DCHECK_EQ(func_to_return_idx, called_func_index);
|
|
||||||
} else {
|
|
||||||
DCHECK_EQ(non_compiled_functions[idx].offset,
|
|
||||||
it.rinfo()->pc() - caller->instruction_start());
|
|
||||||
}
|
|
||||||
++idx;
|
|
||||||
Handle<Code> callee_compiled(
|
Handle<Code> callee_compiled(
|
||||||
Code::cast(compiled_module->code_table()->get(called_func_index)));
|
Code::cast(compiled_module->code_table()->get(called_func_index)));
|
||||||
if (callee_compiled->builtin_index() == Builtins::kWasmCompileLazy) {
|
if (callee_compiled->builtin_index() == Builtins::kWasmCompileLazy) {
|
||||||
|
@ -47,3 +47,17 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
|
|||||||
assertEquals(3, mem1[0]);
|
assertEquals(3, mem1[0]);
|
||||||
assertEquals(0, mem2[0]);
|
assertEquals(0, mem2[0]);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
(function exportImportedFunction() {
|
||||||
|
print(arguments.callee.name);
|
||||||
|
const builder1 = new WasmModuleBuilder();
|
||||||
|
builder1.addFunction('foo', kSig_v_v).addBody([]).exportAs('foo');
|
||||||
|
const instance1 = builder1.instantiate();
|
||||||
|
|
||||||
|
const builder2 = new WasmModuleBuilder();
|
||||||
|
const imp_idx = builder2.addImport('A', 'foo', kSig_v_v);
|
||||||
|
builder2.addExport('foo', imp_idx);
|
||||||
|
const instance2 = builder2.instantiate({A: instance1.exports});
|
||||||
|
|
||||||
|
instance2.exports.foo();
|
||||||
|
})();
|
||||||
|
Loading…
Reference in New Issue
Block a user