| Index: src/runtime/runtime-typedarray.cc
|
| diff --git a/src/runtime/runtime-typedarray.cc b/src/runtime/runtime-typedarray.cc
|
| index 59c417f5b7c92ef548e2370703f94109dc670a66..6e2406010915ae4b93dddd92cfd4eaadd1345d69 100644
|
| --- a/src/runtime/runtime-typedarray.cc
|
| +++ b/src/runtime/runtime-typedarray.cc
|
| @@ -26,16 +26,22 @@ void Runtime::FreeArrayBuffer(Isolate* isolate,
|
| reinterpret_cast<v8::Isolate*>(isolate)
|
| ->AdjustAmountOfExternalAllocatedMemory(
|
| -static_cast<int64_t>(allocated_length));
|
| - CHECK(V8::ArrayBufferAllocator() != NULL);
|
| - V8::ArrayBufferAllocator()->Free(phantom_array_buffer->backing_store(),
|
| - allocated_length);
|
| + if (phantom_array_buffer->is_shared()) {
|
| + CHECK(V8::SharedArrayBufferAllocator() != NULL);
|
| + V8::SharedArrayBufferAllocator()->Free(
|
| + phantom_array_buffer->backing_store(), allocated_length);
|
| + } else {
|
| + CHECK(V8::ArrayBufferAllocator() != NULL);
|
| + V8::ArrayBufferAllocator()->Free(phantom_array_buffer->backing_store(),
|
| + allocated_length);
|
| + }
|
| }
|
|
|
|
|
| void Runtime::SetupArrayBuffer(Isolate* isolate,
|
| Handle<JSArrayBuffer> array_buffer,
|
| bool is_external, void* data,
|
| - size_t allocated_length) {
|
| + size_t allocated_length, bool is_shared) {
|
| DCHECK(array_buffer->GetInternalFieldCount() ==
|
| v8::ArrayBuffer::kInternalFieldCount);
|
| for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
|
| @@ -45,6 +51,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_shared(is_shared);
|
|
|
| Handle<Object> byte_length =
|
| isolate->factory()->NewNumberFromSize(allocated_length);
|
| @@ -60,24 +67,35 @@ void Runtime::SetupArrayBuffer(Isolate* isolate,
|
| bool Runtime::SetupArrayBufferAllocatingData(Isolate* isolate,
|
| Handle<JSArrayBuffer> array_buffer,
|
| size_t allocated_length,
|
| - bool initialize) {
|
| + bool initialize, bool is_shared) {
|
| void* data;
|
| - CHECK(V8::ArrayBufferAllocator() != NULL);
|
| + CHECK(is_shared ? V8::SharedArrayBufferAllocator() != NULL
|
| + : V8::ArrayBufferAllocator() != NULL);
|
| // Prevent creating array buffers when serializing.
|
| DCHECK(!isolate->serializer_enabled());
|
| if (allocated_length != 0) {
|
| - if (initialize) {
|
| - data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
|
| + if (is_shared) {
|
| + if (initialize) {
|
| + data = V8::SharedArrayBufferAllocator()->Allocate(allocated_length);
|
| + } else {
|
| + data = V8::SharedArrayBufferAllocator()->AllocateUninitialized(
|
| + allocated_length);
|
| + }
|
| } else {
|
| - data =
|
| - V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
|
| + if (initialize) {
|
| + data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
|
| + } else {
|
| + data =
|
| + V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
|
| + }
|
| }
|
| if (data == NULL) return false;
|
| } else {
|
| data = NULL;
|
| }
|
|
|
| - SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
|
| + SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length,
|
| + is_shared);
|
|
|
| reinterpret_cast<v8::Isolate*>(isolate)
|
| ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
|
| @@ -126,9 +144,10 @@ void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
|
|
|
| RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
|
| HandleScope scope(isolate);
|
| - DCHECK(args.length() == 2);
|
| + DCHECK(args.length() == 3);
|
| CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
|
| CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
|
| + CONVERT_BOOLEAN_ARG_CHECKED(isShared, 2);
|
| if (!holder->byte_length()->IsUndefined()) {
|
| // ArrayBuffer is already initialized; probably a fuzz test.
|
| return *holder;
|
| @@ -139,8 +158,8 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
|
| isolate, NewRangeError("invalid_array_buffer_length",
|
| HandleVector<Object>(NULL, 0)));
|
| }
|
| - if (!Runtime::SetupArrayBufferAllocatingData(isolate, holder,
|
| - allocated_length)) {
|
| + if (!Runtime::SetupArrayBufferAllocatingData(
|
| + isolate, holder, allocated_length, true, isShared)) {
|
| THROW_NEW_ERROR_RETURN_FAILURE(
|
| isolate, NewRangeError("invalid_array_buffer_length",
|
| HandleVector<Object>(NULL, 0)));
|
| @@ -157,6 +176,14 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
|
| }
|
|
|
|
|
| +RUNTIME_FUNCTION(Runtime_ArrayBufferIsShared) {
|
| + SealHandleScope shs(isolate);
|
| + DCHECK(args.length() == 1);
|
| + CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
|
| + return isolate->heap()->ToBoolean(holder->is_shared());
|
| +}
|
| +
|
| +
|
| RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
|
| HandleScope scope(isolate);
|
| DCHECK(args.length() == 3);
|
| @@ -196,6 +223,8 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
|
| CHECK(Smi::FromInt(0) == array_buffer->byte_length());
|
| return isolate->heap()->undefined_value();
|
| }
|
| + // Shared array buffers should never be neutered.
|
| + DCHECK(!array_buffer->is_shared());
|
| DCHECK(!array_buffer->is_external());
|
| void* backing_store = array_buffer->backing_store();
|
| size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
|
| @@ -230,12 +259,13 @@ void Runtime::ArrayIdToTypeAndSize(int arrayId, ExternalArrayType* array_type,
|
|
|
| RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
|
| HandleScope scope(isolate);
|
| - DCHECK(args.length() == 5);
|
| + DCHECK(args.length() == 6);
|
| CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
|
| CONVERT_SMI_ARG_CHECKED(arrayId, 1);
|
| CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
|
| CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
|
| CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
|
| + CONVERT_BOOLEAN_ARG_CHECKED(isShared, 5);
|
|
|
| RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
|
| arrayId <= Runtime::ARRAY_ID_LAST);
|
| @@ -260,6 +290,7 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
|
| NumberToSize(isolate, buffer->byte_length());
|
| RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
|
| RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
|
| + RUNTIME_ASSERT(isShared == buffer->is_shared());
|
| } else {
|
| RUNTIME_ASSERT(maybe_buffer->IsNull());
|
| }
|
| @@ -284,6 +315,7 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
|
| holder->set_length(*length_obj);
|
| holder->set_byte_offset(*byte_offset_object);
|
| holder->set_byte_length(*byte_length_object);
|
| + holder->set_is_shared(isShared);
|
|
|
| Heap* heap = isolate->heap();
|
| if (!maybe_buffer->IsNull()) {
|
|
|