Index: src/runtime/runtime-typedarray.cc |
diff --git a/src/runtime/runtime-typedarray.cc b/src/runtime/runtime-typedarray.cc |
index 02b5579bf82715a362a40c87f55d43af6f42e726..a1aacd7aa8a744236c311f8698e8b0f8b810016b 100644 |
--- a/src/runtime/runtime-typedarray.cc |
+++ b/src/runtime/runtime-typedarray.cc |
@@ -63,6 +63,7 @@ |
->set_weak_next(*array_buffer); |
isolate->heap()->set_last_array_buffer_in_list(*array_buffer); |
} |
+ array_buffer->set_weak_first_view(isolate->heap()->undefined_value()); |
} |
@@ -96,6 +97,39 @@ |
void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) { |
+ Isolate* isolate = array_buffer->GetIsolate(); |
+ // Firstly, iterate over the views which are referenced directly by the array |
+ // buffer. |
+ for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate); |
+ !view_obj->IsUndefined();) { |
+ Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj)); |
+ if (view->IsJSTypedArray()) { |
+ JSTypedArray::cast(*view)->Neuter(); |
+ } else if (view->IsJSDataView()) { |
+ JSDataView::cast(*view)->Neuter(); |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ view_obj = handle(view->weak_next(), isolate); |
+ } |
+ |
+ // Secondly, iterate over the global list of new space views to find views |
+ // that belong to the neutered array buffer. |
+ Heap* heap = isolate->heap(); |
+ for (Handle<Object> view_obj(heap->new_array_buffer_views_list(), isolate); |
+ !view_obj->IsUndefined();) { |
+ Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj)); |
+ if (view->buffer() == *array_buffer) { |
+ if (view->IsJSTypedArray()) { |
+ JSTypedArray::cast(*view)->Neuter(); |
+ } else if (view->IsJSDataView()) { |
+ JSDataView::cast(*view)->Neuter(); |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ } |
+ view_obj = handle(view->weak_next(), isolate); |
+ } |
array_buffer->Neuter(); |
} |
@@ -261,9 +295,18 @@ |
holder->set_byte_offset(*byte_offset_object); |
holder->set_byte_length(*byte_length_object); |
+ Heap* heap = isolate->heap(); |
if (!maybe_buffer->IsNull()) { |
Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer); |
holder->set_buffer(*buffer); |
+ |
+ if (heap->InNewSpace(*holder)) { |
+ holder->set_weak_next(heap->new_array_buffer_views_list()); |
+ heap->set_new_array_buffer_views_list(*holder); |
+ } else { |
+ holder->set_weak_next(buffer->weak_first_view()); |
+ buffer->set_weak_first_view(*holder); |
+ } |
Handle<ExternalArray> elements = isolate->factory()->NewExternalArray( |
static_cast<int>(length), array_type, |
@@ -274,6 +317,7 @@ |
DCHECK(IsExternalArrayElementsKind(holder->map()->elements_kind())); |
} else { |
holder->set_buffer(Smi::FromInt(0)); |
+ holder->set_weak_next(isolate->heap()->undefined_value()); |
Handle<FixedTypedArrayBase> elements = |
isolate->factory()->NewFixedTypedArray(static_cast<int>(length), |
array_type); |
@@ -361,6 +405,15 @@ |
holder->set_byte_length(*byte_length_obj); |
holder->set_length(*length_obj); |
+ Heap* heap = isolate->heap(); |
+ if (heap->InNewSpace(*holder)) { |
+ holder->set_weak_next(heap->new_array_buffer_views_list()); |
+ heap->set_new_array_buffer_views_list(*holder); |
+ } else { |
+ holder->set_weak_next(buffer->weak_first_view()); |
+ buffer->set_weak_first_view(*holder); |
+ } |
+ |
Handle<ExternalArray> elements = isolate->factory()->NewExternalArray( |
static_cast<int>(length), array_type, |
static_cast<uint8_t*>(buffer->backing_store())); |
@@ -532,6 +585,15 @@ |
holder->set_buffer(*buffer); |
holder->set_byte_offset(*byte_offset); |
holder->set_byte_length(*byte_length); |
+ |
+ Heap* heap = isolate->heap(); |
+ if (heap->InNewSpace(*holder)) { |
+ holder->set_weak_next(heap->new_array_buffer_views_list()); |
+ heap->set_new_array_buffer_views_list(*holder); |
+ } else { |
+ holder->set_weak_next(buffer->weak_first_view()); |
+ buffer->set_weak_first_view(*holder); |
+ } |
return isolate->heap()->undefined_value(); |
} |