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()) { |