When re-importing register values after a tree call, make sure to use the inner tree's nativeStackBase, since we also use the inner tree's sp.
authorAndreas Gal <gal@mozilla.com>
Wed, 13 Aug 2008 16:29:59 -0700
changeset 18140 55d6dbfeeab0582e354479ee3b053141484f9f34
parent 18139 b42fa8f98b1a41db47662cef159594dcd4ad270f
child 18141 f603e7555aefded72dbfd1842476e20bcdeec8c7
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.1a2pre
When re-importing register values after a tree call, make sure to use the inner tree's nativeStackBase, since we also use the inner tree's sp.
js/src/jstracer.cpp
js/src/jstracer.h
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -640,17 +640,17 @@ TraceRecorder::TraceRecorder(JSContext* 
     lirbuf->sp = addName(lir->insLoadi(lirbuf->state, offsetof(InterpState, sp)), "sp");
     lirbuf->rp = addName(lir->insLoadi(lirbuf->state, offsetof(InterpState, rp)), "rp");
     cx_ins = addName(lir->insLoadi(lirbuf->state, offsetof(InterpState, cx)), "cx");
     gp_ins = addName(lir->insLoadi(lirbuf->state, offsetof(InterpState, gp)), "gp");
     eos_ins = addName(lir->insLoadi(lirbuf->state, offsetof(InterpState, eos)), "eos");
     eor_ins = addName(lir->insLoadi(lirbuf->state, offsetof(InterpState, eor)), "eor");
 
     /* read into registers all values on the stack and all globals we know so far */
-    import(lirbuf->sp, ngslots, callDepth, globalTypeMap, stackTypeMap); 
+    import(treeInfo, lirbuf->sp, ngslots, callDepth, globalTypeMap, stackTypeMap); 
 }
 
 TraceRecorder::~TraceRecorder()
 {
 #ifdef DEBUG
     delete verbose_filter;
 #endif
     delete cse_filter;
@@ -1023,17 +1023,17 @@ TraceRecorder::import(LIns* base, ptrdif
     static const char* typestr[] = {
         "object", "int", "double", "3", "string", "5", "boolean", "any"
     };
     printf("import vp=%p name=%s type=%s flags=%d\n", p, name, typestr[t & 7], t >> 3);
 #endif
 }
 
 void
-TraceRecorder::import(LIns* sp, unsigned ngslots, unsigned callDepth, 
+TraceRecorder::import(TreeInfo* treeInfo, LIns* sp, unsigned ngslots, unsigned callDepth, 
                       uint8* globalTypeMap, uint8* stackTypeMap)
 {
     /* the first time we compile a tree this will be empty as we add entries lazily */
     uint16* gslots = treeInfo->globalSlots.data();
     uint8* m = globalTypeMap;
     FORALL_GLOBAL_SLOTS(cx, ngslots, gslots,
         import(gp_ins, nativeGlobalOffset(vp), vp, *m, vpname, vpnum, NULL);
         m++;
@@ -1357,17 +1357,17 @@ TraceRecorder::emitTreeCall(Fragment* in
     }
     /* Invoke the inner tree. */
     LIns* args[] = { lir->insImmPtr(inner), lirbuf->state }; /* reverse order */
     LIns* ret = lir->insCall(F_CallTree, args);
     /* Make a note that we now depend on that tree. */
     ti->dependentTrees.addUnique(fragment);
     /* Read back all registers, in case the called tree changed any of them. */
     SideExit* exit = lr->exit;
-    import(inner_sp, exit->numGlobalSlots, exit->calldepth, 
+    import(ti, inner_sp, exit->numGlobalSlots, exit->calldepth, 
            exit->typeMap, exit->typeMap + exit->numGlobalSlots);
     /* Restore sp and rp to their original values (we still have them in a register). */
     if (callDepth > 0) {
         lir->insStorei(lirbuf->sp, lirbuf->state, offsetof(InterpState, sp));
         lir->insStorei(lirbuf->rp, lirbuf->state, offsetof(InterpState, rp));
     }
     /* Guard that we come out of the inner tree along the same side exit we came out when
        we called the inner tree at recording time. */
@@ -2644,21 +2644,23 @@ TraceRecorder::clearFrameSlotsFromCache(
     vpstop = &fp->slots[fp->script->nslots];
     while (vp < vpstop)
         nativeFrameTracker.set(vp++, (LIns*)0);
 }
 
 bool
 TraceRecorder::record_EnterFrame()
 {
-#ifdef DEBUG
-    printf("EnterFrame %s\n", js_AtomToPrintableString(cx, cx->fp->fun->atom));
-#endif    
     if (++callDepth >= MAX_CALLDEPTH)
         ABORT_TRACE("exceeded maximum call depth");
+#ifdef DEBUG
+    printf("EnterFrame %s, callDepth=%d\n", 
+           js_AtomToPrintableString(cx, cx->fp->fun->atom),
+           callDepth);
+#endif    
     JSStackFrame* fp = cx->fp;
     LIns* void_ins = lir->insImm(JSVAL_TO_BOOLEAN(JSVAL_VOID));
 
     jsval* vp = &fp->argv[fp->argc];
     jsval* vpstop = vp + (fp->fun->nargs - fp->argc);
     while (vp < vpstop) {
         if (vp >= fp->down->regs->sp)
             nativeFrameTracker.set(vp, (LIns*)0);
@@ -2671,17 +2673,19 @@ TraceRecorder::record_EnterFrame()
         set(vp++, void_ins, true);
     return true;
 }
 
 bool
 TraceRecorder::record_LeaveFrame()
 {
 #ifdef DEBUG
-    printf("LeaveFrame (back to %s)\n", js_AtomToPrintableString(cx, cx->fp->fun->atom));
+    printf("LeaveFrame (back to %s), callDept=%d\n", 
+           js_AtomToPrintableString(cx, cx->fp->fun->atom),
+           callDepth);
 #endif    
     if (callDepth-- <= 0)
         return false;
 
     // LeaveFrame gets called after the interpreter popped the frame and
     // stored rval, so cx->fp not cx->fp->down, and -1 not 0.
     atoms = cx->fp->script->atomMap.vector;
     stack(-1, rval_ins);
--- a/js/src/jstracer.h
+++ b/js/src/jstracer.h
@@ -220,17 +220,17 @@ class TraceRecorder {
     nanojit::LIns*          rval_ins;
     nanojit::SideExit       exit;
 
     bool isGlobal(jsval* p) const;
     ptrdiff_t nativeStackOffset(jsval* p) const;
     ptrdiff_t nativeGlobalOffset(jsval* p) const;
     void import(nanojit::LIns* base, ptrdiff_t offset, jsval* p, uint8& t, 
                 const char *prefix, uintN index, JSStackFrame *fp);
-    void import(nanojit::LIns* sp, unsigned ngslots, unsigned callDepth, 
+    void import(TreeInfo* treeInfo, nanojit::LIns* sp, unsigned ngslots, unsigned callDepth, 
                 uint8* globalTypeMap, uint8* stackTypeMap);
     void trackNativeStackUse(unsigned slots);
 
     bool lazilyImportGlobalSlot(unsigned slot);
     
     nanojit::LIns* guard(bool expected, nanojit::LIns* cond, nanojit::ExitType exitType);
     nanojit::LIns* addName(nanojit::LIns* ins, const char* name);