Bug 716068 - de-OptimizeSpanDeps (r=waldo)
authorLuke Wagner <luke@mozilla.com>
Mon, 09 Jan 2012 11:05:06 -0800
changeset 85283 addfdfd36160b333192046e467a05bf5c74fd961
parent 85282 467e926f8a1983b7104bc4dd6f1414db42cfc563
child 85284 4ece35f727c04b97aae58dd49c6275cbf1e7b16e
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs716068
milestone12.0a1
Bug 716068 - de-OptimizeSpanDeps (r=waldo)
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/BytecodeEmitter.h
js/src/jit-test/tests/jaeger/bug563000/trap-self-from-trap.js
js/src/jsanalyze.cpp
js/src/jsanalyze.h
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsopcode.cpp
js/src/jsopcode.h
js/src/jsopcode.tbl
js/src/methodjit/Compiler.cpp
js/src/methodjit/Compiler.h
js/src/methodjit/FastOps.cpp
js/src/methodjit/InvokeHelpers.cpp
js/src/methodjit/LoopState.cpp
js/src/methodjit/StubCalls.cpp
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -105,18 +105,16 @@ TreeContext::trace(JSTracer *trc)
     bindings.trace(trc);
 }
 
 BytecodeEmitter::BytecodeEmitter(Parser *parser, uintN lineno)
   : TreeContext(parser),
     atomIndices(parser->context),
     stackDepth(0), maxStackDepth(0),
     ntrynotes(0), lastTryNode(NULL),
-    spanDeps(NULL), jumpTargets(NULL), jtFreeList(NULL),
-    numSpanDeps(0), numJumpTargets(0), spanDepTodo(0),
     arrayCompDepth(0),
     emitLevel(0),
     constMap(parser->context),
     constList(parser->context),
     upvarIndices(parser->context),
     upvarMap(parser->context),
     globalScope(NULL),
     globalUses(parser->context),
@@ -142,20 +140,16 @@ BytecodeEmitter::init(JSContext *cx, Tre
 BytecodeEmitter::~BytecodeEmitter()
 {
     JSContext *cx = parser->context;
 
     cx->free_(prolog.base);
     cx->free_(prolog.notes);
     cx->free_(main.base);
     cx->free_(main.notes);
-
-    /* NB: non-null only after OOM. */
-    if (spanDeps)
-        cx->free_(spanDeps);
 }
 
 static ptrdiff_t
 EmitCheck(JSContext *cx, BytecodeEmitter *bce, ptrdiff_t delta)
 {
     jsbytecode *base = bce->base();
     jsbytecode *newbase;
     jsbytecode *next = bce->next();
@@ -311,16 +305,31 @@ frontend::EmitN(JSContext *cx, BytecodeE
          * operand yet to be stored in the extra bytes after op.
          */
         if (js_CodeSpec[op].nuses >= 0)
             UpdateDepth(cx, bce, offset);
     }
     return offset;
 }
 
+static ptrdiff_t
+EmitJump(JSContext *cx, BytecodeEmitter *bce, JSOp op, ptrdiff_t off)
+{
+    ptrdiff_t offset = EmitCheck(cx, bce, 5);
+
+    if (offset >= 0) {
+        jsbytecode *next = bce->next();
+        next[0] = (jsbytecode)op;
+        SET_JUMP_OFFSET(next, off);
+        bce->current->next = next + 5;
+        UpdateDepth(cx, bce, offset);
+    }
+    return offset;
+}
+
 /* XXX too many "... statement" L10N gaffes below -- fix via js.msg! */
 const char js_with_statement_str[] = "with statement";
 const char js_finally_block_str[]  = "finally block";
 const char js_script_str[]         = "script";
 
 static const char *statementName[] = {
     "label statement",       /* LABEL */
     "if statement",          /* IF */
@@ -351,908 +360,16 @@ StatementName(BytecodeEmitter *bce)
 
 static void
 ReportStatementTooLarge(JSContext *cx, BytecodeEmitter *bce)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NEED_DIET,
                          StatementName(bce));
 }
 
-/**
-  Span-dependent instructions in JS bytecode consist of the jump (JOF_JUMP)
-  and switch (JOF_LOOKUPSWITCH, JOF_TABLESWITCH) format opcodes, subdivided
-  into unconditional (gotos and gosubs), and conditional jumps or branches
-  (which pop a value, test it, and jump depending on its value).  Most jumps
-  have just one immediate operand, a signed offset from the jump opcode's pc
-  to the target bytecode.  The lookup and table switch opcodes may contain
-  many jump offsets.
-
-  Mozilla bug #80981 (http://bugzilla.mozilla.org/show_bug.cgi?id=80981) was
-  fixed by adding extended "X" counterparts to the opcodes/formats (NB: X is
-  suffixed to prefer JSOP_ORX thereby avoiding a JSOP_XOR name collision for
-  the extended form of the JSOP_OR branch opcode).  The unextended or short
-  formats have 16-bit signed immediate offset operands, the extended or long
-  formats have 32-bit signed immediates.  The span-dependency problem consists
-  of selecting as few long instructions as possible, or about as few -- since
-  jumps can span other jumps, extending one jump may cause another to need to
-  be extended.
-
-  Most JS scripts are short, so need no extended jumps.  We optimize for this
-  case by generating short jumps until we know a long jump is needed.  After
-  that point, we keep generating short jumps, but each jump's 16-bit immediate
-  offset operand is actually an unsigned index into bce->spanDeps, an array of
-  js::SpanDep structs.  Each struct tells the top offset in the script of the
-  opcode, the "before" offset of the jump (which will be the same as top for
-  simplex jumps, but which will index further into the bytecode array for a
-  non-initial jump offset in a lookup or table switch), the after "offset"
-  adjusted during span-dependent instruction selection (initially the same
-  value as the "before" offset), and the jump target (more below).
-
-  Since we generate bce->spanDeps lazily, from within SetJumpOffset, we must
-  ensure that all bytecode generated so far can be inspected to discover where
-  the jump offset immediate operands lie within bce->main. But the bonus is
-  that we generate span-dependency records sorted by their offsets, so we can
-  binary-search when trying to find a SpanDep for a given bytecode offset, or
-  the nearest SpanDep at or above a given pc.
-
-  To avoid limiting scripts to 64K jumps, if the bce->spanDeps index overflows
-  65534, we store SPANDEP_INDEX_HUGE in the jump's immediate operand.  This
-  tells us that we need to binary-search for the bce->spanDeps entry by the
-  jump opcode's bytecode offset (sd->before).
-
-  Jump targets need to be maintained in a data structure that lets us look
-  up an already-known target by its address (jumps may have a common target),
-  and that also lets us update the addresses (script-relative, a.k.a. absolute
-  offsets) of targets that come after a jump target (for when a jump below
-  that target needs to be extended).  We use an AVL tree, implemented using
-  recursion, but with some tricky optimizations to its height-balancing code
-  (see http://www.cmcrossroads.com/bradapp/ftp/src/libs/C++/AvlTrees.html).
-
-  A final wrinkle: backpatch chains are linked by jump-to-jump offsets with
-  positive sign, even though they link "backward" (i.e., toward lower bytecode
-  address).  We don't want to waste space and search time in the AVL tree for
-  such temporary backpatch deltas, so we use a single-bit wildcard scheme to
-  tag true JumpTarget pointers and encode untagged, signed (positive) deltas in
-  SpanDep::target pointers, depending on whether the SpanDep has a known
-  target, or is still awaiting backpatching.
-
-  Note that backpatch chains would present a problem for BuildSpanDepTable,
-  which inspects bytecode to build bce->spanDeps on demand, when the first
-  short jump offset overflows.  To solve this temporary problem, we emit a
-  proxy bytecode (JSOP_BACKPATCH; JSOP_BACKPATCH_POP for branch ops) whose
-  nuses/ndefs counts help keep the stack balanced, but whose opcode format
-  distinguishes its backpatch delta immediate operand from a normal jump
-  offset.
- */
-static int
-BalanceJumpTargets(JumpTarget **jtp)
-{
-    JumpTarget *jt = *jtp;
-    JS_ASSERT(jt->balance != 0);
-
-    int dir;
-    JSBool doubleRotate;
-    if (jt->balance < -1) {
-        dir = JT_RIGHT;
-        doubleRotate = (jt->kids[JT_LEFT]->balance > 0);
-    } else if (jt->balance > 1) {
-        dir = JT_LEFT;
-        doubleRotate = (jt->kids[JT_RIGHT]->balance < 0);
-    } else {
-        return 0;
-    }
-
-    int otherDir = JT_OTHER_DIR(dir);
-    JumpTarget *root;
-    int heightChanged;
-    if (doubleRotate) {
-        JumpTarget *jt2 = jt->kids[otherDir];
-        *jtp = root = jt2->kids[dir];
-
-        jt->kids[otherDir] = root->kids[dir];
-        root->kids[dir] = jt;
-
-        jt2->kids[dir] = root->kids[otherDir];
-        root->kids[otherDir] = jt2;
-
-        heightChanged = 1;
-        root->kids[JT_LEFT]->balance = -JS_MAX(root->balance, 0);
-        root->kids[JT_RIGHT]->balance = -JS_MIN(root->balance, 0);
-        root->balance = 0;
-    } else {
-        *jtp = root = jt->kids[otherDir];
-        jt->kids[otherDir] = root->kids[dir];
-        root->kids[dir] = jt;
-
-        heightChanged = (root->balance != 0);
-        jt->balance = -((dir == JT_LEFT) ? --root->balance : ++root->balance);
-    }
-
-    return heightChanged;
-}
-
-struct AddJumpTargetArgs {
-    JSContext           *cx;
-    BytecodeEmitter     *bce;
-    ptrdiff_t           offset;
-    JumpTarget          *node;
-};
-
-static int
-AddJumpTarget(AddJumpTargetArgs *args, JumpTarget **jtp)
-{
-    JumpTarget *jt = *jtp;
-    if (!jt) {
-        BytecodeEmitter *bce = args->bce;
-
-        jt = bce->jtFreeList;
-        if (jt) {
-            bce->jtFreeList = jt->kids[JT_LEFT];
-        } else {
-            jt = args->cx->tempLifoAlloc().new_<JumpTarget>();
-            if (!jt) {
-                js_ReportOutOfMemory(args->cx);
-                return 0;
-            }
-        }
-        jt->offset = args->offset;
-        jt->balance = 0;
-        jt->kids[JT_LEFT] = jt->kids[JT_RIGHT] = NULL;
-        bce->numJumpTargets++;
-        args->node = jt;
-        *jtp = jt;
-        return 1;
-    }
-
-    if (jt->offset == args->offset) {
-        args->node = jt;
-        return 0;
-    }
-
-    int balanceDelta;
-    if (args->offset < jt->offset)
-        balanceDelta = -AddJumpTarget(args, &jt->kids[JT_LEFT]);
-    else
-        balanceDelta = AddJumpTarget(args, &jt->kids[JT_RIGHT]);
-    if (!args->node)
-        return 0;
-
-    jt->balance += balanceDelta;
-    return (balanceDelta && jt->balance)
-           ? 1 - BalanceJumpTargets(jtp)
-           : 0;
-}
-
-#ifdef DEBUG_brendan
-static int
-AVLCheck(JumpTarget *jt)
-{
-    int lh, rh;
-
-    if (!jt) return 0;
-    JS_ASSERT(-1 <= jt->balance && jt->balance <= 1);
-    lh = AVLCheck(jt->kids[JT_LEFT]);
-    rh = AVLCheck(jt->kids[JT_RIGHT]);
-    JS_ASSERT(jt->balance == rh - lh);
-    return 1 + JS_MAX(lh, rh);
-}
-#endif
-
-static JSBool
-SetSpanDepTarget(JSContext *cx, BytecodeEmitter *bce, SpanDep *sd, ptrdiff_t off)
-{
-    AddJumpTargetArgs args;
-
-    if (off < JUMPX_OFFSET_MIN || JUMPX_OFFSET_MAX < off) {
-        ReportStatementTooLarge(cx, bce);
-        return JS_FALSE;
-    }
-
-    args.cx = cx;
-    args.bce = bce;
-    args.offset = sd->top + off;
-    args.node = NULL;
-    AddJumpTarget(&args, &bce->jumpTargets);
-    if (!args.node)
-        return JS_FALSE;
-
-#ifdef DEBUG_brendan
-    AVLCheck(bce->jumpTargets);
-#endif
-
-    SD_SET_TARGET(sd, args.node);
-    return JS_TRUE;
-}
-
-#define SPANDEPS_MIN            256
-#define SPANDEPS_SIZE(n)        ((n) * sizeof(js::SpanDep))
-#define SPANDEPS_SIZE_MIN       SPANDEPS_SIZE(SPANDEPS_MIN)
-
-static JSBool
-AddSpanDep(JSContext *cx, BytecodeEmitter *bce, jsbytecode *pc, jsbytecode *pc2, ptrdiff_t off)
-{
-    uintN index = bce->numSpanDeps;
-    if (index + 1 == 0) {
-        ReportStatementTooLarge(cx, bce);
-        return JS_FALSE;
-    }
-
-    SpanDep *sdbase;
-    if ((index & (index - 1)) == 0 &&
-        (!(sdbase = bce->spanDeps) || index >= SPANDEPS_MIN))
-    {
-        size_t size = sdbase ? SPANDEPS_SIZE(index) : SPANDEPS_SIZE_MIN / 2;
-        sdbase = (SpanDep *) cx->realloc_(sdbase, size + size);
-        if (!sdbase)
-            return JS_FALSE;
-        bce->spanDeps = sdbase;
-    }
-
-    bce->numSpanDeps = index + 1;
-    SpanDep *sd = bce->spanDeps + index;
-    sd->top = pc - bce->base();
-    sd->offset = sd->before = pc2 - bce->base();
-
-    if (js_CodeSpec[*pc].format & JOF_BACKPATCH) {
-        /* Jump offset will be backpatched if off is a non-zero "bpdelta". */
-        if (off != 0) {
-            JS_ASSERT(off >= 1 + JUMP_OFFSET_LEN);
-            if (off > BPDELTA_MAX) {
-                ReportStatementTooLarge(cx, bce);
-                return JS_FALSE;
-            }
-        }
-        SD_SET_BPDELTA(sd, off);
-    } else if (off == 0) {
-        /* Jump offset will be patched directly, without backpatch chaining. */
-        SD_SET_TARGET(sd, 0);
-    } else {
-        /* The jump offset in off is non-zero, therefore it's already known. */
-        if (!SetSpanDepTarget(cx, bce, sd, off))
-            return JS_FALSE;
-    }
-
-    if (index > SPANDEP_INDEX_MAX)
-        index = SPANDEP_INDEX_HUGE;
-    SET_SPANDEP_INDEX(pc2, index);
-    return JS_TRUE;
-}
-
-static jsbytecode *
-AddSwitchSpanDeps(JSContext *cx, BytecodeEmitter *bce, jsbytecode *pc)
-{
-    JSOp op;
-    jsbytecode *pc2;
-    ptrdiff_t off;
-    jsint low, high;
-    uintN njumps, indexlen;
-
-    op = (JSOp) *pc;
-    JS_ASSERT(op == JSOP_TABLESWITCH || op == JSOP_LOOKUPSWITCH);
-    pc2 = pc;
-    off = GET_JUMP_OFFSET(pc2);
-    if (!AddSpanDep(cx, bce, pc, pc2, off))
-        return NULL;
-    pc2 += JUMP_OFFSET_LEN;
-    if (op == JSOP_TABLESWITCH) {
-        low = GET_JUMP_OFFSET(pc2);
-        pc2 += JUMP_OFFSET_LEN;
-        high = GET_JUMP_OFFSET(pc2);
-        pc2 += JUMP_OFFSET_LEN;
-        njumps = (uintN) (high - low + 1);
-        indexlen = 0;
-    } else {
-        njumps = GET_UINT16(pc2);
-        pc2 += UINT16_LEN;
-        indexlen = INDEX_LEN;
-    }
-    while (njumps) {
-        --njumps;
-        pc2 += indexlen;
-        off = GET_JUMP_OFFSET(pc2);
-        if (!AddSpanDep(cx, bce, pc, pc2, off))
-            return NULL;
-        pc2 += JUMP_OFFSET_LEN;
-    }
-    return 1 + pc2;
-}
-
-static JSBool
-BuildSpanDepTable(JSContext *cx, BytecodeEmitter *bce)
-{
-    jsbytecode *pc, *end;
-    JSOp op;
-    const JSCodeSpec *cs;
-    ptrdiff_t off;
-
-    pc = bce->base() + bce->spanDepTodo;
-    end = bce->next();
-    while (pc != end) {
-        JS_ASSERT(pc < end);
-        op = (JSOp)*pc;
-        cs = &js_CodeSpec[op];
-
-        switch (JOF_TYPE(cs->format)) {
-          case JOF_TABLESWITCH:
-          case JOF_LOOKUPSWITCH:
-            pc = AddSwitchSpanDeps(cx, bce, pc);
-            if (!pc)
-                return JS_FALSE;
-            break;
-
-          case JOF_JUMP:
-            off = GET_JUMP_OFFSET(pc);
-            if (!AddSpanDep(cx, bce, pc, pc, off))
-                return JS_FALSE;
-            /* FALL THROUGH */
-          default:
-            pc += cs->length;
-            break;
-        }
-    }
-
-    return JS_TRUE;
-}
-
-static SpanDep *
-GetSpanDep(BytecodeEmitter *bce, jsbytecode *pc)
-{
-    uintN index;
-    ptrdiff_t offset;
-    int lo, hi, mid;
-    SpanDep *sd;
-
-    index = GET_SPANDEP_INDEX(pc);
-    if (index != SPANDEP_INDEX_HUGE)
-        return bce->spanDeps + index;
-
-    offset = pc - bce->base();
-    lo = 0;
-    hi = bce->numSpanDeps - 1;
-    while (lo <= hi) {
-        mid = (lo + hi) / 2;
-        sd = bce->spanDeps + mid;
-        if (sd->before == offset)
-            return sd;
-        if (sd->before < offset)
-            lo = mid + 1;
-        else
-            hi = mid - 1;
-    }
-
-    JS_ASSERT(0);
-    return NULL;
-}
-
-static JSBool
-SetBackPatchDelta(JSContext *cx, BytecodeEmitter *bce, jsbytecode *pc, ptrdiff_t delta)
-{
-    SpanDep *sd;
-
-    JS_ASSERT(delta >= 1 + JUMP_OFFSET_LEN);
-    if (!bce->spanDeps && delta < JUMP_OFFSET_MAX) {
-        SET_JUMP_OFFSET(pc, delta);
-        return JS_TRUE;
-    }
-
-    if (delta > BPDELTA_MAX) {
-        ReportStatementTooLarge(cx, bce);
-        return JS_FALSE;
-    }
-
-    if (!bce->spanDeps && !BuildSpanDepTable(cx, bce))
-        return JS_FALSE;
-
-    sd = GetSpanDep(bce, pc);
-    JS_ASSERT(SD_GET_BPDELTA(sd) == 0);
-    SD_SET_BPDELTA(sd, delta);
-    return JS_TRUE;
-}
-
-static void
-UpdateJumpTargets(JumpTarget *jt, ptrdiff_t pivot, ptrdiff_t delta)
-{
-    if (jt->offset > pivot) {
-        jt->offset += delta;
-        if (jt->kids[JT_LEFT])
-            UpdateJumpTargets(jt->kids[JT_LEFT], pivot, delta);
-    }
-    if (jt->kids[JT_RIGHT])
-        UpdateJumpTargets(jt->kids[JT_RIGHT], pivot, delta);
-}
-
-static SpanDep *
-FindNearestSpanDep(BytecodeEmitter *bce, ptrdiff_t offset, int lo, SpanDep *guard)
-{
-    int num = bce->numSpanDeps;
-    JS_ASSERT(num > 0);
-    int hi = num - 1;
-    SpanDep *sdbase = bce->spanDeps;
-    while (lo <= hi) {
-        int mid = (lo + hi) / 2;
-        SpanDep *sd = sdbase + mid;
-        if (sd->before == offset)
-            return sd;
-        if (sd->before < offset)
-            lo = mid + 1;
-        else
-            hi = mid - 1;
-    }
-    if (lo == num)
-        return guard;
-    SpanDep *sd = sdbase + lo;
-    JS_ASSERT(sd->before >= offset && (lo == 0 || sd[-1].before < offset));
-    return sd;
-}
-
-static void
-FreeJumpTargets(BytecodeEmitter *bce, JumpTarget *jt)
-{
-    if (jt->kids[JT_LEFT])
-        FreeJumpTargets(bce, jt->kids[JT_LEFT]);
-    if (jt->kids[JT_RIGHT])
-        FreeJumpTargets(bce, jt->kids[JT_RIGHT]);
-    jt->kids[JT_LEFT] = bce->jtFreeList;
-    bce->jtFreeList = jt;
-}
-
-static JSBool
-OptimizeSpanDeps(JSContext *cx, BytecodeEmitter *bce)
-{
-    jsbytecode *pc, *oldpc, *base, *limit, *next;
-    SpanDep *sd, *sd2, *sdbase, *sdlimit, *sdtop, guard;
-    ptrdiff_t offset, growth, delta, top, pivot, span, length, target;
-    JSBool done;
-    JSOp op;
-    uint32_t type;
-    jssrcnote *sn, *snlimit;
-    JSSrcNoteSpec *spec;
-    uintN i, n, noteIndex;
-    TryNode *tryNode;
-    DebugOnly<int> passes = 0;
-
-    base = bce->base();
-    sdbase = bce->spanDeps;
-    sdlimit = sdbase + bce->numSpanDeps;
-    offset = bce->offset();
-    growth = 0;
-
-    do {
-        done = JS_TRUE;
-        delta = 0;
-        top = pivot = -1;
-        sdtop = NULL;
-        pc = NULL;
-        op = JSOP_NOP;
-        type = 0;
-#ifdef DEBUG_brendan
-        passes++;
-#endif
-
-        for (sd = sdbase; sd < sdlimit; sd++) {
-            JS_ASSERT(JT_HAS_TAG(sd->target));
-            sd->offset += delta;
-
-            if (sd->top != top) {
-                sdtop = sd;
-                top = sd->top;
-                JS_ASSERT(top == sd->before);
-                pivot = sd->offset;
-                pc = base + top;
-                op = (JSOp) *pc;
-                type = JOF_OPTYPE(op);
-                if (JOF_TYPE_IS_EXTENDED_JUMP(type)) {
-                    /*
-                     * We already extended all the jump offset operands for
-                     * the opcode at sd->top.  Jumps and branches have only
-                     * one jump offset operand, but switches have many, all
-                     * of which are adjacent in bce->spanDeps.
-                     */
-                    continue;
-                }
-
-                JS_ASSERT(type == JOF_JUMP ||
-                          type == JOF_TABLESWITCH ||
-                          type == JOF_LOOKUPSWITCH);
-            }
-
-            if (!JOF_TYPE_IS_EXTENDED_JUMP(type)) {
-                span = SD_SPAN(sd, pivot);
-                if (span < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < span) {
-                    ptrdiff_t deltaFromTop = 0;
-
-                    done = JS_FALSE;
-
-                    switch (op) {
-                      case JSOP_GOTO:         op = JSOP_GOTOX; break;
-                      case JSOP_IFEQ:         op = JSOP_IFEQX; break;
-                      case JSOP_IFNE:         op = JSOP_IFNEX; break;
-                      case JSOP_OR:           op = JSOP_ORX; break;
-                      case JSOP_AND:          op = JSOP_ANDX; break;
-                      case JSOP_GOSUB:        op = JSOP_GOSUBX; break;
-                      case JSOP_CASE:         op = JSOP_CASEX; break;
-                      case JSOP_DEFAULT:      op = JSOP_DEFAULTX; break;
-                      case JSOP_TABLESWITCH:  op = JSOP_TABLESWITCHX; break;
-                      case JSOP_LOOKUPSWITCH: op = JSOP_LOOKUPSWITCHX; break;
-                      case JSOP_LABEL:        op = JSOP_LABELX; break;
-                      default:
-                        ReportStatementTooLarge(cx, bce);
-                        return JS_FALSE;
-                    }
-                    *pc = (jsbytecode) op;
-
-                    for (sd2 = sdtop; sd2 < sdlimit && sd2->top == top; sd2++) {
-                        if (sd2 <= sd) {
-                            /*
-                             * sd2->offset already includes delta as it stood
-                             * before we entered this loop, but it must also
-                             * include the delta relative to top due to all the
-                             * extended jump offset immediates for the opcode
-                             * starting at top, which we extend in this loop.
-                             *
-                             * If there is only one extended jump offset, then
-                             * sd2->offset won't change and this for loop will
-                             * iterate once only.
-                             */
-                            sd2->offset += deltaFromTop;
-                            deltaFromTop += JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN;
-                        } else {
-                            /*
-                             * sd2 comes after sd, and won't be revisited by
-                             * the outer for loop, so we have to increase its
-                             * offset by delta, not merely by deltaFromTop.
-                             */
-                            sd2->offset += delta;
-                        }
-
-                        delta += JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN;
-                        UpdateJumpTargets(bce->jumpTargets, sd2->offset,
-                                          JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN);
-                    }
-                    sd = sd2 - 1;
-                }
-            }
-        }
-
-        growth += delta;
-    } while (!done);
-
-    if (growth) {
-#ifdef DEBUG_brendan
-        TokenStream *ts = &bce->parser->tokenStream;
-
-        printf("%s:%u: %u/%u jumps extended in %d passes (%d=%d+%d)\n",
-               ts->filename ? ts->filename : "stdin", bce->firstLine,
-               growth / (JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN), bce->numSpanDeps,
-               passes, offset + growth, offset, growth);
-#endif
-
-        /*
-         * Ensure that we have room for the extended jumps, but don't round up
-         * to a power of two -- we're done generating code, so we cut to fit.
-         */
-        limit = bce->limit();
-        length = offset + growth;
-        next = base + length;
-        if (next > limit) {
-            base = (jsbytecode *) cx->realloc_(base, BYTECODE_SIZE(length));
-            if (!base) {
-                js_ReportOutOfMemory(cx);
-                return JS_FALSE;
-            }
-            bce->current->base = base;
-            bce->current->limit = next = base + length;
-        }
-        bce->current->next = next;
-
-        /*
-         * Set up a fake span dependency record to guard the end of the code
-         * being generated.  This guard record is returned as a fencepost by
-         * FindNearestSpanDep if there is no real spandep at or above a given
-         * unextended code offset.
-         */
-        guard.top = -1;
-        guard.offset = offset + growth;
-        guard.before = offset;
-        guard.target = NULL;
-    }
-
-    /*
-     * Now work backwards through the span dependencies, copying chunks of
-     * bytecode between each extended jump toward the end of the grown code
-     * space, and restoring immediate offset operands for all jump bytecodes.
-     * The first chunk of bytecodes, starting at base and ending at the first
-     * extended jump offset (NB: this chunk includes the operation bytecode
-     * just before that immediate jump offset), doesn't need to be copied.
-     */
-    JS_ASSERT(sd == sdlimit);
-    top = -1;
-    while (--sd >= sdbase) {
-        if (sd->top != top) {
-            top = sd->top;
-            op = (JSOp) base[top];
-            type = JOF_OPTYPE(op);
-
-            for (sd2 = sd - 1; sd2 >= sdbase && sd2->top == top; sd2--)
-                continue;
-            sd2++;
-            pivot = sd2->offset;
-            JS_ASSERT(top == sd2->before);
-        }
-
-        oldpc = base + sd->before;
-        span = SD_SPAN(sd, pivot);
-
-        /*
-         * If this jump didn't need to be extended, restore its span immediate
-         * offset operand now, overwriting the index of sd within bce->spanDeps
-         * that was stored temporarily after *pc when BuildSpanDepTable ran.
-         *
-         * Note that span might fit in 16 bits even for an extended jump op,
-         * if the op has multiple span operands, not all of which overflowed
-         * (e.g. JSOP_LOOKUPSWITCH or JSOP_TABLESWITCH where some cases are in
-         * range for a short jump, but others are not).
-         */
-        if (!JOF_TYPE_IS_EXTENDED_JUMP(type)) {
-            JS_ASSERT(JUMP_OFFSET_MIN <= span && span <= JUMP_OFFSET_MAX);
-            SET_JUMP_OFFSET(oldpc, span);
-            continue;
-        }
-
-        /*
-         * Set up parameters needed to copy the next run of bytecode starting
-         * at offset (which is a cursor into the unextended, original bytecode
-         * vector), down to sd->before (a cursor of the same scale as offset,
-         * it's the index of the original jump pc).  Reuse delta to count the
-         * nominal number of bytes to copy.
-         */
-        pc = base + sd->offset;
-        delta = offset - sd->before;
-        JS_ASSERT(delta >= 1 + JUMP_OFFSET_LEN);
-
-        /*
-         * Don't bother copying the jump offset we're about to reset, but do
-         * copy the bytecode at oldpc (which comes just before its immediate
-         * jump offset operand), on the next iteration through the loop, by
-         * including it in offset's new value.
-         */
-        offset = sd->before + 1;
-        size_t size = BYTECODE_SIZE(delta - (1 + JUMP_OFFSET_LEN));
-        if (size) {
-            memmove(pc + 1 + JUMPX_OFFSET_LEN,
-                    oldpc + 1 + JUMP_OFFSET_LEN,
-                    size);
-        }
-
-        SET_JUMPX_OFFSET(pc, span);
-    }
-
-    if (growth) {
-        /*
-         * Fix source note deltas.  Don't hardwire the delta fixup adjustment,
-         * even though currently it must be JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN
-         * at each sd that moved.  The future may bring different offset sizes
-         * for span-dependent instruction operands.  However, we fix only main
-         * notes here, not prolog notes -- we know that prolog opcodes are not
-         * span-dependent, and aren't likely ever to be.
-         */
-        offset = growth = 0;
-        sd = sdbase;
-        for (sn = bce->main.notes, snlimit = sn + bce->main.noteCount;
-             sn < snlimit;
-             sn = SN_NEXT(sn)) {
-            /*
-             * Recall that the offset of a given note includes its delta, and
-             * tells the offset of the annotated bytecode from the main entry
-             * point of the script.
-             */
-            offset += SN_DELTA(sn);
-            while (sd < sdlimit && sd->before < offset) {
-                /*
-                 * To compute the delta to add to sn, we need to look at the
-                 * spandep after sd, whose offset - (before + growth) tells by
-                 * how many bytes sd's instruction grew.
-                 */
-                sd2 = sd + 1;
-                if (sd2 == sdlimit)
-                    sd2 = &guard;
-                delta = sd2->offset - (sd2->before + growth);
-                if (delta > 0) {
-                    JS_ASSERT(delta == JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN);
-                    sn = AddToSrcNoteDelta(cx, bce, sn, delta);
-                    if (!sn)
-                        return JS_FALSE;
-                    snlimit = bce->main.notes + bce->main.noteCount;
-                    growth += delta;
-                }
-                sd++;
-            }
-
-            /*
-             * If sn has span-dependent offset operands, check whether each
-             * covers further span-dependencies, and increase those operands
-             * accordingly.  Some source notes measure offset not from the
-             * annotated pc, but from that pc plus some small bias.  NB: we
-             * assume that spec->offsetBias can't itself span span-dependent
-             * instructions!
-             */
-            spec = &js_SrcNoteSpec[SN_TYPE(sn)];
-            if (spec->isSpanDep) {
-                pivot = offset + spec->offsetBias;
-                n = spec->arity;
-                for (i = 0; i < n; i++) {
-                    span = js_GetSrcNoteOffset(sn, i);
-                    if (span == 0)
-                        continue;
-                    target = pivot + span * spec->isSpanDep;
-                    sd2 = FindNearestSpanDep(bce, target,
-                                             (target >= pivot)
-                                             ? sd - sdbase
-                                             : 0,
-                                             &guard);
-
-                    /*
-                     * Increase target by sd2's before-vs-after offset delta,
-                     * which is absolute (i.e., relative to start of script,
-                     * as is target).  Recompute the span by subtracting its
-                     * adjusted pivot from target.
-                     */
-                    target += sd2->offset - sd2->before;
-                    span = target - (pivot + growth);
-                    span *= spec->isSpanDep;
-                    noteIndex = sn - bce->main.notes;
-                    if (!SetSrcNoteOffset(cx, bce, noteIndex, i, span))
-                        return JS_FALSE;
-                    sn = bce->main.notes + noteIndex;
-                    snlimit = bce->main.notes + bce->main.noteCount;
-                }
-            }
-        }
-        bce->main.lastNoteOffset += growth;
-
-        /*
-         * Fix try/catch notes (O(numTryNotes * log2(numSpanDeps)), but it's
-         * not clear how we can beat that).
-         */
-        for (tryNode = bce->lastTryNode; tryNode; tryNode = tryNode->prev) {
-            /*
-             * First, look for the nearest span dependency at/above tn->start.
-             * There may not be any such spandep, in which case the guard will
-             * be returned.
-             */
-            offset = tryNode->note.start;
-            sd = FindNearestSpanDep(bce, offset, 0, &guard);
-            delta = sd->offset - sd->before;
-            tryNode->note.start = offset + delta;
-
-            /*
-             * Next, find the nearest spandep at/above tn->start + tn->length.
-             * Use its delta minus tn->start's delta to increase tn->length.
-             */
-            length = tryNode->note.length;
-            sd2 = FindNearestSpanDep(bce, offset + length, sd - sdbase, &guard);
-            if (sd2 != sd) {
-                tryNode->note.length =
-                    length + sd2->offset - sd2->before - delta;
-            }
-        }
-    }
-
-#ifdef DEBUG_brendan
-  {
-    uintN bigspans = 0;
-    top = -1;
-    for (sd = sdbase; sd < sdlimit; sd++) {
-        offset = sd->offset;
-
-        /* NB: sd->top cursors into the original, unextended bytecode vector. */
-        if (sd->top != top) {
-            JS_ASSERT(top == -1 ||
-                      !JOF_TYPE_IS_EXTENDED_JUMP(type) ||
-                      bigspans != 0);
-            bigspans = 0;
-            top = sd->top;
-            JS_ASSERT(top == sd->before);
-            op = (JSOp) base[offset];
-            type = JOF_OPTYPE(op);
-            JS_ASSERT(type == JOF_JUMP ||
-                      type == JOF_JUMPX ||
-                      type == JOF_TABLESWITCH ||
-                      type == JOF_TABLESWITCHX ||
-                      type == JOF_LOOKUPSWITCH ||
-                      type == JOF_LOOKUPSWITCHX);
-            pivot = offset;
-        }
-
-        pc = base + offset;
-        if (JOF_TYPE_IS_EXTENDED_JUMP(type)) {
-            span = GET_JUMPX_OFFSET(pc);
-            if (span < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < span) {
-                bigspans++;
-            } else {
-                JS_ASSERT(type == JOF_TABLESWITCHX ||
-                          type == JOF_LOOKUPSWITCHX);
-            }
-        } else {
-            span = GET_JUMP_OFFSET(pc);
-        }
-        JS_ASSERT(SD_SPAN(sd, pivot) == span);
-    }
-    JS_ASSERT(!JOF_TYPE_IS_EXTENDED_JUMP(type) || bigspans != 0);
-  }
-#endif
-
-    /*
-     * Reset so we optimize at most once -- bce may be used for further code
-     * generation of successive, independent, top-level statements.  No jump
-     * can span top-level statements, because JS lacks goto.
-     */
-    cx->free_(bce->spanDeps);
-    bce->spanDeps = NULL;
-    FreeJumpTargets(bce, bce->jumpTargets);
-    bce->jumpTargets = NULL;
-    bce->numSpanDeps = bce->numJumpTargets = 0;
-    bce->spanDepTodo = bce->offset();
-    return JS_TRUE;
-}
-
-static ptrdiff_t
-EmitJump(JSContext *cx, BytecodeEmitter *bce, JSOp op, ptrdiff_t off)
-{
-    JSBool extend;
-    ptrdiff_t jmp;
-    jsbytecode *pc;
-
-    extend = off < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < off;
-    if (extend && !bce->spanDeps && !BuildSpanDepTable(cx, bce))
-        return -1;
-
-    jmp = Emit3(cx, bce, op, JUMP_OFFSET_HI(off), JUMP_OFFSET_LO(off));
-    if (jmp >= 0 && (extend || bce->spanDeps)) {
-        pc = bce->code(jmp);
-        if (!AddSpanDep(cx, bce, pc, pc, off))
-            return -1;
-    }
-    return jmp;
-}
-
-static ptrdiff_t
-GetJumpOffset(BytecodeEmitter *bce, jsbytecode *pc)
-{
-    if (!bce->spanDeps)
-        return GET_JUMP_OFFSET(pc);
-
-    SpanDep *sd = GetSpanDep(bce, pc);
-    JumpTarget *jt = sd->target;
-    if (!JT_HAS_TAG(jt))
-        return JT_TO_BPDELTA(jt);
-
-    ptrdiff_t top = sd->top;
-    while (--sd >= bce->spanDeps && sd->top == top)
-        continue;
-    sd++;
-    return JT_CLR_TAG(jt)->offset - sd->offset;
-}
-
-JSBool
-frontend::SetJumpOffset(JSContext *cx, BytecodeEmitter *bce, jsbytecode *pc, ptrdiff_t off)
-{
-    if (!bce->spanDeps) {
-        if (JUMP_OFFSET_MIN <= off && off <= JUMP_OFFSET_MAX) {
-            SET_JUMP_OFFSET(pc, off);
-            return JS_TRUE;
-        }
-
-        if (!BuildSpanDepTable(cx, bce))
-            return JS_FALSE;
-    }
-
-    return SetSpanDepTarget(cx, bce, GetSpanDep(bce, pc), off);
-}
-
 bool
 TreeContext::inStatement(StmtType type)
 {
     for (StmtInfo *stmt = topStmt; stmt; stmt = stmt->down) {
         if (stmt->type == type)
             return true;
     }
     return false;
@@ -1621,25 +738,19 @@ static JSBool
 BackPatch(JSContext *cx, BytecodeEmitter *bce, ptrdiff_t last, jsbytecode *target, jsbytecode op)
 {
     jsbytecode *pc, *stop;
     ptrdiff_t delta, span;
 
     pc = bce->code(last);
     stop = bce->code(-1);
     while (pc != stop) {
-        delta = GetJumpOffset(bce, pc);
+        delta = GET_JUMP_OFFSET(pc);
         span = target - pc;
-        CHECK_AND_SET_JUMP_OFFSET(cx, bce, pc, span);
-
-        /*
-         * Set *pc after jump offset in case bpdelta didn't overflow, but span
-         * does (if so, CHECK_AND_SET_JUMP_OFFSET might call BuildSpanDepTable
-         * and need to see the JSOP_BACKPATCH* op at *pc).
-         */
+        SET_JUMP_OFFSET(pc, span);
         *pc = op;
         pc -= delta;
     }
     return JS_TRUE;
 }
 
 void
 frontend::PopStatementTC(TreeContext *tc)
@@ -1654,18 +765,18 @@ frontend::PopStatementTC(TreeContext *tc
 }
 
 JSBool
 frontend::PopStatementBCE(JSContext *cx, BytecodeEmitter *bce)
 {
     StmtInfo *stmt = bce->topStmt;
     if (!STMT_IS_TRYING(stmt) &&
         (!BackPatch(cx, bce, stmt->breaks, bce->next(), JSOP_GOTO) ||
-         !BackPatch(cx, bce, stmt->continues, bce->code(stmt->update),
-                    JSOP_GOTO))) {
+         !BackPatch(cx, bce, stmt->continues, bce->code(stmt->update), JSOP_GOTO)))
+    {
         return JS_FALSE;
     }
     PopStatementTC(bce);
     return JS_TRUE;
 }
 
 JSBool
 frontend::DefineCompileTimeConstant(JSContext *cx, BytecodeEmitter *bce, JSAtom *atom, ParseNode *pn)
@@ -3241,16 +2352,22 @@ EmitNumberOp(JSContext *cx, jsdouble dva
  * of large switches, which seems unlikely.
  */
 static Value *
 AllocateSwitchConstant(JSContext *cx)
 {
     return cx->tempLifoAlloc().new_<Value>();
 }
 
+static inline void
+SetJumpOffsetAt(BytecodeEmitter *bce, ptrdiff_t off)
+{
+    SET_JUMP_OFFSET(bce->code(off), bce->offset() - off);
+}
+
 static JSBool
 EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
 {
     JSOp switchOp;
     JSBool ok, hasDefault, constPropagated;
     ptrdiff_t top, off, defaultOffset;
     ParseNode *pn2, *pn3, *pn4;
     uint32_t caseCount, tableLength;
@@ -3496,27 +2613,17 @@ EmitSwitch(JSContext *cx, BytecodeEmitte
          * JSOP_LOOKUPSWITCH:
          * 1 offset (len) and 1 atom index (npairs) before the table,
          * 1 atom index and 1 jump offset per entry.
          */
         switchSize = (size_t)(JUMP_OFFSET_LEN + INDEX_LEN +
                               (INDEX_LEN + JUMP_OFFSET_LEN) * caseCount);
     }
 
-    /*
-     * Emit switchOp followed by switchSize bytes of jump or lookup table.
-     *
-     * If switchOp is JSOP_LOOKUPSWITCH or JSOP_TABLESWITCH, it is crucial
-     * to emit the immediate operand(s) by which bytecode readers such as
-     * BuildSpanDepTable discover the length of the switch opcode *before*
-     * calling SetJumpOffset (which may call BuildSpanDepTable).  It's
-     * also important to zero all unknown jump offset immediate operands,
-     * so they can be converted to span dependencies with null targets to
-     * be computed later (EmitN zeros switchSize bytes after switchOp).
-     */
+    /* Emit switchOp followed by switchSize bytes of jump or lookup table. */
     if (EmitN(cx, bce, switchOp, switchSize) < 0)
         return JS_FALSE;
 
     off = -1;
     if (switchOp == JSOP_CONDSWITCH) {
         intN caseNoteIndex = -1;
         JSBool beforeCases = JS_TRUE;
 
@@ -3611,26 +2718,16 @@ EmitSwitch(JSContext *cx, BytecodeEmitte
         }
 
         /*
          * After this point, all control flow involving JSOP_TABLESWITCH
          * must set ok and goto out to exit this function.  To keep things
          * simple, all switchOp cases exit that way.
          */
         MUST_FLOW_THROUGH("out");
-        if (bce->spanDeps) {
-            /*
-             * We have already generated at least one big jump so we must
-             * explicitly add span dependencies for the switch jumps. When
-             * called below, SetJumpOffset can only do it when patching the
-             * first big jump or when bce->spanDeps is null.
-             */
-            if (!AddSwitchSpanDeps(cx, bce, bce->code(top)))
-                goto bad;
-        }
 
         if (constPropagated) {
             /*
              * Skip switchOp, as we are not setting jump offsets in the two
              * for loops below.  We'll restore bce->next() from savepc after,
              * unless there was an error.
              */
             savepc = bce->next();
@@ -3671,17 +2768,17 @@ EmitSwitch(JSContext *cx, BytecodeEmitte
             }
             bce->current->next = savepc;
         }
     }
 
     /* Emit code for each case's statements, copying pn_offset up to pn3. */
     for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
         if (switchOp == JSOP_CONDSWITCH && !pn3->isKind(PNK_DEFAULT))
-            CHECK_AND_SET_JUMP_OFFSET_AT_CUSTOM(cx, bce, pn3->pn_offset, goto bad);
+            SetJumpOffsetAt(bce, pn3->pn_offset);
         pn4 = pn3->pn_right;
         ok = EmitTree(cx, bce, pn4);
         if (!ok)
             goto out;
         pn3->pn_offset = pn4->pn_offset;
         if (pn3->isKind(PNK_DEFAULT))
             off = pn3->pn_offset - top;
     }
@@ -3693,24 +2790,20 @@ EmitSwitch(JSContext *cx, BytecodeEmitte
 
     /* We better have set "off" by now. */
     JS_ASSERT(off != -1);
 
     /* Set the default offset (to end of switch if no default). */
     if (switchOp == JSOP_CONDSWITCH) {
         pc = NULL;
         JS_ASSERT(defaultOffset != -1);
-        ok = SetJumpOffset(cx, bce, bce->code(defaultOffset), off - (defaultOffset - top));
-        if (!ok)
-            goto out;
+        SET_JUMP_OFFSET(bce->code(defaultOffset), off - (defaultOffset - top));
     } else {
         pc = bce->code(top);
-        ok = SetJumpOffset(cx, bce, pc, off);
-        if (!ok)
-            goto out;
+        SET_JUMP_OFFSET(pc, off);
         pc += JUMP_OFFSET_LEN;
     }
 
     /* Set the SRC_SWITCH note's offset operand to tell end of switch. */
     off = bce->offset() - top;
     ok = SetSrcNoteOffset(cx, bce, (uintN)noteIndex, 0, off);
     if (!ok)
         goto out;
@@ -3718,37 +2811,33 @@ EmitSwitch(JSContext *cx, BytecodeEmitte
     if (switchOp == JSOP_TABLESWITCH) {
         /* Skip over the already-initialized switch bounds. */
         pc += 2 * JUMP_OFFSET_LEN;
 
         /* Fill in the jump table, if there is one. */
         for (i = 0; i < (jsint)tableLength; i++) {
             pn3 = table[i];
             off = pn3 ? pn3->pn_offset - top : 0;
-            ok = SetJumpOffset(cx, bce, pc, off);
-            if (!ok)
-                goto out;
+            SET_JUMP_OFFSET(pc, off);
             pc += JUMP_OFFSET_LEN;
         }
     } else if (switchOp == JSOP_LOOKUPSWITCH) {
         /* Skip over the already-initialized number of cases. */
         pc += INDEX_LEN;
 
         for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
             if (pn3->isKind(PNK_DEFAULT))
                 continue;
             if (!bce->constList.append(*pn3->pn_pval))
                 goto bad;
             SET_INDEX(pc, bce->constList.length() - 1);
             pc += INDEX_LEN;
 
             off = pn3->pn_offset - top;
-            ok = SetJumpOffset(cx, bce, pc, off);
-            if (!ok)
-                goto out;
+            SET_JUMP_OFFSET(pc, off);
             pc += JUMP_OFFSET_LEN;
         }
     }
 
 out:
     if (table)
         cx->free_(table);
     if (ok) {
@@ -5123,17 +4212,17 @@ EmitTry(JSContext *cx, BytecodeEmitter *
          */
         for (ParseNode *pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) {
             ptrdiff_t guardJump, catchNote;
 
             JS_ASSERT(bce->stackDepth == depth);
             guardJump = GUARDJUMP(stmtInfo);
             if (guardJump != -1) {
                 /* Fix up and clean up previous catch block. */
-                CHECK_AND_SET_JUMP_OFFSET_AT(cx, bce, guardJump);
+                SetJumpOffsetAt(bce, guardJump);
 
                 /*
                  * Account for JSOP_ENTERBLOCK (whose block object count
                  * is saved below) and pushed exception object that we
                  * still have after the jumping from the previous guard.
                  */
                 bce->stackDepth = depth + count + 1;
 
@@ -5201,17 +4290,17 @@ EmitTry(JSContext *cx, BytecodeEmitter *
 
     /*
      * Last catch guard jumps to the rethrow code sequence if none of the
      * guards match. Target guardJump at the beginning of the rethrow
      * sequence, just in case a guard expression throws and leaves the
      * stack unbalanced.
      */
     if (lastCatch && lastCatch->pn_kid2) {
-        CHECK_AND_SET_JUMP_OFFSET_AT(cx, bce, GUARDJUMP(stmtInfo));
+        SetJumpOffsetAt(bce, GUARDJUMP(stmtInfo));
 
         /* Sync the stack to take into account pushed exception. */
         JS_ASSERT(bce->stackDepth == depth);
         bce->stackDepth = depth + 1;
 
         /*
          * Rethrow the exception, delegating executing of finally if any
          * to the exception handler.
@@ -5333,17 +4422,17 @@ EmitIf(JSContext *cx, BytecodeEmitter *b
          * this function will fix up the backpatch chain linked from
          * stmtInfo.breaks.
          */
         jmp = EmitGoto(cx, bce, &stmtInfo, &stmtInfo.breaks);
         if (jmp < 0)
             return JS_FALSE;
 
         /* Ensure the branch-if-false comes here, then emit the else. */
-        CHECK_AND_SET_JUMP_OFFSET_AT(cx, bce, beq);
+        SetJumpOffsetAt(bce, beq);
         if (pn3->isKind(PNK_IF)) {
             pn = pn3;
             goto if_again;
         }
 
         if (!EmitTree(cx, bce, pn3))
             return JS_FALSE;
 
@@ -5353,17 +4442,17 @@ EmitIf(JSContext *cx, BytecodeEmitter *b
          * of the else clause, because we don't know whether an extended
          * jump was required to leap from the end of the then clause over
          * the else clause.
          */
         if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, jmp - beq))
             return JS_FALSE;
     } else {
         /* No else part, fixup the branch-if-false to come here. */
-        CHECK_AND_SET_JUMP_OFFSET_AT(cx, bce, beq);
+        SetJumpOffsetAt(bce, beq);
     }
     return PopStatementBCE(cx, bce);
 }
 
 #if JS_HAS_BLOCK_SCOPE
 /*
  * pnLet represents one of:
  *
@@ -5779,17 +4868,17 @@ EmitForIn(JSContext *cx, BytecodeEmitter
     StmtInfo *stmt = &stmtInfo;
     do {
         stmt->update = bce->offset();
     } while ((stmt = stmt->down) != NULL && stmt->type == STMT_LABEL);
 
     /*
      * Fixup the goto that starts the loop to jump down to JSOP_MOREITER.
      */
-    CHECK_AND_SET_JUMP_OFFSET_AT(cx, bce, jmp);
+    SetJumpOffsetAt(bce, jmp);
     if (Emit1(cx, bce, JSOP_MOREITER) < 0)
         return false;
     ptrdiff_t beq = EmitJump(cx, bce, JSOP_IFNE, top - bce->offset());
     if (beq < 0)
         return false;
 
     /* Set the first srcnote offset so we can find the start of the loop body. */
     if (!SetSrcNoteOffset(cx, bce, (uintN)noteIndex, 0, tmp2 - jmp))
@@ -5864,17 +4953,17 @@ EmitNormalFor(JSContext *cx, BytecodeEmi
             }
         }
         bce->flags &= ~TCF_IN_FOR_INIT;
     }
 
     /*
      * NB: the SRC_FOR note has offsetBias 1 (JSOP_{NOP,POP}_LENGTH).
      * Use tmp to hold the biased srcnote "top" offset, which differs
-     * from the top local variable by the length of the JSOP_GOTO{,X}
+     * from the top local variable by the length of the JSOP_GOTO
      * emitted in between tmp and top if this loop has a condition.
      */
     intN noteIndex = NewSrcNote(cx, bce, SRC_FOR);
     if (noteIndex < 0 || Emit1(cx, bce, op) < 0)
         return false;
     ptrdiff_t tmp = bce->offset();
 
     ptrdiff_t jmp = -1;
@@ -5931,17 +5020,17 @@ EmitNormalFor(JSContext *cx, BytecodeEmi
         }
     }
 
     ptrdiff_t tmp3 = bce->offset();
 
     if (forHead->pn_kid2) {
         /* Fix up the goto from top to target the loop condition. */
         JS_ASSERT(jmp >= 0);
-        CHECK_AND_SET_JUMP_OFFSET_AT(cx, bce, jmp);
+        SetJumpOffsetAt(bce, jmp);
 
         if (!EmitTree(cx, bce, forHead->pn_kid2))
             return false;
     }
 
     /* Set the first note offset so we can find the loop condition. */
     if (!SetSrcNoteOffset(cx, bce, (uintN)noteIndex, 0, tmp3 - tmp))
         return false;
@@ -6172,17 +5261,17 @@ EmitWhile(JSContext *cx, BytecodeEmitter
 
     top = EmitTraceOp(cx, bce, pn->pn_right);
     if (top < 0)
         return false;
 
     if (!EmitTree(cx, bce, pn->pn_right))
         return false;
 
-    CHECK_AND_SET_JUMP_OFFSET_AT(cx, bce, jmp);
+    SetJumpOffsetAt(bce, jmp);
     if (!EmitTree(cx, bce, pn->pn_left))
         return false;
 
     ptrdiff_t beq = EmitJump(cx, bce, JSOP_IFNE, top - bce->offset());
     if (beq < 0)
         return false;
 
     if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, beq - jmp))
@@ -6617,17 +5706,17 @@ EmitLogical(JSContext *cx, BytecodeEmitt
         if (top < 0)
             return false;
         if (Emit1(cx, bce, JSOP_POP) < 0)
             return false;
         if (!EmitTree(cx, bce, pn->pn_right))
             return false;
         ptrdiff_t off = bce->offset();
         jsbytecode *pc = bce->code(top);
-        CHECK_AND_SET_JUMP_OFFSET(cx, bce, pc, off - top);
+        SET_JUMP_OFFSET(pc, off - top);
         *pc = pn->getOp();
         return true;
     }
 
     JS_ASSERT(pn->isArity(PN_LIST));
     JS_ASSERT(pn->pn_head->pn_next->pn_next);
 
     /* Left-associative operator chain: avoid too much recursion. */
@@ -6645,29 +5734,28 @@ EmitLogical(JSContext *cx, BytecodeEmitt
     while ((pn2 = pn2->pn_next)->pn_next) {
         if (!EmitTree(cx, bce, pn2))
             return false;
         ptrdiff_t off = EmitJump(cx, bce, JSOP_BACKPATCH, 0);
         if (off < 0)
             return false;
         if (Emit1(cx, bce, JSOP_POP) < 0)
             return false;
-        if (!SetBackPatchDelta(cx, bce, bce->code(jmp), off - jmp))
-            return false;
+        SET_JUMP_OFFSET(bce->code(jmp), off - jmp);
         jmp = off;
     }
     if (!EmitTree(cx, bce, pn2))
         return false;
 
     pn2 = pn->pn_head;
     ptrdiff_t off = bce->offset();
     do {
         jsbytecode *pc = bce->code(top);
-        ptrdiff_t tmp = GetJumpOffset(bce, pc);
-        CHECK_AND_SET_JUMP_OFFSET(cx, bce, pc, off - top);
+        ptrdiff_t tmp = GET_JUMP_OFFSET(pc);
+        SET_JUMP_OFFSET(pc, off - top);
         *pc = pn->getOp();
         top += tmp;
     } while ((pn2 = pn2->pn_next)->pn_next);
 
     return true;
 }
 
 static bool
@@ -6789,17 +5877,17 @@ EmitLabel(JSContext *cx, BytecodeEmitter
     PushStatement(bce, &stmtInfo, STMT_LABEL, bce->offset());
     stmtInfo.label = atom;
     if (!EmitTree(cx, bce, pn2))
         return false;
     if (!PopStatementBCE(cx, bce))
         return false;
 
     /* Patch the JSOP_LABEL offset. */
-    CHECK_AND_SET_JUMP_OFFSET_AT(cx, bce, top);
+    SetJumpOffsetAt(bce, top);
 
     /* If the statement was compound, emit a note for the end brace. */
     if (noteType == SRC_LABELBRACE) {
         if (NewSrcNote(cx, bce, SRC_ENDBRACE) < 0 || Emit1(cx, bce, JSOP_NOP) < 0)
             return false;
     }
 
     return true;
@@ -6830,33 +5918,33 @@ EmitConditionalExpression(JSContext *cx,
     ptrdiff_t beq = EmitJump(cx, bce, JSOP_IFEQ, 0);
     if (beq < 0 || !EmitTree(cx, bce, &conditional.thenExpression()))
         return false;
 
     /* Jump around else, fixup the branch, emit else, fixup jump. */
     ptrdiff_t jmp = EmitJump(cx, bce, JSOP_GOTO, 0);
     if (jmp < 0)
         return false;
-    CHECK_AND_SET_JUMP_OFFSET_AT(cx, bce, beq);
+    SetJumpOffsetAt(bce, beq);
 
     /*
      * Because each branch pushes a single value, but our stack budgeting
      * analysis ignores branches, we now have to adjust bce->stackDepth to
      * ignore the value pushed by the first branch.  Execution will follow
      * only one path, so we must decrement bce->stackDepth.
      *
      * Failing to do this will foil code, such as let expression and block
      * code generation, which must use the stack depth to compute local
      * stack indexes correctly.
      */
     JS_ASSERT(bce->stackDepth > 0);
     bce->stackDepth--;
     if (!EmitTree(cx, bce, &conditional.elseExpression()))
         return false;
-    CHECK_AND_SET_JUMP_OFFSET_AT(cx, bce, jmp);
+    SetJumpOffsetAt(bce, jmp);
     return SetSrcNoteOffset(cx, bce, noteIndex, 0, jmp - beq);
 }
 
 static bool
 EmitObject(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, jsint sharpnum)
 {
 #if JS_HAS_DESTRUCTURING_SHORTHAND
     if (pn->pn_xflags & PNX_DESTRUCT) {
@@ -7409,17 +6497,17 @@ frontend::EmitTree(JSContext *cx, Byteco
         ptrdiff_t jmp = EmitJump(cx, bce, JSOP_FILTER, 0);
         if (jmp < 0)
             return JS_FALSE;
         top = EmitTraceOp(cx, bce, pn->pn_right);
         if (top < 0)
             return JS_FALSE;
         if (!EmitTree(cx, bce, pn->pn_right))
             return JS_FALSE;
-        CHECK_AND_SET_JUMP_OFFSET_AT(cx, bce, jmp);
+        SetJumpOffsetAt(bce, jmp);
         if (EmitJump(cx, bce, JSOP_ENDFILTER, top - bce->offset()) < 0)
             return JS_FALSE;
         break;
       }
 #endif
 
       case PNK_DOT:
         /*
@@ -7655,18 +6743,16 @@ frontend::EmitTree(JSContext *cx, Byteco
 #endif /* JS_HAS_XML_SUPPORT */
 
       default:
         JS_ASSERT(0);
     }
 
     /* bce->emitLevel == 1 means we're last on the stack, so finish up. */
     if (ok && bce->emitLevel == 1) {
-        if (bce->spanDeps)
-            ok = OptimizeSpanDeps(cx, bce);
         if (!UpdateLineNumberNotes(cx, bce, pn->pn_pos.end.lineno))
             return JS_FALSE;
     }
 
     return ok;
 }
 
 static intN
@@ -8091,41 +7177,41 @@ GCConstList::finish(JSConstArray *array)
         *dst = *src;
 }
 
 /*
  * We should try to get rid of offsetBias (always 0 or 1, where 1 is
  * JSOP_{NOP,POP}_LENGTH), which is used only by SRC_FOR and SRC_DECL.
  */
 JS_FRIEND_DATA(JSSrcNoteSpec) js_SrcNoteSpec[] = {
-    {"null",            0,      0,      0},
-    {"if",              0,      0,      0},
-    {"if-else",         2,      0,      1},
-    {"for",             3,      1,      1},
-    {"while",           1,      0,      1},
-    {"continue",        0,      0,      0},
-    {"decl",            1,      1,      1},
-    {"pcdelta",         1,      0,      1},
-    {"assignop",        0,      0,      0},
-    {"cond",            1,      0,      1},
-    {"brace",           1,      0,      1},
-    {"hidden",          0,      0,      0},
-    {"pcbase",          1,      0,     -1},
-    {"label",           1,      0,      0},
-    {"labelbrace",      1,      0,      0},
-    {"endbrace",        0,      0,      0},
-    {"break2label",     1,      0,      0},
-    {"cont2label",      1,      0,      0},
-    {"switch",          2,      0,      1},
-    {"funcdef",         1,      0,      0},
-    {"catch",           1,      0,      1},
-    {"unused",         -1,      0,      0},
-    {"newline",         0,      0,      0},
-    {"setline",         1,      0,      0},
-    {"xdelta",          0,      0,      0},
+    {"null",            0},
+    {"if",              0},
+    {"if-else",         2},
+    {"for",             3},
+    {"while",           1},
+    {"continue",        0},
+    {"decl",            1},
+    {"pcdelta",         1},
+    {"assignop",        0},
+    {"cond",            1},
+    {"brace",           1},
+    {"hidden",          0},
+    {"pcbase",          1},
+    {"label",           1},
+    {"labelbrace",      1},
+    {"endbrace",        0},
+    {"break2label",     1},
+    {"cont2label",      1},
+    {"switch",          2},
+    {"funcdef",         1},
+    {"catch",           1},
+    {"unused",         -1},
+    {"newline",         0},
+    {"setline",         1},
+    {"xdelta",          0},
 };
 
 JS_FRIEND_API(uintN)
 js_SrcNoteLength(jssrcnote *sn)
 {
     uintN arity;
     jssrcnote *base;
 
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -486,76 +486,16 @@ namespace frontend {
 bool
 SetStaticLevel(TreeContext *tc, uintN staticLevel);
 
 bool
 GenerateBlockId(TreeContext *tc, uint32_t &blockid);
 
 } /* namespace frontend */
 
-struct JumpTarget;
-
-/*
- * Span-dependent instructions are jumps whose span (from the jump bytecode to
- * the jump target) may require 2 or 4 bytes of immediate operand.
- */
-struct SpanDep {
-    ptrdiff_t       top;        /* offset of first bytecode in an opcode */
-    ptrdiff_t       offset;     /* offset - 1 within opcode of jump operand */
-    ptrdiff_t       before;     /* original offset - 1 of jump operand */
-    JumpTarget      *target;    /* tagged target pointer or backpatch delta */
-};
-
-/*
- * Jump targets are stored in an AVL tree, for O(log(n)) lookup with targets
- * sorted by offset from left to right, so that targets after a span-dependent
- * instruction whose jump offset operand must be extended can be found quickly
- * and adjusted upward (toward higher offsets).
- */
-struct JumpTarget {
-    ptrdiff_t       offset;     /* offset of span-dependent jump target */
-    int             balance;    /* AVL tree balance number */
-    JumpTarget      *kids[2];   /* left and right AVL tree child pointers */
-};
-
-#define JT_LEFT                 0
-#define JT_RIGHT                1
-#define JT_OTHER_DIR(dir)       (1 - (dir))
-#define JT_IMBALANCE(dir)       (((dir) << 1) - 1)
-#define JT_DIR(imbalance)       (((imbalance) + 1) >> 1)
-
-/*
- * Backpatch deltas are encoded in js::SpanDep::target if JT_TAG_BIT is clear,
- * so we can maintain backpatch chains when using span dependency records to
- * hold jump offsets that overflow 16 bits.
- */
-#define JT_TAG_BIT              ((jsword) 1)
-#define JT_UNTAG_SHIFT          1
-#define JT_SET_TAG(jt)          ((JumpTarget *)((jsword)(jt) | JT_TAG_BIT))
-#define JT_CLR_TAG(jt)          ((JumpTarget *)((jsword)(jt) & ~JT_TAG_BIT))
-#define JT_HAS_TAG(jt)          ((jsword)(jt) & JT_TAG_BIT)
-
-#define BITS_PER_PTRDIFF        (sizeof(ptrdiff_t) * JS_BITS_PER_BYTE)
-#define BITS_PER_BPDELTA        (BITS_PER_PTRDIFF - 1 - JT_UNTAG_SHIFT)
-#define BPDELTA_MAX             (((ptrdiff_t)1 << BITS_PER_BPDELTA) - 1)
-#define BPDELTA_TO_JT(bp)       ((JumpTarget *)((bp) << JT_UNTAG_SHIFT))
-#define JT_TO_BPDELTA(jt)       ((ptrdiff_t)((jsword)(jt) >> JT_UNTAG_SHIFT))
-
-#define SD_SET_TARGET(sd,jt)    ((sd)->target = JT_SET_TAG(jt))
-#define SD_GET_TARGET(sd)       (JS_ASSERT(JT_HAS_TAG((sd)->target)),         \
-                                 JT_CLR_TAG((sd)->target))
-#define SD_SET_BPDELTA(sd,bp)   ((sd)->target = BPDELTA_TO_JT(bp))
-#define SD_GET_BPDELTA(sd)      (JS_ASSERT(!JT_HAS_TAG((sd)->target)),        \
-                                 JT_TO_BPDELTA((sd)->target))
-
-/* Avoid asserting twice by expanding SD_GET_TARGET in the "then" clause. */
-#define SD_SPAN(sd,pivot)       (SD_GET_TARGET(sd)                            \
-                                 ? JT_CLR_TAG((sd)->target)->offset - (pivot) \
-                                 : 0)
-
 struct TryNode {
     JSTryNote       note;
     TryNode       *prev;
 };
 
 struct CGObjectList {
     uint32_t            length;     /* number of emitted so far objects */
     ObjectBox           *lastbox;   /* last emitted object */
@@ -624,24 +564,16 @@ struct BytecodeEmitter : public TreeCont
     uintN           firstLine;      /* first line, for JSScript::NewScriptFromEmitter */
 
     intN            stackDepth;     /* current stack depth in script frame */
     uintN           maxStackDepth;  /* maximum stack depth so far */
 
     uintN           ntrynotes;      /* number of allocated so far try notes */
     TryNode         *lastTryNode;   /* the last allocated try node */
 
-    SpanDep         *spanDeps;      /* span dependent instruction records */
-    JumpTarget      *jumpTargets;   /* AVL tree of jump target offsets */
-    JumpTarget      *jtFreeList;    /* JT_LEFT-linked list of free structs */
-    uintN           numSpanDeps;    /* number of span dependencies */
-    uintN           numJumpTargets; /* number of jump targets */
-    ptrdiff_t       spanDepTodo;    /* offset from main.base of potentially
-                                       unoptimized spandeps */
-
     uintN           arrayCompDepth; /* stack depth of array in comprehension */
 
     uintN           emitLevel;      /* js::frontend::EmitTree recursion level */
 
     typedef HashMap<JSAtom *, Value> ConstMap;
     ConstMap        constMap;       /* compile time constants */
 
     GCConstList     constList;      /* constants to be included with the script */
@@ -797,39 +729,16 @@ Emit3(JSContext *cx, BytecodeEmitter *bc
 
 /*
  * Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand.
  */
 ptrdiff_t
 EmitN(JSContext *cx, BytecodeEmitter *bce, JSOp op, size_t extra);
 
 /*
- * Unsafe macro to call SetJumpOffset and return false if it does.
- */
-#define CHECK_AND_SET_JUMP_OFFSET_CUSTOM(cx,bce,pc,off,BAD_EXIT)              \
-    JS_BEGIN_MACRO                                                            \
-        if (!SetJumpOffset(cx, bce, pc, off)) {                               \
-            BAD_EXIT;                                                         \
-        }                                                                     \
-    JS_END_MACRO
-
-#define CHECK_AND_SET_JUMP_OFFSET(cx,bce,pc,off)                              \
-    CHECK_AND_SET_JUMP_OFFSET_CUSTOM(cx,bce,pc,off,return JS_FALSE)
-
-#define CHECK_AND_SET_JUMP_OFFSET_AT_CUSTOM(cx,bce,off,BAD_EXIT)              \
-    CHECK_AND_SET_JUMP_OFFSET_CUSTOM(cx, bce, (bce)->code(off),               \
-                                     bce->offset() - (off), BAD_EXIT)
-
-#define CHECK_AND_SET_JUMP_OFFSET_AT(cx,bce,off)                              \
-    CHECK_AND_SET_JUMP_OFFSET_AT_CUSTOM(cx, bce, off, return JS_FALSE)
-
-JSBool
-SetJumpOffset(JSContext *cx, BytecodeEmitter *bce, jsbytecode *pc, ptrdiff_t off);
-
-/*
  * Push the C-stack-allocated struct at stmt onto the stmtInfo stack.
  */
 void
 PushStatement(TreeContext *tc, StmtInfo *stmt, StmtType type, ptrdiff_t top);
 
 /*
  * Push a block scope statement and link blockObj into tc->blockChain. To pop
  * this statement info record, use PopStatementTC as usual, or if appropriate
@@ -916,18 +825,18 @@ EmitFunctionScript(JSContext *cx, Byteco
  * SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode.
  *
  * NB: the js_SrcNoteSpec array in BytecodeEmitter.cpp is indexed by this
  * enum, so its initializers need to match the order here.
  *
  * Note on adding new source notes: every pair of bytecodes (A, B) where A and
  * B have disjoint sets of source notes that could apply to each bytecode may
  * reuse the same note type value for two notes (snA, snB) that have the same
- * arity, offsetBias, and isSpanDep initializers in JSSrcNoteSpec. This is
- * why SRC_IF and SRC_INITPROP have the same value below.
+ * arity in JSSrcNoteSpec. This is why SRC_IF and SRC_INITPROP have the same
+ * value below.
  *
  * Don't forget to update JSXDR_BYTECODE_VERSION in jsxdrapi.h for all such
  * incompatible source note or other bytecode changes.
  */
 enum SrcNoteType {
     SRC_NULL        = 0,        /* terminates a note vector */
     SRC_IF          = 1,        /* JSOP_IFEQ bytecode is from an if-then */
     SRC_BREAK       = 1,        /* JSOP_GOTO is a break */
@@ -976,21 +885,17 @@ enum SrcNoteType {
     SRC_CATCH       = 20,       /* catch block has guard */
                                 /* 21 is unused */
     SRC_NEWLINE     = 22,       /* bytecode follows a source newline */
     SRC_SETLINE     = 23,       /* a file-absolute source line number note */
     SRC_XDELTA      = 24        /* 24-31 are for extended delta notes */
 };
 
 /*
- * Constants for the SRC_DECL source note. Note that span-dependent bytecode
- * selection means that any SRC_DECL offset greater than SRC_DECL_LET may need
- * to be adjusted, but these "offsets" are too small to span a span-dependent
- * instruction, so can be used to denote distinct declaration syntaxes to the
- * decompiler.
+ * Constants for the SRC_DECL source note.
  *
  * NB: the var_prefix array in jsopcode.c depends on these dense indexes from
  * SRC_DECL_VAR through SRC_DECL_LET.
  */
 #define SRC_DECL_VAR            0
 #define SRC_DECL_CONST          1
 #define SRC_DECL_LET            2
 #define SRC_DECL_NONE           3
@@ -1130,19 +1035,16 @@ inline bool LetDataToGroupAssign(ptrdiff
     return size_t(w) & 1;
 }
 
 } /* namespace js */
 
 struct JSSrcNoteSpec {
     const char      *name;      /* name for disassembly/debugging output */
     int8_t          arity;      /* number of offset operands */
-    uint8_t         offsetBias; /* bias of offset(s) from annotated pc */
-    int8_t          isSpanDep;  /* 1 or -1 if offsets could span extended ops,
-                                   0 otherwise; sign tells span direction */
 };
 
 extern JS_FRIEND_DATA(JSSrcNoteSpec)  js_SrcNoteSpec[];
 extern JS_FRIEND_API(uintN)         js_SrcNoteLength(jssrcnote *sn);
 
 /*
  * Get and set the offset operand identified by which (0 for the first, etc.).
  */
--- a/js/src/jit-test/tests/jaeger/bug563000/trap-self-from-trap.js
+++ b/js/src/jit-test/tests/jaeger/bug563000/trap-self-from-trap.js
@@ -2,23 +2,23 @@
 setDebug(true);
 x = "notset";
 
 function doNothing() { }
 
 function myparent(nested) {
   if (nested) {
     /* JSOP_CALL to doNothing in myparent with nested = true. */
-    trap(myparent, 26, "success()");
+    trap(myparent, 28, "success()");
     doNothing();
   } else {
     doNothing();
   }
 }
 /* JSOP_CALL to doNothing in myparent with nested = false. */
-trap(myparent, 37, "myparent(true)");
+trap(myparent, 41, "myparent(true)");
 
 function success() {
   x = "success";
 }
 
 myparent(false);
 assertEq(x, "success");
--- a/js/src/jsanalyze.cpp
+++ b/js/src/jsanalyze.cpp
@@ -136,31 +136,26 @@ ScriptAnalysis::checkAliasedName(JSConte
 }
 
 // return whether op bytecodes do not fallthrough (they may do a jump).
 static inline bool
 BytecodeNoFallThrough(JSOp op)
 {
     switch (op) {
       case JSOP_GOTO:
-      case JSOP_GOTOX:
       case JSOP_DEFAULT:
-      case JSOP_DEFAULTX:
       case JSOP_RETURN:
       case JSOP_STOP:
       case JSOP_RETRVAL:
       case JSOP_THROW:
       case JSOP_TABLESWITCH:
-      case JSOP_TABLESWITCHX:
       case JSOP_LOOKUPSWITCH:
-      case JSOP_LOOKUPSWITCHX:
       case JSOP_FILTER:
         return true;
       case JSOP_GOSUB:
-      case JSOP_GOSUBX:
         // these fall through indirectly, after executing a 'finally'.
         return false;
       default:
         return false;
     }
 }
 
 void
@@ -402,69 +397,63 @@ ScriptAnalysis::analyzeBytecode(JSContex
             break;
 
           case JSOP_CALL:
           case JSOP_NEW:
             /* Only consider potentially inlineable calls here. */
             hasFunctionCalls_ = true;
             break;
 
-          case JSOP_TABLESWITCH:
-          case JSOP_TABLESWITCHX: {
+          case JSOP_TABLESWITCH: {
             isInlineable = false;
-            jsbytecode *pc2 = pc;
-            unsigned jmplen = (op == JSOP_TABLESWITCH) ? JUMP_OFFSET_LEN : JUMPX_OFFSET_LEN;
-            unsigned defaultOffset = offset + GetJumpOffset(pc, pc2);
-            pc2 += jmplen;
+            unsigned defaultOffset = offset + GET_JUMP_OFFSET(pc);
+            jsbytecode *pc2 = pc + JUMP_OFFSET_LEN;
             jsint low = GET_JUMP_OFFSET(pc2);
             pc2 += JUMP_OFFSET_LEN;
             jsint high = GET_JUMP_OFFSET(pc2);
             pc2 += JUMP_OFFSET_LEN;
 
             if (!addJump(cx, defaultOffset, &nextOffset, &forwardJump, stackDepth))
                 return;
             getCode(defaultOffset).switchTarget = true;
             getCode(defaultOffset).safePoint = true;
 
             for (jsint i = low; i <= high; i++) {
-                unsigned targetOffset = offset + GetJumpOffset(pc, pc2);
+                unsigned targetOffset = offset + GET_JUMP_OFFSET(pc2);
                 if (targetOffset != offset) {
                     if (!addJump(cx, targetOffset, &nextOffset, &forwardJump, stackDepth))
                         return;
                 }
                 getCode(targetOffset).switchTarget = true;
                 getCode(targetOffset).safePoint = true;
-                pc2 += jmplen;
+                pc2 += JUMP_OFFSET_LEN;
             }
             break;
           }
 
-          case JSOP_LOOKUPSWITCH:
-          case JSOP_LOOKUPSWITCHX: {
+          case JSOP_LOOKUPSWITCH: {
             isInlineable = false;
-            jsbytecode *pc2 = pc;
-            unsigned jmplen = (op == JSOP_LOOKUPSWITCH) ? JUMP_OFFSET_LEN : JUMPX_OFFSET_LEN;
-            unsigned defaultOffset = offset + GetJumpOffset(pc, pc2);
-            pc2 += jmplen;
+            unsigned defaultOffset = offset + GET_JUMP_OFFSET(pc);
+            jsbytecode *pc2 = pc + JUMP_OFFSET_LEN;
             unsigned npairs = GET_UINT16(pc2);
             pc2 += UINT16_LEN;
 
             if (!addJump(cx, defaultOffset, &nextOffset, &forwardJump, stackDepth))
                 return;
             getCode(defaultOffset).switchTarget = true;
             getCode(defaultOffset).safePoint = true;
 
             while (npairs) {
                 pc2 += INDEX_LEN;
-                unsigned targetOffset = offset + GetJumpOffset(pc, pc2);
+                unsigned targetOffset = offset + GET_JUMP_OFFSET(pc2);
                 if (!addJump(cx, targetOffset, &nextOffset, &forwardJump, stackDepth))
                     return;
                 getCode(targetOffset).switchTarget = true;
                 getCode(targetOffset).safePoint = true;
-                pc2 += jmplen;
+                pc2 += JUMP_OFFSET_LEN;
                 npairs--;
             }
             break;
           }
 
           case JSOP_TRY: {
             /*
              * Everything between a try and corresponding catch or finally is conditional.
@@ -553,31 +542,30 @@ ScriptAnalysis::analyzeBytecode(JSContex
 
           default:
             break;
         }
 
         uint32_t type = JOF_TYPE(js_CodeSpec[op].format);
 
         /* Check basic jump opcodes, which may or may not have a fallthrough. */
-        if (type == JOF_JUMP || type == JOF_JUMPX) {
+        if (type == JOF_JUMP) {
             /* Some opcodes behave differently on their branching path. */
             unsigned newStackDepth = stackDepth;
 
             switch (op) {
               case JSOP_CASE:
-              case JSOP_CASEX:
                 /* Case instructions do not push the lvalue back when branching. */
                 newStackDepth--;
                 break;
 
               default:;
             }
 
-            unsigned targetOffset = offset + GetJumpOffset(pc, pc);
+            unsigned targetOffset = offset + GET_JUMP_OFFSET(pc);
             if (!addJump(cx, targetOffset, &nextOffset, &forwardJump, newStackDepth))
                 return;
         }
 
         /* Handle any fallthrough from this opcode. */
         if (!BytecodeNoFallThrough(op)) {
             JS_ASSERT(successorOffset < script->length);
 
@@ -588,21 +576,21 @@ ScriptAnalysis::analyzeBytecode(JSContex
                 if (!nextcode) {
                     setOOM(cx);
                     return;
                 }
                 nextcode->stackDepth = stackDepth;
             }
             JS_ASSERT(nextcode->stackDepth == stackDepth);
 
-            if (type == JOF_JUMP || type == JOF_JUMPX)
+            if (type == JOF_JUMP)
                 nextcode->jumpFallthrough = true;
 
             /* Treat the fallthrough of a branch instruction as a jump target. */
-            if (type == JOF_JUMP || type == JOF_JUMPX)
+            if (type == JOF_JUMP)
                 nextcode->jumpTarget = true;
             else
                 nextcode->fallthrough = true;
         }
     }
 
     JS_ASSERT(!failed());
     JS_ASSERT(forwardJump == 0 && forwardCatch == 0);
@@ -743,19 +731,17 @@ ScriptAnalysis::analyzeLifetimes(JSConte
             if (!slotEscapes(slot)) {
                 killVariable(cx, lifetimes[slot], offset, saved, savedCount);
                 addVariable(cx, lifetimes[slot], offset, saved, savedCount);
             }
             break;
           }
 
           case JSOP_LOOKUPSWITCH:
-          case JSOP_LOOKUPSWITCHX:
           case JSOP_TABLESWITCH:
-          case JSOP_TABLESWITCHX:
             /* Restore all saved variables. :FIXME: maybe do this precisely. */
             for (unsigned i = 0; i < savedCount; i++) {
                 LifetimeVariable &var = *saved[i];
                 var.lifetime = tla.new_<Lifetime>(offset, var.savedEnd, var.saved);
                 if (!var.lifetime) {
                     cx->free_(saved);
                     setOOM(cx);
                     return;
@@ -785,17 +771,17 @@ ScriptAnalysis::analyzeLifetimes(JSConte
             if (loop)
                 loop->hasCallsLoops = true;
             break;
 
           default:;
         }
 
         uint32_t type = JOF_TYPE(js_CodeSpec[op].format);
-        if (type == JOF_JUMP || type == JOF_JUMPX) {
+        if (type == JOF_JUMP) {
             /*
              * Forward jumps need to pull in all variables which are live at
              * their target offset --- the variables live before the jump are
              * the union of those live at the fallthrough and at the target.
              */
             uint32_t targetOffset = FollowBranch(cx, script, offset);
 
             /*
@@ -847,18 +833,18 @@ ScriptAnalysis::analyzeLifetimes(JSConte
                 uint32_t entry = targetOffset;
                 if (entry) {
                     do {
                         entry--;
                     } while (!maybeCode(entry));
 
                     jsbytecode *entrypc = script->code + entry;
 
-                    if (JSOp(*entrypc) == JSOP_GOTO || JSOp(*entrypc) == JSOP_GOTOX)
-                        loop->entry = entry + GetJumpOffset(entrypc, entrypc);
+                    if (JSOp(*entrypc) == JSOP_GOTO)
+                        loop->entry = entry + GET_JUMP_OFFSET(entrypc);
                     else
                         loop->entry = targetOffset;
                 } else {
                     /* Do-while loop at the start of the script. */
                     loop->entry = targetOffset;
                 }
             } else {
                 for (unsigned i = 0; i < savedCount; i++) {
@@ -1426,54 +1412,48 @@ ScriptAnalysis::analyzeSSA(JSContext *cx
             break;
           }
 
           /*
            * Switch and try blocks preserve the stack between the original op
            * and all case statements or exception/finally handlers.
            */
 
-          case JSOP_TABLESWITCH:
-          case JSOP_TABLESWITCHX: {
-            jsbytecode *pc2 = pc;
-            unsigned jmplen = (op == JSOP_TABLESWITCH) ? JUMP_OFFSET_LEN : JUMPX_OFFSET_LEN;
-            unsigned defaultOffset = offset + GetJumpOffset(pc, pc2);
-            pc2 += jmplen;
+          case JSOP_TABLESWITCH: {
+            unsigned defaultOffset = offset + GET_JUMP_OFFSET(pc);
+            jsbytecode *pc2 = pc + JUMP_OFFSET_LEN;
             jsint low = GET_JUMP_OFFSET(pc2);
             pc2 += JUMP_OFFSET_LEN;
             jsint high = GET_JUMP_OFFSET(pc2);
             pc2 += JUMP_OFFSET_LEN;
 
             checkBranchTarget(cx, defaultOffset, branchTargets, values, stackDepth);
 
             for (jsint i = low; i <= high; i++) {
-                unsigned targetOffset = offset + GetJumpOffset(pc, pc2);
+                unsigned targetOffset = offset + GET_JUMP_OFFSET(pc2);
                 if (targetOffset != offset)
                     checkBranchTarget(cx, targetOffset, branchTargets, values, stackDepth);
-                pc2 += jmplen;
+                pc2 += JUMP_OFFSET_LEN;
             }
             break;
           }
 
-          case JSOP_LOOKUPSWITCH:
-          case JSOP_LOOKUPSWITCHX: {
-            jsbytecode *pc2 = pc;
-            unsigned jmplen = (op == JSOP_LOOKUPSWITCH) ? JUMP_OFFSET_LEN : JUMPX_OFFSET_LEN;
-            unsigned defaultOffset = offset + GetJumpOffset(pc, pc2);
-            pc2 += jmplen;
+          case JSOP_LOOKUPSWITCH: {
+            unsigned defaultOffset = offset + GET_JUMP_OFFSET(pc);
+            jsbytecode *pc2 = pc + JUMP_OFFSET_LEN;
             unsigned npairs = GET_UINT16(pc2);
             pc2 += UINT16_LEN;
 
             checkBranchTarget(cx, defaultOffset, branchTargets, values, stackDepth);
 
             while (npairs) {
                 pc2 += INDEX_LEN;
-                unsigned targetOffset = offset + GetJumpOffset(pc, pc2);
+                unsigned targetOffset = offset + GET_JUMP_OFFSET(pc2);
                 checkBranchTarget(cx, targetOffset, branchTargets, values, stackDepth);
-                pc2 += jmplen;
+                pc2 += JUMP_OFFSET_LEN;
                 npairs--;
             }
             break;
           }
 
           case JSOP_TRY: { 
             JSTryNote *tn = script->trynotes()->vector;
             JSTryNote *tnlimit = tn + script->trynotes()->length;
@@ -1490,17 +1470,17 @@ ScriptAnalysis::analyzeSSA(JSContext *cx
             }
             break;
           }
 
           default:;
         }
 
         uint32_t type = JOF_TYPE(js_CodeSpec[op].format);
-        if (type == JOF_JUMP || type == JOF_JUMPX) {
+        if (type == JOF_JUMP) {
             unsigned targetOffset = FollowBranch(cx, script, offset);
             checkBranchTarget(cx, targetOffset, branchTargets, values, stackDepth);
 
             /*
              * If this is a back edge, we're done with the loop and can freeze
              * the phi values at the head now.
              */
             if (targetOffset < offset)
--- a/js/src/jsanalyze.h
+++ b/js/src/jsanalyze.h
@@ -204,19 +204,17 @@ GetDefCount(JSScript *script, unsigned o
     jsbytecode *pc = script->code + offset;
 
     /*
      * Add an extra pushed value for OR/AND opcodes, so that they are included
      * in the pushed array of stack values for type inference.
      */
     switch (JSOp(*pc)) {
       case JSOP_OR:
-      case JSOP_ORX:
       case JSOP_AND:
-      case JSOP_ANDX:
         return 1;
       case JSOP_FILTER:
         return 2;
       case JSOP_PICK:
         /*
          * Pick pops and pushes how deep it looks in the stack + 1
          * items. i.e. if the stack were |a b[2] c[1] d[0]|, pick 2
          * would pop b, c, and d to rearrange the stack to |a c[0]
@@ -283,25 +281,16 @@ ExtendedUse(jsbytecode *pc)
       case JSOP_GETLOCAL:
       case JSOP_CALLLOCAL:
         return true;
       default:
         return false;
     }
 }
 
-static inline ptrdiff_t
-GetJumpOffset(jsbytecode *pc, jsbytecode *pc2)
-{
-    uint32_t type = JOF_OPTYPE(*pc);
-    if (JOF_TYPE_IS_EXTENDED_JUMP(type))
-        return GET_JUMPX_OFFSET(pc2);
-    return GET_JUMP_OFFSET(pc2);
-}
-
 static inline JSOp
 ReverseCompareOp(JSOp op)
 {
     switch (op) {
       case JSOP_GT:
         return JSOP_LT;
       case JSOP_GE:
         return JSOP_LE;
@@ -319,22 +308,22 @@ static inline unsigned
 FollowBranch(JSContext *cx, JSScript *script, unsigned offset)
 {
     /*
      * Get the target offset of a branch. For GOTO opcodes implementing
      * 'continue' statements, short circuit any artificial backwards jump
      * inserted by the emitter.
      */
     jsbytecode *pc = script->code + offset;
-    unsigned targetOffset = offset + GetJumpOffset(pc, pc);
+    unsigned targetOffset = offset + GET_JUMP_OFFSET(pc);
     if (targetOffset < offset) {
         jsbytecode *target = script->code + targetOffset;
         JSOp nop = JSOp(*target);
-        if (nop == JSOP_GOTO || nop == JSOP_GOTOX)
-            return targetOffset + GetJumpOffset(target, target);
+        if (nop == JSOP_GOTO)
+            return targetOffset + GET_JUMP_OFFSET(target);
     }
     return targetOffset;
 }
 
 /* Common representation of slots throughout analyses and the compiler. */
 static inline uint32_t CalleeSlot() {
     return 0;
 }
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -3202,19 +3202,17 @@ static inline bool
 CheckNextTest(jsbytecode *pc)
 {
     jsbytecode *next = pc + GetBytecodeLength(pc);
     switch ((JSOp)*next) {
       case JSOP_IFEQ:
       case JSOP_IFNE:
       case JSOP_NOT:
       case JSOP_OR:
-      case JSOP_ORX:
       case JSOP_AND:
-      case JSOP_ANDX:
       case JSOP_TYPEOF:
       case JSOP_TYPEOFEXPR:
         return true;
       default:
         /* TRAP ok here */
         return false;
     }
 }
@@ -3397,55 +3395,47 @@ ScriptAnalysis::analyzeTypesBytecode(JSC
     /* Add type constraints for the various opcodes. */
     switch (op) {
 
         /* Nop bytecodes. */
       case JSOP_POP:
       case JSOP_NOP:
       case JSOP_LOOPHEAD:
       case JSOP_GOTO:
-      case JSOP_GOTOX:
       case JSOP_IFEQ:
-      case JSOP_IFEQX:
       case JSOP_IFNE:
-      case JSOP_IFNEX:
       case JSOP_LINENO:
       case JSOP_DEFCONST:
       case JSOP_LEAVEWITH:
       case JSOP_LEAVEBLOCK:
       case JSOP_RETRVAL:
       case JSOP_ENDITER:
       case JSOP_THROWING:
       case JSOP_GOSUB:
-      case JSOP_GOSUBX:
       case JSOP_RETSUB:
       case JSOP_CONDSWITCH:
       case JSOP_DEFAULT:
-      case JSOP_DEFAULTX:
       case JSOP_POPN:
       case JSOP_STARTXML:
       case JSOP_STARTXMLEXPR:
       case JSOP_DEFXMLNS:
       case JSOP_SHARPINIT:
       case JSOP_INDEXBASE:
       case JSOP_INDEXBASE1:
       case JSOP_INDEXBASE2:
       case JSOP_INDEXBASE3:
       case JSOP_RESETBASE:
       case JSOP_RESETBASE0:
       case JSOP_POPV:
       case JSOP_DEBUGGER:
       case JSOP_SETCALL:
       case JSOP_TABLESWITCH:
-      case JSOP_TABLESWITCHX:
       case JSOP_LOOKUPSWITCH:
-      case JSOP_LOOKUPSWITCHX:
       case JSOP_TRY:
       case JSOP_LABEL:
-      case JSOP_LABELX:
         break;
 
         /* Bytecodes pushing values of known type. */
       case JSOP_VOID:
       case JSOP_UNDEFINED:
         pushed[0].addType(cx, Type::UndefinedType());
         break;
       case JSOP_ZERO:
@@ -3516,19 +3506,17 @@ ScriptAnalysis::analyzeTypesBytecode(JSC
 
       case JSOP_STOP:
         /* If a stop is reachable then the return type may be void. */
           if (script->function())
             TypeScript::ReturnTypes(script)->addType(cx, Type::UndefinedType());
         break;
 
       case JSOP_OR:
-      case JSOP_ORX:
       case JSOP_AND:
-      case JSOP_ANDX:
         /* OR/AND push whichever operand determined the result. */
         poppedTypes(pc, 0)->addSubset(cx, &pushed[0]);
         break;
 
       case JSOP_DUP:
         poppedTypes(pc, 0)->addSubset(cx, &pushed[0]);
         poppedTypes(pc, 0)->addSubset(cx, &pushed[1]);
         break;
@@ -4048,17 +4036,16 @@ ScriptAnalysis::analyzeTypesBytecode(JSC
       case JSOP_LEAVEBLOCKEXPR:
         poppedTypes(pc, 0)->addSubset(cx, &pushed[0]);
         break;
 
       case JSOP_LEAVEFORLETIN:
         break;
 
       case JSOP_CASE:
-      case JSOP_CASEX:
         poppedTypes(pc, 1)->addSubset(cx, &pushed[0]);
         break;
 
       case JSOP_GENERATOR:
           if (script->function()) {
             if (script->hasGlobal()) {
                 JSObject *proto = script->global()->getOrCreateGeneratorPrototype(cx);
                 if (!proto)
@@ -5435,19 +5422,17 @@ IgnorePushed(const jsbytecode *pc, unsig
       case JSOP_LT:
       case JSOP_LE:
       case JSOP_GT:
       case JSOP_GE:
         return (index == 0);
 
       /* Value not determining result is not pushed by OR/AND. */
       case JSOP_OR:
-      case JSOP_ORX:
       case JSOP_AND:
-      case JSOP_ANDX:
         return (index == 0);
 
       /* Holes tracked separately. */
       case JSOP_HOLE:
         return (index == 0);
       case JSOP_FILTER:
         return (index == 1);
 
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1789,31 +1789,39 @@ js::Interpret(JSContext *cx, StackFrame 
 #endif
     }
 
 /* No-ops for ease of decompilation. */
 ADD_EMPTY_CASE(JSOP_NOP)
 ADD_EMPTY_CASE(JSOP_UNUSED0)
 ADD_EMPTY_CASE(JSOP_UNUSED1)
 ADD_EMPTY_CASE(JSOP_UNUSED2)
+ADD_EMPTY_CASE(JSOP_UNUSED3)
+ADD_EMPTY_CASE(JSOP_UNUSED4)
+ADD_EMPTY_CASE(JSOP_UNUSED5)
+ADD_EMPTY_CASE(JSOP_UNUSED6)
+ADD_EMPTY_CASE(JSOP_UNUSED7)
+ADD_EMPTY_CASE(JSOP_UNUSED8)
+ADD_EMPTY_CASE(JSOP_UNUSED9)
+ADD_EMPTY_CASE(JSOP_UNUSED10)
+ADD_EMPTY_CASE(JSOP_UNUSED11)
+ADD_EMPTY_CASE(JSOP_UNUSED12)
+ADD_EMPTY_CASE(JSOP_UNUSED13)
 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_LOOPHEAD)
 END_EMPTY_CASES
 
 BEGIN_CASE(JSOP_LABEL)
 END_CASE(JSOP_LABEL)
 
-BEGIN_CASE(JSOP_LABELX)
-END_CASE(JSOP_LABELX)
-
 check_backedge:
 {
     CHECK_BRANCH();
     if (op != JSOP_LOOPHEAD)
         DO_OP();
 
 #ifdef JS_METHODJIT
     if (!useMethodJIT)
@@ -2019,74 +2027,16 @@ BEGIN_CASE(JSOP_AND)
     VALUE_TO_BOOLEAN(cx, _, cond);
     if (cond == false) {
         len = GET_JUMP_OFFSET(regs.pc);
         DO_NEXT_OP(len);
     }
 }
 END_CASE(JSOP_AND)
 
-BEGIN_CASE(JSOP_DEFAULTX)
-    regs.sp--;
-    /* FALL THROUGH */
-BEGIN_CASE(JSOP_GOTOX)
-{
-    len = GET_JUMPX_OFFSET(regs.pc);
-    BRANCH(len);
-}
-END_CASE(JSOP_GOTOX);
-
-BEGIN_CASE(JSOP_IFEQX)
-{
-    bool cond;
-    Value *_;
-    POP_BOOLEAN(cx, _, cond);
-    if (cond == false) {
-        len = GET_JUMPX_OFFSET(regs.pc);
-        BRANCH(len);
-    }
-}
-END_CASE(JSOP_IFEQX)
-
-BEGIN_CASE(JSOP_IFNEX)
-{
-    bool cond;
-    Value *_;
-    POP_BOOLEAN(cx, _, cond);
-    if (cond != false) {
-        len = GET_JUMPX_OFFSET(regs.pc);
-        BRANCH(len);
-    }
-}
-END_CASE(JSOP_IFNEX)
-
-BEGIN_CASE(JSOP_ORX)
-{
-    bool cond;
-    Value *_;
-    VALUE_TO_BOOLEAN(cx, _, cond);
-    if (cond == true) {
-        len = GET_JUMPX_OFFSET(regs.pc);
-        DO_NEXT_OP(len);
-    }
-}
-END_CASE(JSOP_ORX)
-
-BEGIN_CASE(JSOP_ANDX)
-{
-    bool cond;
-    Value *_;
-    VALUE_TO_BOOLEAN(cx, _, cond);
-    if (cond == JS_FALSE) {
-        len = GET_JUMPX_OFFSET(regs.pc);
-        DO_NEXT_OP(len);
-    }
-}
-END_CASE(JSOP_ANDX)
-
 /*
  * If the index value at sp[n] is not an int that fits in a jsval, it could
  * be an object (an XML QName, AttributeName, or AnyName), but only if we are
  * compiling with JS_HAS_XML_SUPPORT.  Otherwise convert the index value to a
  * string atom id.
  */
 #define FETCH_ELEMENT_ID(obj, n, id)                                          \
     JS_BEGIN_MACRO                                                            \
@@ -2373,28 +2323,16 @@ BEGIN_CASE(JSOP_CASE)
     if (cond) {
         regs.sp--;
         len = GET_JUMP_OFFSET(regs.pc);
         BRANCH(len);
     }
 }
 END_CASE(JSOP_CASE)
 
-BEGIN_CASE(JSOP_CASEX)
-{
-    bool cond;
-    STRICT_EQUALITY_OP(==, cond);
-    if (cond) {
-        regs.sp--;
-        len = GET_JUMPX_OFFSET(regs.pc);
-        BRANCH(len);
-    }
-}
-END_CASE(JSOP_CASEX)
-
 #undef STRICT_EQUALITY_OP
 
 #define RELATIONAL_OP(OP)                                                     \
     JS_BEGIN_MACRO                                                            \
         Value &rval = regs.sp[-1];                                            \
         Value &lval = regs.sp[-2];                                            \
         bool cond;                                                            \
         /* Optimize for two int-tagged operands (typical loop control). */    \
@@ -3311,67 +3249,24 @@ BEGIN_CASE(JSOP_TABLESWITCH)
         if (off)
             len = off;
     }
 }
 END_VARLEN_CASE
 }
 
 {
-BEGIN_CASE(JSOP_TABLESWITCHX)
+BEGIN_CASE(JSOP_LOOKUPSWITCH)
 {
-    jsbytecode *pc2 = regs.pc;
-    len = GET_JUMPX_OFFSET(pc2);
+    jsint off;
+    off = JUMP_OFFSET_LEN;
 
     /*
-     * ECMAv2+ forbids conversion of discriminant, so we will skip to the
-     * default case if the discriminant isn't already an int jsval.  (This
-     * opcode is emitted only for dense jsint-domain switches.)
-     */
-    const Value &rref = *--regs.sp;
-    int32_t i;
-    if (rref.isInt32()) {
-        i = rref.toInt32();
-    } else if (rref.isDouble() && rref.toDouble() == 0) {
-        /* Treat -0 (double) as 0. */
-        i = 0;
-    } else {
-        DO_NEXT_OP(len);
-    }
-
-    pc2 += JUMPX_OFFSET_LEN;
-    jsint low = GET_JUMP_OFFSET(pc2);
-    pc2 += JUMP_OFFSET_LEN;
-    jsint high = GET_JUMP_OFFSET(pc2);
-
-    i -= low;
-    if ((jsuint)i < (jsuint)(high - low + 1)) {
-        pc2 += JUMP_OFFSET_LEN + JUMPX_OFFSET_LEN * i;
-        jsint off = (jsint) GET_JUMPX_OFFSET(pc2);
-        if (off)
-            len = off;
-    }
-}
-END_VARLEN_CASE
-}
-
-{
-BEGIN_CASE(JSOP_LOOKUPSWITCHX)
-{
-    jsint off;
-    off = JUMPX_OFFSET_LEN;
-    goto do_lookup_switch;
-
-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.
+     * JSOP_LOOKUPSWITCH are never used if any atom index in it would exceed
+     * 64K limit.
      */
     JS_ASSERT(atoms == script->atoms);
     jsbytecode *pc2 = regs.pc;
 
     Value lval = regs.sp[-1];
     regs.sp--;
 
     if (!lval.isPrimitive())
@@ -3416,19 +3311,17 @@ BEGIN_CASE(JSOP_LOOKUPSWITCH)
     } else {
         SEARCH_PAIRS(
             match = (lval == rval);
         )
     }
 #undef SEARCH_PAIRS
 
   end_lookup_switch:
-    len = (op == JSOP_LOOKUPSWITCH)
-          ? GET_JUMP_OFFSET(pc2)
-          : GET_JUMPX_OFFSET(pc2);
+    len = GET_JUMP_OFFSET(pc2);
 }
 END_VARLEN_CASE
 }
 
 BEGIN_CASE(JSOP_ARGUMENTS)
 {
     Value rval;
     if (cx->typeInferenceEnabled() && !script->strictModeCode) {
@@ -4194,26 +4087,17 @@ BEGIN_CASE(JSOP_SHARPINIT)
 END_CASE(JSOP_SHARPINIT)
 
 #endif /* JS_HAS_SHARP_VARS */
 
 {
 BEGIN_CASE(JSOP_GOSUB)
     PUSH_BOOLEAN(false);
     jsint i = (regs.pc - script->code) + JSOP_GOSUB_LENGTH;
-    PUSH_INT32(i);
     len = GET_JUMP_OFFSET(regs.pc);
-END_VARLEN_CASE
-}
-
-{
-BEGIN_CASE(JSOP_GOSUBX)
-    PUSH_BOOLEAN(false);
-    jsint i = (regs.pc - script->code) + JSOP_GOSUBX_LENGTH;
-    len = GET_JUMPX_OFFSET(regs.pc);
     PUSH_INT32(i);
 END_VARLEN_CASE
 }
 
 {
 BEGIN_CASE(JSOP_RETSUB)
     /* Pop [exception or hole, retsub pc-index]. */
     Value rval, lval;
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -140,27 +140,16 @@ const char *js_CodeName[] = {
 typedef Vector<char, 8> DupBuffer;
 
 static bool
 Dup(const char *chars, DupBuffer *cb)
 {
     return cb->append(chars, strlen(chars) + 1);
 }
 
-static ptrdiff_t
-GetJumpOffset(jsbytecode *pc, jsbytecode *pc2)
-{
-    uint32_t type;
-
-    type = JOF_OPTYPE(*pc);
-    if (JOF_TYPE_IS_EXTENDED_JUMP(type))
-        return GET_JUMPX_OFFSET(pc2);
-    return GET_JUMP_OFFSET(pc2);
-}
-
 uintN
 js_GetIndexFromBytecode(JSScript *script, jsbytecode *pc, ptrdiff_t pcoff)
 {
     JSOp op = JSOp(*pc);
     JS_ASSERT(js_CodeSpec[op].length >= 1 + pcoff + UINT16_LEN);
 
     /*
      * We need to detect index base prefix. It presents when resetbase
@@ -180,47 +169,37 @@ js_GetIndexFromBytecode(JSScript *script
         }
     }
     return base + GET_UINT16(pc + pcoff);
 }
 
 size_t
 js_GetVariableBytecodeLength(jsbytecode *pc)
 {
-    uintN jmplen, ncases;
+    uintN ncases;
     jsint low, high;
 
     JSOp op = JSOp(*pc);
     JS_ASSERT(js_CodeSpec[op].length == -1);
     switch (op) {
-      case JSOP_TABLESWITCHX:
-        jmplen = JUMPX_OFFSET_LEN;
-        goto do_table;
       case JSOP_TABLESWITCH:
-        jmplen = JUMP_OFFSET_LEN;
-      do_table:
         /* Structure: default-jump case-low case-high case1-jump ... */
-        pc += jmplen;
+        pc += JUMP_OFFSET_LEN;
         low = GET_JUMP_OFFSET(pc);
         pc += JUMP_OFFSET_LEN;
         high = GET_JUMP_OFFSET(pc);
         ncases = (uintN)(high - low + 1);
-        return 1 + jmplen + INDEX_LEN + INDEX_LEN + ncases * jmplen;
-
-      case JSOP_LOOKUPSWITCHX:
-        jmplen = JUMPX_OFFSET_LEN;
-        goto do_lookup;
+        return 1 + 3 * JUMP_OFFSET_LEN + ncases * JUMP_OFFSET_LEN;
+
       default:
+        /* Structure: default-jump case-count (case1-value case1-jump) ... */
         JS_ASSERT(op == JSOP_LOOKUPSWITCH);
-        jmplen = JUMP_OFFSET_LEN;
-      do_lookup:
-        /* Structure: default-jump case-count (case1-value case1-jump) ... */
-        pc += jmplen;
+        pc += JUMP_OFFSET_LEN;
         ncases = GET_UINT16(pc);
-        return 1 + jmplen + INDEX_LEN + ncases * (INDEX_LEN + jmplen);
+        return 1 + JUMP_OFFSET_LEN + INDEX_LEN + ncases * (INDEX_LEN + JUMP_OFFSET_LEN);
     }
 }
 
 static uint32_t
 NumBlockSlots(JSScript *script, jsbytecode *pc)
 {
     JS_ASSERT(*pc == JSOP_ENTERBLOCK || *pc == JSOP_ENTERLET0 || *pc == JSOP_ENTERLET1);
     JS_STATIC_ASSERT(JSOP_ENTERBLOCK_LENGTH == JSOP_ENTERLET0_LENGTH);
@@ -580,19 +559,18 @@ js_Disassemble1(JSContext *cx, JSScript 
                              (unsigned int) (loc+note.length+1),
                              (int) (note.length+1));
                       break;
                   }
               }
           }
         break;
 
-      case JOF_JUMP:
-      case JOF_JUMPX: {
-        ptrdiff_t off = GetJumpOffset(pc, pc);
+      case JOF_JUMP: {
+        ptrdiff_t off = GET_JUMP_OFFSET(pc);
         Sprint(sp, " %u (%+d)", loc + (intN) off, (intN) off);
         break;
       }
 
       case JOF_ATOM:
       case JOF_OBJECT:
       case JOF_REGEXP: {
         uintN index = js_GetIndexFromBytecode(script, pc, 0);
@@ -623,57 +601,49 @@ js_Disassemble1(JSContext *cx, JSScript 
             if (!ToDisassemblySource(cx, v, &bytes))
                 return 0;
             Sprint(sp, " %s", bytes.ptr());
         }
         break;
       }
 
       case JOF_TABLESWITCH:
-      case JOF_TABLESWITCHX:
       {
-        jsbytecode *pc2;
         jsint i, low, high;
 
-        ptrdiff_t jmplen = (type == JOF_TABLESWITCH) ? JUMP_OFFSET_LEN : JUMPX_OFFSET_LEN;
-        pc2 = pc;
-        ptrdiff_t off = GetJumpOffset(pc, pc2);
-        pc2 += jmplen;
+        ptrdiff_t off = GET_JUMP_OFFSET(pc);
+        jsbytecode *pc2 = pc + JUMP_OFFSET_LEN;
         low = GET_JUMP_OFFSET(pc2);
         pc2 += JUMP_OFFSET_LEN;
         high = GET_JUMP_OFFSET(pc2);
         pc2 += JUMP_OFFSET_LEN;
         Sprint(sp, " defaultOffset %d low %d high %d", intN(off), low, high);
         for (i = low; i <= high; i++) {
-            off = GetJumpOffset(pc, pc2);
+            off = GET_JUMP_OFFSET(pc2);
             Sprint(sp, "\n\t%d: %d", i, intN(off));
-            pc2 += jmplen;
+            pc2 += JUMP_OFFSET_LEN;
         }
         len = 1 + pc2 - pc;
         break;
       }
 
       case JOF_LOOKUPSWITCH:
-      case JOF_LOOKUPSWITCHX:
       {
-        jsbytecode *pc2;
         jsatomid npairs;
 
-        ptrdiff_t jmplen = (type == JOF_LOOKUPSWITCH) ? JUMP_OFFSET_LEN : JUMPX_OFFSET_LEN;
-        pc2 = pc;
-        ptrdiff_t off = GetJumpOffset(pc, pc2);
-        pc2 += jmplen;
+        ptrdiff_t off = GET_JUMP_OFFSET(pc);
+        jsbytecode *pc2 = pc + JUMP_OFFSET_LEN;
         npairs = GET_UINT16(pc2);
         pc2 += UINT16_LEN;
         Sprint(sp, " offset %d npairs %u", intN(off), uintN(npairs));
         while (npairs) {
             uint16_t constIndex = GET_INDEX(pc2);
             pc2 += INDEX_LEN;
-            off = GetJumpOffset(pc, pc2);
-            pc2 += jmplen;
+            off = GET_JUMP_OFFSET(pc2);
+            pc2 += JUMP_OFFSET_LEN;
 
             JSAutoByteString bytes;
             if (!ToDisassemblySource(cx, script->getConst(constIndex), &bytes))
                 return 0;
             Sprint(sp, "\n\t%s: %d", bytes.ptr(), intN(off));
             npairs--;
         }
         len = 1 + pc2 - pc;
@@ -2381,20 +2351,20 @@ SprintNormalFor(JSContext *cx, JSPrinter
     ptrdiff_t tail = js_GetSrcNoteOffset(sn, 2);
 
     /*
      * If this loop has a condition, then pc points at a goto
      * targeting the condition.
      */
     jsbytecode *pc2 = pc;
     if (cond != tail) {
-        LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
-        pc2 += (*pc == JSOP_GOTO) ? JSOP_GOTO_LENGTH : JSOP_GOTOX_LENGTH;
+        LOCAL_ASSERT(*pc == JSOP_GOTO);
+        pc2 += JSOP_GOTO_LENGTH;
     }
-    LOCAL_ASSERT(tail + GetJumpOffset(pc+tail, pc+tail) == pc2 - pc);
+    LOCAL_ASSERT(tail + GET_JUMP_OFFSET(pc + tail) == pc2 - pc);
 
     if (cond != tail) {
         /* Decompile the loop condition. */
         if (!Decompile(ss, pc + cond, tail - cond))
             return -1;
         js_printf(jp, " ");
         jsbytecode *condpc;
         const char *cond = PopStr(ss, JSOP_NOP, &condpc);
@@ -2818,18 +2788,17 @@ Decompile(SprintStack *ss, jsbytecode *p
                 todo = -2;
                 switch (sn ? SN_TYPE(sn) : SRC_NULL) {
                   case SRC_WHILE:
                     /* First instuction (NOP) contains offset to condition */
                     ++pc;
                     /* Second instruction (TRACE) contains offset to JSOP_IFNE */
                     sn = js_GetSrcNote(jp->script, pc);
                     tail = js_GetSrcNoteOffset(sn, 0);
-                    LOCAL_ASSERT(pc[tail] == JSOP_IFNE ||
-                                 pc[tail] == JSOP_IFNEX);
+                    LOCAL_ASSERT(pc[tail] == JSOP_IFNE);
                     js_printf(jp, "\tdo {\n");
                     jp->indent += 4;
                     DECOMPILE_CODE(pc, tail);
                     jp->indent -= 4;
                     js_printf(jp, "\t} while (");
                     rval = PopCondStr(ss, &rvalpc);
                     SprintOpcodePermanent(jp, rval, rvalpc);
                     js_printf(jp, ");\n");
@@ -2875,17 +2844,16 @@ Decompile(SprintStack *ss, jsbytecode *p
                     js_printf(jp, "\t}\n");
                     break;
 
                   default:;
                 }
                 break;
 
               case JSOP_LABEL:
-              case JSOP_LABELX:
                 sn = js_GetSrcNote(jp->script, pc);
                 todo = -2;
                 switch (sn ? SN_TYPE(sn) : SRC_NULL) {
                   case SRC_LABEL:
                     GET_SOURCE_NOTE_ATOM(sn, atom);
                     jp->indent -= 4;
                     rval = QuoteString(&ss->sprinter, atom, 0);
                     if (!rval)
@@ -2942,21 +2910,20 @@ Decompile(SprintStack *ss, jsbytecode *p
                 rval = POP_STR();
                 LOCAL_ASSERT(strcmp(rval, retsub_pc_cookie) == 0);
                 lval = POP_STR();
                 LOCAL_ASSERT(strcmp(lval, exception_cookie) == 0);
                 todo = -2;
                 break;
 
               case JSOP_GOSUB:
-              case JSOP_GOSUBX:
                 /*
-                 * JSOP_GOSUB and GOSUBX have no effect on the decompiler's
-                 * string stack because the next op in bytecode order finds
-                 * the stack balanced by a JSOP_RETSUB executed elsewhere.
+                 * JSOP_GOSUB has no effect on the decompiler's string stack
+                 * because the next op in bytecode order finds the stack
+                 * balanced by a JSOP_RETSUB executed elsewhere.
                  */
                 todo = -2;
                 break;
 
               case JSOP_POPN:
               {
                 uintN newtop, oldtop;
 
@@ -3271,17 +3238,17 @@ Decompile(SprintStack *ss, jsbytecode *p
                     if (len) {
                         len -= pc - pc2;
                         LOCAL_ASSERT(len > 0);
                         js_printf(jp, " if ");
                         if (!Decompile(ss, pc, len))
                             return NULL;
                         js_printf(jp, "%s", POP_STR());
                         pc += len;
-                        LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);
+                        LOCAL_ASSERT(*pc == JSOP_IFEQ);
                         pc += js_CodeSpec[*pc].length;
                     }
 
                     js_printf(jp, ") {\n");
                     jp->indent += 4;
                     len = 0;
                     break;
                   default:;
@@ -3461,22 +3428,22 @@ Decompile(SprintStack *ss, jsbytecode *p
 
                 AtomVector atoms(cx);
                 if (!GetBlockNames(cx, blockObj, &atoms))
                     return NULL;
 
                 LOCAL_ASSERT(js_GetSrcNote(jp->script, pc) == NULL);
                 LOCAL_ASSERT(ss->top - 1 == blockObj.stackDepth() + blockObj.slotCount());
                 jsbytecode *nextpc = pc + JSOP_ENTERLET1_LENGTH;
-                if (*nextpc == JSOP_GOTO || *nextpc == JSOP_GOTOX) {
+                if (*nextpc == JSOP_GOTO) {
                     LOCAL_ASSERT(SN_TYPE(js_GetSrcNote(jp->script, nextpc)) == SRC_FOR_IN);
                 } else {
                     LOCAL_ASSERT(*nextpc == JSOP_CONDSWITCH ||
-                                 *nextpc == JSOP_TABLESWITCH || *nextpc == JSOP_TABLESWITCHX ||
-                                 *nextpc == JSOP_LOOKUPSWITCH || *nextpc == JSOP_LOOKUPSWITCHX);
+                                 *nextpc == JSOP_TABLESWITCH ||
+                                 *nextpc == JSOP_LOOKUPSWITCH);
                 }
 
                 DupBuffer rhs(cx);
                 if (!Dup(PopStr(ss, JSOP_NOP), &rhs))
                     return NULL;
                 if (!AssignBlockNamesToPushedSlots(cx, ss, atoms))
                     return NULL;
                 if (!PushStr(ss, rhs.begin(), op))
@@ -3776,17 +3743,16 @@ Decompile(SprintStack *ss, jsbytecode *p
                 sn = js_GetSrcNote(jp->script, pc);
                 todo = -2;
                 if (sn && SN_TYPE(sn) == SRC_HIDDEN)
                     break;
                 (void) PopOff(ss, op);
                 break;
 
               case JSOP_GOTO:
-              case JSOP_GOTOX:
                 sn = js_GetSrcNote(jp->script, pc);
                 switch (sn ? SN_TYPE(sn) : SRC_NULL) {
                   case SRC_FOR_IN:
                     /*
                      * The bytecode around pc looks like this:
                      *     <<RHS>>
                      *     iter
                      * pc: goto/gotox C         [src_for_in(B, D)]
@@ -3808,17 +3774,17 @@ Decompile(SprintStack *ss, jsbytecode *p
                      * Otherwise this is a for-in statement. We eagerly output
                      * the for-head and recurse to decompile the controlled
                      * statement S.
                      *
                      * We never decompile the obligatory JSOP_POP,
                      * JSOP_MOREITER or JSOP_IFNE, though we do quick asserts
                      * to check that they are there.
                      */
-                    cond = GetJumpOffset(pc, pc);
+                    cond = GET_JUMP_OFFSET(pc);
                     next = js_GetSrcNoteOffset(sn, 0);
                     tail = js_GetSrcNoteOffset(sn, 1);
                     JS_ASSERT(pc[next] == JSOP_POP);
                     JS_ASSERT(pc[cond] == JSOP_MOREITER);
                     DECOMPILE_CODE(pc + oplen, next - oplen);
                     lval = POP_STR();
 
                     /*
@@ -3866,34 +3832,34 @@ Decompile(SprintStack *ss, jsbytecode *p
                                   xval, lval, rval);
                         jp->indent += 4;
                         DECOMPILE_CODE(pc + next + JSOP_POP_LENGTH, cond - next - JSOP_POP_LENGTH);
                         jp->indent -= 4;
                         js_printf(jp, "\t}\n");
                     }
 
                     pc += tail;
-                    LOCAL_ASSERT(*pc == JSOP_IFNE || *pc == JSOP_IFNEX);
+                    LOCAL_ASSERT(*pc == JSOP_IFNE);
                     len = js_CodeSpec[*pc].length;
                     break;
 
                   case SRC_WHILE:
-                    cond = GetJumpOffset(pc, pc);
+                    cond = GET_JUMP_OFFSET(pc);
                     tail = js_GetSrcNoteOffset(sn, 0);
                     DECOMPILE_CODE(pc + cond, tail - cond);
                     js_printf(jp, "\twhile (");
                     rval = PopCondStr(ss, &rvalpc);
                     SprintOpcodePermanent(jp, rval, rvalpc);
                     js_printf(jp, ") {\n");
                     jp->indent += 4;
                     DECOMPILE_CODE(pc + oplen, cond - oplen);
                     jp->indent -= 4;
                     js_printf(jp, "\t}\n");
                     pc += tail;
-                    LOCAL_ASSERT(*pc == JSOP_IFNE || *pc == JSOP_IFNEX);
+                    LOCAL_ASSERT(*pc == JSOP_IFNE);
                     len = js_CodeSpec[*pc].length;
                     todo = -2;
                     break;
 
                   case SRC_CONT2LABEL:
                     GET_SOURCE_NOTE_ATOM(sn, atom);
                     rval = QuoteString(&ss->sprinter, atom, 0);
                     if (!rval)
@@ -3921,22 +3887,21 @@ Decompile(SprintStack *ss, jsbytecode *p
                   default:
                     js_printf(jp, "\tbreak;\n");
                     break;
                 }
                 todo = -2;
                 break;
 
               case JSOP_IFEQ:
-              case JSOP_IFEQX:
               {
                 JSBool elseif = JS_FALSE;
 
               if_again:
-                len = GetJumpOffset(pc, pc);
+                len = GET_JUMP_OFFSET(pc);
                 sn = js_GetSrcNote(jp->script, pc);
 
                 switch (sn ? SN_TYPE(sn) : SRC_NULL) {
                   case SRC_IF:
                   case SRC_IF_ELSE:
                     rval = PopCondStr(ss, &rvalpc);
                     if (ss->inArrayInit || ss->inGenExp) {
                         LOCAL_ASSERT(SN_TYPE(sn) == SRC_IF);
@@ -3954,19 +3919,19 @@ Decompile(SprintStack *ss, jsbytecode *p
                     if (SN_TYPE(sn) == SRC_IF) {
                         DECOMPILE_CODE(pc + oplen, len - oplen);
                     } else {
                         LOCAL_ASSERT(!ss->inArrayInit && !ss->inGenExp);
                         tail = js_GetSrcNoteOffset(sn, 0);
                         DECOMPILE_CODE(pc + oplen, tail - oplen);
                         jp->indent -= 4;
                         pc += tail;
-                        LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
+                        LOCAL_ASSERT(*pc == JSOP_GOTO);
                         oplen = js_CodeSpec[*pc].length;
-                        len = GetJumpOffset(pc, pc);
+                        len = GET_JUMP_OFFSET(pc);
                         js_printf(jp, "\t} else");
 
                         /*
                          * If the second offset for sn is non-zero, it tells
                          * the distance from the goto around the else, to the
                          * ifeq for the if inside the else that forms an "if
                          * else if" chain.  Thus cond spans the condition of
                          * the second if, so we simply decompile it and start
@@ -3996,19 +3961,19 @@ Decompile(SprintStack *ss, jsbytecode *p
 
                   case SRC_COND:
                     xval = PopStrDupe(ss, op, &xvalpc);
                     len = js_GetSrcNoteOffset(sn, 0);
                     DECOMPILE_CODE(pc + oplen, len - oplen);
                     lval = PopStrDupe(ss, op, &lvalpc);
                     pushpc = pc;
                     pc += len;
-                    LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
+                    LOCAL_ASSERT(*pc == JSOP_GOTO);
                     oplen = js_CodeSpec[*pc].length;
-                    len = GetJumpOffset(pc, pc);
+                    len = GET_JUMP_OFFSET(pc);
                     DECOMPILE_CODE(pc + oplen, len - oplen);
                     rval = PopStrDupe(ss, op, &rvalpc);
                     todo = ss->sprinter.offset;
                     SprintOpcode(ss, xval, xvalpc, pushpc, todo);
                     SprintCString(&ss->sprinter, " ? ");
                     SprintOpcode(ss, lval, lvalpc, pushpc, todo);
                     SprintCString(&ss->sprinter, " : ");
                     SprintOpcode(ss, rval, rvalpc, pushpc, todo);
@@ -4016,28 +3981,26 @@ Decompile(SprintStack *ss, jsbytecode *p
 
                   default:
                     break;
                 }
                 break;
               }
 
               case JSOP_IFNE:
-              case JSOP_IFNEX:
                 LOCAL_ASSERT(0);
                 break;
 
               case JSOP_OR:
-              case JSOP_ORX:
                 xval = "||";
 
               do_logical_connective:
                 /* Top of stack is the first clause in a disjunction (||). */
                 lval = PopStrDupe(ss, op, &lvalpc);
-                done = pc + GetJumpOffset(pc, pc);
+                done = pc + GET_JUMP_OFFSET(pc);
                 pushpc = pc;
                 pc += len;
                 JS_ASSERT(*pc == JSOP_POP);
                 pc += JSOP_POP_LENGTH;
                 len = done - pc;
                 if (!Decompile(ss, pc, len))
                     return NULL;
                 rval = PopStrDupe(ss, op, &rvalpc);
@@ -4051,17 +4014,16 @@ Decompile(SprintStack *ss, jsbytecode *p
                     Sprint(&ss->sprinter, "%*s", jp->indent + 4, "");
                 } else {
                     Sprint(&ss->sprinter, " %s ", xval);
                 }
                 SprintOpcode(ss, rval, rvalpc, pushpc, todo);
                 break;
 
               case JSOP_AND:
-              case JSOP_ANDX:
                 xval = "&&";
                 goto do_logical_connective;
 
               case JSOP_ENUMELEM:
               case JSOP_ENUMCONSTELEM:
                 /*
                  * The stack has the object under the (top) index expression.
                  * The "rval" property id is underneath those two on the stack.
@@ -4842,29 +4804,26 @@ Decompile(SprintStack *ss, jsbytecode *p
               case JSOP_REGEXP:
                 GET_REGEXP_FROM_BYTECODE(jp->script, pc, 0, obj);
                 str = obj->asRegExp().toString(cx);
                 if (!str)
                     return NULL;
                 goto sprint_string;
 
               case JSOP_TABLESWITCH:
-              case JSOP_TABLESWITCHX:
               {
-                ptrdiff_t jmplen, off, off2;
+                ptrdiff_t off, off2;
                 jsint j, n, low, high;
                 TableEntry *table, *tmp;
 
                 sn = js_GetSrcNote(jp->script, pc);
                 LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
                 len = js_GetSrcNoteOffset(sn, 0);
-                jmplen = (op == JSOP_TABLESWITCH) ? JUMP_OFFSET_LEN : JUMPX_OFFSET_LEN;
-                pc2 = pc;
-                off = GetJumpOffset(pc, pc2);
-                pc2 += jmplen;
+                off = GET_JUMP_OFFSET(pc);
+                pc2 = pc + JUMP_OFFSET_LEN;
                 low = GET_JUMP_OFFSET(pc2);
                 pc2 += JUMP_OFFSET_LEN;
                 high = GET_JUMP_OFFSET(pc2);
                 pc2 += JUMP_OFFSET_LEN;
 
                 n = high - low + 1;
                 if (n == 0) {
                     table = NULL;
@@ -4872,29 +4831,29 @@ Decompile(SprintStack *ss, jsbytecode *p
                     ok = true;
                 } else {
                     table = (TableEntry *)
                             cx->malloc_((size_t)n * sizeof *table);
                     if (!table)
                         return NULL;
                     for (i = j = 0; i < n; i++) {
                         table[j].label = NULL;
-                        off2 = GetJumpOffset(pc, pc2);
+                        off2 = GET_JUMP_OFFSET(pc2);
                         if (off2) {
                             sn = js_GetSrcNote(jp->script, pc2);
                             if (sn) {
                                 LOCAL_ASSERT(SN_TYPE(sn) == SRC_LABEL);
                                 GET_SOURCE_NOTE_ATOM(sn, table[j].label);
                             }
                             table[j].key = INT_TO_JSVAL(low + i);
                             table[j].offset = off2;
                             table[j].order = j;
                             j++;
                         }
-                        pc2 += jmplen;
+                        pc2 += JUMP_OFFSET_LEN;
                     }
                     tmp = (TableEntry *)
                           cx->malloc_((size_t)j * sizeof *table);
                     if (tmp) {
                         MergeSort(table, size_t(j), tmp, CompareTableEntries);
                         Foreground::free_(tmp);
                         ok = true;
                     } else {
@@ -4907,30 +4866,26 @@ Decompile(SprintStack *ss, jsbytecode *p
                 cx->free_(table);
                 if (!ok)
                     return NULL;
                 todo = -2;
                 break;
               }
 
               case JSOP_LOOKUPSWITCH:
-              case JSOP_LOOKUPSWITCHX:
               {
-                ptrdiff_t jmplen, off, off2;
+                ptrdiff_t off, off2;
                 jsatomid npairs, k;
                 TableEntry *table;
 
                 sn = js_GetSrcNote(jp->script, pc);
                 LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
                 len = js_GetSrcNoteOffset(sn, 0);
-                jmplen = (op == JSOP_LOOKUPSWITCH) ? JUMP_OFFSET_LEN
-                                                   : JUMPX_OFFSET_LEN;
-                pc2 = pc;
-                off = GetJumpOffset(pc, pc2);
-                pc2 += jmplen;
+                off = GET_JUMP_OFFSET(pc);
+                pc2 = pc + JUMP_OFFSET_LEN;
                 npairs = GET_UINT16(pc2);
                 pc2 += UINT16_LEN;
 
                 table = (TableEntry *)
                     cx->malloc_((size_t)npairs * sizeof *table);
                 if (!table)
                     return NULL;
                 for (k = 0; k < npairs; k++) {
@@ -4938,18 +4893,18 @@ Decompile(SprintStack *ss, jsbytecode *p
                     if (sn) {
                         LOCAL_ASSERT(SN_TYPE(sn) == SRC_LABEL);
                         GET_SOURCE_NOTE_ATOM(sn, table[k].label);
                     } else {
                         table[k].label = NULL;
                     }
                     uint16_t constIndex = GET_INDEX(pc2);
                     pc2 += INDEX_LEN;
-                    off2 = GetJumpOffset(pc, pc2);
-                    pc2 += jmplen;
+                    off2 = GET_JUMP_OFFSET(pc2);
+                    pc2 += JUMP_OFFSET_LEN;
                     table[k].key = jp->script->getConst(constIndex);
                     table[k].offset = off2;
                 }
 
                 ok = DecompileSwitch(ss, table, (uintN)npairs, pc, len, off,
                                      JS_FALSE);
                 cx->free_(table);
                 if (!ok)
@@ -4972,19 +4927,18 @@ Decompile(SprintStack *ss, jsbytecode *p
                 /*
                  * Count the cases using offsets from switch to first case,
                  * and case to case, stored in srcnote immediates.
                  */
                 pc2 = pc;
                 off2 = off;
                 for (ncases = 0; off2 != 0; ncases++) {
                     pc2 += off2;
-                    LOCAL_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||
-                                 *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);
-                    if (*pc2 == JSOP_DEFAULT || *pc2 == JSOP_DEFAULTX) {
+                    LOCAL_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT);
+                    if (*pc2 == JSOP_DEFAULT) {
                         /* End of cases, but count default as a case. */
                         off2 = 0;
                     } else {
                         sn = js_GetSrcNote(jp->script, pc2);
                         LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);
                         off2 = js_GetSrcNoteOffset(sn, 0);
                     }
                 }
@@ -4997,48 +4951,46 @@ Decompile(SprintStack *ss, jsbytecode *p
                 table = (TableEntry *)
                     cx->malloc_((size_t)ncases * sizeof *table);
                 if (!table)
                     return NULL;
                 pc2 = pc;
                 off2 = off;
                 for (i = 0; i < ncases; i++) {
                     pc2 += off2;
-                    LOCAL_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT ||
-                                 *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX);
+                    LOCAL_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT);
                     caseOff = pc2 - pc;
                     table[i].key = INT_TO_JSVAL((jsint) caseOff);
-                    table[i].offset = caseOff + GetJumpOffset(pc2, pc2);
-                    if (*pc2 == JSOP_CASE || *pc2 == JSOP_CASEX) {
+                    table[i].offset = caseOff + GET_JUMP_OFFSET(pc2);
+                    if (*pc2 == JSOP_CASE) {
                         sn = js_GetSrcNote(jp->script, pc2);
                         LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA);
                         off2 = js_GetSrcNoteOffset(sn, 0);
                     }
                 }
 
                 /*
                  * Find offset of default code by fetching the default offset
                  * from the end of table.  JSOP_CONDSWITCH always has a default
                  * case at the end.
                  */
                 off = JSVAL_TO_INT(table[ncases-1].key);
                 pc2 = pc + off;
-                off += GetJumpOffset(pc2, pc2);
+                off += GET_JUMP_OFFSET(pc2);
 
                 ok = DecompileSwitch(ss, table, (uintN)ncases, pc, len, off,
                                      JS_TRUE);
                 cx->free_(table);
                 if (!ok)
                     return NULL;
                 todo = -2;
                 break;
               }
 
               case JSOP_CASE:
-              case JSOP_CASEX:
               {
                 lval = PopStr(ss, op, &lvalpc);
                 if (!lval)
                     return NULL;
                 js_printf(jp, "\tcase ");
                 SprintOpcodePermanent(jp, lval, lvalpc);
                 js_printf(jp, ":\n");
                 todo = -2;
@@ -5768,18 +5720,17 @@ static char *
 DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
                     jsbytecode *pc)
 {
     JS_ASSERT(script->code <= pc && pc < script->code + script->length);
 
     JSOp op = (JSOp) *pc;
 
     /* None of these stack-writing ops generates novel values. */
-    JS_ASSERT(op != JSOP_CASE && op != JSOP_CASEX &&
-              op != JSOP_DUP && op != JSOP_DUP2);
+    JS_ASSERT(op != JSOP_CASE && op != JSOP_DUP && op != JSOP_DUP2);
 
     /*
      * |this| could convert to a very long object initialiser, so cite it by
      * its keyword name instead.
      */
     if (op == JSOP_THIS)
         return JS_strdup(cx, js_this_str);
 
@@ -5892,17 +5843,16 @@ SimulateOp(JSContext *cx, JSScript *scri
       default:
         if (pcstack) {
             for (uintN i = 0; i != ndefs; ++i)
                 pcstack[pcdepth + i] = pc;
         }
         break;
 
       case JSOP_CASE:
-      case JSOP_CASEX:
         /* Keep the switch value. */
         JS_ASSERT(ndefs == 1);
         break;
 
       case JSOP_DUP:
         JS_ASSERT(ndefs == 2);
         if (pcstack)
             pcstack[pcdepth + 1] = pcstack[pcdepth];
@@ -5956,31 +5906,31 @@ ReconstructPCStack(JSContext *cx, JSScri
             if (lastDecomposedPC)
                 *lastDecomposedPC = pc;
             continue;
         }
 
         /*
          * A (C ? T : E) expression requires skipping either T (if target is in
          * E) or both T and E (if target is after the whole expression) before
-         * adjusting pcdepth based on the JSOP_IFEQ or JSOP_IFEQX at pc that
-         * tests condition C.  We know that the stack depth can't change from
-         * what it was with C on top of stack.
+         * adjusting pcdepth based on the JSOP_IFEQ at pc that tests condition
+         * C. We know that the stack depth can't change from what it was with
+         * C on top of stack.
          */
         jssrcnote *sn = js_GetSrcNote(script, pc);
         if (sn && SN_TYPE(sn) == SRC_COND) {
             ptrdiff_t jmpoff = js_GetSrcNoteOffset(sn, 0);
             if (pc + jmpoff < target) {
                 pc += jmpoff;
                 op = JSOp(*pc);
-                JS_ASSERT(op == JSOP_GOTO || op == JSOP_GOTOX);
+                JS_ASSERT(op == JSOP_GOTO);
                 cs = &js_CodeSpec[op];
                 oplen = cs->length;
                 JS_ASSERT(oplen > 0);
-                ptrdiff_t jmplen = GetJumpOffset(pc, pc);
+                ptrdiff_t jmplen = GET_JUMP_OFFSET(pc);
                 if (pc + jmplen < target) {
                     oplen = (uintN) jmplen;
                     continue;
                 }
 
                 /*
                  * Ok, target lies in E. Manually pop C off the model stack,
                  * since we have moved beyond the IFEQ now.
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -78,19 +78,16 @@ typedef enum JSOp {
 #define JOF_JUMP          1       /* signed 16-bit jump offset immediate */
 #define JOF_ATOM          2       /* unsigned 16-bit constant index */
 #define JOF_UINT16        3       /* unsigned 16-bit immediate operand */
 #define JOF_TABLESWITCH   4       /* table switch */
 #define JOF_LOOKUPSWITCH  5       /* lookup switch */
 #define JOF_QARG          6       /* quickened get/set function argument ops */
 #define JOF_LOCAL         7       /* var or block-local variable */
 #define JOF_SLOTATOM      8       /* uint16_t slot + constant index */
-#define JOF_JUMPX         9       /* signed 32-bit jump offset immediate */
-#define JOF_TABLESWITCHX  10      /* extended (32-bit offset) table switch */
-#define JOF_LOOKUPSWITCHX 11      /* extended (32-bit offset) lookup switch */
 #define JOF_UINT24        12      /* extended unsigned 24-bit literal (index) */
 #define JOF_UINT8         13      /* uint8_t immediate, e.g. top 8 bits of 24-bit
                                      atom index */
 #define JOF_INT32         14      /* int32_t immediate operand */
 #define JOF_OBJECT        15      /* unsigned 16-bit object index */
 #define JOF_SLOTOBJECT    16      /* uint16_t slot index + object index */
 #define JOF_REGEXP        17      /* unsigned 16-bit regexp index */
 #define JOF_INT8          18      /* int8_t immediate operand */
@@ -143,72 +140,49 @@ typedef enum JSOp {
 #define JOF_TYPE(fmt)   ((fmt) & JOF_TYPEMASK)
 #define JOF_OPTYPE(op)  JOF_TYPE(js_CodeSpec[op].format)
 
 /* Shorthands for mode from format and mode from opcode. */
 #define JOF_MODE(fmt)   ((fmt) & JOF_MODEMASK)
 #define JOF_OPMODE(op)  JOF_MODE(js_CodeSpec[op].format)
 
 #define JOF_TYPE_IS_EXTENDED_JUMP(t) \
-    ((unsigned)((t) - JOF_JUMPX) <= (unsigned)(JOF_LOOKUPSWITCHX - JOF_JUMPX))
+    ((unsigned)((t) - JOF_JUMP) <= (unsigned)(JOF_LOOKUPSWITCH - JOF_JUMP))
 
 /*
  * Immediate operand getters, setters, and bounds.
  */
 
 /* Common uint16_t immediate format helpers. */
 #define UINT16_LEN              2
 #define UINT16_HI(i)            ((jsbytecode)((i) >> 8))
 #define UINT16_LO(i)            ((jsbytecode)(i))
 #define GET_UINT16(pc)          ((uintN)(((pc)[1] << 8) | (pc)[2]))
 #define SET_UINT16(pc,i)        ((pc)[1] = UINT16_HI(i), (pc)[2] = UINT16_LO(i))
 #define UINT16_LIMIT            ((uintN)1 << 16)
 
-/* Short (2-byte signed offset) relative jump macros. */
-#define JUMP_OFFSET_LEN         2
-#define JUMP_OFFSET_HI(off)     ((jsbytecode)((off) >> 8))
-#define JUMP_OFFSET_LO(off)     ((jsbytecode)(off))
-#define GET_JUMP_OFFSET(pc)     (int16_t(GET_UINT16(pc)))
-#define SET_JUMP_OFFSET(pc,off) ((pc)[1] = JUMP_OFFSET_HI(off),               \
-                                 (pc)[2] = JUMP_OFFSET_LO(off))
-#define JUMP_OFFSET_MIN         ((int16_t)0x8000)
-#define JUMP_OFFSET_MAX         ((int16_t)0x7fff)
+/* Helpers for accessing the offsets of jump opcodes. */
+#define JUMP_OFFSET_LEN         4
+#define JUMP_OFFSET_MIN         INT32_MIN
+#define JUMP_OFFSET_MAX         INT32_MAX
 
-/*
- * When a short jump won't hold a relative offset, its 2-byte immediate offset
- * operand is an unsigned index of a span-dependency record, maintained until
- * code generation finishes -- after which some (but we hope not nearly all)
- * span-dependent jumps must be extended (see js::frontend::OptimizeSpanDeps in
- * frontend/BytecodeEmitter.cpp).
- *
- * If the span-dependency record index overflows SPANDEP_INDEX_MAX, the jump
- * offset will contain SPANDEP_INDEX_HUGE, indicating that the record must be
- * found (via binary search) by its "before span-dependency optimization" pc
- * offset (from script main entry point).
- */
-#define GET_SPANDEP_INDEX(pc)   (uint16_t(GET_UINT16(pc)))
-#define SET_SPANDEP_INDEX(pc,i) ((pc)[1] = JUMP_OFFSET_HI(i),                 \
-                                 (pc)[2] = JUMP_OFFSET_LO(i))
-#define SPANDEP_INDEX_MAX       ((uint16_t)0xfffe)
-#define SPANDEP_INDEX_HUGE      ((uint16_t)0xffff)
+static JS_ALWAYS_INLINE int32_t
+GET_JUMP_OFFSET(jsbytecode *pc)
+{
+    return (pc[1] << 24) | (pc[2] << 16) | (pc[3] << 8) | pc[4];
+}
 
-/* Ultimately, if short jumps won't do, emit long (4-byte signed) offsets. */
-#define JUMPX_OFFSET_LEN        4
-#define JUMPX_OFFSET_B3(off)    ((jsbytecode)((off) >> 24))
-#define JUMPX_OFFSET_B2(off)    ((jsbytecode)((off) >> 16))
-#define JUMPX_OFFSET_B1(off)    ((jsbytecode)((off) >> 8))
-#define JUMPX_OFFSET_B0(off)    ((jsbytecode)(off))
-#define GET_JUMPX_OFFSET(pc)    (int32_t(((pc)[1] << 24) | ((pc)[2] << 16)    \
-                                          | ((pc)[3] << 8) | (pc)[4]))
-#define SET_JUMPX_OFFSET(pc,off)((pc)[1] = JUMPX_OFFSET_B3(off),              \
-                                 (pc)[2] = JUMPX_OFFSET_B2(off),              \
-                                 (pc)[3] = JUMPX_OFFSET_B1(off),              \
-                                 (pc)[4] = JUMPX_OFFSET_B0(off))
-#define JUMPX_OFFSET_MIN        (int32_t(0x80000000))
-#define JUMPX_OFFSET_MAX        (int32_t(0x7fffffff))
+static JS_ALWAYS_INLINE void
+SET_JUMP_OFFSET(jsbytecode *pc, int32_t off)
+{
+    pc[1] = (jsbytecode)(off >> 24);
+    pc[2] = (jsbytecode)(off >> 16);
+    pc[3] = (jsbytecode)(off >> 8);
+    pc[4] = (jsbytecode)off;
+}
 
 /*
  * A literal is indexed by a per-script atom or object maps. Most scripts
  * have relatively few literals, so the standard JOF_ATOM, JOF_OBJECT and
  * JOF_REGEXP formats specifies a fixed 16 bits of immediate operand index.
  * A script with more than 64K literals must wrap the bytecode into
  * JSOP_INDEXBASE and JSOP_RESETBASE pair.
  */
@@ -527,17 +501,17 @@ GetBytecodeLength(jsbytecode *pc)
 extern bool
 IsValidBytecodeOffset(JSContext *cx, JSScript *script, size_t offset);
 
 inline bool
 FlowsIntoNext(JSOp op)
 {
     /* JSOP_YIELD is considered to flow into the next instruction, like JSOP_CALL. */
     return op != JSOP_STOP && op != JSOP_RETURN && op != JSOP_RETRVAL && op != JSOP_THROW &&
-           op != JSOP_GOTO && op != JSOP_GOTOX && op != JSOP_RETSUB;
+           op != JSOP_GOTO && op != JSOP_RETSUB;
 }
 
 /*
  * Counts accumulated for a single opcode in a script. The counts tracked vary
  * between opcodes, and this structure ensures that counts are accessed in
  * a coherent fashion.
  */
 class OpcodeCounts
--- a/js/src/jsopcode.tbl
+++ b/js/src/jsopcode.tbl
@@ -65,19 +65,19 @@
  * prec         Operator precedence, zero if not an operator
  * format       Bytecode plus immediate operand encoding format
  *
  * Precedence   Operators               Opcodes
  *  1           yield w                 JSOP_YIELD
  *  2           ,                       JSOP_POP with SRC_PCDELTA, JSOP_RETURN
  *  3           =, +=, etc.             JSOP_SETNAME, etc. (all JOF_SET);
  *                let (...) ...           and JSOP_LEAVEBLOCKEXPR
- *  4           ?:                      JSOP_IFEQ, JSOP_IFEQX
- *  5           ||                      JSOP_OR, JSOP_ORX
- *  6           &&                      JSOP_AND, JSOP_ANDX
+ *  4           ?:                      JSOP_IFEQ
+ *  5           ||                      JSOP_OR
+ *  6           &&                      JSOP_AND
  *  7           |                       JSOP_BITOR
  *  8           ^                       JSOP_BITXOR
  *  9           &                       JSOP_BITAND
  * 10           ==, !=, etc.            JSOP_EQ, JSOP_NE, etc.
  * 11           <, in, etc.             JSOP_LT, JSOP_IN, etc.
  * 12           <<, >>, >>>             JSOP_LSH, JSOP_RSH, JSOP_URSH
  * 13           +, -, etc.              JSOP_ADD, JSOP_SUB, etc.
  * 14           *, /, %                 JSOP_MUL, JSOP_DIV, JSOP_MOD
@@ -113,19 +113,19 @@ 1234567890123456789012345678901234567890
 OPDEF(JSOP_NOP,       0,  "nop",        NULL,         1,  0,  0,  0,  JOF_BYTE)
 
 /* Long-standing JavaScript bytecodes. */
 OPDEF(JSOP_UNDEFINED, 1,  js_undefined_str, "",       1,  0,  1,  0,  JOF_BYTE)
 OPDEF(JSOP_POPV,      2,  "popv",       NULL,         1,  1,  0,  2,  JOF_BYTE)
 OPDEF(JSOP_ENTERWITH, 3,  "enterwith",  NULL,         1,  1,  1,  0,  JOF_BYTE|JOF_PARENHEAD)
 OPDEF(JSOP_LEAVEWITH, 4,  "leavewith",  NULL,         1,  1,  0,  0,  JOF_BYTE)
 OPDEF(JSOP_RETURN,    5,  "return",     NULL,         1,  1,  0,  2,  JOF_BYTE)
-OPDEF(JSOP_GOTO,      6,  "goto",       NULL,         3,  0,  0,  0,  JOF_JUMP)
-OPDEF(JSOP_IFEQ,      7,  "ifeq",       NULL,         3,  1,  0,  4,  JOF_JUMP|JOF_DETECTING)
-OPDEF(JSOP_IFNE,      8,  "ifne",       NULL,         3,  1,  0,  0,  JOF_JUMP|JOF_PARENHEAD)
+OPDEF(JSOP_GOTO,      6,  "goto",       NULL,         5,  0,  0,  0,  JOF_JUMP)
+OPDEF(JSOP_IFEQ,      7,  "ifeq",       NULL,         5,  1,  0,  4,  JOF_JUMP|JOF_DETECTING)
+OPDEF(JSOP_IFNE,      8,  "ifne",       NULL,         5,  1,  0,  0,  JOF_JUMP|JOF_PARENHEAD)
 
 /* Get the arguments object for the current, lightweight function activation. */
 OPDEF(JSOP_ARGUMENTS, 9, js_arguments_str, js_arguments_str, 1, 0, 1, 18, JOF_BYTE)
 
 OPDEF(JSOP_SWAP,      10, "swap",       NULL,         1,  2,  2,  0,  JOF_BYTE)
 OPDEF(JSOP_POPN,      11, "popn",       NULL,         3, -1,  0,  0,  JOF_UINT16)
 
 /* More long-standing bytecodes. */
@@ -182,21 +182,21 @@ OPDEF(JSOP_NAME,      59, "name",       
 OPDEF(JSOP_DOUBLE,    60, "double",     NULL,         3,  0,  1, 16,  JOF_ATOM)
 OPDEF(JSOP_STRING,    61, "string",     NULL,         3,  0,  1, 19,  JOF_ATOM)
 OPDEF(JSOP_ZERO,      62, "zero",       "0",          1,  0,  1, 16,  JOF_BYTE)
 OPDEF(JSOP_ONE,       63, "one",        "1",          1,  0,  1, 16,  JOF_BYTE)
 OPDEF(JSOP_NULL,      64, js_null_str,  js_null_str,  1,  0,  1, 19,  JOF_BYTE)
 OPDEF(JSOP_THIS,      65, js_this_str,  js_this_str,  1,  0,  1, 19,  JOF_BYTE)
 OPDEF(JSOP_FALSE,     66, js_false_str, js_false_str, 1,  0,  1, 19,  JOF_BYTE)
 OPDEF(JSOP_TRUE,      67, js_true_str,  js_true_str,  1,  0,  1, 19,  JOF_BYTE)
-OPDEF(JSOP_OR,        68, "or",         NULL,         3,  1,  1,  5,  JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC)
-OPDEF(JSOP_AND,       69, "and",        NULL,         3,  1,  1,  6,  JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC)
+OPDEF(JSOP_OR,        68, "or",         NULL,         5,  1,  1,  5,  JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC)
+OPDEF(JSOP_AND,       69, "and",        NULL,         5,  1,  1,  6,  JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC)
 
 /* The switch bytecodes have variable length. */
-OPDEF(JSOP_TABLESWITCH,  70, "tableswitch",  NULL,   -1,  1,  0,  0,  JOF_TABLESWITCH|JOF_DETECTING|JOF_PARENHEAD)
+OPDEF(JSOP_TABLESWITCH, 70, "tableswitch", NULL,     -1,  1,  0,  0,  JOF_TABLESWITCH|JOF_DETECTING|JOF_PARENHEAD)
 OPDEF(JSOP_LOOKUPSWITCH, 71, "lookupswitch", NULL,   -1,  1,  0,  0,  JOF_LOOKUPSWITCH|JOF_DETECTING|JOF_PARENHEAD)
 
 /* New, infallible/transitive identity ops. */
 OPDEF(JSOP_STRICTEQ,  72, "stricteq",   "===",        1,  2,  1, 10,  JOF_BYTE|JOF_DETECTING|JOF_LEFTASSOC|JOF_ARITH)
 OPDEF(JSOP_STRICTNE,  73, "strictne",   "!==",        1,  2,  1, 10,  JOF_BYTE|JOF_DETECTING|JOF_LEFTASSOC|JOF_ARITH)
 
 /*
  * Host object extension: given 'o.item(i) = j', the left-hand side compiles
@@ -206,17 +206,17 @@ OPDEF(JSOP_SETCALL,   74, "setcall",    
 
 /*
  * JSOP_ITER sets up a for-in or for-each-in loop using the JSITER_* flag bits
  * in this op's uint8_t immediate operand. It replaces the top of stack value
  * with an iterator for that value.
  *
  * JSOP_MOREITER stores the next iterated value into cx->iterValue and pushes
  * true if another value is available, and false otherwise. It is followed
- * immediately by JSOP_IFNE{,X}.
+ * immediately by JSOP_IFNE.
  *
  * JSOP_ENDITER cleans up after the loop. It uses the slot above the iterator
  * for temporary GC rooting.
  */
 OPDEF(JSOP_ITER,      75, "iter",       NULL,         2,  1,  1,  0,  JOF_UINT8)
 OPDEF(JSOP_MOREITER,  76, "moreiter",   NULL,         1,  1,  2,  0,  JOF_BYTE)
 OPDEF(JSOP_ITERNEXT,  77, "iternext",   "<next>",     2,  0,  1,  0,  JOF_UINT8)
 OPDEF(JSOP_ENDITER,   78, "enditer",    NULL,         1,  1,  0,  0,  JOF_BYTE)
@@ -270,18 +270,18 @@ OPDEF(JSOP_INCLOCAL,  101,"inclocal",   
 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)
 
 /* Leave a for-let-in block leaving its storage pushed (to be popped after enditer). */
 OPDEF(JSOP_LEAVEFORLETIN, 105,"leaveforletin",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)
+OPDEF(JSOP_LABEL,     106,"label",     NULL,          5,  0,  0,  0,  JOF_JUMP)
+OPDEF(JSOP_UNUSED3,   107,"unused3",   NULL,          1,  0,  0,  0,  JOF_BYTE)
 
 /* 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)
 
 /* This opcode is the target of the backwards jump for some loop. */
 OPDEF(JSOP_LOOPHEAD,  109,"loophead",   NULL,         1,  0,  0,  0,  JOF_BYTE)
 
 /* ECMA-compliant assignment ops. */
@@ -294,33 +294,33 @@ OPDEF(JSOP_THROW,     112,js_throw_str, 
 /* 'in' and 'instanceof' ops. */
 OPDEF(JSOP_IN,        113,js_in_str,    js_in_str,    1,  2,  1, 11,  JOF_BYTE|JOF_LEFTASSOC)
 OPDEF(JSOP_INSTANCEOF,114,js_instanceof_str,js_instanceof_str,1,2,1,11,JOF_BYTE|JOF_LEFTASSOC|JOF_TMPSLOT)
 
 /* debugger op */
 OPDEF(JSOP_DEBUGGER,  115,"debugger",   NULL,         1,  0,  0,  0,  JOF_BYTE)
 
 /* gosub/retsub for finally handling */
-OPDEF(JSOP_GOSUB,     116,"gosub",      NULL,         3,  0,  0,  0,  JOF_JUMP)
+OPDEF(JSOP_GOSUB,     116,"gosub",      NULL,         5,  0,  0,  0,  JOF_JUMP)
 OPDEF(JSOP_RETSUB,    117,"retsub",     NULL,         1,  2,  0,  0,  JOF_BYTE)
 
 /* More exception handling ops. */
 OPDEF(JSOP_EXCEPTION, 118,"exception",  NULL,         1,  0,  1,  0,  JOF_BYTE)
 
 /* Embedded lineno to speedup pc->line mapping. */
 OPDEF(JSOP_LINENO,    119,"lineno",     NULL,         3,  0,  0,  0,  JOF_UINT16)
 
 /*
  * ECMA-compliant switch statement ops.
  * CONDSWITCH is a decompilable NOP; CASE is ===, POP, jump if true, re-push
  * lval if false; and DEFAULT is POP lval and GOTO.
  */
 OPDEF(JSOP_CONDSWITCH,120,"condswitch", NULL,         1,  0,  0,  0,  JOF_BYTE|JOF_PARENHEAD)
-OPDEF(JSOP_CASE,      121,"case",       NULL,         3,  2,  1,  0,  JOF_JUMP|JOF_TMPSLOT2)
-OPDEF(JSOP_DEFAULT,   122,"default",    NULL,         3,  1,  0,  0,  JOF_JUMP)
+OPDEF(JSOP_CASE,      121,"case",       NULL,         5,  2,  1,  0,  JOF_JUMP)
+OPDEF(JSOP_DEFAULT,   122,"default",    NULL,         5,  1,  0,  0,  JOF_JUMP)
 
 /*
  * ECMA-compliant call to eval op
  */
 OPDEF(JSOP_EVAL,      123,"eval",       NULL,         3, -1,  1, 18,  JOF_UINT16|JOF_INVOKE|JOF_TYPESET)
 
 /*
  * ECMA-compliant helper for 'for (x[i] in o)' loops.
@@ -375,30 +375,30 @@ OPDEF(JSOP_CALLFCSLOT,  137,"callfcslot"
 /*
  * Define a local function object as a local variable.
  * The local variable's slot number is the first immediate two-byte operand.
  * The function object's atom index is the second immediate operand.
  */
 OPDEF(JSOP_DEFLOCALFUN, 138,"deflocalfun",NULL,       5,  0,  0,  0,  JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT)
 
 /* Extended jumps. */
-OPDEF(JSOP_GOTOX,         139,"gotox",    NULL,       5,  0,  0,  0,  JOF_JUMPX)
-OPDEF(JSOP_IFEQX,         140,"ifeqx",    NULL,       5,  1,  0,  4,  JOF_JUMPX|JOF_DETECTING)
-OPDEF(JSOP_IFNEX,         141,"ifnex",    NULL,       5,  1,  0,  0,  JOF_JUMPX|JOF_PARENHEAD)
-OPDEF(JSOP_ORX,           142,"orx",      NULL,       5,  1,  1,  5,  JOF_JUMPX|JOF_DETECTING)
-OPDEF(JSOP_ANDX,          143,"andx",     NULL,       5,  1,  1,  6,  JOF_JUMPX|JOF_DETECTING)
-OPDEF(JSOP_GOSUBX,        144,"gosubx",   NULL,       5,  0,  0,  0,  JOF_JUMPX)
-OPDEF(JSOP_CASEX,         145,"casex",    NULL,       5,  2,  1,  0,  JOF_JUMPX)
-OPDEF(JSOP_DEFAULTX,      146,"defaultx", NULL,       5,  1,  0,  0,  JOF_JUMPX)
-OPDEF(JSOP_TABLESWITCHX,  147,"tableswitchx",NULL,   -1,  1,  0,  0,  JOF_TABLESWITCHX|JOF_DETECTING|JOF_PARENHEAD)
-OPDEF(JSOP_LOOKUPSWITCHX, 148,"lookupswitchx",NULL,  -1,  1,  0,  0,  JOF_LOOKUPSWITCHX|JOF_DETECTING|JOF_PARENHEAD)
+OPDEF(JSOP_UNUSED4,       139,"unused4",  NULL,       1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED5,       140,"unused5",  NULL,       1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED6,       141,"unused6",  NULL,       1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED7,       142,"unused7",  NULL,       1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED8,       143,"unused8",  NULL,       1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED9,       144,"unused9",  NULL,       1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED10,      145,"unused10", NULL,       1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED11,      146,"unused11", NULL,       1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED12,      147,"unused12", NULL,       1,  0,  0,  0,  JOF_BYTE)
+OPDEF(JSOP_UNUSED13,      148,"unused13", NULL,       1,  0,  0,  0,  JOF_BYTE)
 
 /* Placeholders for a real jump opcode set during backpatch chain fixup. */
-OPDEF(JSOP_BACKPATCH,     149,"backpatch",NULL,       3,  0,  0,  0,  JOF_JUMP|JOF_BACKPATCH)
-OPDEF(JSOP_BACKPATCH_POP, 150,"backpatch_pop",NULL,   3,  1,  0,  0,  JOF_JUMP|JOF_BACKPATCH)
+OPDEF(JSOP_BACKPATCH,     149,"backpatch",NULL,       5,  0,  0,  0,  JOF_JUMP|JOF_BACKPATCH)
+OPDEF(JSOP_BACKPATCH_POP, 150,"backpatch_pop",NULL,   5,  1,  0,  0,  JOF_JUMP|JOF_BACKPATCH)
 
 /* Set pending exception from the stack, to trigger rethrow. */
 OPDEF(JSOP_THROWING,      151,"throwing", NULL,       1,  1,  0,  0,  JOF_BYTE)
 
 /* Set and get return value pseudo-register in stack frame. */
 OPDEF(JSOP_SETRVAL,       152,"setrval",  NULL,       1,  1,  0,  2,  JOF_BYTE)
 OPDEF(JSOP_RETRVAL,       153,"retrval",  NULL,       1,  0,  0,  0,  JOF_BYTE)
 
@@ -422,18 +422,18 @@ OPDEF(JSOP_QNAME,         165,"qname",  
 OPDEF(JSOP_TOATTRNAME,    166,"toattrname", NULL,     1,  1,  1, 19,  JOF_BYTE|JOF_XMLNAME)
 OPDEF(JSOP_TOATTRVAL,     167,"toattrval",  NULL,     1,  1,  1, 19,  JOF_BYTE)
 OPDEF(JSOP_ADDATTRNAME,   168,"addattrname",NULL,     1,  2,  1, 13,  JOF_BYTE)
 OPDEF(JSOP_ADDATTRVAL,    169,"addattrval", NULL,     1,  2,  1, 13,  JOF_BYTE)
 OPDEF(JSOP_BINDXMLNAME,   170,"bindxmlname",NULL,     1,  1,  2,  3,  JOF_BYTE|JOF_SET)
 OPDEF(JSOP_SETXMLNAME,    171,"setxmlname", NULL,     1,  3,  1,  3,  JOF_BYTE|JOF_SET|JOF_DETECTING)
 OPDEF(JSOP_XMLNAME,       172,"xmlname",    NULL,     1,  1,  1, 19,  JOF_BYTE)
 OPDEF(JSOP_DESCENDANTS,   173,"descendants",NULL,     1,  2,  1, 18,  JOF_BYTE)
-OPDEF(JSOP_FILTER,        174,"filter",     NULL,     3,  1,  1,  0,  JOF_JUMP)
-OPDEF(JSOP_ENDFILTER,     175,"endfilter",  NULL,     3,  2,  1, 18,  JOF_JUMP)
+OPDEF(JSOP_FILTER,        174,"filter",     NULL,     5,  1,  1,  0,  JOF_JUMP)
+OPDEF(JSOP_ENDFILTER,     175,"endfilter",  NULL,     5,  2,  1, 18,  JOF_JUMP)
 OPDEF(JSOP_TOXML,         176,"toxml",      NULL,     1,  1,  1, 19,  JOF_BYTE)
 OPDEF(JSOP_TOXMLLIST,     177,"toxmllist",  NULL,     1,  1,  1, 19,  JOF_BYTE)
 OPDEF(JSOP_XMLTAGEXPR,    178,"xmltagexpr", NULL,     1,  1,  1,  0,  JOF_BYTE)
 OPDEF(JSOP_XMLELTEXPR,    179,"xmleltexpr", NULL,     1,  1,  1,  0,  JOF_BYTE)
 OPDEF(JSOP_XMLCDATA,      180,"xmlcdata",   NULL,     3,  0,  1, 19,  JOF_ATOM)
 OPDEF(JSOP_XMLCOMMENT,    181,"xmlcomment", NULL,     3,  0,  1, 19,  JOF_ATOM)
 OPDEF(JSOP_XMLPI,         182,"xmlpi",      NULL,     3,  1,  1, 19,  JOF_ATOM)
 OPDEF(JSOP_DELDESC,       183,"deldesc",    NULL,     1,  2,  1, 15,  JOF_BYTE|JOF_ELEM|JOF_DEL)
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -1641,17 +1641,16 @@ mjit::Compiler::generateMethod()
           BEGIN_CASE(JSOP_RETURN)
             if (script->pcCounters)
                 updatePCCounters(PC, &codeStart, &countersUpdated);
             emitReturn(frame.peek(-1));
             fallthrough = false;
           END_CASE(JSOP_RETURN)
 
           BEGIN_CASE(JSOP_GOTO)
-          BEGIN_CASE(JSOP_GOTOX)
           BEGIN_CASE(JSOP_DEFAULT)
           {
             unsigned targetOffset = FollowBranch(cx, script, PC - script->code);
             jsbytecode *target = script->code + targetOffset;
 
             fixDoubleTypes(target);
 
             /*
@@ -1676,20 +1675,18 @@ mjit::Compiler::generateMethod()
             fallthrough = false;
             PC += js_CodeSpec[op].length;
             break;
           }
           END_CASE(JSOP_GOTO)
 
           BEGIN_CASE(JSOP_IFEQ)
           BEGIN_CASE(JSOP_IFNE)
-          BEGIN_CASE(JSOP_IFEQX)
-          BEGIN_CASE(JSOP_IFNEX)
           {
-            jsbytecode *target = PC + GetJumpOffset(PC, PC);
+            jsbytecode *target = PC + GET_JUMP_OFFSET(PC);
             fixDoubleTypes(target);
             if (!jsop_ifneq(op, target))
                 return Compile_Error;
             PC += js_CodeSpec[op].length;
             break;
           }
           END_CASE(JSOP_IFNE)
 
@@ -2143,17 +2140,16 @@ mjit::Compiler::generateMethod()
             jsbytecode *target = PC + GET_JUMP_OFFSET(PC);
             fixDoubleTypes(target);
             if (!jsop_andor(op, target))
                 return Compile_Error;
           }
           END_CASE(JSOP_AND)
 
           BEGIN_CASE(JSOP_TABLESWITCH)
-          BEGIN_CASE(JSOP_TABLESWITCHX)
             /*
              * Note: there is no need to syncForBranch for the various targets of
              * switch statement. The liveness analysis has already marked these as
              * allocated with no registers in use. There is also no need to fix
              * double types, as we don't track types of slots in scripts with
              * switch statements (could be fixed).
              */
             if (script->pcCounters)
@@ -2219,21 +2215,19 @@ mjit::Compiler::generateMethod()
 
           BEGIN_CASE(JSOP_MOREITER)
           {
             /* At the byte level, this is always fused with IFNE or IFNEX. */
             if (script->pcCounters)
                 updatePCCounters(PC, &codeStart, &countersUpdated);
             jsbytecode *target = &PC[JSOP_MOREITER_LENGTH];
             JSOp next = JSOp(*target);
-            JS_ASSERT(next == JSOP_IFNE || next == JSOP_IFNEX);
-
-            target += (next == JSOP_IFNE)
-                      ? GET_JUMP_OFFSET(target)
-                      : GET_JUMPX_OFFSET(target);
+            JS_ASSERT(next == JSOP_IFNE);
+
+            target += GET_JUMP_OFFSET(target);
 
             fixDoubleTypes(target);
             if (!iterMore(target))
                 return Compile_Error;
             PC += JSOP_MOREITER_LENGTH;
             PC += js_CodeSpec[next].length;
             break;
           }
@@ -2482,19 +2476,16 @@ mjit::Compiler::generateMethod()
 
           BEGIN_CASE(JSOP_CONDSWITCH)
             /* No-op for the decompiler. */
           END_CASE(JSOP_CONDSWITCH)
 
           BEGIN_CASE(JSOP_LABEL)
           END_CASE(JSOP_LABEL)
 
-          BEGIN_CASE(JSOP_LABELX)
-          END_CASE(JSOP_LABELX)
-
           BEGIN_CASE(JSOP_DEFFUN)
           {
             uint32_t index = fullAtomIndex(PC);
             JSFunction *innerFun = script->getFunction(index);
 
             prepareStubCall(Uses(0));
             masm.move(ImmPtr(innerFun), Registers::ArgReg1);
             INLINE_STUBCALL(STRICT_VARIANT(stubs::DefFun), REJOIN_FALLTHROUGH);
@@ -6790,21 +6781,20 @@ bool
 mjit::Compiler::jsop_tableswitch(jsbytecode *pc)
 {
 #if defined JS_CPU_ARM
     JS_NOT_REACHED("Implement jump(BaseIndex) for ARM");
     return true;
 #else
     jsbytecode *originalPC = pc;
     JSOp op = JSOp(*originalPC);
-    JS_ASSERT(op == JSOP_TABLESWITCH || op == JSOP_TABLESWITCHX);
-
-    uint32_t defaultTarget = GetJumpOffset(pc, pc);
-    unsigned jumpLength = (op == JSOP_TABLESWITCHX) ? JUMPX_OFFSET_LEN : JUMP_OFFSET_LEN;
-    pc += jumpLength;
+    JS_ASSERT(op == JSOP_TABLESWITCH);
+
+    uint32_t defaultTarget = GET_JUMP_OFFSET(pc);
+    pc += JUMP_OFFSET_LEN;
 
     jsint low = GET_JUMP_OFFSET(pc);
     pc += JUMP_OFFSET_LEN;
     jsint high = GET_JUMP_OFFSET(pc);
     pc += JUMP_OFFSET_LEN;
     int numJumps = high + 1 - low;
     JS_ASSERT(numJumps >= 0);
 
@@ -6846,22 +6836,22 @@ mjit::Compiler::jsop_tableswitch(jsbytec
         notInt = masm.testInt32(Assembler::NotEqual, frame.addressOf(fe));
 
     JumpTable jt;
     jt.offsetIndex = jumpTableOffsets.length();
     jt.label = masm.moveWithPatch(ImmPtr(NULL), reg);
     jumpTables.append(jt);
 
     for (int i = 0; i < numJumps; i++) {
-        uint32_t target = GetJumpOffset(originalPC, pc);
+        uint32_t target = GET_JUMP_OFFSET(pc);
         if (!target)
             target = defaultTarget;
         uint32_t offset = (originalPC + target) - script->code;
         jumpTableOffsets.append(offset);
-        pc += jumpLength;
+        pc += JUMP_OFFSET_LEN;
     }
     if (low != 0)
         masm.sub32(Imm32(low), dataReg);
     Jump defaultCase = masm.branch32(Assembler::AboveOrEqual, dataReg, Imm32(numJumps));
     BaseIndex jumpTarget(reg, dataReg, Assembler::ScalePtr);
     masm.jump(jumpTarget);
 
     if (notInt.isSet()) {
--- a/js/src/methodjit/Compiler.h
+++ b/js/src/methodjit/Compiler.h
@@ -724,17 +724,17 @@ private:
             JS_NOT_REACHED("unrecognized op");
             return Assembler::Equal;
         }
     }
 
     static inline Assembler::Condition
     GetStubCompareCondition(JSOp fused)
     {
-        return (fused == JSOP_IFEQ) ? Assembler::Zero : Assembler::NonZero;
+        return fused == JSOP_IFEQ ? Assembler::Zero : Assembler::NonZero;
     }
 
     /* Fast builtins. */
     JSObject *pushedSingleton(unsigned pushed);
     CompileStatus callArrayBuiltin(uint32_t argc, bool callingNew);
     CompileStatus inlineNativeFunction(uint32_t argc, bool callingNew);
     CompileStatus inlineScriptedFunction(uint32_t argc, bool callingNew);
     CompileStatus compileMathAbsInt(FrameEntry *arg);
--- a/js/src/methodjit/FastOps.cpp
+++ b/js/src/methodjit/FastOps.cpp
@@ -784,23 +784,22 @@ mjit::Compiler::jsop_typeof()
 bool
 mjit::Compiler::booleanJumpScript(JSOp op, jsbytecode *target)
 {
     // JSOP_AND and JSOP_OR may leave the value on the stack (despite
     // the frame.pop() below), so we need to sync it.
     if (op == JSOP_AND || op == JSOP_OR) {
         frame.syncForBranch(target, Uses(0));
     } else {
-        JS_ASSERT(op == JSOP_IFEQ || op == JSOP_IFEQX ||
-                  op == JSOP_IFNE || op == JSOP_IFNEX);
+        JS_ASSERT(op == JSOP_IFEQ || op == JSOP_IFNE);
         frame.syncForBranch(target, Uses(1));
     }
 
     FrameEntry *fe = frame.peek(-1);
-    Assembler::Condition cond = (op == JSOP_IFNE || op == JSOP_IFNEX || op == JSOP_OR)
+    Assembler::Condition cond = (op == JSOP_IFNE || op == JSOP_OR)
                                 ? Assembler::NonZero
                                 : Assembler::Zero;
 
     // Load data register and pin it so that frame.testBoolean
     // below cannot evict it.
     MaybeRegisterID data;
     if (!fe->isType(JSVAL_TYPE_DOUBLE)) {
         data = frame.tempRegForData(fe);
@@ -854,17 +853,17 @@ mjit::Compiler::jsop_ifneq(JSOp op, jsby
 {
     FrameEntry *fe = frame.peek(-1);
 
     if (fe->isConstant()) {
         JSBool b = js_ValueToBoolean(fe->getValue());
 
         frame.pop();
 
-        if (op == JSOP_IFEQ || op == JSOP_IFEQX)
+        if (op == JSOP_IFEQ)
             b = !b;
         if (b) {
             if (!frame.syncForBranch(target, Uses(0)))
                 return false;
             if (!jumpAndRun(masm.jump(), target))
                 return false;
         } else {
             if (target < PC && !finishLoop(target))
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -1049,28 +1049,26 @@ js_InternalInterpret(void *returnData, v
         /*
          * This must be an opcode fused with IFNE/IFEQ. Unfused IFNE/IFEQ are
          * implemented in terms of ValueToBoolean, which is infallible and
          * cannot trigger recompilation.
          */
         bool takeBranch = false;
         switch (JSOp(*nextpc)) {
           case JSOP_IFNE:
-          case JSOP_IFNEX:
             takeBranch = returnReg != NULL;
             break;
           case JSOP_IFEQ:
-          case JSOP_IFEQX:
             takeBranch = returnReg == NULL;
             break;
           default:
             JS_NOT_REACHED("Bad branch op");
         }
         if (takeBranch)
-            f.regs.pc = nextpc + analyze::GetJumpOffset(nextpc, nextpc);
+            f.regs.pc = nextpc + GET_JUMP_OFFSET(nextpc);
         else
             f.regs.pc = nextpc + GetBytecodeLength(nextpc);
         break;
       }
 
       default:
         JS_NOT_REACHED("Missing rejoin");
     }
--- a/js/src/methodjit/LoopState.cpp
+++ b/js/src/methodjit/LoopState.cpp
@@ -1916,25 +1916,20 @@ LoopState::analyzeLoopBody(unsigned fram
           case JSOP_GETLOCAL:
           case JSOP_SETLOCAL:
           case JSOP_SETLOCALPOP:
           case JSOP_INCLOCAL:
           case JSOP_DECLOCAL:
           case JSOP_LOCALINC:
           case JSOP_LOCALDEC:
           case JSOP_IFEQ:
-          case JSOP_IFEQX:
           case JSOP_IFNE:
-          case JSOP_IFNEX:
           case JSOP_AND:
-          case JSOP_ANDX:
           case JSOP_OR:
-          case JSOP_ORX:
           case JSOP_GOTO:
-          case JSOP_GOTOX:
             break;
 
           case JSOP_ADD:
           case JSOP_SUB:
           case JSOP_MUL:
           case JSOP_MOD:
           case JSOP_DIV:
           case JSOP_BITAND:
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -1550,25 +1550,23 @@ stubs::LookupSwitch(VMFrame &f, jsbyteco
     JS_ASSERT(native);
     return native;
 }
 
 void * JS_FASTCALL
 stubs::TableSwitch(VMFrame &f, jsbytecode *origPc)
 {
     jsbytecode * const originalPC = origPc;
-    jsbytecode *pc = originalPC;
 
     JSOp op = JSOp(*originalPC);
-    JS_ASSERT(op == JSOP_TABLESWITCH || op == JSOP_TABLESWITCHX);
+    JS_ASSERT(op == JSOP_TABLESWITCH);
 
-    uint32_t jumpOffset = js::analyze::GetJumpOffset(originalPC, pc);
-    unsigned jumpLength = (op == JSOP_TABLESWITCHX) ? JUMPX_OFFSET_LEN : JUMP_OFFSET_LEN;
-    pc += jumpLength;
-
+    uint32_t jumpOffset = GET_JUMP_OFFSET(originalPC);
+    jsbytecode *pc = originalPC + JUMP_OFFSET_LEN;
+    
     /* Note: compiler adjusts the stack beforehand. */
     Value rval = f.regs.sp[-1];
 
     jsint tableIdx;
     if (rval.isInt32()) {
         tableIdx = rval.toInt32();
     } else if (rval.isDouble()) {
         double d = rval.toDouble();
@@ -1585,19 +1583,18 @@ stubs::TableSwitch(VMFrame &f, jsbytecod
     {
         jsint low = GET_JUMP_OFFSET(pc);
         pc += JUMP_OFFSET_LEN;
         jsint high = GET_JUMP_OFFSET(pc);
         pc += JUMP_OFFSET_LEN;
 
         tableIdx -= low;
         if ((jsuint) tableIdx < (jsuint)(high - low + 1)) {
-            pc += jumpLength * tableIdx;
-            uint32_t candidateOffset = js::analyze::GetJumpOffset(originalPC, pc);
-            if (candidateOffset)
+            pc += JUMP_OFFSET_LEN * tableIdx;
+            if (uint32_t candidateOffset = GET_JUMP_OFFSET(pc))
                 jumpOffset = candidateOffset;
         }
     }
 
 finally:
     /* Provide the native address. */
     JSScript* script = f.fp()->script();
     void* native = script->nativeCodeForPC(f.fp()->isConstructing(),
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1822,36 +1822,28 @@ UpdateSwitchTableBounds(JSContext *cx, J
     jsbytecode *pc;
     JSOp op;
     ptrdiff_t jmplen;
     jsint low, high, n;
 
     pc = script->code + offset;
     op = JSOp(*pc);
     switch (op) {
-      case JSOP_TABLESWITCHX:
-        jmplen = JUMPX_OFFSET_LEN;
-        goto jump_table;
       case JSOP_TABLESWITCH:
         jmplen = JUMP_OFFSET_LEN;
-      jump_table:
         pc += jmplen;
         low = GET_JUMP_OFFSET(pc);
         pc += JUMP_OFFSET_LEN;
         high = GET_JUMP_OFFSET(pc);
         pc += JUMP_OFFSET_LEN;
         n = high - low + 1;
         break;
 
-      case JSOP_LOOKUPSWITCHX:
-        jmplen = JUMPX_OFFSET_LEN;
-        goto lookup_table;
       case JSOP_LOOKUPSWITCH:
         jmplen = JUMP_OFFSET_LEN;
-      lookup_table:
         pc += jmplen;
         n = GET_INDEX(pc);
         pc += INDEX_LEN;
         jmplen += JUMP_OFFSET_LEN;
         break;
 
       default:
         /* [condswitch] switch does not have any jump or lookup tables. */
@@ -1880,17 +1872,17 @@ SrcNotes(JSContext *cx, JSScript *script
         SrcNoteType type = (SrcNoteType) SN_TYPE(sn);
         const char *name = js_SrcNoteSpec[type].name;
         if (type == SRC_LABEL) {
             /* Check if the source note is for a switch case. */
             if (switchTableStart <= offset && offset < switchTableEnd) {
                 name = "case";
             } else {
                 JSOp op = JSOp(script->code[offset]);
-                JS_ASSERT(op == JSOP_LABEL || op == JSOP_LABELX);
+                JS_ASSERT(op == JSOP_LABEL);
             }
         }
         Sprint(sp, "%3u: %4u %5u [%4u] %-8s", uintN(sn - notes), lineno, offset, delta, name);
         switch (type) {
           case SRC_SETLINE:
             lineno = js_GetSrcNoteOffset(sn, 0);
             Sprint(sp, " lineno %u", lineno);
             break;
@@ -1939,17 +1931,17 @@ SrcNotes(JSContext *cx, JSScript *script
             JSAutoByteString bytes;
             if (!str || !bytes.encode(cx, str))
                 ReportException(cx);
             Sprint(sp, " function %u (%s)", index, !!bytes ? bytes.ptr() : "N/A");
             break;
           }
           case SRC_SWITCH: {
             JSOp op = JSOp(script->code[offset]);
-            if (op == JSOP_GOTO || op == JSOP_GOTOX)
+            if (op == JSOP_GOTO)
                 break;
             Sprint(sp, " length %u", uintN(js_GetSrcNoteOffset(sn, 0)));
             uintN caseOff = (uintN) js_GetSrcNoteOffset(sn, 1);
             if (caseOff)
                 Sprint(sp, " first case offset %u", caseOff);
             UpdateSwitchTableBounds(cx, script, offset,
                                     &switchTableStart, &switchTableEnd);
             break;
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2124,46 +2124,40 @@ class FlowGraphSummary : public Vector<s
             size_t lineno = r.frontLineNumber();
             JSOp op = r.frontOpcode();
 
             if (FlowsIntoNext(prevOp))
                 addEdge(prevLine, r.frontOffset());
 
             if (js_CodeSpec[op].type() == JOF_JUMP) {
                 addEdge(lineno, r.frontOffset() + GET_JUMP_OFFSET(r.frontPC()));
-            } else if (js_CodeSpec[op].type() == JOF_JUMPX) {
-                addEdge(lineno, r.frontOffset() + GET_JUMPX_OFFSET(r.frontPC()));
-            } else if (op == JSOP_TABLESWITCH || op == JSOP_TABLESWITCHX ||
-                       op == JSOP_LOOKUPSWITCH || op == JSOP_LOOKUPSWITCHX) {
-                bool table = op == JSOP_TABLESWITCH || op == JSOP_TABLESWITCHX;
-                bool big = op == JSOP_TABLESWITCHX || op == JSOP_LOOKUPSWITCHX;
-
+            } else if (op == JSOP_TABLESWITCH || op == JSOP_LOOKUPSWITCH) {
                 jsbytecode *pc = r.frontPC();
                 size_t offset = r.frontOffset();
-                ptrdiff_t step = big ? JUMPX_OFFSET_LEN : JUMP_OFFSET_LEN;
-                size_t defaultOffset = offset + (big ? GET_JUMPX_OFFSET(pc) : GET_JUMP_OFFSET(pc));
+                ptrdiff_t step = JUMP_OFFSET_LEN;
+                size_t defaultOffset = offset + GET_JUMP_OFFSET(pc);
                 pc += step;
                 addEdge(lineno, defaultOffset);
 
                 jsint ncases;
-                if (table) {
+                if (op == JSOP_TABLESWITCH) {
                     jsint low = GET_JUMP_OFFSET(pc);
                     pc += JUMP_OFFSET_LEN;
                     ncases = GET_JUMP_OFFSET(pc) - low + 1;
                     pc += JUMP_OFFSET_LEN;
                 } else {
                     ncases = (jsint) GET_UINT16(pc);
                     pc += UINT16_LEN;
                     JS_ASSERT(ncases > 0);
                 }
 
                 for (jsint i = 0; i < ncases; i++) {
-                    if (!table)
+                    if (op == JSOP_LOOKUPSWITCH)
                         pc += INDEX_LEN;
-                    size_t target = offset + (big ? GET_JUMPX_OFFSET(pc) : GET_JUMP_OFFSET(pc));
+                    size_t target = offset + GET_JUMP_OFFSET(pc);
                     addEdge(lineno, target);
                     pc += step;
                 }
             }
 
             prevOp = op;
             prevLine = lineno;
         }