Backed out changeset 5ac1564bff87 (bug 865059) for causing intermittent Linux32 dromaeo crashes.
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 02 May 2013 14:19:15 -0400
changeset 141586 9c426bd08d289acaf72e49929881dccb4aa5c079
parent 141585 555f2b757639248c396ed4370db2bf1a3098faa5
child 141587 4c1074ad5172ebe7dd4a9948206366c9c23a9b94
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs865059
milestone23.0a1
backs out5ac1564bff87ff999bb461ffebceb0a6308c95a2
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 5ac1564bff87 (bug 865059) for causing intermittent Linux32 dromaeo crashes. CLOSED TREE
js/src/frontend/BytecodeEmitter.cpp
js/src/ion/IonFrames.cpp
js/src/jsanalyze.cpp
js/src/jscntxt.h
js/src/jscompartment.h
js/src/jsinfer.cpp
js/src/jsinfer.h
js/src/jsinferinlines.h
js/src/jsinterp.cpp
js/src/jsobj.cpp
js/src/jsscript.h
js/src/methodjit/Compiler.cpp
js/src/methodjit/InvokeHelpers.cpp
js/src/shell/js.cpp
js/src/vm/Xdr.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -4362,19 +4362,16 @@ EmitNormalFor(JSContext *cx, BytecodeEmi
     if (!SetSrcNoteOffset(cx, bce, (unsigned)noteIndex, 2, bce->offset() - tmp))
         return false;
 
     /* If no loop condition, just emit a loop-closing jump. */
     op = forHead->pn_kid2 ? JSOP_IFNE : JSOP_GOTO;
     if (EmitJump(cx, bce, op, top - bce->offset()) < 0)
         return false;
 
-    if (!bce->tryNoteList.append(JSTRY_LOOP, bce->stackDepth, top, bce->offset()))
-        return false;
-
     /* Now fixup all breaks and continues. */
     return PopStatementBCE(cx, bce);
 }
 
 static inline bool
 EmitFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
 {
     JS_ASSERT(pn->pn_left->isKind(PNK_FORIN) || pn->pn_left->isKind(PNK_FORHEAD));
@@ -4551,19 +4548,16 @@ EmitDo(JSContext *cx, BytecodeEmitter *b
      * Since we use JSOP_IFNE for other purposes as well as for do-while
      * loops, we must store 1 + (beq - top) in the SRC_WHILE note offset,
      * and the decompiler must get that delta and decompile recursively.
      */
     ptrdiff_t beq = EmitJump(cx, bce, JSOP_IFNE, top - bce->offset());
     if (beq < 0)
         return false;
 
-    if (!bce->tryNoteList.append(JSTRY_LOOP, bce->stackDepth, top, bce->offset()))
-        return false;
-
     /*
      * Be careful: We must set noteIndex2 before noteIndex in case the noteIndex
      * note gets bigger.
      */
     if (!SetSrcNoteOffset(cx, bce, noteIndex2, 0, beq - top))
         return false;
     if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, 1 + (off - top)))
         return false;
@@ -4610,19 +4604,16 @@ EmitWhile(JSContext *cx, BytecodeEmitter
         return false;
     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 (!bce->tryNoteList.append(JSTRY_LOOP, bce->stackDepth, top, bce->offset()))
-        return false;
-
     if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, beq - jmp))
         return false;
 
     return PopStatementBCE(cx, bce);
 }
 
 static bool
 EmitBreak(JSContext *cx, BytecodeEmitter *bce, PropertyName *label)
--- a/js/src/ion/IonFrames.cpp
+++ b/js/src/ion/IonFrames.cpp
@@ -430,19 +430,16 @@ HandleException(JSContext *cx, const Ion
             RootedObject iterObject(cx, &iterValue.toObject());
             if (cx->isExceptionPending())
                 UnwindIteratorForException(cx, iterObject);
             else
                 UnwindIteratorForUncatchableException(cx, iterObject);
             break;
           }
 
-          case JSTRY_LOOP:
-            break;
-
           default:
             JS_NOT_REACHED("Invalid try note");
         }
     }
 
 }
 
 void
--- a/js/src/jsanalyze.cpp
+++ b/js/src/jsanalyze.cpp
@@ -400,17 +400,17 @@ ScriptAnalysis::analyzeBytecode(JSContex
                 unsigned startOffset = script_->mainOffset + tn->start;
                 if (startOffset == offset + 1) {
                     unsigned catchOffset = startOffset + tn->length;
 
                     /* This will overestimate try block code, for multiple catch/finally. */
                     if (catchOffset > forwardCatch)
                         forwardCatch = catchOffset;
 
-                    if (tn->kind != JSTRY_ITER && tn->kind != JSTRY_LOOP) {
+                    if (tn->kind != JSTRY_ITER) {
                         if (!addJump(cx, catchOffset, &nextOffset, &forwardJump, &forwardLoop, stackDepth))
                             return;
                         getCode(catchOffset).exceptionEntry = true;
                         getCode(catchOffset).safePoint = true;
                     }
                 }
             }
             break;
@@ -1502,17 +1502,17 @@ ScriptAnalysis::analyzeSSA(JSContext *cx
           case JSOP_TRY: {
             JSTryNote *tn = script_->trynotes()->vector;
             JSTryNote *tnlimit = tn + script_->trynotes()->length;
             for (; tn < tnlimit; tn++) {
                 unsigned startOffset = script_->mainOffset + tn->start;
                 if (startOffset == offset + 1) {
                     unsigned catchOffset = startOffset + tn->length;
 
-                    if (tn->kind != JSTRY_ITER && tn->kind != JSTRY_LOOP) {
+                    if (tn->kind != JSTRY_ITER) {
                         checkBranchTarget(cx, catchOffset, branchTargets, values, stackDepth);
                         checkExceptionTarget(cx, catchOffset, exceptionTargets);
                     }
                 }
             }
             break;
           }
 
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1747,17 +1747,16 @@ struct JSContext : js::ContextFriendFiel
 #ifdef JS_METHODJIT
     bool methodJitEnabled;
     bool jitIsBroken;
 
     js::mjit::JaegerRuntime &jaegerRuntime() { return runtime->jaegerRuntime(); }
 #endif
 
     inline bool typeInferenceEnabled() const;
-    inline bool jaegerCompilationAllowed() const;
 
     void updateJITEnabled();
 
 #ifdef MOZ_TRACE_JSCALLS
     /* Function entry/exit debugging callback. */
     JSFunctionCallback    functionCallback;
 
     void doFunctionCallback(const JSFunction *fun,
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -406,22 +406,16 @@ class js::AutoDebugModeGC
 };
 
 inline bool
 JSContext::typeInferenceEnabled() const
 {
     return compartment->zone()->types.inferenceEnabled;
 }
 
-inline bool
-JSContext::jaegerCompilationAllowed() const
-{
-    return compartment->zone()->types.jaegerCompilationAllowed;
-}
-
 inline js::Handle<js::GlobalObject*>
 JSContext::global() const
 {
     /*
      * It's safe to use |unsafeGet()| here because any compartment that is
      * on-stack will be marked automatically, so there's no need for a read
      * barrier on it. Once the compartment is popped, the handle is no longer
      * safe to use.
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -2462,22 +2462,20 @@ TypeCompartment::TypeCompartment()
 
 void
 TypeZone::init(JSContext *cx)
 {
     if (!cx ||
         !cx->hasOption(JSOPTION_TYPE_INFERENCE) ||
         !cx->runtime->jitSupportsFloatingPoint)
     {
-        jaegerCompilationAllowed = true;
         return;
     }
 
     inferenceEnabled = true;
-    jaegerCompilationAllowed = cx->hasOption(JSOPTION_METHODJIT);
 }
 
 TypeObject *
 TypeCompartment::newTypeObject(JSContext *cx, Class *clasp, Handle<TaggedProto> proto, bool unknown)
 {
     JS_ASSERT_IF(proto.isObject(), cx->compartment == proto.toObject()->compartment());
 
     TypeObject *object = gc::NewGCThing<TypeObject, CanGC>(cx, gc::FINALIZE_TYPE_OBJECT,
@@ -2689,38 +2687,23 @@ types::UseNewTypeForInitializer(JSContex
      */
 
     if (!cx->typeInferenceEnabled() || (script->function() && !script->treatAsRunOnce))
         return GenericObject;
 
     if (key != JSProto_Object && !(key >= JSProto_Int8Array && key <= JSProto_Uint8ClampedArray))
         return GenericObject;
 
-    /*
-     * All loops in the script will have a JSTRY_ITER or JSTRY_LOOP try note
-     * indicating their boundary.
-     */
-
-    if (!script->hasTrynotes())
-        return SingletonObject;
-
-    unsigned offset = pc - script->code;
-
-    JSTryNote *tn = script->trynotes()->vector;
-    JSTryNote *tnlimit = tn + script->trynotes()->length;
-    for (; tn < tnlimit; tn++) {
-        if (tn->kind != JSTRY_ITER && tn->kind != JSTRY_LOOP)
-            continue;
-
-        unsigned startOffset = script->mainOffset + tn->start;
-        unsigned endOffset = startOffset + tn->length;
-
-        if (offset >= startOffset && offset < endOffset)
-            return GenericObject;
-    }
+    AutoEnterAnalysis enter(cx);
+
+    if (!script->ensureRanAnalysis(cx))
+        return GenericObject;
+
+    if (script->analysis()->getCode(pc).inLoop)
+        return GenericObject;
 
     return SingletonObject;
 }
 
 NewObjectKind
 types::UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc, Class *clasp)
 {
     return UseNewTypeForInitializer(cx, script, pc, JSCLASS_CACHED_PROTO_KEY(clasp));
@@ -5623,26 +5606,18 @@ types::MarkIteratorUnknownSlow(JSContext
     jsbytecode *pc;
     RootedScript script(cx, cx->stack.currentScript(&pc));
     if (!script || !pc)
         return;
 
     if (JSOp(*pc) != JSOP_ITER)
         return;
 
-    if (IgnoreTypeChanges(cx, script))
-        return;
-
     AutoEnterAnalysis enter(cx);
 
-    if (!script->ensureRanAnalysis(cx)) {
-        cx->compartment->types.setPendingNukeTypes(cx);
-        return;
-    }
-
     /*
      * This script is iterating over an actual Iterator or Generator object, or
      * an object with a custom __iterator__ hook. In such cases 'for in' loops
      * can produce values other than strings, and the types of the ITER opcodes
      * in the script need to be updated. During analysis this is done with the
      * forTypes in the analysis state, but we don't keep a pointer to this type
      * set and need to scan the script to fix affected opcodes.
      */
@@ -5716,20 +5691,16 @@ IsAboutToBeFinalized(TypeObjectKey *key)
     JS_ASSERT(tmp == reinterpret_cast<gc::Cell *>(uintptr_t(key) & ~1));
     return isAboutToBeFinalized;
 }
 
 void
 types::TypeDynamicResult(JSContext *cx, JSScript *script, jsbytecode *pc, Type type)
 {
     JS_ASSERT(cx->typeInferenceEnabled());
-
-    if (IgnoreTypeChanges(cx, script))
-        return;
-
     AutoEnterAnalysis enter(cx);
 
     /* Directly update associated type sets for applicable bytecodes. */
     if (js_CodeSpec[*pc].format & JOF_TYPESET) {
         if (!script->ensureRanAnalysis(cx)) {
             cx->compartment->types.setPendingNukeTypes(cx);
             return;
         }
@@ -5825,19 +5796,16 @@ types::TypeDynamicResult(JSContext *cx, 
 
 void
 types::TypeMonitorResult(JSContext *cx, JSScript *script, jsbytecode *pc, const js::Value &rval)
 {
     /* Allow the non-TYPESET scenario to simplify stubs used in compound opcodes. */
     if (!(js_CodeSpec[*pc].format & JOF_TYPESET))
         return;
 
-    if (IgnoreTypeChanges(cx, script))
-        return;
-
     AutoEnterAnalysis enter(cx);
 
     if (!script->ensureRanAnalysis(cx)) {
         cx->compartment->types.setPendingNukeTypes(cx);
         return;
     }
 
     Type type = GetValueType(cx, rval);
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -1461,23 +1461,16 @@ struct TypeZone
      * Bit set if all current types must be marked as unknown, and all scripts
      * recompiled. Caused by OOM failure within inference operations.
      */
     bool                         pendingNukeTypes;
 
     /* Whether type inference is enabled in this compartment. */
     bool                         inferenceEnabled;
 
-    /*
-     * JM compilation is allowed only if script analysis has been used to
-     * monitor the behavior of all scripts in this zone since its creation.
-     * OSR in JM requires this property.
-     */
-    bool jaegerCompilationAllowed;
-
     TypeZone(JS::Zone *zone);
     ~TypeZone();
     void init(JSContext *cx);
 
     JS::Zone *zone() const { return zone_; }
 
     void sweep(FreeOp *fop, bool releaseTypes);
 
--- a/js/src/jsinferinlines.h
+++ b/js/src/jsinferinlines.h
@@ -568,46 +568,29 @@ void MarkIteratorUnknownSlow(JSContext *
  */
 inline void
 MarkIteratorUnknown(JSContext *cx)
 {
     if (cx->typeInferenceEnabled())
         MarkIteratorUnknownSlow(cx);
 }
 
-/*
- * Return whether new type information in the specified script should be
- * ignored. Tracking new types in a script requires the script to be analyzed,
- * which can consume a large amount of memory when dealing with scripts that
- * don't run long enough to be compiled (as is the case for the majority of
- * executed scripts in web code).
- */
-inline bool
-IgnoreTypeChanges(JSContext *cx, JSScript *script)
-{
-    return !script->hasAnalysis() &&
-           !cx->jaegerCompilationAllowed() &&
-           script->analyzedArgsUsage();
-}
-
 void TypeMonitorCallSlow(JSContext *cx, JSObject *callee, const CallArgs &args,
                          bool constructing);
 
 /*
  * Monitor a javascript call, either on entry to the interpreter or made
  * from within the interpreter.
  */
 inline bool
 TypeMonitorCall(JSContext *cx, const js::CallArgs &args, bool constructing)
 {
     if (args.callee().isFunction()) {
         JSFunction *fun = args.callee().toFunction();
         if (fun->isInterpreted()) {
-            if (IgnoreTypeChanges(cx, fun->nonLazyScript()))
-                return true;
             if (!fun->nonLazyScript()->ensureRanAnalysis(cx))
                 return false;
             if (cx->typeInferenceEnabled())
                 TypeMonitorCallSlow(cx, &args.callee(), args, constructing);
         }
     }
 
     return true;
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -560,21 +560,19 @@ js::ExecuteKernel(JSContext *cx, HandleS
             result->setUndefined();
         return true;
     }
 
     ExecuteFrameGuard efg;
     if (!cx->stack.pushExecuteFrame(cx, script, thisv, scopeChain, type, evalInFrame, &efg))
         return false;
 
-    if (!types::IgnoreTypeChanges(cx, script)) {
-        if (!script->ensureRanAnalysis(cx))
-            return false;
-        TypeScript::SetThis(cx, script, efg.fp()->thisValue());
-    }
+    if (!script->ensureRanAnalysis(cx))
+        return false;
+    TypeScript::SetThis(cx, script, efg.fp()->thisValue());
 
     Probes::startExecution(script);
     bool ok = RunScript(cx, efg.fp());
     Probes::stopExecution(script);
 
     /* Propgate the return value out. */
     if (result)
         *result = efg.fp()->returnValue();
@@ -3363,21 +3361,17 @@ END_CASE(JSOP_ARRAYPUSH)
                 /* This is similar to JSOP_ENDITER in the interpreter loop. */
                 JS_ASSERT(JSOp(*regs.pc) == JSOP_ENDITER);
                 RootedObject &obj = rootObject0;
                 obj = &regs.sp[-1].toObject();
                 bool ok = UnwindIteratorForException(cx, obj);
                 regs.sp -= 1;
                 if (!ok)
                     goto error;
-                break;
               }
-
-              case JSTRY_LOOP:
-                break;
            }
         }
 
         /*
          * Propagate the exception or error to the caller unless the exception
          * is an asynchronous return from a generator.
          */
         interpReturnOK = false;
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1515,22 +1515,18 @@ js::CreateThisForFunctionWithProto(JSCon
             return NULL;
         res = CreateThisForFunctionWithType(cx, type, callee->getParent(), newKind);
     } else {
         gc::AllocKind allocKind = NewObjectGCKind(&ObjectClass);
         res = NewObjectWithClassProto(cx, &ObjectClass, proto, callee->getParent(), allocKind, newKind);
     }
 
     if (res && cx->typeInferenceEnabled()) {
-        JSScript *script = callee->toFunction()->nonLazyScript();
-        if (!types::IgnoreTypeChanges(cx, script)) {
-            if (!script->ensureRanAnalysis(cx))
-                return NULL;
-            TypeScript::SetThis(cx, script, types::Type::ObjectType(res));
-        }
+        RootedScript script(cx, callee->toFunction()->nonLazyScript());
+        TypeScript::SetThis(cx, script, types::Type::ObjectType(res));
     }
 
     return res;
 }
 
 JSObject *
 js::CreateThisForFunction(JSContext *cx, HandleObject callee, bool newType)
 {
@@ -1546,22 +1542,18 @@ js::CreateThisForFunction(JSContext *cx,
     JSObject *obj = CreateThisForFunctionWithProto(cx, callee, proto, newKind);
 
     if (obj && newType) {
         RootedObject nobj(cx, obj);
 
         /* Reshape the singleton before passing it as the 'this' value. */
         JSObject::clear(cx, nobj);
 
-        JSScript *calleeScript = callee->toFunction()->nonLazyScript();
-        if (!IgnoreTypeChanges(cx, calleeScript)) {
-            if (!calleeScript->ensureRanAnalysis(cx))
-                return NULL;
-            TypeScript::SetThis(cx, calleeScript, types::Type::ObjectType(nobj));
-        }
+        RootedScript calleeScript(cx, callee->toFunction()->nonLazyScript());
+        TypeScript::SetThis(cx, calleeScript, types::Type::ObjectType(nobj));
 
         return nobj;
     }
 
     return obj;
 }
 
 /*
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -44,37 +44,34 @@ namespace mjit {
 namespace analyze {
     class ScriptAnalysis;
 }
 
 }
 
 /*
  * Type of try note associated with each catch or finally block, and also with
- * for-in and other kinds of loops. Non-for-in loops do not need these notes
- * for exception unwinding, but storing their boundaries here is helpful for
- * heuristics that need to know whether a given op is inside a loop.
+ * for-in loops.
  */
 typedef enum JSTryNoteKind {
     JSTRY_CATCH,
     JSTRY_FINALLY,
-    JSTRY_ITER,
-    JSTRY_LOOP
+    JSTRY_ITER
 } JSTryNoteKind;
 
 /*
  * Exception handling record.
  */
 struct JSTryNote {
     uint8_t         kind;       /* one of JSTryNoteKind */
     uint8_t         padding;    /* explicit padding on uint16_t boundary */
     uint16_t        stackDepth; /* stack depth upon exception handler entry */
-    uint32_t        start;      /* start of the try statement or loop
+    uint32_t        start;      /* start of the try statement or for-in loop
                                    relative to script->main */
-    uint32_t        length;     /* length of the try statement or loop */
+    uint32_t        length;     /* length of the try statement or for-in loop */
 };
 
 namespace js {
 
 struct ConstArray {
     js::HeapValue   *vector;    /* array of indexed constant values */
     uint32_t        length;
 };
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -116,18 +116,16 @@ mjit::Compiler::Compiler(JSContext *cx, 
     debugMode_(cx->compartment->debugMode()),
     inlining_(false),
     hasGlobalReallocation(false),
     oomInVector(false),
     overflowICSpace(false),
     gcNumber(cx->runtime->gcNumber),
     pcLengths(NULL)
 {
-    JS_ASSERT(cx->jaegerCompilationAllowed());
-
     if (!IsIonEnabled(cx)) {
         /* Once a script starts getting really hot we will inline calls in it. */
         if (!debugMode() && cx->typeInferenceEnabled() && globalObj &&
             (outerScript->getUseCount() >= USES_BEFORE_INLINING ||
              cx->hasOption(JSOPTION_METHODJIT_ALWAYS))) {
             inlining_ = true;
         }
     }
@@ -991,19 +989,16 @@ CompileStatus
 mjit::CanMethodJIT(JSContext *cx, JSScript *script, jsbytecode *pc,
                    bool construct, CompileRequest request, StackFrame *frame)
 {
     bool compiledOnce = false;
   checkOutput:
     if (!cx->methodJitEnabled)
         return Compile_Abort;
 
-    if (!cx->jaegerCompilationAllowed())
-        return Compile_Abort;
-
 #ifdef JS_ION
     if (ion::IsBaselineEnabled(cx) || ion::IsEnabled(cx))
         return Compile_Abort;
 #endif
 
     /*
      * If SPS (profiling) is enabled, then the emitted instrumentation has to be
      * careful to not wildly write to random locations. This is relevant
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -110,21 +110,17 @@ FindExceptionHandler(JSContext *cx)
                    * pending exception.
                    */
                   JS_ASSERT(JSOp(*pc) == JSOP_ENDITER);
                   RootedObject obj(cx, &cx->regs().sp[-1].toObject());
                   bool ok = UnwindIteratorForException(cx, obj);
                   cx->regs().sp -= 1;
                   if (!ok)
                       goto error;
-                  break;
                 }
-
-                case JSTRY_LOOP:
-                  break;
             }
         }
     } else {
         UnwindForUncatchableException(cx, cx->regs());
     }
 
     return NULL;
 }
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4922,16 +4922,21 @@ ProcessArgs(JSContext *cx, JSObject *obj
     if (op->getBoolOption('w'))
         reportWarnings = JS_TRUE;
     else if (op->getBoolOption('W'))
         reportWarnings = JS_FALSE;
 
     if (op->getBoolOption('s'))
         JS_ToggleOptions(cx, JSOPTION_STRICT);
 
+    if (op->getBoolOption("no-jm")) {
+        enableMethodJit = false;
+        JS_ToggleOptions(cx, JSOPTION_METHODJIT);
+    }
+
     if (op->getBoolOption('d')) {
         JS_SetRuntimeDebugMode(JS_GetRuntime(cx), true);
         JS_SetDebugMode(cx, true);
     }
 
     if (op->getBoolOption('b'))
         printTiming = true;
 
@@ -5111,27 +5116,23 @@ ProcessArgs(JSContext *cx, JSObject *obj
 }
 
 int
 Shell(JSContext *cx, OptionParser *op, char **envp)
 {
     JSAutoRequest ar(cx);
 
     /*
-     * First check to see if type inference and JM are enabled. These flags
-     * must be set on the compartment when it is constructed.
+     * First check to see if type inference is enabled. This flag must be set
+     * on the compartment when it is constructed.
      */
     if (op->getBoolOption("no-ti")) {
         enableTypeInference = false;
         JS_ToggleOptions(cx, JSOPTION_TYPE_INFERENCE);
     }
-    if (op->getBoolOption("no-jm")) {
-        enableMethodJit = false;
-        JS_ToggleOptions(cx, JSOPTION_METHODJIT);
-    }
 
     RootedObject glob(cx);
     glob = NewGlobalObject(cx, NULL);
     if (!glob)
         return 1;
 
     JS_SetGlobalObject(cx, glob);
 
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -21,17 +21,17 @@ namespace js {
  * Bytecode version number. Increment the subtrahend whenever JS bytecode
  * changes incompatibly.
  *
  * This version number is XDR'd near the front of xdr bytecode and
  * aborts deserialization if there is a mismatch between the current
  * and saved versions. If deserialization fails, the data should be
  * invalidated if possible.
  */
-static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 142);
+static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 141);
 
 class XDRBuffer {
   public:
     XDRBuffer(JSContext *cx)
       : context(cx), base(NULL), cursor(NULL), limit(NULL) { }
 
     JSContext *cx() const {
         return context;