Trace GETGVAR and INCGVAR, though not yet correctly.
authorshaver@mozilla.org
Sun, 06 Jul 2008 16:59:59 -0400
changeset 17468 360a6ce57d28f76b5f739770c81c1d0ff57926ce
parent 17467 d84c7e0344ed2c6bd7c28ba6a3eb286558c490e4
child 17469 8374e34d597e56684f05628edb4f5c0bf8752e44
push id1452
push usershaver@mozilla.com
push dateFri, 22 Aug 2008 00:08:22 +0000
treeherderautoland@d13bb0868596 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.1a1pre
Trace GETGVAR and INCGVAR, though not yet correctly.
js/src/jstracer.cpp
js/src/jstracer.h
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -1195,16 +1195,30 @@ TraceRecorder::jsval_to_boolean(LIns* v_
 LIns*
 TraceRecorder::jsval_to_object(LIns* v_ins)
 {
     guard_jsval_tag(v_ins, JSVAL_OBJECT);
     return lir->ins2(LIR_and, v_ins, lir->insImmPtr((void*)~JSVAL_TAGMASK));
 }
 
 bool
+TraceRecorder::box_jsval(jsval v, LIns*& v_ins)
+{
+    if (isInt(v))
+        v_ins = int32_to_jsval(v_ins);
+    else if (isDouble(v))
+        v_ins = double_to_jsval(v_ins);
+    else if (JSVAL_IS_BOOLEAN(v))
+        v_ins = boolean_to_jsval(v_ins);
+    else
+        return false; /* don't know how to box this type */
+    return true;
+}
+
+bool
 TraceRecorder::unbox_jsval(jsval v, LIns*& v_ins)
 {
     if (isInt(v))
         v_ins = jsval_to_int32(v_ins);
     else if (isDouble(v))
         v_ins = jsval_to_double(v_ins);
     else if (JSVAL_IS_BOOLEAN(v))
         v_ins = jsval_to_boolean(v_ins);
@@ -1526,24 +1540,18 @@ bool TraceRecorder::JSOP_SETELEM()
     LIns* isHole = lir->ins2(LIR_eq, oldval, lir->insImmPtr((void*)JSVAL_HOLE));
     LIns* count = lir->insLoadi(obj_ins,
                                 offsetof(JSObject, fslots[JSSLOT_ARRAY_COUNT]));
     lir->insStorei(lir->ins2(LIR_add, count, isHole), obj_ins,
                    offsetof(JSObject, fslots[JSSLOT_ARRAY_COUNT]));
     /* ok, box the value we are storing, store it and we are done */
     LIns* v_ins = get(&v);
     LIns* boxed_ins;
-    if (isInt(v))
-        boxed_ins = int32_to_jsval(v_ins);
-    else if (isDouble(v))
-        boxed_ins = double_to_jsval(v_ins);
-    else if (JSVAL_IS_BOOLEAN(v))
-        boxed_ins = boolean_to_jsval(v_ins);
-    else
-        return false; /* don't know how to box this type */
+    if (!box_jsval(v, boxed_ins))
+        return false;
     lir->insStorei(boxed_ins, addr, 0);
     set(&l, v_ins);
     return true;
 }
 bool TraceRecorder::JSOP_CALLNAME()
 {
     return false;
 }
@@ -1979,27 +1987,59 @@ bool TraceRecorder::JSOP_THROWING()
 bool TraceRecorder::JSOP_SETRVAL()
 {
     return false;
 }
 bool TraceRecorder::JSOP_RETRVAL()
 {
     return false;
 }
+
 bool TraceRecorder::JSOP_GETGVAR()
 {
-    return false;
+    jsval slotval = cx->fp->vars[GET_VARNO(cx->fp->regs->pc)];
+    if (JSVAL_IS_NULL(slotval))
+        return true; // We will see JSOP_NAME from the interpreter's jump, so no-op here.
+
+    uint32 slot = JSVAL_TO_INT(slotval);
+    LIns* varobj_ins = lir->insLoadi(lir->insLoadi(cx_ins, offsetof(JSContext, fp)),
+                                     offsetof(JSStackFrame, varobj));
+    LIns* dslots_ins = NULL;
+    LIns* v_ins = stobj_get_slot(varobj_ins, slot, dslots_ins);
+    if (!unbox_jsval(STOBJ_GET_SLOT(cx->fp->varobj, slot), v_ins))
+        return false;
+
+    stack(0, v_ins);
+    return true;
 }
 bool TraceRecorder::JSOP_SETGVAR()
 {
     return false;
 }
 bool TraceRecorder::JSOP_INCGVAR()
 {
-    return false;
+    jsval slotval = cx->fp->vars[GET_VARNO(cx->fp->regs->pc)];
+    if (JSVAL_IS_NULL(slotval))
+        return true; // We will see JSOP_INCNAME from the interpreter's jump, so no-op here.
+
+    uint32 slot = JSVAL_TO_INT(slotval);
+    LIns* varobj_ins = lir->insLoadi(lir->insLoadi(cx_ins, offsetof(JSContext, fp)),
+                                     offsetof(JSStackFrame, varobj));
+    LIns* dslots_ins = NULL;
+    LIns* v_ins = stobj_get_slot(varobj_ins, slot, dslots_ins);
+    jsval v = STOBJ_GET_SLOT(cx->fp->varobj, slot);
+    if (!unbox_jsval(v, v_ins))
+        return false;
+    LIns* incr = lir->ins2i(LIR_add, v_ins, 1);
+    guard(false, lir->ins1(LIR_ov, incr));
+    if (!box_jsval(v, incr))
+        return false;
+    stobj_set_slot(varobj_ins, slot, dslots_ins, incr);
+    stack(0, incr);
+    return true;
 }
 bool TraceRecorder::JSOP_DECGVAR()
 {
     return false;
 }
 bool TraceRecorder::JSOP_GVARINC()
 {
     return false;
--- a/js/src/jstracer.h
+++ b/js/src/jstracer.h
@@ -179,16 +179,17 @@ class TraceRecorder {
     nanojit::LIns* double_to_jsval(nanojit::LIns* d_ins);
     nanojit::LIns* boolean_to_jsval(nanojit::LIns* b_ins);
     nanojit::LIns* object_to_jsval(nanojit::LIns* b_ins);
     nanojit::LIns* jsval_to_int32(nanojit::LIns* v_ins);
     nanojit::LIns* jsval_to_double(nanojit::LIns* v_ins);
     nanojit::LIns* jsval_to_boolean(nanojit::LIns* v_ins);
     nanojit::LIns* jsval_to_object(nanojit::LIns* v_ins);
 
+    bool box_jsval(jsval v, nanojit::LIns*& v_ins);
     bool unbox_jsval(jsval v, nanojit::LIns*& v_ins);
     bool guardThatObjectIsDenseArray(JSObject* obj, 
             nanojit::LIns* obj_ins, nanojit::LIns*& dslots_ins);
     bool guardDenseArrayIndexWithinBounds(JSObject* obj, jsint idx, 
             nanojit::LIns* obj_ins, nanojit::LIns*& dslots_ins, nanojit::LIns* idx_ins);
 public:
     TraceRecorder(JSContext* cx, nanojit::Fragmento*, nanojit::Fragment*);
     ~TraceRecorder();