Backout 36fa9b176a91 (bug 710516) for M1 bustage.
authorBrian Hackett <bhackett1024@gmail.com>
Thu, 15 Dec 2011 09:07:00 -0800
changeset 82665 c5ebfdbe12d9edeaa083f4cde5bedbd4b8926acd
parent 82664 8780747bbc5c7c89d4bde166b623c693a38119a4
child 82666 e9014ab86f5dc0634566fb4023ebb16045bc51ae
push id4048
push userbhackett@mozilla.com
push dateThu, 15 Dec 2011 17:07:15 +0000
treeherdermozilla-inbound@c5ebfdbe12d9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs710516
milestone11.0a1
backs out36fa9b176a915490c892378a3c568725f5d563e4
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
Backout 36fa9b176a91 (bug 710516) for M1 bustage.
js/src/frontend/BytecodeEmitter.cpp
js/src/jsdbgapi.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -1776,18 +1776,18 @@ LookupCompileTimeConstant(JSContext *cx,
                 if (shape) {
                     /*
                      * We're compiling code that will be executed immediately,
                      * not re-executed against a different scope chain and/or
                      * variable object.  Therefore we can get constant values
                      * from our variable object here.
                      */
                     if (!shape->writable() && !shape->configurable() &&
-                        shape->hasDefaultGetter() && shape->hasSlot()) {
-                        *constp = obj->nativeGetSlot(shape->slot());
+                        shape->hasDefaultGetter() && obj->containsSlot(shape->slot())) {
+                        *constp = obj->getSlot(shape->slot());
                     }
                 }
 
                 if (shape)
                     break;
             }
         }
     } while (bce->parent && (bce = bce->parent->asBytecodeEmitter()));
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -856,16 +856,25 @@ JS_GetPropertyDesc(JSContext *cx, JSObje
     } else if (shape->getter() == GetCallVar) {
         pd->slot = shape->shortid();
         pd->flags |= JSPD_VARIABLE;
     } else {
         pd->slot = 0;
     }
     pd->alias = JSVAL_VOID;
 
+    if (obj->containsSlot(shape->slot())) {
+        for (Shape::Range r = obj->lastProperty()->all(); !r.empty(); r.popFront()) {
+            const Shape &aprop = r.front();
+            if (&aprop != shape && aprop.slot() == shape->slot()) {
+                pd->alias = IdToJsval(aprop.propid());
+                break;
+            }
+        }
+    }
     return JS_TRUE;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
 {
     assertSameCompartment(cx, obj);
     Class *clasp = obj->getClass();
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -5023,17 +5023,17 @@ js_FindClassObject(JSContext *cx, JSObje
     }
 
     JS_ASSERT(obj->isNative());
     if (!LookupPropertyWithFlags(cx, obj, id, JSRESOLVE_CLASSNAME, &pobj, &prop))
         return false;
     Value v = UndefinedValue();
     if (prop && pobj->isNative()) {
         shape = (Shape *) prop;
-        if (shape->hasSlot()) {
+        if (pobj->containsSlot(shape->slot())) {
             v = pobj->nativeGetSlot(shape->slot());
             if (v.isPrimitive())
                 v.setUndefined();
         }
     }
     *vp = v;
     return true;
 }
@@ -5280,17 +5280,17 @@ static inline bool
 CallAddPropertyHook(JSContext *cx, Class *clasp, JSObject *obj, const Shape *shape, Value *vp)
 {
     if (clasp->addProperty != JS_PropertyStub) {
         Value nominal = *vp;
 
         if (!CallJSPropertyOp(cx, clasp->addProperty, obj, shape->propid(), vp))
             return false;
         if (*vp != nominal) {
-            if (shape->hasSlot())
+            if (obj->containsSlot(shape->slot()))
                 obj->nativeSetSlotWithType(cx, shape, *vp);
         }
     }
     return true;
 }
 
 namespace js {
 
@@ -5410,17 +5410,17 @@ DefineNativeProperty(JSContext *cx, JSOb
 
         shape = obj->putProperty(cx, id, getter, setter, SHAPE_INVALID_SLOT,
                                  attrs, flags, shortid);
         if (!shape)
             return NULL;
     }
 
     /* Store valueCopy before calling addProperty, in case the latter GC's. */
-    if (shape->hasSlot())
+    if (shape->hasSlot() && obj->containsSlot(shape->slot()))
         obj->nativeSetSlot(shape->slot(), valueCopy);
 
     /* XXXbe called with lock held */
     if (!CallAddPropertyHook(cx, clasp, obj, shape, &valueCopy)) {
         obj->removeProperty(cx, id);
         return NULL;
     }
 
@@ -5845,16 +5845,17 @@ JSBool
 js_NativeSet(JSContext *cx, JSObject *obj, const Shape *shape, bool added, bool strict, Value *vp)
 {
     AddTypePropertyId(cx, obj, shape->propid(), *vp);
 
     JS_ASSERT(obj->isNative());
 
     if (shape->hasSlot()) {
         uint32 slot = shape->slot();
+        JS_ASSERT(obj->containsSlot(slot));
 
         /* If shape has a stub setter, just store *vp. */
         if (shape->hasDefaultSetter()) {
             if (!added) {
                 if (shape->isMethod() && !obj->methodShapeChange(cx, *shape))
                     return false;
             }
             obj->nativeSetSlot(slot, *vp);
@@ -6326,17 +6327,17 @@ js_SetPropertyHelper(JSContext *cx, JSOb
         if (!shape)
             return JS_FALSE;
 
         /*
          * Initialize the new property value (passed to setter) to undefined.
          * Note that we store before calling addProperty, to match the order
          * in DefineNativeProperty.
          */
-        if (shape->hasSlot())
+        if (obj->containsSlot(shape->slot()))
             obj->nativeSetSlot(shape->slot(), UndefinedValue());
 
         /* XXXbe called with obj locked */
         if (!CallAddPropertyHook(cx, clasp, obj, shape, vp)) {
             obj->removeProperty(cx, id);
             return JS_FALSE;
         }
         added = true;
@@ -6458,17 +6459,17 @@ js_DeleteProperty(JSContext *cx, JSObjec
         return true;
     }
 
     if (!CallJSPropertyOp(cx, obj->getClass()->delProperty, obj, shape->getUserId(), rval))
         return false;
     if (rval->isFalse())
         return true;
 
-    if (shape->hasSlot()) {
+    if (shape->hasSlot() && obj->containsSlot(shape->slot())) {
         const Value &v = obj->nativeGetSlot(shape->slot());
         GCPoke(cx, v);
 
         /*
          * Delete is rare enough that we can take the hit of checking for an
          * active cloned method function object that must be homed to a callee
          * slot on the active stack frame before this delete completes, in case
          * someone saved the clone and checks it against foo.caller for a foo
@@ -6511,16 +6512,17 @@ js_DeleteElement(JSContext *cx, JSObject
 
 namespace js {
 
 bool
 HasDataProperty(JSContext *cx, JSObject *obj, jsid methodid, Value *vp)
 {
     if (const Shape *shape = obj->nativeLookup(cx, methodid)) {
         if (shape->hasDefaultGetterOrIsMethod() && shape->hasSlot()) {
+            JS_ASSERT(obj->containsSlot(shape->slot()));
             *vp = obj->nativeGetSlot(shape->slot());
             return true;
         }
     }
 
     return false;
 }
 
@@ -6952,18 +6954,20 @@ js_PrintObjectSlotName(JSTracer *trc, ch
     JS_ASSERT(trc->debugPrinter == js_PrintObjectSlotName);
 
     JSObject *obj = (JSObject *)trc->debugPrintArg;
     uint32 slot = (uint32)trc->debugPrintIndex;
 
     const Shape *shape;
     if (obj->isNative()) {
         shape = obj->lastProperty();
-        while (shape && (!shape->hasSlot() || shape->slot() != slot))
+        while (shape->previous() && shape->maybeSlot() != slot)
             shape = shape->previous();
+        if (shape->maybeSlot() != slot)
+            shape = NULL;
     } else {
         shape = NULL;
     }
 
     if (!shape) {
         const char *slotname = NULL;
         if (obj->isGlobal()) {
 #define JS_PROTO(name,code,init)                                              \
@@ -7010,18 +7014,18 @@ js_ClearNative(JSContext *cx, JSObject *
     }
 
     /* Set all remaining writable plain data properties to undefined. */
     for (Shape::Range r(obj->lastProperty()->all()); !r.empty(); r.popFront()) {
         const Shape *shape = &r.front();
         if (shape->isDataDescriptor() &&
             shape->writable() &&
             shape->hasDefaultSetter() &&
-            shape->hasSlot()) {
-            obj->nativeSetSlot(shape->slot(), UndefinedValue());
+            obj->containsSlot(shape->maybeSlot())) {
+            obj->setSlot(shape->slot(), UndefinedValue());
         }
     }
     return true;
 }
 
 bool
 js_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 slot, Value *vp)
 {
@@ -7278,17 +7282,17 @@ DumpProperty(JSObject *obj, const Shape 
         dumpString(JSID_TO_STRING(id));
     else if (JSID_IS_INT(id))
         fprintf(stderr, "%d", (int) JSID_TO_INT(id));
     else
         fprintf(stderr, "unknown jsid %p", (void *) JSID_BITS(id));
 
     uint32 slot = shape.hasSlot() ? shape.maybeSlot() : SHAPE_INVALID_SLOT;
     fprintf(stderr, ": slot %d", slot);
-    if (shape.hasSlot()) {
+    if (obj->containsSlot(slot)) {
         fprintf(stderr, " = ");
         dumpValue(obj->getSlot(slot));
     } else if (slot != SHAPE_INVALID_SLOT) {
         fprintf(stderr, " (INVALID!)");
     }
     fprintf(stderr, "\n");
 }
 
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -705,16 +705,18 @@ struct JSObject : js::gc::Cell
      * ensure there are enough slots in this object. If |valid|, then the slots
      * being overwritten hold valid data and must be invalidated for the write
      * barrier.
      */
     void copySlotRange(size_t start, const js::Value *vector, size_t length, bool valid);
 
     inline uint32 slotSpan() const;
 
+    inline bool containsSlot(uint32 slot) const;
+
     void rollbackProperties(JSContext *cx, uint32 slotSpan);
 
 #ifdef DEBUG
     enum SentinelAllowed {
         SENTINEL_NOT_ALLOWED,
         SENTINEL_ALLOWED
     };
 
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -1136,29 +1136,35 @@ JSObject::principals(JSContext *cx)
 inline uint32
 JSObject::slotSpan() const
 {
     if (inDictionaryMode())
         return lastProperty()->base()->slotSpan();
     return lastProperty()->slotSpan();
 }
 
+inline bool
+JSObject::containsSlot(uint32 slot) const
+{
+    return slot < slotSpan();
+}
+
 inline js::HeapValue &
 JSObject::nativeGetSlotRef(uintN slot)
 {
     JS_ASSERT(isNative());
-    JS_ASSERT(slot < slotSpan());
+    JS_ASSERT(containsSlot(slot));
     return getSlotRef(slot);
 }
 
 inline const js::Value &
 JSObject::nativeGetSlot(uintN slot) const
 {
     JS_ASSERT(isNative());
-    JS_ASSERT(slot < slotSpan());
+    JS_ASSERT(containsSlot(slot));
     return getSlot(slot);
 }
 
 inline JSFunction *
 JSObject::nativeGetMethod(const js::Shape *shape) const
 {
     /*
      * For method shapes, this object must have an uncloned function object in
@@ -1172,17 +1178,17 @@ JSObject::nativeGetMethod(const js::Shap
 
     return static_cast<JSFunction *>(&nativeGetSlot(shape->slot()).toObject());
 }
 
 inline void
 JSObject::nativeSetSlot(uintN slot, const js::Value &value)
 {
     JS_ASSERT(isNative());
-    JS_ASSERT(slot < slotSpan());
+    JS_ASSERT(containsSlot(slot));
     return setSlot(slot, value);
 }
 
 inline void
 JSObject::nativeSetSlotWithType(JSContext *cx, const js::Shape *shape, const js::Value &value)
 {
     nativeSetSlot(shape->slot(), value);
     js::types::AddTypePropertyId(cx, this, shape->propid(), value);