Commit 6802775e authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

Reland "[wasm] Fix importing wasm-lazy-compile stubs"

This is a reland of 77b0baa6.

Original change's description:
> [wasm] Fix importing wasm-lazy-compile stubs
>
> If two modules use lazy compilation, and one imports a function of
> another, we are unwrapping the js-to-wasm wrapper of the export. This
> was failing so far, because during unwrapping we did not find the wasm
> code.
> This CL fixes this by also recognizing WasmCompileLazy stubs as "wasm
> code".
>
> R=ahaas@chromium.org
>
> Bug: chromium:779569, v8:5991
> Change-Id: If2260c3721e3746a7635b9d0182fd520df2fb773
> Reviewed-on: https://chromium-review.googlesource.com/771672
> Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
> Reviewed-by: Andreas Haas <ahaas@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#49405}

Bug: chromium:779569, v8:5991
Change-Id: I4818e933467bd5a040f1514b8fc18db219a092c7
Reviewed-on: https://chromium-review.googlesource.com/774538Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49426}
parent 82f5cbac
......@@ -615,8 +615,10 @@ Handle<Code> CompileLazy(Isolate* isolate) {
Handle<WasmInstanceObject> instance;
Handle<FixedArray> exp_deopt_data;
int func_index = -1;
// If the lazy compile stub has deopt data, use that to determine the
// instance and function index. Otherwise this must be a wasm->wasm call
// within one instance, so extract the information from the caller.
if (lazy_compile_code->deoptimization_data()->length() > 0) {
// Then it's an indirect call or via JS->wasm wrapper.
DCHECK_LE(2, lazy_compile_code->deoptimization_data()->length());
exp_deopt_data = handle(lazy_compile_code->deoptimization_data(), isolate);
auto* weak_cell = WeakCell::cast(exp_deopt_data->get(0));
......@@ -810,14 +812,20 @@ Handle<Code> LazyCompilationOrchestrator::CompileLazy(
non_compiled_functions.push_back({0, exported_func_index});
} else if (patch_caller) {
DisallowHeapAllocation no_gc;
SeqOneByteString* module_bytes = compiled_module->module_bytes();
SourcePositionTableIterator source_pos_iterator(
caller->SourcePositionTable());
DCHECK_EQ(2, caller->deoptimization_data()->length());
Handle<WeakCell> weak_caller_instance(
WeakCell::cast(caller->deoptimization_data()->get(0)), isolate);
Handle<WasmInstanceObject> caller_instance(
WasmInstanceObject::cast(weak_caller_instance->value()), isolate);
Handle<WasmCompiledModule> caller_module(caller_instance->compiled_module(),
isolate);
SeqOneByteString* module_bytes = caller_module->module_bytes();
int caller_func_index = Smi::ToInt(caller->deoptimization_data()->get(1));
const byte* func_bytes =
module_bytes->GetChars() +
compiled_module->module()->functions[caller_func_index].code.offset();
caller_module->module()->functions[caller_func_index].code.offset();
for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done();
it.next()) {
Code* callee =
......
......@@ -679,20 +679,21 @@ Handle<Code> WasmExportedFunction::GetWasmCode() {
Handle<Code> export_wrapper_code = handle(this->code());
DCHECK_EQ(export_wrapper_code->kind(), Code::JS_TO_WASM_FUNCTION);
int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
auto IsWasmFunctionCode = [](Code* code) {
return code->kind() == Code::WASM_FUNCTION ||
code->kind() == Code::WASM_TO_JS_FUNCTION ||
code->kind() == Code::WASM_INTERPRETER_ENTRY ||
code->builtin_index() == Builtins::kWasmCompileLazy;
};
for (RelocIterator it(*export_wrapper_code, mask);; 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->kind() != Code::WASM_INTERPRETER_ENTRY)
continue;
if (!IsWasmFunctionCode(target)) continue;
// There should only be this one call to wasm code.
#ifdef DEBUG
for (it.next(); !it.done(); it.next()) {
Code* code = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
DCHECK(code->kind() != Code::WASM_FUNCTION &&
code->kind() != Code::WASM_TO_JS_FUNCTION &&
code->kind() != Code::WASM_INTERPRETER_ENTRY);
DCHECK(!IsWasmFunctionCode(code));
}
#endif
return handle(target);
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --wasm-lazy-compilation
load('test/mjsunit/wasm/wasm-constants.js');
load('test/mjsunit/wasm/wasm-module-builder.js');
(function importFromOtherInstance() {
print(arguments.callee.name);
const builder1 = new WasmModuleBuilder();
builder1.addFunction('func', kSig_v_v).addBody([]).exportFunc();
const instance1 = builder1.instantiate();
const builder2 = new WasmModuleBuilder();
builder2.addImport('mod', 'fn', kSig_v_v);
builder2.instantiate({mod: {fn: instance1.exports.func}});
})();
(function testWasmToWasmWithDifferentMemory() {
print(arguments.callee.name);
const builder1 = new WasmModuleBuilder();
builder1.addMemory(1, 1, true);
builder1.addFunction('store', kSig_v_i)
.addBody([
kExprI32Const, 0, // i32.const 1
kExprGetLocal, 0, // get_local 0
kExprI32StoreMem, 0, 0, // i32.store offset=0 align=0
])
.exportFunc();
const instance1 = builder1.instantiate();
const mem1 = new Int32Array(instance1.exports.memory.buffer);
const builder2 = new WasmModuleBuilder();
builder2.addMemory(1, 1, true);
builder2.addImport('mod', 'store', kSig_v_i);
builder2.addFunction('call_store', kSig_v_i)
.addBody([kExprGetLocal, 0, kExprCallFunction, 0])
.exportFunc();
const instance2 = builder2.instantiate({mod: {store: instance1.exports.store}});
const mem2 = new Int32Array(instance2.exports.memory.buffer);
assertEquals(0, mem1[0]);
assertEquals(0, mem2[0]);
instance2.exports.call_store(3);
assertEquals(3, mem1[0]);
assertEquals(0, mem2[0]);
})();
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