Bug 707051 - Change MarkChildren for shapes (r=igor)
☠☠ backed out by 527a79f535d8 ☠ ☠
authorBill McCloskey <wmccloskey@mozilla.com>
Sun, 04 Dec 2011 17:16:21 -0800
changeset 83068 e0cb9fb3075080be64d10079892d48b074c49098
parent 83067 014f175b66d0fd6111cd10b37186999c8ddd61d2
child 83069 527a79f535d8c261c3210860b5b824f8a47ce74b
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)
reviewersigor
bugs707051
milestone11.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
Bug 707051 - Change MarkChildren for shapes (r=igor)
js/src/jsapi.cpp
js/src/jsgcmark.cpp
js/src/jsscope.h
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4178,17 +4178,17 @@ JS_NextProperty(JSContext *cx, JSObject 
 
         while (shape->previous() && !shape->enumerable())
             shape = shape->previous();
 
         if (!shape->previous()) {
             JS_ASSERT(shape->isEmptyShape());
             *idp = JSID_VOID;
         } else {
-            iterobj->setPrivate(const_cast<Shape *>(shape->previous()));
+            iterobj->setPrivate(const_cast<Shape *>(shape->previous().get()));
             *idp = shape->propid();
         }
     } else {
         /* Non-native case: use the ida enumerated when iterobj was created. */
         ida = (JSIdArray *) iterobj->getPrivate();
         JS_ASSERT(i <= ida->length);
         STATIC_ASSUME(i <= ida->length);
         if (i == 0) {
--- a/js/src/jsgcmark.cpp
+++ b/js/src/jsgcmark.cpp
@@ -730,16 +730,17 @@ restart:
     PushMarkStack(gcmarker, shape->base());
 
     jsid id = shape->maybePropid();
     if (JSID_IS_STRING(id))
         PushMarkStack(gcmarker, JSID_TO_STRING(id));
     else if (JS_UNLIKELY(JSID_IS_OBJECT(id)))
         PushMarkStack(gcmarker, JSID_TO_OBJECT(id));
 
+    /* We need the loop here to prevent unbounded recursion. */
     shape = shape->previous();
     if (shape && shape->markIfUnmarked(gcmarker->getMarkColor()))
         goto restart;
 }
 
 static void
 ScanBaseShape(GCMarker *gcmarker, BaseShape *base)
 {
@@ -969,23 +970,21 @@ MarkChildren(JSTracer *trc, JSScript *sc
 
     if (script->types)
         script->types->trace(trc);
 }
 
 void
 MarkChildren(JSTracer *trc, const Shape *shape)
 {
-restart:
     MarkBaseShapeUnbarriered(trc, shape->base(), "base");
     MarkIdUnbarriered(trc, shape->maybePropid(), "propid");
 
-    shape = shape->previous();
-    if (shape)
-        goto restart;
+    if (shape->previous())
+        MarkShape(trc, shape->previous(), "parent");
 }
 
 void
 MarkChildren(JSTracer *trc, BaseShape *base)
 {
     if (base->hasGetterObject()) {
         MarkObjectWithPrinterUnbarriered(trc, base->getterObject(),
                                          PrintPropertyGetterOrSetter, base, 0);
--- a/js/src/jsscope.h
+++ b/js/src/jsscope.h
@@ -587,17 +587,17 @@ struct Shape : public js::gc::Cell
              : 0;
     }
 
     bool isNative() const {
         JS_ASSERT(!(flags & NON_NATIVE) == getObjectClass()->isNative());
         return !(flags & NON_NATIVE);
     }
 
-    const js::Shape *previous() const {
+    const HeapPtrShape &previous() const {
         return parent;
     }
 
     class Range {
       protected:
         friend struct Shape;
 
         const Shape *cursor;