Commit 05ed6cb6 authored by jochen's avatar jochen Committed by Commit bot

Put newly allocated buffers at the right end of the buffers list

If a major gc happens between allocation and initialization of the
buffer, it might be already in old space. Since we need the list of
buffers to be sorted from new to old, we keep track of the last buffer
and put old buffers to the end

BUG=chromium:476032
R=hpayer@chromium.org,dslomov@chromium.org
LOG=n

Review URL: https://codereview.chromium.org/1079923003

Cr-Commit-Position: refs/heads/master@{#27811}
parent 0a9aa174
...@@ -156,6 +156,7 @@ Heap::Heap() ...@@ -156,6 +156,7 @@ Heap::Heap()
memset(roots_, 0, sizeof(roots_[0]) * kRootListLength); memset(roots_, 0, sizeof(roots_[0]) * kRootListLength);
set_native_contexts_list(NULL); set_native_contexts_list(NULL);
set_array_buffers_list(Smi::FromInt(0)); set_array_buffers_list(Smi::FromInt(0));
set_last_array_buffer_in_list(Smi::FromInt(0));
set_allocation_sites_list(Smi::FromInt(0)); set_allocation_sites_list(Smi::FromInt(0));
set_encountered_weak_collections(Smi::FromInt(0)); set_encountered_weak_collections(Smi::FromInt(0));
set_encountered_weak_cells(Smi::FromInt(0)); set_encountered_weak_cells(Smi::FromInt(0));
...@@ -1674,8 +1675,8 @@ void Heap::ProcessYoungWeakReferences(WeakObjectRetainer* retainer) { ...@@ -1674,8 +1675,8 @@ void Heap::ProcessYoungWeakReferences(WeakObjectRetainer* retainer) {
void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) { void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) {
Object* head = Object* head = VisitWeakList<Context>(this, native_contexts_list(), retainer,
VisitWeakList<Context>(this, native_contexts_list(), retainer, false); false, NULL);
// Update the head of the list of contexts. // Update the head of the list of contexts.
set_native_contexts_list(head); set_native_contexts_list(head);
} }
...@@ -1683,9 +1684,12 @@ void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) { ...@@ -1683,9 +1684,12 @@ void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) {
void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer, void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer,
bool stop_after_young) { bool stop_after_young) {
Object* array_buffer_obj = VisitWeakList<JSArrayBuffer>( Object* last_array_buffer = undefined_value();
this, array_buffers_list(), retainer, stop_after_young); Object* array_buffer_obj =
VisitWeakList<JSArrayBuffer>(this, array_buffers_list(), retainer,
stop_after_young, &last_array_buffer);
set_array_buffers_list(array_buffer_obj); set_array_buffers_list(array_buffer_obj);
set_last_array_buffer_in_list(last_array_buffer);
// Verify invariant that young array buffers come before old array buffers // Verify invariant that young array buffers come before old array buffers
// in array buffers list if there was no promotion failure. // in array buffers list if there was no promotion failure.
...@@ -1706,7 +1710,7 @@ void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer, ...@@ -1706,7 +1710,7 @@ void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer,
void Heap::ProcessNewArrayBufferViews(WeakObjectRetainer* retainer) { void Heap::ProcessNewArrayBufferViews(WeakObjectRetainer* retainer) {
// Retain the list of new space views. // Retain the list of new space views.
Object* typed_array_obj = VisitWeakList<JSArrayBufferView>( Object* typed_array_obj = VisitWeakList<JSArrayBufferView>(
this, new_array_buffer_views_list_, retainer, false); this, new_array_buffer_views_list_, retainer, false, NULL);
set_new_array_buffer_views_list(typed_array_obj); set_new_array_buffer_views_list(typed_array_obj);
// Some objects in the list may be in old space now. Find them // Some objects in the list may be in old space now. Find them
...@@ -1730,7 +1734,7 @@ void Heap::TearDownArrayBuffers() { ...@@ -1730,7 +1734,7 @@ void Heap::TearDownArrayBuffers() {
void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer) { void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer) {
Object* allocation_site_obj = VisitWeakList<AllocationSite>( Object* allocation_site_obj = VisitWeakList<AllocationSite>(
this, allocation_sites_list(), retainer, false); this, allocation_sites_list(), retainer, false, NULL);
set_allocation_sites_list(allocation_site_obj); set_allocation_sites_list(allocation_site_obj);
} }
...@@ -5339,6 +5343,7 @@ bool Heap::CreateHeapObjects() { ...@@ -5339,6 +5343,7 @@ bool Heap::CreateHeapObjects() {
set_native_contexts_list(undefined_value()); set_native_contexts_list(undefined_value());
set_array_buffers_list(undefined_value()); set_array_buffers_list(undefined_value());
set_last_array_buffer_in_list(undefined_value());
set_new_array_buffer_views_list(undefined_value()); set_new_array_buffer_views_list(undefined_value());
set_allocation_sites_list(undefined_value()); set_allocation_sites_list(undefined_value());
return true; return true;
......
...@@ -855,6 +855,13 @@ class Heap { ...@@ -855,6 +855,13 @@ class Heap {
void set_array_buffers_list(Object* object) { array_buffers_list_ = object; } void set_array_buffers_list(Object* object) { array_buffers_list_ = object; }
Object* array_buffers_list() const { return array_buffers_list_; } Object* array_buffers_list() const { return array_buffers_list_; }
void set_last_array_buffer_in_list(Object* object) {
last_array_buffer_in_list_ = object;
}
Object* last_array_buffer_in_list() const {
return last_array_buffer_in_list_;
}
void set_new_array_buffer_views_list(Object* object) { void set_new_array_buffer_views_list(Object* object) {
new_array_buffer_views_list_ = object; new_array_buffer_views_list_ = object;
} }
...@@ -1638,6 +1645,7 @@ class Heap { ...@@ -1638,6 +1645,7 @@ class Heap {
// List heads are initialized lazily and contain the undefined_value at start. // List heads are initialized lazily and contain the undefined_value at start.
Object* native_contexts_list_; Object* native_contexts_list_;
Object* array_buffers_list_; Object* array_buffers_list_;
Object* last_array_buffer_in_list_;
Object* allocation_sites_list_; Object* allocation_sites_list_;
// This is a global list of array buffer views in new space. When the views // This is a global list of array buffer views in new space. When the views
......
...@@ -192,7 +192,7 @@ struct WeakListVisitor; ...@@ -192,7 +192,7 @@ struct WeakListVisitor;
template <class T> template <class T>
Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer, Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer,
bool stop_after_young) { bool stop_after_young, Object** list_tail) {
Object* undefined = heap->undefined_value(); Object* undefined = heap->undefined_value();
Object* head = undefined; Object* head = undefined;
T* tail = NULL; T* tail = NULL;
...@@ -237,6 +237,7 @@ Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer, ...@@ -237,6 +237,7 @@ Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer,
// Terminate the list if there is one or more elements. // Terminate the list if there is one or more elements.
if (tail != NULL) { if (tail != NULL) {
WeakListVisitor<T>::SetWeakNext(tail, undefined); WeakListVisitor<T>::SetWeakNext(tail, undefined);
if (list_tail) *list_tail = tail;
} }
return head; return head;
} }
...@@ -370,7 +371,7 @@ struct WeakListVisitor<Context> { ...@@ -370,7 +371,7 @@ struct WeakListVisitor<Context> {
WeakObjectRetainer* retainer, int index) { WeakObjectRetainer* retainer, int index) {
// Visit the weak list, removing dead intermediate elements. // Visit the weak list, removing dead intermediate elements.
Object* list_head = Object* list_head =
VisitWeakList<T>(heap, context->get(index), retainer, false); VisitWeakList<T>(heap, context->get(index), retainer, false, NULL);
// Update the list head. // Update the list head.
context->set(index, list_head, UPDATE_WRITE_BARRIER); context->set(index, list_head, UPDATE_WRITE_BARRIER);
...@@ -422,7 +423,7 @@ struct WeakListVisitor<JSArrayBuffer> { ...@@ -422,7 +423,7 @@ struct WeakListVisitor<JSArrayBuffer> {
static void VisitLiveObject(Heap* heap, JSArrayBuffer* array_buffer, static void VisitLiveObject(Heap* heap, JSArrayBuffer* array_buffer,
WeakObjectRetainer* retainer) { WeakObjectRetainer* retainer) {
Object* typed_array_obj = VisitWeakList<JSArrayBufferView>( Object* typed_array_obj = VisitWeakList<JSArrayBufferView>(
heap, array_buffer->weak_first_view(), retainer, false); heap, array_buffer->weak_first_view(), retainer, false, NULL);
array_buffer->set_weak_first_view(typed_array_obj); array_buffer->set_weak_first_view(typed_array_obj);
if (typed_array_obj != heap->undefined_value() && MustRecordSlots(heap)) { if (typed_array_obj != heap->undefined_value() && MustRecordSlots(heap)) {
Object** slot = HeapObject::RawField(array_buffer, Object** slot = HeapObject::RawField(array_buffer,
...@@ -455,19 +456,23 @@ struct WeakListVisitor<AllocationSite> { ...@@ -455,19 +456,23 @@ struct WeakListVisitor<AllocationSite> {
template Object* VisitWeakList<Context>(Heap* heap, Object* list, template Object* VisitWeakList<Context>(Heap* heap, Object* list,
WeakObjectRetainer* retainer, WeakObjectRetainer* retainer,
bool stop_after_young); bool stop_after_young,
Object** list_tail);
template Object* VisitWeakList<JSArrayBuffer>(Heap* heap, Object* list, template Object* VisitWeakList<JSArrayBuffer>(Heap* heap, Object* list,
WeakObjectRetainer* retainer, WeakObjectRetainer* retainer,
bool stop_after_young); bool stop_after_young,
Object** list_tail);
template Object* VisitWeakList<JSArrayBufferView>(Heap* heap, Object* list, template Object* VisitWeakList<JSArrayBufferView>(Heap* heap, Object* list,
WeakObjectRetainer* retainer, WeakObjectRetainer* retainer,
bool stop_after_young); bool stop_after_young,
Object** list_tail);
template Object* VisitWeakList<AllocationSite>(Heap* heap, Object* list, template Object* VisitWeakList<AllocationSite>(Heap* heap, Object* list,
WeakObjectRetainer* retainer, WeakObjectRetainer* retainer,
bool stop_after_young); bool stop_after_young,
Object** list_tail);
} }
} // namespace v8::internal } // namespace v8::internal
...@@ -491,7 +491,7 @@ class WeakObjectRetainer; ...@@ -491,7 +491,7 @@ class WeakObjectRetainer;
// access the next-element pointers. // access the next-element pointers.
template <class T> template <class T>
Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer, Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer,
bool stop_after_young); bool stop_after_young, Object** list_tail);
Object* VisitNewArrayBufferViewsWeakList(Heap* heap, Object* list, Object* VisitNewArrayBufferViewsWeakList(Heap* heap, Object* list,
WeakObjectRetainer* retainer); WeakObjectRetainer* retainer);
} }
......
...@@ -51,9 +51,18 @@ void Runtime::SetupArrayBuffer(Isolate* isolate, ...@@ -51,9 +51,18 @@ void Runtime::SetupArrayBuffer(Isolate* isolate,
CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber()); CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
array_buffer->set_byte_length(*byte_length); array_buffer->set_byte_length(*byte_length);
array_buffer->set_weak_next(isolate->heap()->array_buffers_list()); if (isolate->heap()->InNewSpace(*array_buffer) ||
CHECK(isolate->heap()->InNewSpace(*array_buffer)); isolate->heap()->array_buffers_list()->IsUndefined()) {
isolate->heap()->set_array_buffers_list(*array_buffer); array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
isolate->heap()->set_array_buffers_list(*array_buffer);
if (isolate->heap()->last_array_buffer_in_list()->IsUndefined()) {
isolate->heap()->set_last_array_buffer_in_list(*array_buffer);
}
} else {
JSArrayBuffer::cast(isolate->heap()->last_array_buffer_in_list())
->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()); array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
} }
......
...@@ -565,6 +565,8 @@ void Deserializer::Deserialize(Isolate* isolate) { ...@@ -565,6 +565,8 @@ void Deserializer::Deserialize(Isolate* isolate) {
isolate_->heap()->undefined_value()); isolate_->heap()->undefined_value());
isolate_->heap()->set_array_buffers_list( isolate_->heap()->set_array_buffers_list(
isolate_->heap()->undefined_value()); isolate_->heap()->undefined_value());
isolate_->heap()->set_last_array_buffer_in_list(
isolate_->heap()->undefined_value());
isolate->heap()->set_new_array_buffer_views_list( isolate->heap()->set_new_array_buffer_views_list(
isolate_->heap()->undefined_value()); isolate_->heap()->undefined_value());
......
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