Preserve last shape while converting to dictionary mode, bug 693966.
authorBrian Hackett <bhackett1024@gmail.com>
Thu, 13 Oct 2011 08:38:05 -0700
changeset 82892 01a5df36675f6f1e8a6df23f916599811409bf7d
parent 82891 7b634ad714fd756ac801f37d619464251baaeb83
child 82893 eb68a225437d5a635786a384c9e003e63a912f36
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs693966
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Preserve last shape while converting to dictionary mode, bug 693966.
js/src/jsscope.cpp
--- a/js/src/jsscope.cpp
+++ b/js/src/jsscope.cpp
@@ -418,19 +418,30 @@ JSObject::toDictionaryMode(JSContext *cx
 {
     JS_ASSERT(!inDictionaryMode());
 
     /* We allocate the shapes from cx->compartment, so make sure it's right. */
     JS_ASSERT(compartment() == cx->compartment);
 
     uint32 span = slotSpan();
 
-    if (!Shape::newDictionaryList(cx, &shape_))
+    /*
+     * Clone the shapes into a new dictionary list. Don't update the
+     * last property of this object until done, otherwise a GC
+     * triggered while creating the dictionary will get the wrong
+     * slot span for this object.
+     */
+    Shape *last = lastProperty();
+    if (!Shape::newDictionaryList(cx, &last))
         return false;
 
+    JS_ASSERT(last->listp == &last);
+    last->listp = &shape_;
+    shape_ = last;
+
     JS_ASSERT(lastProperty()->hasTable());
     lastProperty()->base()->setSlotSpan(span);
 
     return true;
 }
 
 /*
  * Normalize stub getter and setter values for faster is-stub testing in the