| Index: src/runtime/runtime-typedarray.cc
|
| diff --git a/src/runtime/runtime-typedarray.cc b/src/runtime/runtime-typedarray.cc
|
| index cd2c0eb9fa1a3b5ca90b85b0c949b7f383c92b25..fd271fa405680040f53d08531be659448486730e 100644
|
| --- a/src/runtime/runtime-typedarray.cc
|
| +++ b/src/runtime/runtime-typedarray.cc
|
| @@ -12,17 +12,34 @@
|
| namespace v8 {
|
| namespace internal {
|
|
|
| +namespace {
|
| +
|
| +size_t MaybeUnguardArrayBuffer(Isolate* isolate, JSArrayBuffer* array_buffer) {
|
| + size_t allocated_length = NumberToSize(isolate, array_buffer->byte_length());
|
| + if (!array_buffer->is_guarded()) return allocated_length;
|
| + array_buffer->set_is_guarded(false);
|
| + size_t const page_size = base::OS::CommitPageSize();
|
| + CHECK(allocated_length % page_size == 0);
|
| + CHECK((bit_cast<uintptr_t>(array_buffer->backing_store()) % page_size) == 0);
|
| + isolate->RemoveGuardArea(
|
| + bit_cast<uint8_t*>(array_buffer->backing_store()) + allocated_length,
|
| + page_size);
|
| + return allocated_length += page_size;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +
|
| void Runtime::FreeArrayBuffer(Isolate* isolate,
|
| JSArrayBuffer* phantom_array_buffer) {
|
| + size_t const allocated_length =
|
| + MaybeUnguardArrayBuffer(isolate, phantom_array_buffer);
|
| if (phantom_array_buffer->should_be_freed()) {
|
| DCHECK(phantom_array_buffer->is_external());
|
| free(phantom_array_buffer->backing_store());
|
| }
|
| if (phantom_array_buffer->is_external()) return;
|
|
|
| - size_t allocated_length =
|
| - NumberToSize(isolate, phantom_array_buffer->byte_length());
|
| -
|
| reinterpret_cast<v8::Isolate*>(isolate)
|
| ->AdjustAmountOfExternalAllocatedMemory(
|
| -static_cast<int64_t>(allocated_length));
|
| @@ -34,7 +51,7 @@ void Runtime::FreeArrayBuffer(Isolate* isolate,
|
|
|
| void Runtime::SetupArrayBuffer(Isolate* isolate,
|
| Handle<JSArrayBuffer> array_buffer,
|
| - bool is_external, void* data,
|
| + bool is_external, bool is_guarded, void* data,
|
| size_t allocated_length) {
|
| DCHECK(array_buffer->GetInternalFieldCount() ==
|
| v8::ArrayBuffer::kInternalFieldCount);
|
| @@ -45,6 +62,7 @@ void Runtime::SetupArrayBuffer(Isolate* isolate,
|
| array_buffer->set_flag(Smi::FromInt(0));
|
| array_buffer->set_is_external(is_external);
|
| array_buffer->set_is_neuterable(true);
|
| + array_buffer->set_is_guarded(is_guarded);
|
|
|
| Handle<Object> byte_length =
|
| isolate->factory()->NewNumberFromSize(allocated_length);
|
| @@ -62,20 +80,27 @@ bool Runtime::SetupArrayBufferAllocatingData(Isolate* isolate,
|
| size_t allocated_length,
|
| bool initialize) {
|
| void* data;
|
| + bool is_guarded = false;
|
| CHECK(V8::ArrayBufferAllocator() != NULL);
|
| if (allocated_length != 0) {
|
| - if (initialize) {
|
| - data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
|
| + const size_t page_size = base::OS::CommitPageSize();
|
| + if (allocated_length % page_size == 0) {
|
| + data = V8::ArrayBufferAllocator()->Allocate(allocated_length + page_size,
|
| + page_size);
|
| + if (data == NULL) return false;
|
| + isolate->AddGuardArea(bit_cast<uint8_t*>(data) + allocated_length,
|
| + page_size);
|
| + is_guarded = true;
|
| } else {
|
| - data =
|
| - V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
|
| + data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
|
| }
|
| if (data == NULL) return false;
|
| } else {
|
| data = NULL;
|
| }
|
|
|
| - SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
|
| + SetupArrayBuffer(isolate, array_buffer, false, is_guarded, data,
|
| + allocated_length);
|
|
|
| reinterpret_cast<v8::Isolate*>(isolate)
|
| ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
|
| @@ -176,10 +201,11 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
|
| }
|
| DCHECK(!array_buffer->is_external());
|
| void* backing_store = array_buffer->backing_store();
|
| - size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
|
| + size_t const allocated_length =
|
| + MaybeUnguardArrayBuffer(isolate, *array_buffer);
|
| array_buffer->set_is_external(true);
|
| Runtime::NeuterArrayBuffer(array_buffer);
|
| - V8::ArrayBufferAllocator()->Free(backing_store, byte_length);
|
| + V8::ArrayBufferAllocator()->Free(backing_store, allocated_length);
|
| return isolate->heap()->undefined_value();
|
| }
|
|
|
|
|