Avoid JSOP_POPV in global scripts from load(), etc.
authorBrendan Eich <brendan@mozilla.org>
Sat, 26 Jul 2008 01:23:12 +0200
changeset 17828 c2f49e1a25942d9b9ae9fe54f7a344c5da466d8b
parent 17827 fd9cf3c556ee0d410dc934be71956a0d33271d2c
child 17830 72893c1ee4a4714172689fe781860d7b4f9ccc8c
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
Avoid JSOP_POPV in global scripts from load(), etc.
js/src/js.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsemit.cpp
js/src/jsemit.h
js/src/jsinterp.cpp
js/src/jsparse.cpp
js/src/jstracer.cpp
--- a/js/src/js.cpp
+++ b/js/src/js.cpp
@@ -1,10 +1,10 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sw=4 et tw=78:
+ * vim: set ts=8 sw=4 et tw=99:
  *
  * ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
@@ -264,22 +264,22 @@ Process(JSContext *cx, JSObject *obj, ch
             while((ch = fgetc(file)) != EOF) {
                 if (ch == '\n' || ch == '\r')
                     break;
             }
         }
         ungetc(ch, file);
 
         oldopts = JS_GetOptions(cx);
-        JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO);
+        JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
         script = JS_CompileFileHandle(cx, obj, filename, file);
         JS_SetOptions(cx, oldopts);
         if (script) {
             if (!compileOnly)
-                (void)JS_ExecuteScript(cx, obj, script, &result);
+                (void)JS_ExecuteScript(cx, obj, script, NULL);
             JS_DestroyScript(cx, script);
         }
 
         if (file != stdin)
             fclose(file);
         return;
     }
 
@@ -648,24 +648,24 @@ Load(JSContext *cx, JSObject *obj, uintN
     for (i = 0; i < argc; i++) {
         str = JS_ValueToString(cx, argv[i]);
         if (!str)
             return JS_FALSE;
         argv[i] = STRING_TO_JSVAL(str);
         filename = JS_GetStringBytes(str);
         errno = 0;
         oldopts = JS_GetOptions(cx);
-        JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO);
+        JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
         script = JS_CompileFile(cx, obj, filename);
         JS_SetOptions(cx, oldopts);
         if (!script) {
             ok = JS_FALSE;
         } else {
             ok = !compileOnly
-                 ? JS_ExecuteScript(cx, obj, script, &result)
+                 ? JS_ExecuteScript(cx, obj, script, NULL)
                  : JS_TRUE;
             JS_DestroyScript(cx, script);
         }
         if (!ok)
             return JS_FALSE;
     }
 
     return JS_TRUE;
@@ -1432,17 +1432,17 @@ DisassFile(JSContext *cx, JSObject *obj,
 
     str = JS_ValueToString(cx, argv[0]);
     if (!str)
         return JS_FALSE;
     argv[0] = STRING_TO_JSVAL(str);
 
     filename = JS_GetStringBytes(str);
     oldopts = JS_GetOptions(cx);
-    JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO);
+    JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
     script = JS_CompileFile(cx, obj, filename);
     JS_SetOptions(cx, oldopts);
     if (!script)
         return JS_FALSE;
 
     obj = JS_NewScriptObject(cx, script);
     if (!obj)
         return JS_FALSE;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4580,27 +4580,31 @@ JS_CompileUCScript(JSContext *cx, JSObje
 #define LAST_FRAME_CHECKS(cx,result)                                          \
     JS_BEGIN_MACRO                                                            \
         if (!(cx)->fp) {                                                      \
             (cx)->weakRoots.lastInternalResult = JSVAL_NULL;                  \
             LAST_FRAME_EXCEPTION_CHECK(cx, result);                           \
         }                                                                     \
     JS_END_MACRO
 
+#define JS_OPTIONS_TO_TCFLAGS(cx)                                             \
+    ((((cx)->options & JSOPTION_COMPILE_N_GO) ? TCF_COMPILE_N_GO : 0) |       \
+     (((cx)->options & JSOPTION_NO_SCRIPT_RVAL) ? TCF_NO_SCRIPT_RVAL : 0))
+
 JS_PUBLIC_API(JSScript *)
 JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj,
                                 JSPrincipals *principals,
                                 const jschar *chars, size_t length,
                                 const char *filename, uintN lineno)
 {
     uint32 tcflags;
     JSScript *script;
 
     CHECK_REQUEST(cx);
-    tcflags = JS_HAS_COMPILE_N_GO_OPTION(cx) ? TCF_COMPILE_N_GO : 0;
+    tcflags = JS_OPTIONS_TO_TCFLAGS(cx);
     script = js_CompileScript(cx, obj, principals, tcflags,
                               chars, length, NULL, filename, lineno);
     LAST_FRAME_CHECKS(cx, script);
     return script;
 }
 
 JS_PUBLIC_API(JSBool)
 JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj,
@@ -4656,17 +4660,17 @@ JS_CompileFile(JSContext *cx, JSObject *
         fp = fopen(filename, "r");
         if (!fp) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_OPEN,
                                  filename, "No such file or directory");
             return NULL;
         }
     }
 
-    tcflags = JS_HAS_COMPILE_N_GO_OPTION(cx) ? TCF_COMPILE_N_GO : 0;
+    tcflags = JS_OPTIONS_TO_TCFLAGS(cx);
     script = js_CompileScript(cx, obj, NULL, tcflags,
                               NULL, 0, fp, filename, 1);
     if (fp != stdin)
         fclose(fp);
     LAST_FRAME_CHECKS(cx, script);
     return script;
 }
 
@@ -4681,17 +4685,17 @@ JS_PUBLIC_API(JSScript *)
 JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj,
                                   const char *filename, FILE *file,
                                   JSPrincipals *principals)
 {
     uint32 tcflags;
     JSScript *script;
 
     CHECK_REQUEST(cx);
-    tcflags = JS_HAS_COMPILE_N_GO_OPTION(cx) ? TCF_COMPILE_N_GO : 0;
+    tcflags = JS_OPTIONS_TO_TCFLAGS(cx);
     script = js_CompileScript(cx, obj, principals, tcflags,
                               NULL, 0, file, filename, 1);
     LAST_FRAME_CHECKS(cx, script);
     return script;
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_NewScriptObject(JSContext *cx, JSScript *script)
@@ -5017,17 +5021,20 @@ JS_EvaluateUCScriptForPrincipals(JSConte
                                  const jschar *chars, uintN length,
                                  const char *filename, uintN lineno,
                                  jsval *rval)
 {
     JSScript *script;
     JSBool ok;
 
     CHECK_REQUEST(cx);
-    script = js_CompileScript(cx, obj, principals, TCF_COMPILE_N_GO,
+    script = js_CompileScript(cx, obj, principals,
+                              !rval
+                              ? TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL
+                              : TCF_COMPILE_N_GO,
                               chars, length, NULL, filename, lineno);
     if (!script)
         return JS_FALSE;
     ok = js_Execute(cx, obj, script, NULL, 0, rval);
     LAST_FRAME_CHECKS(cx, ok);
     JS_DestroyScript(cx, script);
     return ok;
 }
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -583,16 +583,21 @@ JS_StringToVersion(const char *string);
                                                    times, where n is length
                                                    of the input string */
 #define JSOPTION_ANONFUNFIX     JS_BIT(10)      /* Disallow function () {} in
                                                    statement context per
                                                    ECMA-262 Edition 3. */
 
 #define JSOPTION_JIT            JS_BIT(11)      /* Enable JIT compilation. */
 
+#define JSOPTION_NO_SCRIPT_RVAL JS_BIT(12)      /* A promise to the compiler
+                                                   that a null rval out-param
+                                                   will be passed to each call
+                                                   to JS_ExecuteScript. */
+
 extern JS_PUBLIC_API(uint32)
 JS_GetOptions(JSContext *cx);
 
 extern JS_PUBLIC_API(uint32)
 JS_SetOptions(JSContext *cx, uint32 options);
 
 extern JS_PUBLIC_API(uint32)
 JS_ToggleOptions(JSContext *cx, uint32 options);
--- a/js/src/jsemit.cpp
+++ b/js/src/jsemit.cpp
@@ -5220,18 +5220,22 @@ js_EmitTree(JSContext *cx, JSCodeGenerat
       case TOK_SEMI:
         pn2 = pn->pn_kid;
         if (pn2) {
             /*
              * Top-level or called-from-a-native JS_Execute/EvaluateScript,
              * debugger, and eval frames may need the value of the ultimate
              * expression statement as the script's result, despite the fact
              * that it appears useless to the compiler.
+             *
+             * API users may also set the JSOPTION_NO_SCRIPT_RVAL option when
+             * calling JS_Compile* suppress JSOP_POPV.
              */
-            useful = wantval = !(cg->treeContext.flags & TCF_IN_FUNCTION);
+            useful = wantval =
+                !(cg->treeContext.flags & (TCF_IN_FUNCTION | TCF_NO_SCRIPT_RVAL));
             if (!useful) {
                 if (!CheckSideEffects(cx, cg, pn2, &useful))
                     return JS_FALSE;
             }
 
             /*
              * Don't eliminate apparently useless expressions if they are
              * labeled expression statements.  The tc->topStmt->update test
--- a/js/src/jsemit.h
+++ b/js/src/jsemit.h
@@ -188,16 +188,18 @@ struct JSTreeContext {              /* t
 #define TCF_FUN_HEAVYWEIGHT    0x40 /* function needs Call object per call */
 #define TCF_FUN_IS_GENERATOR   0x80 /* parsed yield statement in function */
 #define TCF_HAS_DEFXMLNS      0x100 /* default xml namespace = ...; parsed */
 #define TCF_HAS_FUNCTION_STMT 0x200 /* block contains a function statement */
 #define TCF_GENEXP_LAMBDA     0x400 /* flag lambda from generator expression */
 #define TCF_COMPILE_N_GO      0x800 /* compiler-and-go mode of script, can
                                        optimize name references based on scope
                                        chain */
+#define TCF_NO_SCRIPT_RVAL   0x1000 /* API caller does not want result value
+                                       from global script */
 
 /*
  * Flags to propagate out of the blocks.
  */
 #define TCF_RETURN_FLAGS        (TCF_RETURN_EXPR | TCF_RETURN_VOID)
 
 /*
  * Flags to propagate from FunctionBody.
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1549,17 +1549,18 @@ js_Execute(JSContext *cx, JSObject *chai
     }
 
     if (hook) {
         hookData = hook(cx, &frame, JS_TRUE, 0,
                         cx->debugHooks->executeHookData);
     }
 
     ok = js_Interpret(cx);
-    *result = frame.rval;
+    if (result)
+        *result = frame.rval;
 
     if (hookData) {
         hook = cx->debugHooks->executeHook;
         if (hook)
             hook(cx, &frame, JS_FALSE, &ok, hookData);
     }
 
 out2:
--- a/js/src/jsparse.cpp
+++ b/js/src/jsparse.cpp
@@ -561,17 +561,17 @@ js_CompileScript(JSContext *cx, JSObject
     JSTokenType tt;
     JSParseNode *pn;
     uint32 scriptGlobals;
     JSScript *script;
 #ifdef METER_PARSENODES
     void *sbrk(ptrdiff_t), *before = sbrk(0);
 #endif
 
-    JS_ASSERT(!(tcflags & ~TCF_COMPILE_N_GO));
+    JS_ASSERT(!(tcflags & ~(TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL)));
 
     if (!js_InitParseContext(cx, &pc, principals, chars, length, file,
                              filename, lineno)) {
         return NULL;
     }
 
     /*
      * From this point the control must flow through the label out.
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -64,17 +64,17 @@
 #include "jsautooplen.h"        // generated headers last
 
 /* Number of iterations of a loop before we start tracing. */
 #define HOTLOOP 2
 
 /* Number of times we wait to exit on a side exit before we try to extend the tree. */
 #define HOTEXIT 0
 
-/* Maximum number of guards after which we no longer try to demote loop variables. 
+/* Maximum number of guards after which we no longer try to demote loop variables.
    0=off */
 #define DEMOTE_THRESHOLD 32
 
 #ifdef DEBUG
 #define ABORT_TRACE(msg)   do { fprintf(stdout, "abort: %d: %s\n", __LINE__, msg); return false; } while(0)
 #else
 #define ABORT_TRACE(msg)   return false
 #endif
@@ -306,30 +306,30 @@ public:
                 v = (LOpcode)((int)v & ~LIR64);
                 LIns* d0;
                 LIns* d1;
                 LIns* result = out->ins2(v, d0 = demote(out, s0), d1 = demote(out, s1));
                 if (!overflowSafe(d0) || !overflowSafe(d1))
                     out->insGuard(LIR_xt, out->ins1(LIR_ov, result), recorder.snapshot());
                 return out->ins1(LIR_i2f, result);
             }
-        } else if (v == LIR_or && 
+        } else if (v == LIR_or &&
                    s0->isop(LIR_lsh) && isconst(s0->oprnd2(), 16) &&
                    s1->isop(LIR_and) && isconst(s1->oprnd2(), 0xffff)) {
             LIns* msw = s0->oprnd1();
             LIns* lsw = s1->oprnd1();
             LIns* x;
             LIns* y;
             if (lsw->isop(LIR_add) &&
-                lsw->oprnd1()->isop(LIR_and) && 
+                lsw->oprnd1()->isop(LIR_and) &&
                 lsw->oprnd2()->isop(LIR_and) &&
-                isconst(lsw->oprnd1()->oprnd2(), 0xffff) && 
+                isconst(lsw->oprnd1()->oprnd2(), 0xffff) &&
                 isconst(lsw->oprnd2()->oprnd2(), 0xffff) &&
-                msw->isop(LIR_add) && 
-                msw->oprnd1()->isop(LIR_add) && 
+                msw->isop(LIR_add) &&
+                msw->oprnd1()->isop(LIR_add) &&
                 msw->oprnd2()->isop(LIR_rsh) &&
                 msw->oprnd1()->oprnd1()->isop(LIR_rsh) &&
                 msw->oprnd1()->oprnd2()->isop(LIR_rsh) &&
                 isconst(msw->oprnd2()->oprnd2(), 16) &&
                 isconst(msw->oprnd1()->oprnd1()->oprnd2(), 16) &&
                 isconst(msw->oprnd1()->oprnd2()->oprnd2(), 16) &&
                 (x = lsw->oprnd1()->oprnd1()) == msw->oprnd1()->oprnd1()->oprnd1() &&
                 (y = lsw->oprnd2()->oprnd1()) == msw->oprnd1()->oprnd2()->oprnd1() &&
@@ -403,17 +403,17 @@ public:
         for (n = 0; n < ngslots; ++n) {                                       \
             vp = &STOBJ_GET_SLOT(globalObj, gslots[n]);                       \
             { code; }                                                         \
             INC_VPNUM();                                                      \
         }                                                                     \
     JS_END_MACRO
 
 /* This macro can be used to iterate over all slots in currently pending
-   frames that make up the native frame, consisting of rval, args, vars, 
+   frames that make up the native frame, consisting of rval, args, vars,
    and stack (except for the top-level frame which does not have args or vars. */
 #define FORALL_SLOTS_IN_PENDING_FRAMES(cx, callDepth, code)                   \
     JS_BEGIN_MACRO                                                            \
         DEF_VPNAME;                                                           \
         unsigned n;                                                           \
         jsval* vp;                                                            \
         JSStackFrame* currentFrame = cx->fp;                                  \
         JSStackFrame* entryFrame;                                             \
@@ -499,22 +499,22 @@ TraceRecorder::TraceRecorder(JSContext* 
         mark = JS_ARENA_MARK(&cx->tempPool);
         localNames = js_GetLocalNameArray(cx, cx->fp->fun, &cx->tempPool);
     }
 #else
     localNames = NULL;
 #endif
     ptrdiff_t offset = 0;
     FORALL_GLOBAL_SLOTS(cx, treeInfo->ngslots, treeInfo->gslots,
-        import(gp_ins, offset, vp, *m, vpname, vpnum, localNames); 
+        import(gp_ins, offset, vp, *m, vpname, vpnum, localNames);
         m++; offset += sizeof(double);
     );
     offset = -treeInfo->nativeStackBase + 8;
     FORALL_SLOTS_IN_PENDING_FRAMES(cx, callDepth,
-        import(lirbuf->sp, offset, vp, *m, vpname, vpnum, localNames); 
+        import(lirbuf->sp, offset, vp, *m, vpname, vpnum, localNames);
         m++; offset += sizeof(double);
     );
 #ifdef DEBUG
     JS_ARENA_RELEASE(&cx->tempPool, mark);
 #endif
 
     recompileFlag = false;
 }
@@ -591,17 +591,17 @@ findInternableGlobals(JSContext* cx, JSS
         }
         JS_UNLOCK_OBJ(cx, pobj);
     }
     return count;
 }
 
 /* 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(unsigned callDepth, 
+static unsigned nativeStackSlots(unsigned callDepth,
         JSStackFrame* fp, JSFrameRegs& regs)
 {
     unsigned slots = 0;
     for (;;) {
         slots += 1/*rval*/ + (regs.sp - StackBase(fp));
         if (fp->callee)
             slots += 1/*this*/ + fp->fun->nargs + fp->script->nfixed;
         if (callDepth-- == 0)
@@ -613,37 +613,37 @@ static unsigned nativeStackSlots(unsigne
 
 /* Determine the offset in the native global frame for a jsval we track */
 ptrdiff_t
 TraceRecorder::nativeGlobalOffset(jsval* p) const
 {
     size_t offset = 0;
     unsigned ngslots = treeInfo->ngslots;
     uint16* gslots = treeInfo->gslots;
-    for (unsigned n = 0; n < ngslots; ++n, offset += sizeof(double)) 
-        if (p == &STOBJ_GET_SLOT(globalObj, gslots[n])) 
+    for (unsigned n = 0; n < ngslots; ++n, offset += sizeof(double))
+        if (p == &STOBJ_GET_SLOT(globalObj, gslots[n]))
             return offset;
     return -1; /* not a global */
 }
-    
+
 /* Determine the offset in the native stack for a jsval we track */
 ptrdiff_t
 TraceRecorder::nativeStackOffset(jsval* p) const
 {
-#ifdef DEBUG    
+#ifdef DEBUG
     size_t slow_offset = 0;
     FORALL_SLOTS_IN_PENDING_FRAMES(cx, callDepth,
         if (vp == p) goto done;
         slow_offset += sizeof(double)
     );
     /* if its not in a pending frame, it must be on the stack of the current frame above
        sp but below script->depth */
     JS_ASSERT(size_t(p - StackBase(cx->fp)) < StackDepth(cx->fp->script));
     slow_offset += size_t(p - cx->fp->regs->sp) * sizeof(double);
-done:    
+done:
 #define RETURN(offset) { JS_ASSERT((offset) == slow_offset); return offset; }
 #else
 #define RETURN(offset) { return offset; }
 #endif
     size_t offset = 0;
     JSStackFrame* currentFrame = cx->fp;
     JSStackFrame* entryFrame;
     JSStackFrame* fp = currentFrame;
@@ -652,17 +652,17 @@ done:
     unsigned frames = callDepth+1;
     JSStackFrame** fstack = (JSStackFrame **)alloca(frames * sizeof (JSStackFrame *));
     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) {
         JSStackFrame* f = *fsp;
-        if (p == &f->rval) 
+        if (p == &f->rval)
             RETURN(offset);
         offset += sizeof(double);
         if (f->callee) {
             if (size_t(p - &f->argv[-1]) < (unsigned)f->fun->nargs+1)
                 RETURN(offset + size_t(p - &f->argv[-1]) * sizeof(double));
             offset += (f->fun->nargs+1) * sizeof(double);
             if (size_t(p - &f->slots[0]) < f->script->nfixed)
                 RETURN(offset + size_t(p - &f->slots[0]) * sizeof(double));
@@ -672,17 +672,17 @@ done:
             RETURN(offset + size_t(p - StackBase(f)) * sizeof(double));
         offset += size_t(f->regs->sp - StackBase(f)) * sizeof(double);
     }
     /* if its not in a pending frame, it must be on the stack of the current frame above
        sp but below script->depth */
     JS_ASSERT(size_t(p - StackBase(currentFrame)) < StackDepth(currentFrame->script));
     offset += size_t(p - currentFrame->regs->sp) * sizeof(double);
     RETURN(offset);
-#undef RETURN    
+#undef RETURN
 }
 
 /* Track the maximum number of native frame slots we need during
    execution. */
 void
 TraceRecorder::trackNativeStackUse(unsigned slots)
 {
     if (slots > treeInfo->maxNativeStackSlots)
@@ -865,17 +865,17 @@ box(JSContext* cx, unsigned ngslots, uin
         ++mp; ++np
     );
     debug_only(printf("\n");)
     return true;
 }
 
 /* Emit load instructions onto the trace that read the initial stack state. */
 void
-TraceRecorder::import(LIns* base, ptrdiff_t offset, jsval* p, uint8& t, 
+TraceRecorder::import(LIns* base, ptrdiff_t offset, jsval* p, uint8& t,
         const char *prefix, int index, jsuword *localNames)
 {
     JS_ASSERT(TYPEMAP_GET_TYPE(t) != TYPEMAP_TYPE_ANY);
     LIns* ins;
     if (TYPEMAP_GET_TYPE(t) == JSVAL_INT) { /* demoted */
         JS_ASSERT(isInt32(*p));
         /* Ok, we have a valid demotion attempt pending, so insert an integer
            read and promote it to double since all arithmetic operations expect
@@ -926,17 +926,17 @@ TraceRecorder::set(jsval* p, LIns* i, bo
         i = ::demote(lir, i);
     /* If we are writing to this location for the first time, calculate the offset into the
        native frame manually, otherwise just look up the last load or store associated with
        the same source address (p) and use the same offset/base. */
     LIns* x;
     if ((x = nativeFrameTracker.get(p)) == NULL) {
         ptrdiff_t offset = nativeGlobalOffset(p);
         nativeFrameTracker.set(p, (offset == -1) /* not a global */
-                ? lir->insStorei(i, lirbuf->sp, 
+                ? lir->insStorei(i, lirbuf->sp,
                         -treeInfo->nativeStackBase + nativeStackOffset(p) + 8)
                 : lir->insStorei(i, gp_ins,
                         offset));
     } else {
 #define ASSERT_VALID_CACHE_HIT(base, offset)                                  \
     JS_ASSERT(base == lirbuf->sp || base == gp_ins);                          \
     JS_ASSERT(offset == ((base == lirbuf->sp)                                 \
         ? -treeInfo->nativeStackBase + nativeStackOffset(p) + 8               \
@@ -949,17 +949,17 @@ TraceRecorder::set(jsval* p, LIns* i, bo
             ASSERT_VALID_CACHE_HIT(x->oprnd2(), x->oprnd3()->constval());
             lir->insStorei(i, x->oprnd2(), x->oprnd3()->constval());
         } else {
             JS_ASSERT(x->isop(LIR_sti) || x->isop(LIR_stqi));
             ASSERT_VALID_CACHE_HIT(x->oprnd2(), x->immdisp());
             lir->insStorei(i, x->oprnd2(), x->immdisp());
         }
     }
-#undef ASSERT_VALID_CACHE_HIT    
+#undef ASSERT_VALID_CACHE_HIT
 }
 
 LIns*
 TraceRecorder::get(jsval* p)
 {
     return tracker.get(p);
 }
 
@@ -1073,17 +1073,17 @@ TraceRecorder::checkType(jsval& v, uint8
         JS_ASSERT(TYPEMAP_GET_TYPE(t) == JSVAL_INT &&
                 TYPEMAP_GET_FLAG(t, TYPEMAP_FLAG_DEMOTE) &&
                 !TYPEMAP_GET_FLAG(t, TYPEMAP_FLAG_DONT_DEMOTE));
         if (!i->isop(LIR_i2f)) {
             AUDIT(slotPromoted);
 #ifdef DEBUG
             ptrdiff_t offset;
             printf("demoting type of a slot #%d failed, locking it and re-compiling\n",
-                    ((offset = nativeGlobalOffset(&v)) == -1) 
+                    ((offset = nativeGlobalOffset(&v)) == -1)
                      ? nativeStackOffset(&v)
                      : offset);
 #endif
             TYPEMAP_SET_FLAG(t, TYPEMAP_FLAG_DONT_DEMOTE);
             TYPEMAP_SET_TYPE(t, JSVAL_DOUBLE);
             recompileFlag = true;
             return true; /* keep going, recompileFlag will trigger error when we are done with
                             all the slots */
@@ -1231,17 +1231,17 @@ js_ExecuteTree(JSContext* cx, Fragment* 
         f->releaseCode(JS_TRACE_MONITOR(cx).fragmento);
         return NULL;
     }
 
     double* global = (double *)alloca((ti->ngslots+1) * sizeof(double));
     debug_only(*(uint64*)&global[ti->ngslots] = 0xdeadbeefdeadbeefLL;)
     double* stack = (double *)alloca((ti->maxNativeStackSlots+1) * sizeof(double));
     debug_only(*(uint64*)&stack[ti->maxNativeStackSlots] = 0xdeadbeefdeadbeefLL;)
-    if (!unbox(cx, ti->ngslots, ti->gslots, 0 /*callDepth*/, 
+    if (!unbox(cx, ti->ngslots, ti->gslots, 0 /*callDepth*/,
             ti->typeMap, global, stack)) {
         AUDIT(typeMapMismatchAtEntry);
         debug_only(printf("type-map mismatch, skipping trace.\n");)
         return NULL;
     }
     double* entry_sp = &stack[ti->nativeStackBase/sizeof(double) +
                                (cx->fp->regs->sp - StackBase(cx->fp) - 1)];
     JSObject** callstack = (JSObject**)alloca(ti->maxCallDepth * sizeof(JSObject*));
@@ -1266,23 +1266,23 @@ js_ExecuteTree(JSContext* cx, Fragment* 
     cx->fp->regs->pc += lr->exit->ip_adj;
 #if defined(DEBUG) && defined(NANOJIT_IA32)
     printf("leaving trace at %s:%u@%u, sp=%p, ip=%p, cycles=%llu\n",
            cx->fp->script->filename, js_PCToLineNumber(cx, cx->fp->script, cx->fp->regs->pc),
            cx->fp->regs->pc - cx->fp->script->code,
            state.sp, lr->jmp,
            (rdtsc() - start));
 #endif
-    box(cx, ti->ngslots, ti->gslots, lr->calldepth, 
+    box(cx, ti->ngslots, ti->gslots, lr->calldepth,
             lr->exit->typeMap, global, stack);
     JS_ASSERT(*(uint64*)&stack[ti->maxNativeStackSlots] == 0xdeadbeefdeadbeefLL);
     JS_ASSERT(*(uint64*)&global[ti->ngslots] == 0xdeadbeefdeadbeefLL);
 
     AUDIT(sideExitIntoInterpreter);
-    
+
     return lr;
 }
 
 static bool
 js_AttemptToExtendTree(JSContext* cx, GuardRecord* lr, Fragment* f)
 {
     debug_only(printf("trying to attach another branch to the tree\n");)
 
@@ -1389,20 +1389,20 @@ js_LoopEdge(JSContext* cx, jsbytecode* o
             }
             /* recording primary trace */
             return js_StartRecorder(cx, NULL, f, ti->typeMap);
         }
         return false;
     }
 
     GuardRecord* lr = js_ExecuteTree(cx, f);
-    
+
     if (!lr) /* did the tree actually execute? */
         return false;
-    
+
     /* if the side exit terminates the loop, don't try to attach a trace here */
     if (lr->exit->loopExit)
         return false;
 
     return js_AttemptToExtendTree(cx, lr, f);
 }
 
 void
@@ -1544,17 +1544,17 @@ TraceRecorder::inc(jsval& v, jsint incr,
 {
     LIns* v_ins = get(&v);
     if (!inc(v, v_ins, incr, pre))
         return false;
     set(&v, v_ins);
     return true;
 }
 
-/* 
+/*
  * On exit, v_ins is the incremented unboxed value, and the appropriate
  * value (pre- or post-increment as described by pre) is stacked.
  */
 bool
 TraceRecorder::inc(jsval& v, LIns*& v_ins, jsint incr, bool pre)
 {
     if (!isNumber(v))
         ABORT_TRACE("can only inc numbers");
@@ -1996,17 +1996,17 @@ TraceRecorder::record_EnterFrame()
     LIns* void_ins = lir->insImm(JSVAL_TO_BOOLEAN(JSVAL_VOID));
     set(&fp->rval, void_ins, true);
     unsigned n;
     for (n = 0; n < fp->script->nfixed; ++n)
         set(&fp->slots[n], void_ins, true);
     return true;
 }
 
-bool 
+bool
 TraceRecorder::record_LeaveFrame()
 {
     if (callDepth-- <= 0)
         return false;
     atoms = cx->fp->script->atomMap.vector;
     stack(-1, rval_ins); // LeaveFrame gets called after the interpreter stored rval so -1, not 0
     return true;
 }