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