Bug 775166 - Remove some ugly optimization in jsarray. r=bhackett
authorTom Schuster <evilpies@gmail.com>
Sat, 21 Jul 2012 13:06:37 +0200
changeset 100027 60b949c0eaefd84a770db89459d2825494ada42f
parent 100026 28711b9f49cdd827451380906d9a0226a4436c47
child 100028 c6e2e6537d701f4ffe6b1d56099c89160ed016f3
push id12303
push userevilpies@gmail.com
push dateSat, 21 Jul 2012 11:08:04 +0000
treeherdermozilla-inbound@60b949c0eaef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs775166
milestone17.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 775166 - Remove some ugly optimization in jsarray. r=bhackett
js/src/jsarray.cpp
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -200,55 +200,16 @@ StringIsArrayIndex(JSLinearString *str, 
         return true;
     }
 
     return false;
 }
 
 }
 
-static JSBool
-BigIndexToId(JSContext *cx, JSObject *obj, uint32_t index, JSBool createAtom,
-             jsid *idp)
-{
-
-    JS_ASSERT(index > JSID_INT_MAX);
-
-    jschar buf[10];
-    jschar *start = ArrayEnd(buf);
-    do {
-        --start;
-        *start = (jschar)('0' + index % 10);
-        index /= 10;
-    } while (index != 0);
-
-    /*
-     * Skip the atomization if the class is known to store atoms corresponding
-     * to big indexes together with elements. In such case we know that the
-     * array does not have an element at the given index if its atom does not
-     * exist.  Dense arrays don't use atoms for any indexes, though it would be
-     * rare to see them have a big index in any case.
-     */
-    JSAtom *atom;
-    if (!createAtom && (obj->isSlowArray() || obj->isArguments() || obj->isObject())) {
-        atom = js_GetExistingStringAtom(cx, start, ArrayEnd(buf) - start);
-        if (!atom) {
-            *idp = JSID_VOID;
-            return JS_TRUE;
-        }
-    } else {
-        atom = js_AtomizeChars(cx, start, ArrayEnd(buf) - start);
-        if (!atom)
-            return JS_FALSE;
-    }
-
-    *idp = NON_INTEGER_ATOM_TO_JSID(atom);
-    return JS_TRUE;
-}
-
 bool
 JSObject::willBeSparseDenseArray(unsigned requiredCapacity, unsigned newElementsHint)
 {
     JS_ASSERT(isDenseArray());
     JS_ASSERT(requiredCapacity > MIN_SPARSE_INDEX);
 
     unsigned cap = getDenseArrayCapacity();
     JS_ASSERT(requiredCapacity >= cap);
@@ -268,104 +229,82 @@ JSObject::willBeSparseDenseArray(unsigne
     const Value *elems = getDenseArrayElements();
     for (unsigned i = 0; i < len; i++) {
         if (!elems[i].isMagic(JS_ARRAY_HOLE) && !--minimalDenseCount)
             return false;
     }
     return true;
 }
 
-static bool
-ReallyBigIndexToId(JSContext* cx, double index, jsid* idp)
-{
-    return ValueToId(cx, DoubleValue(index), idp);
-}
-
-static bool
-IndexToId(JSContext* cx, JSObject* obj, double index, JSBool* hole, jsid* idp,
-          JSBool createAtom = JS_FALSE)
-{
-    if (index <= JSID_INT_MAX) {
-        *idp = INT_TO_JSID(int(index));
-        return JS_TRUE;
-    }
-
-    if (index <= uint32_t(-1)) {
-        if (!BigIndexToId(cx, obj, uint32_t(index), createAtom, idp))
-            return JS_FALSE;
-        if (hole && JSID_IS_VOID(*idp))
-            *hole = JS_TRUE;
-        return JS_TRUE;
-    }
-
-    return ReallyBigIndexToId(cx, index, idp);
-}
-
 bool
 JSObject::arrayGetOwnDataElement(JSContext *cx, size_t i, Value *vp)
 {
     JS_ASSERT(isArray());
 
     if (isDenseArray()) {
         if (i >= getArrayLength())
             vp->setMagic(JS_ARRAY_HOLE);
         else
             *vp = getDenseArrayElement(uint32_t(i));
         return true;
     }
 
-    JSBool hole;
     jsid id;
-    if (!IndexToId(cx, this, i, &hole, &id))
+    if (!IndexToId(cx, i, &id))
         return false;
 
     Shape *shape = nativeLookup(cx, id);
     if (!shape || !shape->isDataDescriptor())
         vp->setMagic(JS_ARRAY_HOLE);
     else
         *vp = getSlot(shape->slot());
     return true;
 }
 
+bool
+DoubleIndexToId(JSContext *cx, double index, jsid *id)
+{
+    if (index == uint32_t(index))
+        return IndexToId(cx, uint32_t(index), id);
+
+    return ValueToId(cx, DoubleValue(index), id);
+}
+
 /*
  * If the property at the given index exists, get its value into location
  * pointed by vp and set *hole to false. Otherwise set *hole to true and *vp
  * to JSVAL_VOID. This function assumes that the location pointed by vp is
  * properly rooted and can be used as GC-protected storage for temporaries.
  */
-static inline JSBool
+static inline bool
 DoGetElement(JSContext *cx, JSObject *obj_, double index, JSBool *hole, Value *vp)
 {
     RootedObject obj(cx, obj_);
     RootedId id(cx);
 
-    *hole = JS_FALSE;
-    if (!IndexToId(cx, obj, index, hole, id.address()))
-        return JS_FALSE;
-    if (*hole) {
-        vp->setUndefined();
-        return JS_TRUE;
-    }
+    if (!DoubleIndexToId(cx, index, id.address()))
+        return false;
 
     RootedObject obj2(cx);
     RootedShape prop(cx);
     if (!obj->lookupGeneric(cx, id, &obj2, &prop))
-        return JS_FALSE;
+        return false;
+
     if (!prop) {
         vp->setUndefined();
-        *hole = JS_TRUE;
+        *hole = true;
     } else {
         if (!obj->getGeneric(cx, id, vp))
-            return JS_FALSE;
-        *hole = JS_FALSE;
+            return false;
+        *hole = false;
     }
-    return JS_TRUE;
+    return true;
 }
 
-static inline JSBool
+static inline bool
 DoGetElement(JSContext *cx, HandleObject obj, uint32_t index, JSBool *hole, Value *vp)
 {
     bool present;
     if (!obj->getElementIfPresent(cx, obj, index, vp, &present))
         return false;
 
     *hole = !present;
     if (*hole)
@@ -374,16 +313,17 @@ DoGetElement(JSContext *cx, HandleObject
     return true;
 }
 
 template<typename IndexType>
 static void
 AssertGreaterThanZero(IndexType index)
 {
     JS_ASSERT(index >= 0);
+    JS_ASSERT(index == floor(index));
 }
 
 template<>
 void
 AssertGreaterThanZero(uint32_t index)
 {
 }
 
@@ -474,19 +414,18 @@ SetArrayElement(JSContext *cx, HandleObj
         if (result == JSObject::ED_FAILED)
             return false;
         JS_ASSERT(result == JSObject::ED_SPARSE);
         if (!JSObject::makeDenseArraySlow(cx, obj))
             return JS_FALSE;
     }
 
     RootedId id(cx);
-    if (!IndexToId(cx, obj, index, NULL, id.address(), JS_TRUE))
-        return JS_FALSE;
-    JS_ASSERT(!JSID_IS_VOID(id));
+    if (!DoubleIndexToId(cx, index, id.address()))
+        return false;
 
     RootedValue tmp(cx, v);
     return obj->setGeneric(cx, obj, id, tmp.address(), true);
 }
 
 /*
  * Delete the element |index| from |obj|. If |strict|, do a strict
  * deletion: throw if the property is not configurable.