Put newly allocated buffers at the right end of the buffers list
authorjochen <jochen@chromium.org>
Tue, 14 Apr 2015 09:26:13 +0000 (02:26 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 14 Apr 2015 09:26:10 +0000 (09:26 +0000)
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}

src/heap/heap.cc
src/heap/heap.h
src/heap/objects-visiting.cc
src/heap/objects-visiting.h
src/runtime/runtime-typedarray.cc
src/snapshot/serialize.cc

index 8e3c42d7d645a9f807b6af4d06b3526a84a53dd1..274d9ef0c22e83a5cc1f92ad8a03da6e7b9c6244 100644 (file)
@@ -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;
index b90a8da5d9a76a6799fedb43cb55ffff06fdeb3b..4f624a3ab4b538d0b0eb128fc094516d6e03883c 100644 (file)
@@ -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
index 520e539c7cca5e779f71aa1096ad72e4b2fd20c7..cf71fb2bdaf540423a3ec3c8f46c03771d1a888b 100644 (file)
@@ -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
index 2bc90457acdbb63bb70fcd5a0d7b362b7c25acb6..12da9e9e34eaba2046ec905306880916ac94ab57 100644 (file)
@@ -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);
 }
index 510ceb1ac9631e4ebb9fc97f2f958fb0d3fccf2d..a1aacd7aa8a744236c311f8698e8b0f8b810016b 100644 (file)
@@ -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());
 }
 
index fa353f7759efd5ce0778ef986227f5c697c3218b..b8fc206f2bdb73258cd055931277e078ca43ba78 100644 (file)
@@ -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());