Commit c8b26566 authored by gdeepti's avatar gdeepti Committed by Commit bot

[wasm] Detach memory buffer only when GrowMemory is called from the JS API

BUG=chromium:699485

R=ahaas@chromium.org, bradnelson@chromium.org

Review-Url: https://codereview.chromium.org/2772973002
Cr-Commit-Position: refs/heads/master@{#44166}
parent b7e94287
...@@ -706,6 +706,7 @@ void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -706,6 +706,7 @@ void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
thrower.RangeError("Unable to grow instance memory."); thrower.RangeError("Unable to grow instance memory.");
return; return;
} }
i::wasm::DetachWebAssemblyMemoryBuffer(i_isolate, old_buffer);
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
return_value.Set(ret); return_value.Set(ret);
} }
......
...@@ -2358,7 +2358,8 @@ Handle<JSArrayBuffer> GrowMemoryBuffer(Isolate* isolate, ...@@ -2358,7 +2358,8 @@ Handle<JSArrayBuffer> GrowMemoryBuffer(Isolate* isolate,
Handle<JSArrayBuffer> old_buffer; Handle<JSArrayBuffer> old_buffer;
Address old_mem_start = nullptr; Address old_mem_start = nullptr;
uint32_t old_size = 0; uint32_t old_size = 0;
if (buffer.ToHandle(&old_buffer) && old_buffer->backing_store() != nullptr) { if (buffer.ToHandle(&old_buffer) && old_buffer->backing_store() != nullptr &&
old_buffer->byte_length()->IsNumber()) {
old_mem_start = static_cast<Address>(old_buffer->backing_store()); old_mem_start = static_cast<Address>(old_buffer->backing_store());
DCHECK_NOT_NULL(old_mem_start); DCHECK_NOT_NULL(old_mem_start);
old_size = old_buffer->byte_length()->Number(); old_size = old_buffer->byte_length()->Number();
...@@ -2401,28 +2402,30 @@ void UncheckedUpdateInstanceMemory(Isolate* isolate, ...@@ -2401,28 +2402,30 @@ void UncheckedUpdateInstanceMemory(Isolate* isolate,
code_specialization.ApplyToWholeInstance(*instance); code_specialization.ApplyToWholeInstance(*instance);
} }
void DetachArrayBuffer(Isolate* isolate, Handle<JSArrayBuffer> buffer) { void wasm::DetachWebAssemblyMemoryBuffer(Isolate* isolate,
const bool has_guard_regions = Handle<JSArrayBuffer> buffer) {
(!buffer.is_null() && buffer->has_guard_region()); int64_t byte_length =
buffer->byte_length()->IsNumber()
? static_cast<uint32_t>(buffer->byte_length()->Number())
: 0;
if (buffer.is_null() || byte_length == 0) return;
const bool has_guard_regions = buffer->has_guard_region();
const bool is_external = buffer->is_external(); const bool is_external = buffer->is_external();
void* backing_store = buffer->backing_store(); void* backing_store = buffer->backing_store();
if (backing_store != nullptr) { DCHECK(!buffer->is_neuterable());
DCHECK(!buffer->is_neuterable()); if (!has_guard_regions && !is_external) {
int64_t byte_length = NumberToSize(buffer->byte_length()); buffer->set_is_external(true);
buffer->set_is_neuterable(true); isolate->heap()->UnregisterArrayBuffer(*buffer);
if (!has_guard_regions && !is_external) { }
buffer->set_is_external(true); buffer->set_is_neuterable(true);
isolate->heap()->UnregisterArrayBuffer(*buffer); buffer->Neuter();
} if (has_guard_regions) {
buffer->Neuter(); base::OS::Free(backing_store, RoundUp(i::wasm::kWasmMaxHeapOffset,
if (has_guard_regions) { base::OS::CommitPageSize()));
base::OS::Free(backing_store, RoundUp(i::wasm::kWasmMaxHeapOffset, reinterpret_cast<v8::Isolate*>(isolate)
base::OS::CommitPageSize())); ->AdjustAmountOfExternalAllocatedMemory(-byte_length);
reinterpret_cast<v8::Isolate*>(isolate) } else if (!has_guard_regions && !is_external) {
->AdjustAmountOfExternalAllocatedMemory(-byte_length); isolate->array_buffer_allocator()->Free(backing_store, byte_length);
} else if (!has_guard_regions && !is_external) {
isolate->array_buffer_allocator()->Free(backing_store, byte_length);
}
} }
} }
...@@ -2436,8 +2439,10 @@ int32_t wasm::GrowWebAssemblyMemory(Isolate* isolate, ...@@ -2436,8 +2439,10 @@ int32_t wasm::GrowWebAssemblyMemory(Isolate* isolate,
Handle<JSArrayBuffer> old_buffer; Handle<JSArrayBuffer> old_buffer;
uint32_t old_size = 0; uint32_t old_size = 0;
Address old_mem_start = nullptr; Address old_mem_start = nullptr;
// Force byte_length to 0, if byte_length fails IsNumber() check.
if (memory_buffer.ToHandle(&old_buffer) && if (memory_buffer.ToHandle(&old_buffer) &&
old_buffer->backing_store() != nullptr) { old_buffer->backing_store() != nullptr &&
old_buffer->byte_length()->IsNumber()) {
old_size = old_buffer->byte_length()->Number(); old_size = old_buffer->byte_length()->Number();
old_mem_start = static_cast<Address>(old_buffer->backing_store()); old_mem_start = static_cast<Address>(old_buffer->backing_store());
} }
...@@ -2497,7 +2502,6 @@ int32_t wasm::GrowWebAssemblyMemory(Isolate* isolate, ...@@ -2497,7 +2502,6 @@ int32_t wasm::GrowWebAssemblyMemory(Isolate* isolate,
} }
} }
memory_object->set_buffer(*new_buffer); memory_object->set_buffer(*new_buffer);
DetachArrayBuffer(isolate, old_buffer);
DCHECK(old_size % WasmModule::kPageSize == 0); DCHECK(old_size % WasmModule::kPageSize == 0);
return (old_size / WasmModule::kPageSize); return (old_size / WasmModule::kPageSize);
} }
......
...@@ -437,6 +437,9 @@ int32_t GrowWebAssemblyMemory(Isolate* isolate, ...@@ -437,6 +437,9 @@ int32_t GrowWebAssemblyMemory(Isolate* isolate,
int32_t GrowMemory(Isolate* isolate, Handle<WasmInstanceObject> instance, int32_t GrowMemory(Isolate* isolate, Handle<WasmInstanceObject> instance,
uint32_t pages); uint32_t pages);
void DetachWebAssemblyMemoryBuffer(Isolate* isolate,
Handle<JSArrayBuffer> buffer);
void UpdateDispatchTables(Isolate* isolate, Handle<FixedArray> dispatch_tables, void UpdateDispatchTables(Isolate* isolate, Handle<FixedArray> dispatch_tables,
int index, Handle<JSFunction> js_function); int index, Handle<JSFunction> js_function);
......
// Copyright 2016 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: --expose-wasm
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
(function() {
"use asm";
var builder = new WasmModuleBuilder();
builder.addMemory(0, 5, false);
builder.addFunction("regression_699485", kSig_i_v)
.addBody([
kExprI32Const, 0x04,
kExprNop,
kExprGrowMemory, 0x00,
]).exportFunc();
let module = builder.instantiate();
assertEquals(0, module.exports.regression_699485());
})();
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