[INFER] Disable generation of native stubs within inlined frames, bug 659639.
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 25 May 2011 10:22:03 -0700
changeset 75111 8bcb569c9bf9b7ec8dbc4b0d62e2a2c433716837
parent 75110 d5538f680ab43c4682d42d5ffe1b3cb7a6923dc4
child 75112 81997070017e97efc8a005dbe03c946fb6c26f8f
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs659639
milestone6.0a1
[INFER] Disable generation of native stubs within inlined frames, bug 659639.
js/src/jit-test/tests/jaeger/recompile/bug659639.js
js/src/methodjit/MethodJIT.h
js/src/methodjit/MonoIC.cpp
js/src/methodjit/Retcon.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/recompile/bug659639.js
@@ -0,0 +1,16 @@
+test();
+function iso(d) { new Date(d).toISOString() }
+function check(s,millis) { iso(millis); }
+function dd(year, month, day, hour, minute, second, millis) {
+    return Date.UTC(year, 1, day, hour, minute, second, millis);
+}
+function test() {
+    try {
+        check("", 20092353211)
+        check("", 2009)
+        check("", 0)
+        check("", dd(BUGNUMBER, 7, 23, 19, 53, 21, 1))
+    } catch (e) {}
+}
+var BUGNUMBER = "10278";
+test()
--- a/js/src/methodjit/MethodJIT.h
+++ b/js/src/methodjit/MethodJIT.h
@@ -258,23 +258,16 @@ enum RejoinState {
     /*
      * As for REJOIN_FALLTHROUGH, but holds a reference on the compartment's
      * orphaned native pools which needs to be reclaimed by InternalInterpret.
      * The return value needs to be adjusted if REJOIN_NATIVE_LOWERED.
      */
     REJOIN_NATIVE,
     REJOIN_NATIVE_LOWERED,
 
-    /*
-     * Placeholder for a VMFrame's stubRejoin on which a native call was
-     * performed (so the frame return address is incoherent and can't be
-     * examined), but the native has already been stolen.
-     */
-    REJOIN_NATIVE_EXPANDED,
-
     /* Call returns a payload, which should be pushed before starting next bytecode. */
     REJOIN_PUSH_BOOLEAN,
     REJOIN_PUSH_OBJECT,
 
     /* Call returns an object, which should be assigned to a local per the current bytecode. */
     REJOIN_DEFLOCALFUN,
 
     /*
--- a/js/src/methodjit/MonoIC.cpp
+++ b/js/src/methodjit/MonoIC.cpp
@@ -836,16 +836,20 @@ class CallCompiler : public BaseCompiler
         /* Don't touch the IC if the call triggered a recompilation. */
         if (monitor.recompiled())
             return true;
 
         /* Right now, take slow-path for IC misses or multiple stubs. */
         if (ic.fastGuardedNative || ic.hasJsFunCheck)
             return true;
 
+        /* Don't generate native MICs within inlined frames, we can't recompile them yet. */
+        if (f.regs.inlined())
+            return true;
+
         /* Native MIC needs to warm up first. */
         if (!ic.hit) {
             ic.hit = true;
             return true;
         }
 
         /* Generate fast-path for calling this native. */
         Assembler masm;
--- a/js/src/methodjit/Retcon.cpp
+++ b/js/src/methodjit/Retcon.cpp
@@ -228,39 +228,33 @@ Recompiler::expandInlineFrames(JSContext
 
     /*
      * Treat any frame expansion as a recompilation event, so that f.jit() is
      * stable if no recompilations have occurred.
      */
     cx->compartment->types.frameExpansions++;
 
     RejoinState rejoin = (RejoinState) f->stubRejoin;
-    JS_ASSERT(rejoin != REJOIN_NATIVE_LOWERED && rejoin != REJOIN_NATIVE_EXPANDED);
+    JS_ASSERT(rejoin != REJOIN_NATIVE && rejoin != REJOIN_NATIVE_LOWERED);
 
     /*
      * Patch the VMFrame's return address if it is returning at the given inline site.
      * Note there is no worry about handling a native or CompileFunction call here,
      * as such IC stubs are not generated within inline frames.
      */
     void **frameAddr = f->returnAddressLocation();
     uint8* codeStart = (uint8 *)fp->jit()->code.m_code.executableAddress();
 
     InlineFrame *inner = &fp->jit()->inlineFrames()[inlined->inlineIndex];
     jsbytecode *innerpc = inner->fun->script()->code + inlined->pcOffset;
 
     StackFrame *innerfp = expandInlineFrameChain(cx, fp, inner);
 
     /* Check if the VMFrame returns into the inlined frame. */
-    if (f->stubRejoin == REJOIN_NATIVE) {
-        /* The VMFrame returns into a native stub. */
-        if (f->regs.fp() == fp) {
-            patchNative(cx, fp->jit(), innerfp, f->regs.pc, f->regs.inlined(), rejoin);
-            f->stubRejoin = REJOIN_NATIVE_EXPANDED;
-        }
-    } else if (f->stubRejoin) {
+    if (f->stubRejoin) {
         /* The VMFrame is calling CompileFunction. */
         if (f->regs.fp()->prev() == fp) {
             fp->prev()->setRejoin(StubRejoin(rejoin));
             *frameAddr = JS_FUNC_TO_DATA_PTR(void *, JaegerInterpoline);
         }
     } else if (*frameAddr == codeStart + inlined->codeOffset) {
         /* The VMFrame returns directly into the expanded frame. */
         SetRejoinState(innerfp, *inlined, frameAddr);
@@ -416,25 +410,20 @@ Recompiler::recompile(bool resetUses)
          * frame at the point where the call occurred, irregardless of any
          * frames which were pushed inside the call.
          */
         StackFrame *fp = f->fp();
         void **addr = f->returnAddressLocation();
         RejoinState rejoin = (RejoinState) f->stubRejoin;
         if (rejoin == REJOIN_NATIVE || rejoin == REJOIN_NATIVE_LOWERED) {
             // Native call.
-            if (fp->script() == script && fp->isConstructing()) {
+            if (fp->script() == script && fp->isConstructing())
                 patchNative(cx, script->jitCtor, fp, fp->pc(cx, NULL), NULL, rejoin);
-                f->stubRejoin = REJOIN_NATIVE_EXPANDED;
-            } else if (fp->script() == script) {
+            else if (fp->script() == script)
                 patchNative(cx, script->jitNormal, fp, fp->pc(cx, NULL), NULL, rejoin);
-                f->stubRejoin = REJOIN_NATIVE_EXPANDED;
-            }
-        } else if (rejoin == REJOIN_NATIVE_EXPANDED) {
-            /* This frame will already be redirected to the interpoline. */
         } else if (rejoin) {
             /* Recompilation triggered by CompileFunction. */
             if (fp->prev()->script() == script) {
                 fp->prev()->setRejoin(StubRejoin(rejoin));
                 *addr = JS_FUNC_TO_DATA_PTR(void *, JaegerInterpoline);
             }
         } else if (script->jitCtor && script->jitCtor->isValidCode(*addr)) {
             patchCall(script->jitCtor, fp, addr);