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, ...@@ -910,7 +910,7 @@ uint32_t WasmJs::GetWasmMemoryMaximumSize(Isolate* isolate,
DCHECK(IsWasmMemoryObject(isolate, value)); DCHECK(IsWasmMemoryObject(isolate, value));
Object* max_mem = Object* max_mem =
JSObject::cast(*value)->GetInternalField(kWasmMemoryMaximum); 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(); uint32_t max_pages = Smi::cast(max_mem)->value();
return max_pages; return max_pages;
} }
......
...@@ -364,7 +364,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const { ...@@ -364,7 +364,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const {
buffer.write_u8(1); // memory count buffer.write_u8(1); // memory count
buffer.write_u32v(kResizableMaximumFlag); buffer.write_u32v(kResizableMaximumFlag);
buffer.write_u32v(16); // min memory size buffer.write_u32v(16); // min memory size
buffer.write_u32v(16); // max memory size buffer.write_u32v(32); // max memory size
FixupSection(buffer, start); FixupSection(buffer, start);
} }
......
...@@ -836,6 +836,7 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions( ...@@ -836,6 +836,7 @@ MaybeHandle<WasmCompiledModule> WasmModule::CompileFunctions(
WasmCompiledModule::New(isolate, module_wrapper); WasmCompiledModule::New(isolate, module_wrapper);
ret->set_code_table(code_table); ret->set_code_table(code_table);
ret->set_min_mem_pages(min_mem_pages); ret->set_min_mem_pages(min_mem_pages);
ret->set_max_mem_pages(max_mem_pages);
if (function_table_count > 0) { if (function_table_count > 0) {
ret->set_function_tables(function_tables); ret->set_function_tables(function_tables);
ret->set_empty_function_tables(function_tables); ret->set_empty_function_tables(function_tables);
...@@ -1123,7 +1124,6 @@ class WasmInstanceBuilder { ...@@ -1123,7 +1124,6 @@ class WasmInstanceBuilder {
uint32_t min_mem_pages = module_->min_mem_pages; uint32_t min_mem_pages = module_->min_mem_pages;
isolate_->counters()->wasm_min_mem_pages_count()->AddSample(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()) { if (!memory_.is_null()) {
// Set externally passed ArrayBuffer non neuterable. // Set externally passed ArrayBuffer non neuterable.
...@@ -1676,8 +1676,9 @@ class WasmInstanceBuilder { ...@@ -1676,8 +1676,9 @@ class WasmInstanceBuilder {
JSArrayBuffer::cast( JSArrayBuffer::cast(
instance->GetInternalField(kWasmMemArrayBuffer)), instance->GetInternalField(kWasmMemArrayBuffer)),
isolate_); isolate_);
memory_object = memory_object = WasmJs::CreateWasmMemoryObject(
WasmJs::CreateWasmMemoryObject(isolate_, buffer, false, 0); isolate_, buffer, (module_->max_mem_pages != 0),
module_->max_mem_pages);
instance->SetInternalField(kWasmMemObject, *memory_object); instance->SetInternalField(kWasmMemObject, *memory_object);
} }
...@@ -2101,11 +2102,18 @@ int32_t wasm::GetInstanceMemorySize(Isolate* isolate, ...@@ -2101,11 +2102,18 @@ int32_t wasm::GetInstanceMemorySize(Isolate* isolate,
} }
uint32_t GetMaxInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance) { uint32_t GetMaxInstanceMemorySize(Isolate* isolate, Handle<JSObject> instance) {
uint32_t max_pages = WasmModule::kV8MaxPages;
Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject), Handle<Object> memory_object(instance->GetInternalField(kWasmMemObject),
isolate); isolate);
if (memory_object->IsUndefined(isolate)) return max_pages; if (!memory_object->IsUndefined(isolate)) {
return WasmJs::GetWasmMemoryMaximumSize(isolate, memory_object); 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, int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance,
...@@ -2113,7 +2121,6 @@ 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 (!IsWasmInstance(*instance)) return -1;
if (pages == 0) return GetInstanceMemorySize(isolate, instance); if (pages == 0) return GetInstanceMemorySize(isolate, instance);
uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance); uint32_t max_pages = GetMaxInstanceMemorySize(isolate, instance);
if (WasmModule::kV8MaxPages < max_pages) return -1;
Address old_mem_start = nullptr; Address old_mem_start = nullptr;
uint32_t old_size = 0, new_size = 0; uint32_t old_size = 0, new_size = 0;
...@@ -2138,7 +2145,8 @@ int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance, ...@@ -2138,7 +2145,8 @@ int32_t wasm::GrowInstanceMemory(Isolate* isolate, Handle<JSObject> instance,
new_size = old_size + pages * WasmModule::kPageSize; 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; return -1;
} }
Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size); Handle<JSArrayBuffer> buffer = NewArrayBuffer(isolate, new_size);
......
...@@ -406,6 +406,7 @@ class WasmCompiledModule : public FixedArray { ...@@ -406,6 +406,7 @@ class WasmCompiledModule : public FixedArray {
MACRO(OBJECT, ByteArray, asm_js_offset_tables) \ MACRO(OBJECT, ByteArray, asm_js_offset_tables) \
MACRO(OBJECT, JSArrayBuffer, memory) \ MACRO(OBJECT, JSArrayBuffer, memory) \
MACRO(SMALL_NUMBER, uint32_t, min_mem_pages) \ 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, next_instance) \
MACRO(WEAK_LINK, WasmCompiledModule, prev_instance) \ MACRO(WEAK_LINK, WasmCompiledModule, prev_instance) \
MACRO(WEAK_LINK, JSObject, owning_instance) \ MACRO(WEAK_LINK, JSObject, owning_instance) \
......
...@@ -9,7 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -9,7 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
(function() { (function() {
var builder = new WasmModuleBuilder(); var builder = new WasmModuleBuilder();
builder.addMemory(1, 1, false); builder.addMemory(1, 32, false);
builder.addFunction("foo", kSig_i_v) builder.addFunction("foo", kSig_i_v)
.addBody([ .addBody([
kExprMemorySize, kMemoryZero, kExprMemorySize, kMemoryZero,
......
...@@ -8,6 +8,7 @@ load("test/mjsunit/wasm/wasm-constants.js"); ...@@ -8,6 +8,7 @@ load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js"); load("test/mjsunit/wasm/wasm-module-builder.js");
var kPageSize = 0x10000; var kPageSize = 0x10000;
var kV8MaxPages = 16384;
function genGrowMemoryBuilder() { function genGrowMemoryBuilder() {
var builder = new WasmModuleBuilder(); var builder = new WasmModuleBuilder();
...@@ -42,7 +43,7 @@ function genGrowMemoryBuilder() { ...@@ -42,7 +43,7 @@ function genGrowMemoryBuilder() {
// current implementation. // current implementation.
function testGrowMemoryReadWrite32() { function testGrowMemoryReadWrite32() {
var builder = genGrowMemoryBuilder(); var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false); builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate(); var module = builder.instantiate();
var offset; var offset;
function peek() { return module.exports.load(offset); } function peek() { return module.exports.load(offset); }
...@@ -89,7 +90,7 @@ testGrowMemoryReadWrite32(); ...@@ -89,7 +90,7 @@ testGrowMemoryReadWrite32();
function testGrowMemoryReadWrite16() { function testGrowMemoryReadWrite16() {
var builder = genGrowMemoryBuilder(); var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false); builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate(); var module = builder.instantiate();
var offset; var offset;
function peek() { return module.exports.load16(offset); } function peek() { return module.exports.load16(offset); }
...@@ -136,7 +137,7 @@ testGrowMemoryReadWrite16(); ...@@ -136,7 +137,7 @@ testGrowMemoryReadWrite16();
function testGrowMemoryReadWrite8() { function testGrowMemoryReadWrite8() {
var builder = genGrowMemoryBuilder(); var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false); builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate(); var module = builder.instantiate();
var offset; var offset;
function peek() { return module.exports.load8(offset); } function peek() { return module.exports.load8(offset); }
...@@ -323,7 +324,7 @@ testGrowMemoryTrapsWithNonSmiInput(); ...@@ -323,7 +324,7 @@ testGrowMemoryTrapsWithNonSmiInput();
function testGrowMemoryCurrentMemory() { function testGrowMemoryCurrentMemory() {
var builder = genGrowMemoryBuilder(); var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false); builder.addMemory(1, kV8MaxPages, false);
builder.addFunction("memory_size", kSig_i_v) builder.addFunction("memory_size", kSig_i_v)
.addBody([kExprMemorySize, kMemoryZero]) .addBody([kExprMemorySize, kMemoryZero])
.exportFunc(); .exportFunc();
...@@ -339,7 +340,7 @@ testGrowMemoryCurrentMemory(); ...@@ -339,7 +340,7 @@ testGrowMemoryCurrentMemory();
function testGrowMemoryPreservesDataMemOp32() { function testGrowMemoryPreservesDataMemOp32() {
var builder = genGrowMemoryBuilder(); var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false); builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate(); var module = builder.instantiate();
var offset, val; var offset, val;
function peek() { return module.exports.load(offset); } function peek() { return module.exports.load(offset); }
...@@ -362,7 +363,7 @@ testGrowMemoryPreservesDataMemOp32(); ...@@ -362,7 +363,7 @@ testGrowMemoryPreservesDataMemOp32();
function testGrowMemoryPreservesDataMemOp16() { function testGrowMemoryPreservesDataMemOp16() {
var builder = genGrowMemoryBuilder(); var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false); builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate(); var module = builder.instantiate();
var offset, val; var offset, val;
function peek() { return module.exports.load16(offset); } function peek() { return module.exports.load16(offset); }
...@@ -385,7 +386,7 @@ testGrowMemoryPreservesDataMemOp16(); ...@@ -385,7 +386,7 @@ testGrowMemoryPreservesDataMemOp16();
function testGrowMemoryPreservesDataMemOp8() { function testGrowMemoryPreservesDataMemOp8() {
var builder = genGrowMemoryBuilder(); var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false); builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate(); var module = builder.instantiate();
var offset, val = 0; var offset, val = 0;
function peek() { return module.exports.load8(offset); } function peek() { return module.exports.load8(offset); }
...@@ -412,7 +413,7 @@ testGrowMemoryPreservesDataMemOp8(); ...@@ -412,7 +413,7 @@ testGrowMemoryPreservesDataMemOp8();
function testGrowMemoryOutOfBoundsOffset() { function testGrowMemoryOutOfBoundsOffset() {
var builder = genGrowMemoryBuilder(); var builder = genGrowMemoryBuilder();
builder.addMemory(1, 1, false); builder.addMemory(1, kV8MaxPages, false);
var module = builder.instantiate(); var module = builder.instantiate();
var offset, val; var offset, val;
function peek() { return module.exports.load(offset); } function peek() { return module.exports.load(offset); }
...@@ -458,3 +459,31 @@ function testGrowMemoryOutOfBoundsOffset2() { ...@@ -458,3 +459,31 @@ function testGrowMemoryOutOfBoundsOffset2() {
} }
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"); ...@@ -199,3 +199,33 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
assertEquals(10*kPageSize, memory.buffer.byteLength); assertEquals(10*kPageSize, memory.buffer.byteLength);
assertThrows(() => memory.grow(1)); 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