Commit 625767df authored by gdeepti's avatar gdeepti Committed by Commit bot

[wasm] Linear/Exported memory maximum property should be set when maximum is defined.

 - When module bytes have a memory maximum defined, compiled module object should set maximum memory
 - Exported memory objects should set maximum value on the memory objects
 - Update tests to use declared maximum values.

R=ahaas@chromium.org

Review-Url: https://codereview.chromium.org/2474333003
Cr-Commit-Position: refs/heads/master@{#40820}
parent 5a44be9a
......@@ -910,7 +910,7 @@ uint32_t WasmJs::GetWasmMemoryMaximumSize(Isolate* isolate,
DCHECK(IsWasmMemoryObject(isolate, value));
Object* max_mem =
JSObject::cast(*value)->GetInternalField(kWasmMemoryMaximum);
if (max_mem->IsUndefined(isolate)) return wasm::WasmModule::kV8MaxPages;
if (max_mem->IsUndefined(isolate)) return 0;
uint32_t max_pages = Smi::cast(max_mem)->value();
return max_pages;
}
......
......@@ -364,7 +364,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const {
buffer.write_u8(1); // memory count
buffer.write_u32v(kResizableMaximumFlag);
buffer.write_u32v(16); // min memory size
buffer.write_u32v(16); // max memory size
buffer.write_u32v(32); // max memory size
FixupSection(buffer, start);
}
......
......@@ -836,6 +836,7 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
WasmCompiledModule::New(isolate, module_wrapper);
ret->set_code_table(code_table);
ret->set_min_mem_pages(min_mem_pages);
ret->set_max_mem_pages(max_mem_pages);
if (function_table_count > 0) {
ret->set_function_tables(function_tables);
ret->set_empty_function_tables(function_tables);
......@@ -1123,7 +1124,6 @@ class WasmInstanceBuilder {
uint32_t min_mem_pages = module_->min_mem_pages;
isolate_->counters()->wasm_min_mem_pages_count()->AddSample(min_mem_pages);
// TODO(wasm): re-enable counter for max_mem_pages when we use that field.
if (!memory_.is_null()) {
// Set externally passed ArrayBuffer non neuterable.
......@@ -1676,8 +1676,9 @@ class WasmInstanceBuilder {
JSArrayBuffer::cast(
instance->GetInternalField(kWasmMemArrayBuffer)),
isolate_);
memory_object =
WasmJs::CreateWasmMemoryObject(isolate_, buffer, false, 0);
memory_object = WasmJs::CreateWasmMemoryObject(
isolate_, buffer, (module_->max_mem_pages != 0),
module_->max_mem_pages);
instance->SetInternalField(kWasmMemObject, *memory_object);
}
......@@ -2101,11 +2102,18 @@ int32_t wasm::GetInstanceMemorySize(Isolate* isolate,
}
uint32_t GetMaxInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance) {
uint32_t max_pages = WasmModule::kV8MaxPages;
Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject),
isolate);
if (memory_object->IsUndefined(isolate)) return max_pages;
return WasmJs::GetWasmMemoryMaximumSize(isolate, memory_object);
if (!memory_object->IsUndefined(isolate)) {
uint32_t mem_obj_max =
WasmJs::GetWasmMemoryMaximumSize(isolate, memory_object);
if (mem_obj_max != 0) return mem_obj_max;
}
uint32_t compiled_max_pages = GetCompiledModule(*instance)->max_mem_pages();
isolate->counters()->wasm_max_mem_pages_count()->AddSample(
compiled_max_pages);
if (compiled_max_pages != 0) return compiled_max_pages;
return WasmModule::kV8MaxPages;
}
int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance,
......@@ -2113,7 +2121,6 @@ int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance,
if (!IsWasmInstance(*instance)) return -1;
if (pages == 0) return GetInstanceMemorySize(isolate, instance);
uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance);
if (WasmModule::kV8MaxPages < max_pages) return -1;
Address old_mem_start = nullptr;
uint32_t old_size = 0, new_size = 0;
......@@ -2138,7 +2145,8 @@ int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance,
new_size = old_size + pages * WasmModule::kPageSize;
}
if (new_size <= old_size || max_pages * WasmModule::kPageSize < new_size) {
if (new_size <= old_size || max_pages * WasmModule::kPageSize < new_size ||
WasmModule::kV8MaxPages * WasmModule::kPageSize < new_size) {
return -1;
}
Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size);
......
......@@ -406,6 +406,7 @@ class WasmCompiledModule : public FixedArray {
MACRO(OBJECT, ByteArray, asm_js_offset_tables) \
MACRO(OBJECT, JSArrayBuffer, memory) \
MACRO(SMALL_NUMBER, uint32_t, min_mem_pages) \
MACRO(SMALL_NUMBER, uint32_t, max_mem_pages) \
MACRO(WEAK_LINK, WasmCompiledModule, next_instance) \
MACRO(WEAK_LINK, WasmCompiledModule, prev_instance) \
MACRO(WEAK_LINK, JSObject, owning_instance) \
......
......@@ -9,7 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
(function() {
var builder = new WasmModuleBuilder();
builder.addMemory(1, 1, false);
builder.addMemory(1, 32, false);
builder.addFunction("foo", kSig_i_v)
.addBody([
kExprMemorySize, kMemoryZero,
......
......@@ -8,6 +8,7 @@ load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
var kPageSize = 0x10000;
var kV8MaxPages = 16384;
function genGrowMemoryBuilder() {
var builder = new WasmModuleBuilder();
......@@ -42,7 +43,7 @@ function genGrowMemoryBuilder() {
// current implementation.
function testGrowMemoryReadWrite32() {
var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false);
builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate();
var offset;
function peek() { return module.exports.load(offset); }
......@@ -89,7 +90,7 @@ testGrowMemoryReadWrite32();
function testGrowMemoryReadWrite16() {
var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false);
builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate();
var offset;
function peek() { return module.exports.load16(offset); }
......@@ -136,7 +137,7 @@ testGrowMemoryReadWrite16();
function testGrowMemoryReadWrite8() {
var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false);
builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate();
var offset;
function peek() { return module.exports.load8(offset); }
......@@ -323,7 +324,7 @@ testGrowMemoryTrapsWithNonSmiInput();
function testGrowMemoryCurrentMemory() {
var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false);
builder.addMemory(1, kV8MaxPages, false);
builder.addFunction("memory_size", kSig_i_v)
.addBody([kExprMemorySize, kMemoryZero])
.exportFunc();
......@@ -339,7 +340,7 @@ testGrowMemoryCurrentMemory();
function testGrowMemoryPreservesDataMemOp32() {
var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false);
builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate();
var offset, val;
function peek() { return module.exports.load(offset); }
......@@ -362,7 +363,7 @@ testGrowMemoryPreservesDataMemOp32();
function testGrowMemoryPreservesDataMemOp16() {
var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false);
builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate();
var offset, val;
function peek() { return module.exports.load16(offset); }
......@@ -385,7 +386,7 @@ testGrowMemoryPreservesDataMemOp16();
function testGrowMemoryPreservesDataMemOp8() {
var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false);
builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate();
var offset, val = 0;
function peek() { return module.exports.load8(offset); }
......@@ -412,7 +413,7 @@ testGrowMemoryPreservesDataMemOp8();
function testGrowMemoryOutOfBoundsOffset() {
var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false);
builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate();
var offset, val;
function peek() { return module.exports.load(offset); }
......@@ -458,3 +459,31 @@ function testGrowMemoryOutOfBoundsOffset2() {
}
testGrowMemoryOutOfBoundsOffset2();
function testGrowMemoryDeclaredMaxTraps() {
var builder = genGrowMemoryBuilder();
builder.addMemory(1, 16, false);
var module = builder.instantiate();
function growMem(pages) { return module.exports.grow_memory(pages); }
assertEquals(1, growMem(5));
assertEquals(6, growMem(5));
assertEquals(-1, growMem(6));
}
testGrowMemoryDeclaredMaxTraps();
function testGrowMemoryDeclaredSpecMaxTraps() {
// The spec maximum is higher than the internal V8 maximum. This test only
// checks that grow_memory does not grow past the internally defined maximum
// to reflect the currentl implementation.
var builder = genGrowMemoryBuilder();
var kSpecMaxPages = 65535;
builder.addMemory(1, kSpecMaxPages, false);
var module = builder.instantiate();
function poke(value) { return module.exports.store(offset, value); }
function growMem(pages) { return module.exports.grow_memory(pages); }
assertEquals(1, growMem(20));
assertEquals(-1, growMem(kV8MaxPages - 20));
}
testGrowMemoryDeclaredSpecMaxTraps();
......@@ -199,3 +199,33 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
assertEquals(10*kPageSize, memory.buffer.byteLength);
assertThrows(() => memory.grow(1));
})();
(function TestGrowMemoryExportedMaximum() {
print("TestGrowMemoryExportedMaximum");
let initial_size = 1, maximum_size = 10;
var exp_instance;
{
let builder = new WasmModuleBuilder();
builder.addMemory(initial_size, maximum_size, true);
builder.exportMemoryAs("exported_mem");
exp_instance = builder.instantiate();
}
var instance;
{
var builder = new WasmModuleBuilder();
builder.addImportedMemory("imported_mem");
builder.addFunction("mem_size", kSig_i_v)
.addBody([kExprMemorySize, kMemoryZero])
.exportFunc();
builder.addFunction("grow", kSig_i_i)
.addBody([kExprGetLocal, 0, kExprGrowMemory, kMemoryZero])
.exportFunc();
instance = builder.instantiate({
imported_mem: exp_instance.exports.exported_mem});
}
for (var i = initial_size; i < maximum_size; i++) {
assertEquals(i, instance.exports.grow(1));
assertEquals((i+1), instance.exports.mem_size());
}
assertEquals(-1, instance.exports.grow(1));
})();
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