[wasm] Fix memory initialization on instantiate
Memory instantiate on initialize should always patch memory references. If memory references are not patched for no initial memory, on subsequent calls to grow_memory in wasm functions for instances that share a module, the references will be patched without resetting cloned compiled values to their correct initial values. BUG=chromium:763439 Change-Id: I666439332379b02aa344e99d61ef3dc88ab86cc8 Reviewed-on: https://chromium-review.googlesource.com/674707 Reviewed-by: Mircea Trofin <mtrofin@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Commit-Queue: Deepti Gandluri <gdeepti@chromium.org> Cr-Commit-Position: refs/heads/master@{#48097}
This commit is contained in:
parent
c701bd2ebf
commit
327df0b8c2
@ -1013,27 +1013,29 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
|
||||
//--------------------------------------------------------------------------
|
||||
// Initialize memory.
|
||||
//--------------------------------------------------------------------------
|
||||
uint32_t mem_size = 0;
|
||||
Address mem_start = nullptr;
|
||||
|
||||
// Stash old values of mem_start, and mem_size before
|
||||
// SetSpecializationMemInfoFrom, to patch memory references
|
||||
uint32_t old_mem_size = compiled_module_->GetEmbeddedMemSizeOrZero();
|
||||
Address old_mem_start = compiled_module_->GetEmbeddedMemStartOrNull();
|
||||
if (!memory_.is_null()) {
|
||||
Handle<JSArrayBuffer> memory = memory_.ToHandleChecked();
|
||||
Address mem_start = static_cast<Address>(memory->backing_store());
|
||||
uint32_t mem_size;
|
||||
mem_start = static_cast<Address>(memory->backing_store());
|
||||
CHECK(memory->byte_length()->ToUint32(&mem_size));
|
||||
LoadDataSegments(mem_start, mem_size);
|
||||
|
||||
uint32_t old_mem_size = compiled_module_->GetEmbeddedMemSizeOrZero();
|
||||
Address old_mem_start = compiled_module_->GetEmbeddedMemStartOrNull();
|
||||
// We might get instantiated again with the same memory. No patching
|
||||
// needed in this case.
|
||||
if (old_mem_start != mem_start || old_mem_size != mem_size) {
|
||||
code_specialization.RelocateMemoryReferences(old_mem_start, old_mem_size,
|
||||
mem_start, mem_size);
|
||||
}
|
||||
// Just like with globals, we need to keep both the JSArrayBuffer
|
||||
// and save the start pointer.
|
||||
instance->set_memory_buffer(*memory);
|
||||
WasmCompiledModule::SetSpecializationMemInfoFrom(factory, compiled_module_,
|
||||
memory);
|
||||
}
|
||||
// We might get instantiated again with the same memory. No patching
|
||||
// needed in this case.
|
||||
code_specialization.RelocateMemoryReferences(old_mem_start, old_mem_size,
|
||||
mem_start, mem_size);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Set up the runtime support for the new instance.
|
||||
|
22
test/mjsunit/regress/wasm/regression-763439.js
Normal file
22
test/mjsunit/regress/wasm/regression-763439.js
Normal file
@ -0,0 +1,22 @@
|
||||
// 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.
|
||||
|
||||
load('test/mjsunit/wasm/wasm-constants.js');
|
||||
load('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
|
||||
var builder = new WasmModuleBuilder();
|
||||
builder.addMemory(0, 1234, false);
|
||||
builder.addFunction('f', kSig_i_v)
|
||||
.addBody([
|
||||
kExprI32Const, 0x1d, // --
|
||||
kExprGrowMemory, 0x00, // --
|
||||
kExprI32LoadMem, 0x00, 0xff, 0xff, 0x45, // --
|
||||
])
|
||||
.exportFunc();
|
||||
|
||||
var module = new WebAssembly.Module(builder.toBuffer());
|
||||
var instance1 = new WebAssembly.Instance(module);
|
||||
instance1.exports.f();
|
||||
var instance2 = new WebAssembly.Instance(module);
|
||||
instance2.exports.f();
|
@ -442,3 +442,29 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
assertEquals(0, buffer.byteLength);
|
||||
assertEquals(3*kPageSize, memory.buffer.byteLength);
|
||||
})();
|
||||
|
||||
(function TestInitialMemorySharedModule() {
|
||||
print("TestInitialMemorySharedModule");
|
||||
var builder = new WasmModuleBuilder();
|
||||
builder.addImportedMemory("m", "imported_mem");
|
||||
builder.addFunction('f', kSig_i_v)
|
||||
.addBody([
|
||||
kExprI32Const, 0x1d, // --
|
||||
kExprI32Const, 0x20, // --
|
||||
kExprI32StoreMem, 0, 0, // --
|
||||
kExprI32Const, 0x1d, // --
|
||||
kExprI32LoadMem, 0, 0, // --
|
||||
])
|
||||
.exportFunc();
|
||||
|
||||
// First instance load/store success
|
||||
var module = new WebAssembly.Module(builder.toBuffer());
|
||||
let memory1= new WebAssembly.Memory({initial: 1, maximum: 20});
|
||||
let instance1 = new WebAssembly.Instance(module, {m: {imported_mem: memory1}});
|
||||
assertEquals(0x20, instance1.exports.f());
|
||||
|
||||
// Second instance should trap as it has no initial memory
|
||||
let memory2= new WebAssembly.Memory({initial: 0, maximum: 2});
|
||||
let instance2 = new WebAssembly.Instance(module, {m: {imported_mem: memory2}});
|
||||
assertTraps(kTrapMemOutOfBounds, () => instance2.exports.f());
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user