Bug 939472 - Remove buffer from multiview list when neutered. r=billm, a=abillings
authorSteve Fink <sfink@mozilla.com>
Mon, 18 Nov 2013 14:50:14 -0800
changeset 166646 ab93ba38200e961772de83940c48fe25df2875f2
parent 166645 ffd436abd69e8afc86abb2a3fcda35a748bae635
child 166647 39bbf50c35ed8791f2e91136be449c682bfdee63
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm, abillings
bugs939472
milestone27.0a2
Bug 939472 - Remove buffer from multiview list when neutered. r=billm, a=abillings
js/src/vm/TypedArrayObject.cpp
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -330,30 +330,51 @@ GetViewListRef(ArrayBufferObject *obj)
     JS_ASSERT(obj->runtimeFromMainThread()->isHeapBusy());
     return reinterpret_cast<OldObjectRepresentationHack*>(obj->getElementsHeader())->views;
 }
 
 bool
 ArrayBufferObject::neuterViews(JSContext *cx)
 {
     ArrayBufferViewObject *view;
+    size_t numViews = 0;
     for (view = GetViewList(this); view; view = view->nextView()) {
+        numViews++;
         view->neuter();
 
         // Notify compiled jit code that the base pointer has moved.
         MarkObjectStateChange(cx, view);
     }
 
     // neuterAsmJSArrayBuffer adjusts state specific to the ArrayBuffer data
     // itself, but it only affects the behavior of views
     if (isAsmJSArrayBuffer()) {
         if (!ArrayBufferObject::neuterAsmJSArrayBuffer(cx, *this))
             return false;
     }
 
+    // Remove buffer from the list of buffers with > 1 view.
+    if (numViews > 1 && GetViewList(this)->bufferLink() != UNSET_BUFFER_LINK) {
+        ArrayBufferObject *prev = compartment()->gcLiveArrayBuffers;
+        if (prev == this) {
+            compartment()->gcLiveArrayBuffers = GetViewList(prev)->bufferLink();
+        } else {
+            for (ArrayBufferObject *buf = GetViewList(prev)->bufferLink();
+                 buf;
+                 buf = GetViewList(buf)->bufferLink())
+            {
+                if (buf == this) {
+                    GetViewList(prev)->setBufferLink(GetViewList(buf)->bufferLink());
+                    break;
+                }
+                prev = buf;
+            }
+        }
+    }
+
     return true;
 }
 
 void
 ArrayBufferObject::changeContents(JSContext *maybecx, ObjectElements *newHeader)
 {
    JS_ASSERT(!isAsmJSArrayBuffer());