Remove JSObject::containsSlot, bug 710516. r=luke
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 21 Dec 2011 06:31:11 -0800
changeset 83185 2c7cd0b499ba2237825c205ca7e1ad26ded6ff4d
parent 83184 2c536eeba1109a0f8f444828d5b0024ef7c615a5
child 83186 c33646a41d9456969908ef5fa6607f72d3cbe4cd
push id4290
push userbhackett@mozilla.com
push dateWed, 21 Dec 2011 14:31:48 +0000
treeherdermozilla-inbound@2c7cd0b499ba [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs710516
milestone12.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
Remove JSObject::containsSlot, bug 710516. r=luke
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() && obj->containsSlot(shape->slot())) {
-                        *constp = obj->getSlot(shape->slot());
+                        shape->hasDefaultGetter() && shape->hasSlot()) {
+                        *constp = obj->nativeGetSlot(shape->slot());
                     }
                 }
 
                 if (shape)
                     break;
             }
         }
     } while (bce->parent && (bce = bce->parent->asBytecodeEmitter()));
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -861,25 +861,16 @@ 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
@@ -5029,17 +5029,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 (pobj->containsSlot(shape->slot())) {
+        if (shape->hasSlot()) {
             v = pobj->nativeGetSlot(shape->slot());
             if (v.isPrimitive())
                 v.setUndefined();
         }
     }
     *vp = v;
     return true;
 }
@@ -5286,17 +5286,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 (obj->containsSlot(shape->slot()))
+            if (shape->hasSlot())
                 obj->nativeSetSlotWithType(cx, shape, *vp);
         }
     }
     return true;
 }
 
 namespace js {
 
@@ -5416,17 +5416,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() && obj->containsSlot(shape->slot()))
+    if (shape->hasSlot())
         obj->nativeSetSlot(shape->slot(), valueCopy);
 
     /* XXXbe called with lock held */
     if (!CallAddPropertyHook(cx, clasp, obj, shape, &valueCopy)) {
         obj->removeProperty(cx, id);
         return NULL;
     }
 
@@ -5851,17 +5851,16 @@ 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_t 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);
@@ -6333,17 +6332,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 (obj->containsSlot(shape->slot()))
+        if (shape->hasSlot())
             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;
@@ -6460,22 +6459,17 @@ js_DeleteProperty(JSContext *cx, JSObjec
     shape = (Shape *)prop;
     if (!shape->configurable()) {
         if (strict)
             return obj->reportNotConfigurable(cx, id);
         rval->setBoolean(false);
         return true;
     }
 
-    if (!CallJSPropertyOp(cx, obj->getClass()->delProperty, obj, shape->getUserId(), rval))
-        return false;
-    if (rval->isFalse())
-        return true;
-
-    if (shape->hasSlot() && obj->containsSlot(shape->slot())) {
+    if (shape->hasSlot()) {
         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
@@ -6499,16 +6493,21 @@ js_DeleteProperty(JSContext *cx, JSObjec
                             break;
                         }
                     } while ((tmp = tmp->getProto()) != NULL);
                 }
             }
         }
     }
 
+    if (!CallJSPropertyOp(cx, obj->getClass()->delProperty, obj, shape->getUserId(), rval))
+        return false;
+    if (rval->isFalse())
+        return true;
+
     return obj->removeProperty(cx, id) && js_SuppressDeletedProperty(cx, obj, id);
 }
 
 JSBool
 js_DeleteElement(JSContext *cx, JSObject *obj, uint32_t index, Value *rval, JSBool strict)
 {
     jsid id;
     if (!IndexToId(cx, index, &id))
@@ -6518,17 +6517,16 @@ 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;
 }
 
@@ -6962,20 +6960,18 @@ js_PrintObjectSlotName(JSTracer *trc, ch
     JS_ASSERT(trc->debugPrinter == js_PrintObjectSlotName);
 
     JSObject *obj = (JSObject *)trc->debugPrintArg;
     uint32_t slot = uint32_t(trc->debugPrintIndex);
 
     const Shape *shape;
     if (obj->isNative()) {
         shape = obj->lastProperty();
-        while (shape->previous() && shape->maybeSlot() != slot)
+        while (shape && (!shape->hasSlot() || shape->slot() != 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)                                              \
@@ -7022,18 +7018,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() &&
-            obj->containsSlot(shape->maybeSlot())) {
-            obj->setSlot(shape->slot(), UndefinedValue());
+            shape->hasSlot()) {
+            obj->nativeSetSlot(shape->slot(), UndefinedValue());
         }
     }
     return true;
 }
 
 bool
 js_GetReservedSlot(JSContext *cx, JSObject *obj, uint32_t slot, Value *vp)
 {
@@ -7290,17 +7286,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_t slot = shape.hasSlot() ? shape.maybeSlot() : SHAPE_INVALID_SLOT;
     fprintf(stderr, ": slot %d", slot);
-    if (obj->containsSlot(slot)) {
+    if (shape.hasSlot()) {
         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
@@ -706,18 +706,16 @@ 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_t slotSpan() const;
 
-    inline bool containsSlot(uint32_t slot) const;
-
     void rollbackProperties(JSContext *cx, uint32_t slotSpan);
 
 #ifdef DEBUG
     enum SentinelAllowed {
         SENTINEL_NOT_ALLOWED,
         SENTINEL_ALLOWED
     };
 
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -1137,35 +1137,29 @@ JSObject::principals(JSContext *cx)
 inline uint32_t
 JSObject::slotSpan() const
 {
     if (inDictionaryMode())
         return lastProperty()->base()->slotSpan();
     return lastProperty()->slotSpan();
 }
 
-inline bool
-JSObject::containsSlot(uint32_t slot) const
-{
-    return slot < slotSpan();
-}
-
 inline js::HeapValue &
 JSObject::nativeGetSlotRef(uintN slot)
 {
     JS_ASSERT(isNative());
-    JS_ASSERT(containsSlot(slot));
+    JS_ASSERT(slot < slotSpan());
     return getSlotRef(slot);
 }
 
 inline const js::Value &
 JSObject::nativeGetSlot(uintN slot) const
 {
     JS_ASSERT(isNative());
-    JS_ASSERT(containsSlot(slot));
+    JS_ASSERT(slot < slotSpan());
     return getSlot(slot);
 }
 
 inline JSFunction *
 JSObject::nativeGetMethod(const js::Shape *shape) const
 {
     /*
      * For method shapes, this object must have an uncloned function object in
@@ -1179,17 +1173,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(containsSlot(slot));
+    JS_ASSERT(slot < slotSpan());
     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);