Remove imacros (bug 698201 part 2, r=luke).
authorDavid Anderson <dvander@alliedmods.net>
Tue, 22 Nov 2011 17:41:41 -0500
changeset 82294 565abbb3f5d79eee93a9b505e11e28be26673d9c
parent 82293 b2e8d10f25a1fd4cba7fed248ce8059b5070dfe1
child 82295 1d20af78b1788e91030467fbe36bec71876e0c18
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs698201
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Remove imacros (bug 698201 part 2, r=luke).
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jsinterp.cpp
js/src/jsobj.cpp
js/src/jsopcode.cpp
js/src/jsopcode.h
js/src/jsopcode.tbl
js/src/jspropertycache.cpp
js/src/jsscript.cpp
js/src/methodjit/StubCalls.cpp
js/src/vm/Stack-inl.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/vm/StackSpace.h
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -1341,51 +1341,17 @@ js_GetScriptedCaller(JSContext *cx, Stac
         fp = fp->prev();
     JS_ASSERT_IF(fp, fp->isScriptFrame());
     return fp;
 }
 
 jsbytecode*
 js_GetCurrentBytecodePC(JSContext* cx)
 {
-    jsbytecode *pc, *imacpc;
-
-#ifdef JS_TRACER
-    if (JS_ON_TRACE(cx)) {
-        pc = JS_TRACE_MONITOR_ON_TRACE(cx)->bailExit->pc;
-        imacpc = JS_TRACE_MONITOR_ON_TRACE(cx)->bailExit->imacpc;
-    } else
-#endif
-    {
-        JS_ASSERT_NOT_ON_TRACE(cx);  /* for static analysis */
-        pc = cx->hasfp() ? cx->regs().pc : NULL;
-        if (!pc)
-            return NULL;
-        imacpc = cx->fp()->maybeImacropc();
-    }
-
-    /*
-     * If we are inside GetProperty_tn or similar, return a pointer to the
-     * current instruction in the script, not the CALL instruction in the
-     * imacro, for the benefit of callers doing bytecode inspection.
-     */
-    return (*pc == JSOP_CALL && imacpc) ? imacpc : pc;
-}
-
-bool
-js_CurrentPCIsInImacro(JSContext *cx)
-{
-#ifdef JS_TRACER
-    VOUCH_DOES_NOT_REQUIRE_STACK();
-    if (JS_ON_TRACE(cx))
-        return JS_TRACE_MONITOR_ON_TRACE(cx)->bailExit->imacpc != NULL;
-    return cx->fp()->hasImacropc();
-#else
-    return false;
-#endif
+    return cx->hasfp() ? cx->regs().pc : NULL;
 }
 
 void
 DSTOffsetCache::purge()
 {
     /*
      * NB: The initial range values are carefully chosen to result in a cache
      *     miss on first use given the range of possible values.  Be careful
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -2180,19 +2180,16 @@ extern js::StackFrame *
 js_GetScriptedCaller(JSContext *cx, js::StackFrame *fp);
 
 extern jsbytecode*
 js_GetCurrentBytecodePC(JSContext* cx);
 
 extern JSScript *
 js_GetCurrentScript(JSContext* cx);
 
-extern bool
-js_CurrentPCIsInImacro(JSContext *cx);
-
 namespace js {
 
 extern JS_FORCES_STACK JS_FRIEND_API(void)
 LeaveTrace(JSContext *cx);
 
 extern bool
 CanLeaveTrace(JSContext *cx);
 
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -397,19 +397,17 @@ LeaveTraceIfArgumentsObject(JSContext *c
 {
     if (obj->isArguments())
         LeaveTrace(cx);
 }
 
 static inline JSAtom **
 FrameAtomBase(JSContext *cx, js::StackFrame *fp)
 {
-    return fp->hasImacropc()
-           ? cx->runtime->atomState.commonAtomsStart()
-           : fp->script()->atoms;
+    return fp->script()->atoms;
 }
 
 }  /* namespace js */
 
 inline JSVersion
 JSContext::findVersion() const
 {
     if (hasVersionOverride)
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -147,17 +147,17 @@ js::GetScopeChain(JSContext *cx)
  */
 JSObject *
 js::GetBlockChain(JSContext *cx, StackFrame *fp)
 {
     if (!fp->isScriptFrame())
         return NULL;
 
     /* Assume that imacros don't affect blockChain */
-    jsbytecode *target = fp->hasImacropc() ? fp->imacropc() : fp->pcQuadratic(cx->stack);
+    jsbytecode *target = fp->pcQuadratic(cx->stack);
 
     JSScript *script = fp->script();
     jsbytecode *start = script->code;
 
     /*
      * If the debugger asks for the scope chain at a pc where we are about to
      * fix it up, advance target past the fixup. See bug 672804.
      */
@@ -1690,21 +1690,18 @@ js::Interpret(JSContext *cx, StackFrame 
 # define END_EMPTY_CASES    goto advance_pc_by_one;
 
 #endif /* !JS_THREADED_INTERP */
 
 #define ENABLE_INTERRUPTS() (interruptEnabler.enableInterrupts())
 
 #define LOAD_ATOM(PCOFF, atom)                                                \
     JS_BEGIN_MACRO                                                            \
-        JS_ASSERT(regs.fp()->hasImacropc()                                    \
-                  ? atoms == rt->atomState.commonAtomsStart() &&              \
-                    GET_INDEX(regs.pc + PCOFF) < js_common_atom_count         \
-                  : (size_t)(atoms - script->atoms) <                         \
-                    (size_t)(script->natoms - GET_INDEX(regs.pc + PCOFF)));   \
+        JS_ASSERT((size_t)(atoms - script->atoms) <                           \
+                  (size_t)(script->natoms - GET_INDEX(regs.pc + PCOFF)));     \
         atom = atoms[GET_INDEX(regs.pc + PCOFF)];                             \
     JS_END_MACRO
 
 #define GET_FULL_INDEX(PCOFF)                                                 \
     (atoms - script->atoms + GET_INDEX(regs.pc + (PCOFF)))
 
 #define LOAD_OBJECT(PCOFF, obj)                                               \
     (obj = script->getObject(GET_FULL_INDEX(PCOFF)))
@@ -1875,19 +1872,16 @@ js::Interpret(JSContext *cx, StackFrame 
         JS_ASSERT(TRACE_RECORDER(cx));
         JS_ASSERT(!TRACE_PROFILER(cx));
         ENABLE_INTERRUPTS();
     } else if (interpMode == JSINTERP_PROFILE) {
         ENABLE_INTERRUPTS();
     } else if (TRACE_RECORDER(cx)) {
         AbortRecording(cx, "attempt to reenter interpreter while recording");
     }
-
-    if (regs.fp()->hasImacropc())
-        atoms = rt->atomState.commonAtomsStart();
 #endif
 
     /* Don't call the script prologue if executing between Method and Trace JIT. */
     if (interpMode == JSINTERP_NORMAL) {
         StackFrame *fp = regs.fp();
         JS_ASSERT_IF(!fp->isGeneratorFrame(), regs.pc == script->code);
         if (!ScriptPrologueOrGeneratorResume(cx, fp, UseNewTypeAtEntry(cx, fp)))
             goto error;
@@ -1973,20 +1967,18 @@ js::Interpret(JSContext *cx, StackFrame 
 #else /* !JS_THREADED_INTERP */
   case -1:
     JS_ASSERT(switchMask == -1);
 #endif /* !JS_THREADED_INTERP */
     {
         bool moreInterrupts = false;
 
         if (script->pcCounters) {
-            if (!regs.fp()->hasImacropc()) {
-                OpcodeCounts counts = script->getCounts(regs.pc);
-                counts.get(OpcodeCounts::BASE_INTERP)++;
-            }
+            OpcodeCounts counts = script->getCounts(regs.pc);
+            counts.get(OpcodeCounts::BASE_INTERP)++;
             moreInterrupts = true;
         }
 
         JSInterruptHook hook = cx->debugHooks->interruptHook;
         if (hook || script->stepModeEnabled()) {
 #ifdef JS_TRACER
             if (TRACE_RECORDER(cx))
                 AbortRecording(cx, "interrupt hook or singleStepMode");
@@ -2069,16 +2061,17 @@ js::Interpret(JSContext *cx, StackFrame 
         switchMask = moreInterrupts ? -1 : 0;
         switchOp = intN(op);
         goto do_switch;
 #endif
     }
 
 /* No-ops for ease of decompilation. */
 ADD_EMPTY_CASE(JSOP_NOP)
+ADD_EMPTY_CASE(JSOP_UNUSED0)
 ADD_EMPTY_CASE(JSOP_CONDSWITCH)
 ADD_EMPTY_CASE(JSOP_TRY)
 #if JS_HAS_XML_SUPPORT
 ADD_EMPTY_CASE(JSOP_STARTXML)
 ADD_EMPTY_CASE(JSOP_STARTXMLEXPR)
 #endif
 ADD_EMPTY_CASE(JSOP_NULLBLOCKCHAIN)
 END_EMPTY_CASES
@@ -2214,40 +2207,20 @@ BEGIN_CASE(JSOP_RETRVAL)    /* fp return
 BEGIN_CASE(JSOP_STOP)
 {
     /*
      * When the inlined frame exits with an exception or an error, ok will be
      * false after the inline_return label.
      */
     CHECK_BRANCH();
 
-#ifdef JS_TRACER
-    if (regs.fp()->hasImacropc()) {
-        /*
-         * If we are at the end of an imacro, return to its caller in the
-         * current frame.
-         */
-        JS_ASSERT(op == JSOP_STOP);
-        JS_ASSERT((uintN)(regs.sp - regs.fp()->slots()) <= script->nslots);
-        jsbytecode *imacpc = regs.fp()->imacropc();
-        regs.pc = imacpc + js_CodeSpec[*imacpc].length;
-        if (js_CodeSpec[*imacpc].format & JOF_DECOMPOSE)
-            regs.pc += GetDecomposeLength(imacpc, js_CodeSpec[*imacpc].length);
-        regs.fp()->clearImacropc();
-        atoms = script->atoms;
-        op = JSOp(*regs.pc);
-        DO_OP();
-    }
-#endif
-
     interpReturnOK = true;
     if (entryFrame != regs.fp())
   inline_return:
     {
-        JS_ASSERT(!regs.fp()->hasImacropc());
         JS_ASSERT(!IsActiveWithOrBlock(cx, regs.fp()->scopeChain(), 0));
         interpReturnOK = ScriptEpilogue(cx, regs.fp(), interpReturnOK);
 
         /* The JIT inlines ScriptEpilogue. */
 #ifdef JS_METHODJIT
   jit_return:
 #endif
 
@@ -2674,21 +2647,16 @@ BEGIN_CASE(JSOP_BINDNAME)
         obj = js_FindIdentifierBase(cx, &regs.fp()->scopeChain(), id);
         if (!obj)
             goto error;
     } while (0);
     PUSH_OBJECT(*obj);
 }
 END_CASE(JSOP_BINDNAME)
 
-BEGIN_CASE(JSOP_IMACOP)
-    JS_ASSERT(UnsignedPtrDiff(regs.fp()->imacropc(), script->code) < script->length);
-    op = JSOp(*regs.fp()->imacropc());
-    DO_OP();
-
 #define BITWISE_OP(OP)                                                        \
     JS_BEGIN_MACRO                                                            \
         int32_t i, j;                                                         \
         if (!ValueToECMAInt32(cx, regs.sp[-2], &i))                           \
             goto error;                                                       \
         if (!ValueToECMAInt32(cx, regs.sp[-1], &j))                           \
             goto error;                                                       \
         i = i OP j;                                                           \
@@ -3462,28 +3430,25 @@ BEGIN_CASE(JSOP_LENGTH)
             if (entry->vword.isFunObj()) {
                 rval.setObject(entry->vword.toFunObj());
             } else if (entry->vword.isSlot()) {
                 uint32 slot = entry->vword.toSlot();
                 rval = obj2->nativeGetSlot(slot);
             } else {
                 JS_ASSERT(entry->vword.isShape());
                 const Shape *shape = entry->vword.toShape();
-                NATIVE_GET(cx, obj, obj2, shape,
-                           regs.fp()->hasImacropc() ? JSGET_NO_METHOD_BARRIER : JSGET_METHOD_BARRIER,
-                           &rval);
+                NATIVE_GET(cx, obj, obj2, shape, JSGET_METHOD_BARRIER, &rval);
             }
             break;
         }
 
         jsid id = ATOM_TO_JSID(atom);
         if (JS_LIKELY(!aobj->getOps()->getProperty)
             ? !js_GetPropertyHelper(cx, obj, id,
-                                    (regs.fp()->hasImacropc() ||
-                                     regs.pc[JSOP_GETPROP_LENGTH] == JSOP_IFEQ)
+                                    (regs.pc[JSOP_GETPROP_LENGTH] == JSOP_IFEQ)
                                     ? JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER
                                     : JSGET_CACHE_RESULT | JSGET_METHOD_BARRIER,
                                     &rval)
             : !obj->getGeneric(cx, id, &rval))
         {
             goto error;
         }
     } while (0);
@@ -3794,17 +3759,17 @@ BEGIN_CASE(JSOP_GETELEM)
         } else if (obj->isArguments()) {
             if (obj->asArguments()->getElement(index, &rval))
                 goto end_getelem;
         }
 
         if (!obj->getElement(cx, index, &rval))
             goto error;
     } else {
-        if (script->hasAnalysis() && !regs.fp()->hasImacropc())
+        if (script->hasAnalysis())
             script->analysis()->getCode(regs.pc).getStringElement = true;
 
         SpecialId special;
         if (ValueIsSpecial(obj, &rref, &special, cx)) {
             if (!obj->getSpecial(cx, special, &rval))
                 goto error;
         } else {
             JSAtom *name;
@@ -3878,17 +3843,17 @@ BEGIN_CASE(JSOP_SETELEM)
                     if (js_PrototypeHasIndexedProperties(cx, obj))
                         break;
                     if ((jsuint)i >= obj->getArrayLength())
                         obj->setArrayLength(cx, i + 1);
                 }
                 obj->setDenseArrayElementWithType(cx, i, regs.sp[-1]);
                 goto end_setelem;
             } else {
-                if (script->hasAnalysis() && !regs.fp()->hasImacropc())
+                if (script->hasAnalysis())
                     script->analysis()->getCode(regs.pc).arrayWriteHole = true;
             }
         }
     } while (0);
     rval = regs.sp[-1];
     if (!obj->setGeneric(cx, id, &rval, script->strictModeCode))
         goto error;
   end_setelem:;
@@ -4126,17 +4091,16 @@ END_CASE(JSOP_INDEXBASE3)
 
 BEGIN_CASE(JSOP_RESETBASE0)
 BEGIN_CASE(JSOP_RESETBASE)
     atoms = script->atoms;
 END_CASE(JSOP_RESETBASE)
 
 BEGIN_CASE(JSOP_DOUBLE)
 {
-    JS_ASSERT(!regs.fp()->hasImacropc());
     double dbl;
     LOAD_DOUBLE(0, dbl);
     PUSH_DOUBLE(dbl);
 }
 END_CASE(JSOP_DOUBLE)
 
 BEGIN_CASE(JSOP_STRING)
 {
@@ -4277,17 +4241,16 @@ BEGIN_CASE(JSOP_LOOKUPSWITCHX)
 BEGIN_CASE(JSOP_LOOKUPSWITCH)
     off = JUMP_OFFSET_LEN;
 
   do_lookup_switch:
     /*
      * JSOP_LOOKUPSWITCH and JSOP_LOOKUPSWITCHX are never used if any atom
      * index in it would exceed 64K limit.
      */
-    JS_ASSERT(!regs.fp()->hasImacropc());
     JS_ASSERT(atoms == script->atoms);
     jsbytecode *pc2 = regs.pc;
 
     Value lval = regs.sp[-1];
     regs.sp--;
 
     if (!lval.isPrimitive())
         goto end_lookup_switch;
@@ -5888,26 +5851,17 @@ END_CASE(JSOP_ARRAYPUSH)
 
 #if !JS_THREADED_INTERP
         } /* switch (op) */
     } /* for (;;) */
 #endif /* !JS_THREADED_INTERP */
 
   error:
     JS_ASSERT(&cx->regs() == &regs);
-#ifdef JS_TRACER
-    if (regs.fp()->hasImacropc() && cx->isExceptionPending()) {
-        // Handle exceptions as if they came from the imacro-calling pc.
-        regs.pc = regs.fp()->imacropc();
-        regs.fp()->clearImacropc();
-    }
-#endif
-
-    JS_ASSERT(size_t((regs.fp()->hasImacropc() ? regs.fp()->imacropc() : regs.pc) - script->code) <
-              script->length);
+    JS_ASSERT(uint32(regs.pc - script->code) < script->length);
 
 #ifdef JS_TRACER
     /*
      * This abort could be weakened to permit tracing through exceptions that
      * are thrown and caught within a loop, with the co-operation of the tracer.
      * For now just bail on any sign of trouble.
      */
     if (TRACE_RECORDER(cx))
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3148,17 +3148,17 @@ Detecting(JSContext *cx, jsbytecode *pc)
 {
     jsbytecode *endpc;
     JSOp op;
     JSAtom *atom;
 
     JSScript *script = cx->stack.currentScript();
     endpc = script->code + script->length;
     for (;; pc += js_CodeSpec[op].length) {
-        JS_ASSERT_IF(!cx->fp()->hasImacropc(), script->code <= pc && pc < endpc);
+        JS_ASSERT(script->code <= pc && pc < endpc);
 
         /* General case: a branch or equality op follows the access. */
         op = js_GetOpcode(cx, script, pc);
         if (js_CodeSpec[op].format & JOF_DETECTING)
             return JS_TRUE;
 
         switch (op) {
           case JSOP_NULL:
@@ -5728,17 +5728,17 @@ js_NativeGetInline(JSContext *cx, JSObje
 
     if (JS_UNLIKELY(shape->isMethod()) && (getHow & JSGET_NO_METHOD_BARRIER)) {
         JS_ASSERT(shape->methodObject() == vp->toObject());
         return true;
     }
 
     jsbytecode *pc;
     JSScript *script = cx->stack.currentScript(&pc);
-    if (script && script->hasAnalysis() && !cx->fp()->hasImacropc()) {
+    if (script && script->hasAnalysis()) {
         analyze::Bytecode *code = script->analysis()->maybeCode(pc);
         if (code)
             code->accessGetter = true;
     }
 
     sample = cx->runtime->propertyRemovals;
     if (!shape->get(cx, receiver, obj, pobj, vp))
         return false;
@@ -5862,18 +5862,17 @@ js_GetPropertyHelperInline(JSContext *cx
                 JS_ASSERT_NOT_ON_TRACE(cx);
                 op = JS_GetTrapOpcode(cx, cx->fp()->script(), pc);
             }
             if (op == JSOP_GETXPROP) {
                 flags = JSREPORT_ERROR;
             } else {
                 if (!cx->hasStrictOption() ||
                     cx->stack.currentScript()->warnedAboutUndefinedProp ||
-                    (op != JSOP_GETPROP && op != JSOP_GETELEM) ||
-                    js_CurrentPCIsInImacro(cx)) {
+                    (op != JSOP_GETPROP && op != JSOP_GETELEM)) {
                     return JS_TRUE;
                 }
 
                 /*
                  * XXX do not warn about missing __iterator__ as the function
                  * may be called from JS_GetMethodById. See bug 355145.
                  */
                 if (JSID_IS_ATOM(id, cx->runtime->atomState.iteratorAtom))
@@ -7413,23 +7412,17 @@ js_DumpStackFrame(JSContext *cx, StackFr
                     fp->script()->filename, (unsigned) fp->script()->lineno);
         }
 
         if (jsbytecode *pc = i.pc()) {
             if (!fp->isScriptFrame()) {
                 fprintf(stderr, "*** pc && !script, skipping frame\n\n");
                 continue;
             }
-            if (fp->hasImacropc()) {
-                fprintf(stderr, "  pc in imacro at %p\n  called from ", pc);
-                pc = fp->imacropc();
-            } else {
-                fprintf(stderr, "  ");
-            }
-            fprintf(stderr, "pc = %p\n", pc);
+            fprintf(stderr, "  pc = %p\n", pc);
             fprintf(stderr, "  current op: %s\n", js_CodeName[*pc]);
         }
         Value *sp = i.sp();
         fprintf(stderr, "  slots: %p\n", (void *) fp->slots());
         fprintf(stderr, "  sp:    %p = slots + %u\n", (void *) sp, (unsigned) (sp - fp->slots()));
         if (sp - fp->slots() < 10000) { // sanity
             for (Value *p = fp->slots(); p < sp; p++) {
                 fprintf(stderr, "    %p: ", (void *) p);
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -5156,17 +5156,17 @@ js_DecompileValueGenerator(JSContext *cx
 
     LeaveTrace(cx);
     
     if (!cx->hasfp() || !cx->fp()->isScriptFrame())
         goto do_fallback;
 
     fp = js_GetTopStackFrame(cx, FRAME_EXPAND_ALL);
     script = fp->script();
-    pc = fp->hasImacropc() ? fp->imacropc() : cx->regs().pc;
+    pc = cx->regs().pc;
     JS_ASSERT(script->code <= pc && pc < script->code + script->length);
 
     if (pc < script->main())
         goto do_fallback;
     
     if (spindex != JSDVG_IGNORE_STACK) {
         jsbytecode **pcstack;
 
@@ -5218,38 +5218,17 @@ js_DecompileValueGenerator(JSContext *cx
 
       release_pcstack:
         cx->free_(pcstack);
         if (pcdepth < 0)
             goto do_fallback;
     }
 
     {
-        jsbytecode* basepc = cx->regs().pc;
-        jsbytecode* savedImacropc = fp->maybeImacropc();
-        if (savedImacropc) {
-            cx->regs().pc = savedImacropc;
-            fp->clearImacropc();
-        }
-
-        /*
-         * FIXME: bug 489843. Stack reconstruction may have returned a pc
-         * value *inside* an imacro; this would confuse the decompiler.
-         */
-        char *name;
-        if (savedImacropc && size_t(pc - script->code) >= script->length)
-            name = FAILED_EXPRESSION_DECOMPILER;
-        else
-            name = DecompileExpression(cx, script, fp->maybeFun(), pc);
-
-        if (savedImacropc) {
-            cx->regs().pc = basepc;
-            fp->setImacropc(savedImacropc);
-        }
-
+        char *name = DecompileExpression(cx, script, fp->maybeFun(), pc);
         if (name != FAILED_EXPRESSION_DECOMPILER)
             return name;
     }
 
   do_fallback:
     if (!fallback) {
         fallback = js_ValueToSource(cx, v);
         if (!fallback)
@@ -5419,122 +5398,27 @@ SimulateOp(JSContext *cx, JSScript *scri
             pcstack[pcdepth] = tmp;
         }
         break;
     }
     pcdepth += ndefs;
     return pcdepth;
 }
 
-#ifdef JS_TRACER
-
-#undef LOCAL_ASSERT
-#define LOCAL_ASSERT(expr)      LOCAL_ASSERT_CUSTOM(expr, goto failure);
-
-static intN
-SimulateImacroCFG(JSContext *cx, JSScript *script,
-                  uintN pcdepth, jsbytecode *pc, jsbytecode *target,
-                  jsbytecode **pcstack)
-{
-    size_t nbytes = 0;
-    jsbytecode** tmp_pcstack = NULL;
-    if (pcstack) {
-        nbytes = StackDepth(script) * sizeof *pcstack;
-        tmp_pcstack = (jsbytecode **) cx->malloc_(nbytes);
-        if (!tmp_pcstack)
-            return -1;
-        memcpy(tmp_pcstack, pcstack, nbytes);
-    }
-
-    ptrdiff_t oplen;
-    for (; pc < target; pc += oplen) {
-        JSOp op = js_GetOpcode(cx, script, pc);
-        const JSCodeSpec *cs = &js_CodeSpec[op];
-        oplen = cs->length;
-        if (oplen < 0)
-            oplen = js_GetVariableBytecodeLength(pc);
-
-        if (SimulateOp(cx, script, op, cs, pc, tmp_pcstack, pcdepth) < 0)
-            goto failure;
-
-        uint32 type = cs->format & JOF_TYPEMASK;
-        if (type == JOF_JUMP || type == JOF_JUMPX) {
-            ptrdiff_t jmpoff = (type == JOF_JUMP) ? GET_JUMP_OFFSET(pc)
-                                                  : GET_JUMPX_OFFSET(pc);
-            LOCAL_ASSERT(jmpoff >= 0);
-            intN tmp_pcdepth = SimulateImacroCFG(cx, script, pcdepth, pc + jmpoff,
-                                                 target, tmp_pcstack);
-            if (tmp_pcdepth >= 0) {
-                pcdepth = uintN(tmp_pcdepth);
-                goto success;
-            }
-
-            if (op == JSOP_GOTO || op == JSOP_GOTOX)
-                goto failure;
-        }
-    }
-
-    if (pc > target)
-        goto failure;
-
-    LOCAL_ASSERT(pc == target);
-
-  success:
-    if (tmp_pcstack) {
-        memcpy(pcstack, tmp_pcstack, nbytes);
-        cx->free_(tmp_pcstack);
-    }
-    return pcdepth;
-
-  failure:
-    if (tmp_pcstack)
-        cx->free_(tmp_pcstack);
-    return -1;
-}
-
-#undef LOCAL_ASSERT
-#define LOCAL_ASSERT(expr)      LOCAL_ASSERT_RV(expr, -1);
-
-static intN
-ReconstructImacroPCStack(JSContext *cx, JSScript *script,
-                         jsbytecode *imacstart, jsbytecode *target,
-                         jsbytecode **pcstack)
-{
-    /*
-     * Begin with a recursive call back to ReconstructPCStack to pick up
-     * the state-of-the-world at the *start* of the imacro.
-     */
-    StackFrame *fp = js_GetScriptedCaller(cx, NULL);
-    JS_ASSERT(fp->hasImacropc());
-    intN pcdepth = ReconstructPCStack(cx, script, fp->imacropc(), pcstack);
-    if (pcdepth < 0)
-        return pcdepth;
-    return SimulateImacroCFG(cx, script, pcdepth, imacstart, target, pcstack);
-}
-
-extern jsbytecode* js_GetImacroStart(jsbytecode* pc);
-#endif
-
 static intN
 ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *target,
                    jsbytecode **pcstack)
 {
     /*
      * Walk forward from script->main and compute the stack depth and stack of
      * operand-generating opcode PCs in pcstack.
      *
      * FIXME: Code to compute oplen copied from js_Disassemble1 and reduced.
      * FIXME: Optimize to use last empty-stack sequence point.
      */
-#ifdef JS_TRACER
-    jsbytecode *imacstart = js_GetImacroStart(target);
-
-    if (imacstart)
-        return ReconstructImacroPCStack(cx, script, imacstart, target, pcstack);
-#endif
 
     LOCAL_ASSERT(script->code <= target && target < script->code + script->length);
     jsbytecode *pc = script->code;
     uintN pcdepth = 0;
     ptrdiff_t oplen;
     for (; pc < target; pc += oplen) {
         JSOp op = js_GetOpcode(cx, script, pc);
         const JSCodeSpec *cs = &js_CodeSpec[op];
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -342,26 +342,16 @@ js_GetIndexFromBytecode(JSContext *cx, J
  */
 #define GET_ATOM_FROM_BYTECODE(script, pc, pcoff, atom)                       \
     JS_BEGIN_MACRO                                                            \
         JS_ASSERT(*(pc) != JSOP_DOUBLE);                                      \
         uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff));  \
         JS_GET_SCRIPT_ATOM(script, pc, index_, atom);                         \
     JS_END_MACRO
 
-/*
- * Variant for getting a double atom when we might be in an imacro. Bytecodes
- * with literals that are only ever doubles must use this macro, and never use
- * GET_ATOM_FROM_BYTECODE or JS_GET_SCRIPT_ATOM.
- *
- * Unfortunately some bytecodes such as JSOP_LOOKUPSWITCH have immediates that
- * might be string or double atoms. Those opcodes cannot be used from imacros.
- * See the assertions in the JSOP_DOUBLE and JSOP_LOOKUPSWTICH* opcode cases in
- * jsinterp.cpp.
- */
 #define GET_DOUBLE_FROM_BYTECODE(script, pc, pcoff, dbl)                      \
     JS_BEGIN_MACRO                                                            \
         uintN index_ = js_GetIndexFromBytecode(cx, (script), (pc), (pcoff));  \
         JS_ASSERT(index_ < (script)->consts()->length);                       \
         (dbl) = (script)->getConst(index_).toDouble();                        \
     JS_END_MACRO
 
 #define GET_OBJECT_FROM_BYTECODE(script, pc, pcoff, obj)                      \
--- a/js/src/jsopcode.tbl
+++ b/js/src/jsopcode.tbl
@@ -267,17 +267,17 @@ OPDEF(JSOP_DECARG,    98, "decarg",     
 OPDEF(JSOP_ARGINC,    99, "arginc",     NULL,         3,  0,  1, 15,  JOF_QARG |JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3)
 OPDEF(JSOP_ARGDEC,   100, "argdec",     NULL,         3,  0,  1, 15,  JOF_QARG |JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3)
 
 OPDEF(JSOP_INCLOCAL,  101,"inclocal",   NULL,         3,  0,  1, 15,  JOF_LOCAL|JOF_NAME|JOF_INC|JOF_TMPSLOT3)
 OPDEF(JSOP_DECLOCAL,  102,"declocal",   NULL,         3,  0,  1, 15,  JOF_LOCAL|JOF_NAME|JOF_DEC|JOF_TMPSLOT3)
 OPDEF(JSOP_LOCALINC,  103,"localinc",   NULL,         3,  0,  1, 15,  JOF_LOCAL|JOF_NAME|JOF_INC|JOF_POST|JOF_TMPSLOT3)
 OPDEF(JSOP_LOCALDEC,  104,"localdec",   NULL,         3,  0,  1, 15,  JOF_LOCAL|JOF_NAME|JOF_DEC|JOF_POST|JOF_TMPSLOT3)
 
-OPDEF(JSOP_IMACOP,    105,"imacop",     NULL,         1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED0,   105,"unused0",    NULL,         1,  0,  0,  0,  JOF_BYTE)
 
 /* The argument is the offset to the next statement and is used by IonMonkey. */
 OPDEF(JSOP_LABEL,     106,"label",     NULL,          3,  0,  0,  0,  JOF_JUMP)
 OPDEF(JSOP_LABELX,    107,"labelx",    NULL,          5,  0,  0,  0,  JOF_JUMPX)
 
 /* Like JSOP_FUNAPPLY but for f.call instead of f.apply. */
 OPDEF(JSOP_FUNCALL,   108,"funcall",    NULL,         3, -1,  1, 18,  JOF_UINT16|JOF_INVOKE|JOF_TYPESET)
 
--- a/js/src/jspropertycache.cpp
+++ b/js/src/jspropertycache.cpp
@@ -322,18 +322,17 @@ PropertyCache::fullTest(JSContext *cx, j
                         PropertyCacheEntry *entry)
 {
     JSObject *obj, *pobj, *tmp;
     uint32 vcap;
 
     JSScript *script = cx->stack.currentScript();
 
     JS_ASSERT(this == &JS_PROPERTY_CACHE(cx));
-    JS_ASSERT(uintN((cx->fp()->hasImacropc() ? cx->fp()->imacropc() : pc) - script->code)
-              < script->length);
+    JS_ASSERT(uint32(pc - script->code) < script->length);
 
     JSOp op = js_GetOpcode(cx, script, pc);
     const JSCodeSpec &cs = js_CodeSpec[op];
 
     obj = *objp;
     vcap = entry->vcap;
 
     if (entry->kpc != pc) {
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1426,17 +1426,17 @@ js_GetSrcNoteCached(JSContext *cx, JSScr
     }
 
     return result;
 }
 
 uintN
 js_FramePCToLineNumber(JSContext *cx, StackFrame *fp, jsbytecode *pc)
 {
-    return js_PCToLineNumber(cx, fp->script(), fp->hasImacropc() ? fp->imacropc() : pc);
+    return js_PCToLineNumber(cx, fp->script(), pc);
 }
 
 uintN
 js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc)
 {
     /* Cope with StackFrame.pc value prior to entering js_Interpret. */
     if (!pc)
         return 0;
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -1573,29 +1573,25 @@ InlineGetProp(VMFrame &f)
             if (entry->vword.isFunObj()) {
                 rval.setObject(entry->vword.toFunObj());
             } else if (entry->vword.isSlot()) {
                 uint32 slot = entry->vword.toSlot();
                 rval = obj2->nativeGetSlot(slot);
             } else {
                 JS_ASSERT(entry->vword.isShape());
                 const Shape *shape = entry->vword.toShape();
-                NATIVE_GET(cx, obj, obj2, shape,
-                        f.fp()->hasImacropc() ? JSGET_NO_METHOD_BARRIER : JSGET_METHOD_BARRIER,
-                        &rval, return false);
+                NATIVE_GET(cx, obj, obj2, shape, JSGET_METHOD_BARRIER, &rval, return false);
             }
             break;
         }
 
         jsid id = ATOM_TO_JSID(atom);
         if (JS_LIKELY(!aobj->getOps()->getProperty)
                 ? !js_GetPropertyHelper(cx, obj, id,
-                    f.fp()->hasImacropc()
-                    ? JSGET_CACHE_RESULT | JSGET_NO_METHOD_BARRIER
-                    : JSGET_CACHE_RESULT | JSGET_METHOD_BARRIER,
+                    JSGET_CACHE_RESULT | JSGET_METHOD_BARRIER,
                     &rval)
                 : !obj->getGeneric(cx, id, &rval)) {
             return false;
         }
     } while(0);
 
     regs.sp[-1] = rval;
     return true;
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -57,17 +57,17 @@ namespace js {
 inline void
 StackFrame::initPrev(JSContext *cx)
 {
     JS_ASSERT(flags_ & HAS_PREVPC);
     if (FrameRegs *regs = cx->maybeRegs()) {
         prev_ = regs->fp();
         prevpc_ = regs->pc;
         prevInline_ = regs->inlined();
-        JS_ASSERT_IF(!prev_->isDummyFrame() && !prev_->hasImacropc(),
+        JS_ASSERT_IF(!prev_->isDummyFrame(),
                      uint32(prevpc_ - prev_->script()->code) < prev_->script()->length);
     } else {
         prev_ = NULL;
 #ifdef DEBUG
         prevpc_ = (jsbytecode *)0xbadc;
         prevInline_ = (JSInlinedSite *)0xbadc;
 #endif
     }
@@ -115,17 +115,16 @@ StackFrame::initCallFrame(JSContext *cx,
 
     /* Initialize stack frame members. */
     flags_ = FUNCTION | HAS_PREVPC | HAS_SCOPECHAIN | flagsArg;
     exec.fun = fun;
     args.nactual = nactual;
     scopeChain_ = callee.getParent();
     ncode_ = NULL;
     initPrev(cx);
-    JS_ASSERT(!hasImacropc());
     JS_ASSERT(!hasHookData());
     JS_ASSERT(annotation() == NULL);
     JS_ASSERT(!hasCallObj());
 
     SetValueRangeToUndefined(slots(), script->nfixed);
 }
 
 inline void
@@ -633,22 +632,18 @@ ContextStack::currentScript(jsbytecode *
         return script;
     }
 #endif
 
     JSScript *script = fp->script();
     if (script->compartment() != cx_->compartment)
         return NULL;
 
-    if (ppc) {
-        if (fp->hasImacropc())
-            *ppc = fp->imacropc();
-        else
-            *ppc = fp->pcQuadratic(*this);
-    }
+    if (ppc)
+        *ppc = fp->pcQuadratic(*this);
     return script;
 }
 
 inline JSObject *
 ContextStack::currentScriptedScopeChain() const
 {
     return &fp()->scopeChain();
 }
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -1042,34 +1042,33 @@ StackIter::settleOnNewState()
              * a dynamic number of arguments have been pushed onto the stack
              * (see SplatApplyArgs), there is no efficient way to know how to
              * find the callee. Thus, calls to apply are lost completely.
              */
             JSOp op = js_GetOpcode(cx_, fp_->script(), pc_);
             if (op == JSOP_CALL || op == JSOP_FUNCALL) {
                 uintN argc = GET_ARGC(pc_);
                 DebugOnly<uintN> spoff = sp_ - fp_->base();
-                JS_ASSERT_IF(cx_->stackIterAssertionEnabled && !fp_->hasImacropc(),
+                JS_ASSERT_IF(cx_->stackIterAssertionEnabled,
                              spoff == js_ReconstructStackDepth(cx_, fp_->script(), pc_));
                 Value *vp = sp_ - (2 + argc);
 
                 CrashIfInvalidSlot(fp_, vp);
                 if (IsNativeFunction(*vp)) {
                     state_ = IMPLICIT_NATIVE;
                     args_ = CallArgsFromVp(argc, vp);
                     return;
                 }
             }
 
             state_ = SCRIPTED;
             DebugOnly<JSScript *> script = fp_->script();
             JS_ASSERT_IF(op != JSOP_FUNAPPLY,
                          sp_ >= fp_->base() && sp_ <= fp_->slots() + script->nslots);
-            JS_ASSERT_IF(!fp_->hasImacropc(),
-                         pc_ >= script->code && pc_ < script->code + script->length);
+            JS_ASSERT(pc_ >= script->code && pc_ < script->code + script->length);
             return;
         }
 
         /*
          * A CallArgsList element is pushed for any call to Invoke, regardless
          * of whether the callee is a scripted function or even a callable
          * object. Thus, it is necessary to filter calleev for natives.
          *
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -333,28 +333,27 @@ class StackFrame
         FINISHED_IN_INTERP =      0x200,  /* set if frame finished in Interpret() */
 
         /* Concerning function arguments */
         OVERRIDE_ARGS      =      0x400,  /* overridden arguments local variable */
         OVERFLOW_ARGS      =      0x800,  /* numActualArgs > numFormalArgs */
         UNDERFLOW_ARGS     =     0x1000,  /* numActualArgs < numFormalArgs */
 
         /* Lazy frame initialization */
-        HAS_IMACRO_PC      =     0x2000,  /* frame has imacpc value available */
-        HAS_CALL_OBJ       =     0x4000,  /* frame has a callobj reachable from scopeChain_ */
-        HAS_ARGS_OBJ       =     0x8000,  /* frame has an argsobj in StackFrame::args */
-        HAS_HOOK_DATA      =    0x10000,  /* frame has hookData_ set */
-        HAS_ANNOTATION     =    0x20000,  /* frame has annotation_ set */
-        HAS_RVAL           =    0x40000,  /* frame has rval_ set */
-        HAS_SCOPECHAIN     =    0x80000,  /* frame has scopeChain_ set */
-        HAS_PREVPC         =   0x100000,  /* frame has prevpc_ and prevInline_ set */
+        HAS_CALL_OBJ       =     0x2000,  /* frame has a callobj reachable from scopeChain_ */
+        HAS_ARGS_OBJ       =     0x4000,  /* frame has an argsobj in StackFrame::args */
+        HAS_HOOK_DATA      =     0x8000,  /* frame has hookData_ set */
+        HAS_ANNOTATION     =    0x10000,  /* frame has annotation_ set */
+        HAS_RVAL           =    0x20000,  /* frame has rval_ set */
+        HAS_SCOPECHAIN     =    0x40000,  /* frame has scopeChain_ set */
+        HAS_PREVPC         =    0x80000,  /* frame has prevpc_ and prevInline_ set */
 
         /* Method JIT state */
-        DOWN_FRAMES_EXPANDED = 0x200000,  /* inlining in down frames has been expanded */
-        LOWERED_CALL_APPLY   = 0x400000   /* Pushed by a lowered call/apply */
+        DOWN_FRAMES_EXPANDED = 0x100000,  /* inlining in down frames has been expanded */
+        LOWERED_CALL_APPLY   = 0x200000   /* Pushed by a lowered call/apply */
     };
 
   private:
     mutable uint32      flags_;         /* bits described by Flags */
     union {                             /* describes what code is executing in a */
         JSScript        *script;        /*   global frame */
         JSFunction      *fun;           /*   function frame, pre GetScopeChain */
     } exec;
@@ -366,17 +365,16 @@ class StackFrame
     mutable JSObject    *scopeChain_;   /* current scope chain */
     StackFrame          *prev_;         /* previous cx->regs->fp */
     void                *ncode_;        /* return address for method JIT */
 
     /* Lazily initialized */
     Value               rval_;          /* return value of the frame */
     jsbytecode          *prevpc_;       /* pc of previous frame*/
     JSInlinedSite       *prevInline_;   /* inlined site in previous frame */
-    jsbytecode          *imacropc_;     /* pc of macro caller */
     void                *hookData_;     /* closure returned by call hook */
     void                *annotation_;   /* perhaps remove with bug 546848 */
     JSRejoinState       rejoin_;        /* If rejoining into the interpreter
                                          * from JIT code, state at rejoin. */
 
     static void staticAsserts() {
         JS_STATIC_ASSERT(offsetof(StackFrame, rval_) % sizeof(Value) == 0);
         JS_STATIC_ASSERT(sizeof(StackFrame) % sizeof(Value) == 0);
@@ -891,48 +889,16 @@ class StackFrame
      * compartment when the frame was pushed.
      */
 
     JSCompartment *compartment() const {
         JS_ASSERT_IF(isScriptFrame(), scopeChain().compartment() == script()->compartment());
         return scopeChain().compartment();
     }
 
-    /*
-     * Imacropc
-     *
-     * A frame's IMacro pc is the bytecode address when an imacro started
-     * executing (guaranteed non-null). An imacro does not push a frame, so
-     * when the imacro finishes, the frame's IMacro pc becomes the current pc.
-     */
-
-    bool hasImacropc() const {
-        return flags_ & HAS_IMACRO_PC;
-    }
-
-    jsbytecode *imacropc() const {
-        JS_ASSERT(hasImacropc());
-        return imacropc_;
-    }
-
-    jsbytecode *maybeImacropc() const {
-        return hasImacropc() ? imacropc() : NULL;
-    }
-
-    void clearImacropc() {
-        flags_ &= ~HAS_IMACRO_PC;
-    }
-
-    void setImacropc(jsbytecode *pc) {
-        JS_ASSERT(pc);
-        JS_ASSERT(!(flags_ & HAS_IMACRO_PC));
-        imacropc_ = pc;
-        flags_ |= HAS_IMACRO_PC;
-    }
-
     /* Annotation (will be removed after bug 546848) */
 
     void* annotation() const {
         return (flags_ & HAS_ANNOTATION) ? annotation_ : NULL;
     }
 
     void setAnnotation(void *annot) {
         flags_ |= HAS_ANNOTATION;
--- a/js/src/vm/StackSpace.h
+++ b/js/src/vm/StackSpace.h
@@ -50,17 +50,17 @@ class FrameGuard;
 class DummyFrameGuard;
 class ExecuteFrameGuard;
 class GeneratorFrameGuard;
 
 /* Flags specified for a frame as it is constructed. */
 enum InitialFrameFlags {
     INITIAL_NONE           =          0,
     INITIAL_CONSTRUCT      =       0x80, /* == StackFrame::CONSTRUCTING, asserted in Stack.h */
-    INITIAL_LOWERED        =   0x400000  /* == StackFrame::LOWERED_CALL_APPLY, asserted in Stack.h */
+    INITIAL_LOWERED        =   0x200000  /* == StackFrame::LOWERED_CALL_APPLY, asserted in Stack.h */
 };
 
 enum ExecuteType {
     EXECUTE_GLOBAL         =        0x1, /* == StackFrame::GLOBAL */
     EXECUTE_DIRECT_EVAL    =        0x8, /* == StackFrame::EVAL */
     EXECUTE_INDIRECT_EVAL  =        0x9, /* == StackFrame::GLOBAL | EVAL */
     EXECUTE_DEBUG          =       0x18  /* == StackFrame::EVAL | DEBUGGER */
 };