Fixed cases where argc varied between recording time and execution time (bug 451727; also warning fix fe54f7fb89d1 from tracemonkey).
authorBrendan Eich <brendan@mozilla.org>
Tue, 26 Aug 2008 12:28:26 -0700
changeset 18425 074d733dbdb8156416a8765c445417c0b67219b0
parent 18424 5f139476ea3ec7158c8ed3712946c6958613d8f1
child 18426 e49ce187bae5c8eeda2e89c2c661d61f91e1c8c0
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)
bugs451727
milestone1.9.1a2pre
Fixed cases where argc varied between recording time and execution time (bug 451727; also warning fix fe54f7fb89d1 from tracemonkey).
js/src/jstracer.cpp
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -509,18 +509,17 @@ public:
             if (depth == 0) {                                                 \
                 SET_VPNAME("callee");                                         \
                 vp = &fp->argv[-2];                                           \
                 { code; }                                                     \
                 SET_VPNAME("this");                                           \
                 vp = &fp->argv[-1];                                           \
                 { code; }                                                     \
                 SET_VPNAME("argv");                                           \
-                unsigned nargs = JS_MAX(fp->fun->nargs, fp->argc);            \
-                vp = &fp->argv[0]; vpstop = &fp->argv[nargs];                 \
+                vp = &fp->argv[0]; vpstop = &fp->argv[fp->fun->nargs];        \
                 while (vp < vpstop) { code; ++vp; INC_VPNUM(); }              \
             }                                                                 \
             SET_VPNAME("vars");                                               \
             vp = fp->slots; vpstop = &fp->slots[fp->script->nfixed];          \
             while (vp < vpstop) { code; ++vp; INC_VPNUM(); }                  \
         }                                                                     \
         SET_VPNAME("stack");                                                  \
         vp = StackBase(fp); vpstop = fp->regs->sp;                            \
@@ -564,49 +563,48 @@ public:
 #define FORALL_SLOTS(cx, ngslots, gslots, callDepth, code)                    \
     JS_BEGIN_MACRO                                                            \
         FORALL_GLOBAL_SLOTS(cx, ngslots, gslots, code);                       \
         FORALL_SLOTS_IN_PENDING_FRAMES(cx, callDepth, code);                  \
     JS_END_MACRO
 
 /* Calculate the total number of native frame slots we need from this frame
    all the way back to the entry frame, including the current stack usage. */
-static unsigned
-nativeStackSlots(JSContext *cx, unsigned callDepth)
+unsigned
+js_NativeStackSlots(JSContext *cx, unsigned callDepth)
 {
     JSStackFrame* fp = cx->fp;
     unsigned slots = 0;
 #if defined _DEBUG
     unsigned int origCallDepth = callDepth;
 #endif
     for (;;) {
         unsigned operands = fp->regs->sp - StackBase(fp);
         JS_ASSERT(operands <= unsigned(fp->script->nslots - fp->script->nfixed));
         slots += operands;
         if (fp->callee)
             slots += fp->script->nfixed;
         if (callDepth-- == 0) {
             if (fp->callee) {
-                unsigned nargs = JS_MAX(fp->fun->nargs, fp->argc);
-                slots += 2/*callee,this*/ + nargs;
+                slots += 2/*callee,this*/ + fp->fun->nargs;
             }
 #if defined _DEBUG
             unsigned int m = 0;
             FORALL_SLOTS_IN_PENDING_FRAMES(cx, origCallDepth, m++);
             JS_ASSERT(m == slots);
 #endif
             return slots;
         }
         JSStackFrame* fp2 = fp;
         fp = fp->down;
         int missing = fp2->fun->nargs - fp2->argc;
         if (missing > 0)
             slots += missing;
     }
-    JS_NOT_REACHED("nativeStackSlots");
+    JS_NOT_REACHED("js_NativeStackSlots");
 }
 
 /* Capture the type map for the selected slots of the global object. */
 void
 TypeMap::captureGlobalTypes(JSContext* cx, SlotList& slots)
 {
     unsigned ngslots = slots.length();
     uint16* gslots = slots.data();
@@ -620,17 +618,17 @@ TypeMap::captureGlobalTypes(JSContext* c
         *m++ = type;
     );
 }
 
 /* Capture the type map for the currently pending stack frames. */
 void
 TypeMap::captureStackTypes(JSContext* cx, unsigned callDepth)
 {
-    setLength(nativeStackSlots(cx, callDepth));
+    setLength(js_NativeStackSlots(cx, callDepth));
     uint8* map = data();
     uint8* m = map;
     FORALL_SLOTS_IN_PENDING_FRAMES(cx, callDepth,
         uint8 type = getCoercedType(*vp);
         if ((type == JSVAL_INT) &&
             oracle.isStackSlotUndemotable(cx->fp->script, cx->fp->regs->pc, unsigned(m - map))) {
             type = JSVAL_DOUBLE;
         }
@@ -800,20 +798,19 @@ done:
     JSStackFrame** fspstop = &fstack[frames];
     JSStackFrame** fsp = fspstop-1;
     fp = currentFrame;
     for (;; fp = fp->down) { *fsp-- = fp; if (fp == entryFrame) break; }
     for (fsp = fstack; fsp < fspstop; ++fsp) {
         fp = *fsp;
         if (fp->callee) {
             if (fsp == fstack) {
-                unsigned nargs = JS_MAX(fp->fun->nargs, fp->argc);
-                if (size_t(p - &fp->argv[-2]) < 2/*callee,this*/ + nargs)
+                if (size_t(p - &fp->argv[-2]) < size_t(2/*callee,this*/ + fp->fun->nargs))
                     RETURN(offset + size_t(p - &fp->argv[-2]) * sizeof(double));
-                offset += (2/*callee,this*/ + nargs) * sizeof(double);
+                offset += (2/*callee,this*/ + fp->fun->nargs) * sizeof(double);
             }
             if (size_t(p - &fp->slots[0]) < fp->script->nfixed)
                 RETURN(offset + size_t(p - &fp->slots[0]) * sizeof(double));
             offset += fp->script->nfixed * sizeof(double);
         }
         jsval* spbase = StackBase(fp);
         if (size_t(p - spbase) < size_t(fp->regs->sp - spbase))
             RETURN(offset + size_t(p - spbase) * sizeof(double));
@@ -1318,17 +1315,17 @@ bool TraceRecorder::selectCallablePeerFr
 
 SideExit*
 TraceRecorder::snapshot(ExitType exitType)
 {
     JSStackFrame* fp = cx->fp;
     if (exitType == BRANCH_EXIT && js_IsLoopExit(cx, fp->script, fp->regs->pc))
         exitType = LOOP_EXIT;
     /* Generate the entry map and stash it in the trace. */
-    unsigned stackSlots = nativeStackSlots(cx, callDepth);
+    unsigned stackSlots = js_NativeStackSlots(cx, callDepth);
     /* It's sufficient to track the native stack use here since all stores above the
        stack watermark defined by guards are killed. */
     trackNativeStackUse(stackSlots + 1);
     /* reserve space for the type map */
     unsigned ngslots = traceMonitor->globalSlots->length();
     LIns* data = lir_buf_writer->skip((stackSlots + ngslots) * sizeof(uint8));
     /* setup side exit structure */
     memset(&exit, 0, sizeof(exit));
@@ -1789,17 +1786,17 @@ js_RecordTree(JSContext* cx, JSTraceMoni
     /* setup the VM-private treeInfo structure for this fragment */
     TreeInfo* ti = new (&gc) TreeInfo(f);
 
     /* capture the coerced type of each active slot in the stack type map */
     ti->stackTypeMap.captureStackTypes(cx, 0/*callDepth*/);
 
     /* determine the native frame layout at the entry point */
     unsigned entryNativeStackSlots = ti->stackTypeMap.length();
-    JS_ASSERT(entryNativeStackSlots == nativeStackSlots(cx, 0/*callDepth*/));
+    JS_ASSERT(entryNativeStackSlots == js_NativeStackSlots(cx, 0/*callDepth*/));
     ti->nativeStackBase = (entryNativeStackSlots -
             (cx->fp->regs->sp - StackBase(cx->fp))) * sizeof(double);
     ti->maxNativeStackSlots = entryNativeStackSlots;
     ti->maxCallDepth = 0;
 
     /* recording primary trace */
     return js_StartRecorder(cx, NULL, f, ti,
                             tm->globalSlots->length(), tm->globalTypeMap->data(), 
@@ -3072,17 +3069,17 @@ TraceRecorder::clearFrameSlotsFromCache(
        VM stack might map to different locations on the native stack depending on the
        number of arguments (i.e.) of the next call, so we have to make sure we map
        those in to the cache with the right offsets. */
     JSStackFrame* fp = cx->fp;
     jsval* vp;
     jsval* vpstop;
     if (fp->callee) {
         vp = &fp->argv[-2];
-        vpstop = &fp->argv[JS_MAX(fp->fun->nargs,fp->argc)];
+        vpstop = &fp->argv[fp->fun->nargs];
         while (vp < vpstop)
             nativeFrameTracker.set(vp++, (LIns*)0);
     }
     vp = &fp->slots[0];
     vpstop = &fp->slots[fp->script->nslots];
     while (vp < vpstop)
         nativeFrameTracker.set(vp++, (LIns*)0);
 }