Bug 492912 - Clean up the way that TraceRecorder::elem interacts with the rest of the world. r=gal
authorBlake Kaplan <mrbkap@gmail.com>
Fri, 15 May 2009 15:41:41 -0700
changeset 28411 c0cb2d11b999
parent 28410 f9f05f6e7faa
child 28412 7ce0b431da23
push id7050
push userrsayre@mozilla.com
push dateFri, 15 May 2009 23:10:19 +0000
treeherdermozilla-central@a45e505e585b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgal
bugs492912
milestone1.9.2a1pre
Bug 492912 - Clean up the way that TraceRecorder::elem interacts with the rest of the world. r=gal
js/src/jstracer.cpp
js/src/jstracer.h
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -5839,17 +5839,23 @@ TraceRecorder::incProp(jsint incr, bool 
 JS_REQUIRES_STACK JSRecordingStatus
 TraceRecorder::incElem(jsint incr, bool pre)
 {
     jsval& r = stackval(-1);
     jsval& l = stackval(-2);
     jsval* vp;
     LIns* v_ins;
     LIns* addr_ins;
-    CHECK_STATUS(elem(l, r, vp, v_ins, addr_ins));
+
+    if (!JSVAL_IS_OBJECT(l) || !JSVAL_IS_INT(r) ||
+        !guardDenseArray(JSVAL_TO_OBJECT(l), get(&l))) {
+        return JSRS_STOP;
+    }
+
+    CHECK_STATUS(denseArrayElement(l, r, vp, v_ins, addr_ins));
     if (!addr_ins) // if we read a hole, abort
         return JSRS_STOP;
     CHECK_STATUS(inc(*vp, v_ins, incr, pre));
     box_jsval(*vp, v_ins);
     lir->insStorei(v_ins, addr_ins, 0);
     return JSRS_CONTINUE;
 }
 
@@ -8154,27 +8160,26 @@ TraceRecorder::record_JSOP_GETELEM()
 
         // The object is not guaranteed to be a dense array at this point, so it might be the
         // global object, which we have to guard against.
         CHECK_STATUS(guardNotGlobalObject(obj, obj_ins));
 
         return call_imacro(call ? callelem_imacros.callprop : getelem_imacros.getprop);
     }
 
-    // Invalid dense array index or not a dense array.
-    if (JSVAL_TO_INT(idx) < 0 || !OBJ_IS_DENSE_ARRAY(cx, obj)) {
+    if (!guardDenseArray(obj, obj_ins, BRANCH_EXIT)) {
         CHECK_STATUS(guardNotGlobalObject(obj, obj_ins));
 
         return call_imacro(call ? callelem_imacros.callelem : getelem_imacros.getelem);
     }
 
-    // Fast path for dense arrays accessed with a non-negative integer index.
+    // Fast path for dense arrays accessed with a integer index.
     jsval* vp;
     LIns* addr_ins;
-    CHECK_STATUS(elem(lval, idx, vp, v_ins, addr_ins));
+    CHECK_STATUS(denseArrayElement(lval, idx, vp, v_ins, addr_ins));
     set(&lval, v_ins);
     if (call)
         set(&idx, obj_ins);
     return JSRS_CONTINUE;
 }
 
 /* Functions used by JSOP_SETELEM */
 
@@ -8922,31 +8927,26 @@ TraceRecorder::prop(JSObject* obj, LIns*
 
     v_ins = stobj_get_slot(obj_ins, slot, dslots_ins);
     unbox_jsval(STOBJ_GET_SLOT(obj, slot), v_ins, snapshot(BRANCH_EXIT));
 
     return JSRS_CONTINUE;
 }
 
 JS_REQUIRES_STACK JSRecordingStatus
-TraceRecorder::elem(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_ins, LIns*& addr_ins)
-{
-    /* no guards for type checks, trace specialized this already */
-    if (JSVAL_IS_PRIMITIVE(oval) || !JSVAL_IS_INT(ival))
-        return JSRS_STOP;
+TraceRecorder::denseArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_ins,
+                                 LIns*& addr_ins)
+{
+    JS_ASSERT(JSVAL_IS_OBJECT(oval) && JSVAL_IS_INT(ival));
 
     JSObject* obj = JSVAL_TO_OBJECT(oval);
     LIns* obj_ins = get(&oval);
     jsint idx = JSVAL_TO_INT(ival);
     LIns* idx_ins = makeNumberInt32(get(&ival));
 
-    /* make sure the object is actually a dense array */
-    if (!guardDenseArray(obj, obj_ins))
-        return JSRS_STOP;
-
     VMSideExit* exit = snapshot(BRANCH_EXIT);
 
     /* check that the index is within bounds */
     LIns* dslots_ins = lir->insLoad(LIR_ldp, obj_ins, offsetof(JSObject, dslots));
     jsuint capacity = js_DenseArrayCapacity(obj);
     bool within = (jsuint(idx) < jsuint(obj->fslots[JSSLOT_ARRAY_LENGTH]) && jsuint(idx) < capacity);
     if (!within) {
         /* If idx < 0, stay on trace (and read value as undefined, since this is a dense array). */
--- a/js/src/jstracer.h
+++ b/js/src/jstracer.h
@@ -571,18 +571,19 @@ class TraceRecorder : public avmplus::GC
                                  JSScopeProperty* sprop, nanojit::LIns*& dslots_ins,
                                  nanojit::LIns*& v_ins);
 
     nanojit::LIns* getStringLength(nanojit::LIns* str_ins);
 
     JS_REQUIRES_STACK JSRecordingStatus name(jsval*& vp);
     JS_REQUIRES_STACK JSRecordingStatus prop(JSObject* obj, nanojit::LIns* obj_ins, uint32& slot,
                                              nanojit::LIns*& v_ins);
-    JS_REQUIRES_STACK JSRecordingStatus elem(jsval& oval, jsval& idx, jsval*& vp,
-                                             nanojit::LIns*& v_ins, nanojit::LIns*& addr_ins);
+    JS_REQUIRES_STACK JSRecordingStatus denseArrayElement(jsval& oval, jsval& idx, jsval*& vp,
+                                                          nanojit::LIns*& v_ins,
+                                                          nanojit::LIns*& addr_ins);
     JS_REQUIRES_STACK JSRecordingStatus getProp(JSObject* obj, nanojit::LIns* obj_ins);
     JS_REQUIRES_STACK JSRecordingStatus getProp(jsval& v);
     JS_REQUIRES_STACK JSRecordingStatus getThis(nanojit::LIns*& this_ins);
 
     JS_REQUIRES_STACK void box_jsval(jsval v, nanojit::LIns*& v_ins);
     JS_REQUIRES_STACK void unbox_jsval(jsval v, nanojit::LIns*& v_ins, VMSideExit* exit);
     JS_REQUIRES_STACK bool guardClass(JSObject* obj, nanojit::LIns* obj_ins, JSClass* clasp,
                                       VMSideExit* exit);