Bug 794025 - Detect IC purging in JM generateNativeStub(). r=dvander a=akeybl
authorSean Stangl <sstangl@mozilla.com>
Wed, 26 Sep 2012 17:02:53 -0700
changeset 82003 89026001a0a9980bbecd39f1a64f361b724be05f
parent 82002 92fa61f340bd0ba4e0fcd319b97175bafaac7b89
child 82004 cd49928c08fbd1f065f97272aaf8b4d740fe5873
push id278
push usersean.stangl@gmail.com
push dateThu, 27 Sep 2012 00:04:16 +0000
reviewersdvander, akeybl
bugs794025
milestone10.0.8esrpre
Bug 794025 - Detect IC purging in JM generateNativeStub(). r=dvander a=akeybl
js/src/methodjit/MonoIC.cpp
--- a/js/src/methodjit/MonoIC.cpp
+++ b/js/src/methodjit/MonoIC.cpp
@@ -901,45 +901,47 @@ class CallCompiler : public BaseCompiler
 
     bool generateNativeStub()
     {
         JITScript *jit = f.jit();
 
         /* Snapshot the frameDepth before SplatApplyArgs modifies it. */
         uintN initialFrameDepth = f.regs.sp - f.fp()->slots();
 
+        /* Protect against accessing the IC if it may have been purged. */
+        RecompilationMonitor monitor(cx);
+
         /*
          * SplatApplyArgs has not been called, so we call it here before
          * potentially touching f.u.call.dynamicArgc.
          */
         CallArgs args;
         if (ic.frameSize.isStatic()) {
             JS_ASSERT(f.regs.sp - f.fp()->slots() == (int)ic.frameSize.staticLocalSlots());
             args = CallArgsFromSp(ic.frameSize.staticArgc(), f.regs.sp);
         } else {
             JS_ASSERT(!f.regs.inlined());
             JS_ASSERT(*f.regs.pc == JSOP_FUNAPPLY && GET_ARGC(f.regs.pc) == 2);
-            if (!ic::SplatApplyArgs(f))       /* updates regs.sp */
+            /* Updates regs.sp -- may cause GC. */
+            if (!ic::SplatApplyArgs(f))
                 THROWV(true);
             args = CallArgsFromSp(f.u.call.dynamicArgc, f.regs.sp);
         }
 
         JSObject *obj;
         if (!IsFunctionObject(args.calleev(), &obj))
             return false;
 
         JSFunction *fun = obj->getFunctionPrivate();
         if ((!callingNew && !fun->isNative()) || (callingNew && !fun->isConstructor()))
             return false;
 
         if (callingNew)
             args.thisv().setMagicWithObjectOrNullPayload(NULL);
 
-        RecompilationMonitor monitor(cx);
-
         if (!CallJSNative(cx, fun->u.n.native, args))
             THROWV(true);
 
         types::TypeScript::Monitor(f.cx, f.script(), f.pc(), args.rval());
 
         /*
          * Native stubs are not generated for inline frames. The overhead of
          * bailing out from the IC is far greater than the time saved by