[INFER] Handle recompilation hazard in NAME ICs, recompilation triggered by BINDNAME, bug 676764.
authorBrian Hackett <bhackett1024@gmail.com>
Fri, 05 Aug 2011 07:41:11 -0700
changeset 76098 723b6c2995741f3c3c68aa83571834a8e7f8db20
parent 76097 cc17967ae10b11d746e69e1b1687c885d14f2239
child 76099 4e4822ab5a03a68257863f8c34601ddd77bd3b0f
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
bugs676764
milestone8.0a1
[INFER] Handle recompilation hazard in NAME ICs, recompilation triggered by BINDNAME, bug 676764.
js/src/jit-test/tests/jaeger/recompile/bug676764.js
js/src/methodjit/Compiler.cpp
js/src/methodjit/MethodJIT.h
js/src/methodjit/PolyIC.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/recompile/bug676764.js
@@ -0,0 +1,14 @@
+
+try { with( <x/> ) {
+    (function () {
+        for (;;) {
+            t
+        }
+    })()
+} } catch (e) {}
+
+with( <x/> ) {
+  (function () {
+    for (b = 0; b < 18; ++b) {}
+  })();
+}
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -5294,17 +5294,17 @@ mjit::Compiler::jsop_bindname(JSAtom *at
 
     pic.shapeGuard = masm.label();
     Jump inlineJump = masm.branchPtr(Assembler::NotEqual, parent, ImmPtr(0));
     {
         RESERVE_OOL_SPACE(stubcc.masm);
         pic.slowPathStart = stubcc.linkExit(inlineJump, Uses(0));
         stubcc.leave();
         passICAddress(&pic);
-        pic.slowPathCall = OOL_STUBCALL(ic::BindName, REJOIN_BINDNAME);
+        pic.slowPathCall = OOL_STUBCALL(ic::BindName, REJOIN_FALLTHROUGH);
         CHECK_OOL_SPACE();
     }
 
     pic.fastPathRejoin = masm.label();
 
     /* Initialize op labels. */
     BindNameLabels &labels = pic.bindNameLabels();
     labels.setInlineJump(masm, pic.shapeGuard, inlineJump);
@@ -5365,20 +5365,20 @@ mjit::Compiler::jsop_bindname(JSAtom *at
 
     Address address(reg, offsetof(JSObject, parent));
 
     Jump j = masm.branchPtr(Assembler::NotEqual, address, ImmPtr(0));
 
     stubcc.linkExit(j, Uses(0));
     stubcc.leave();
     if (usePropCache) {
-        OOL_STUBCALL(stubs::BindName, REJOIN_BINDNAME);
+        OOL_STUBCALL(stubs::BindName, REJOIN_FALLTHROUGH);
     } else {
         stubcc.masm.move(ImmPtr(atom), Registers::ArgReg1);
-        OOL_STUBCALL(stubs::BindNameNoCache, REJOIN_BINDNAME);
+        OOL_STUBCALL(stubs::BindNameNoCache, REJOIN_FALLTHROUGH);
     }
 
     frame.pushTypedPayload(JSVAL_TYPE_OBJECT, reg);
 
     stubcc.rejoin(Changes(1));
 }
 #endif
 
--- a/js/src/methodjit/MethodJIT.h
+++ b/js/src/methodjit/MethodJIT.h
@@ -299,17 +299,16 @@ enum RejoinState {
     REJOIN_CALL_PROLOGUE,
     REJOIN_CALL_PROLOGUE_LOWERED_CALL,
     REJOIN_CALL_PROLOGUE_LOWERED_APPLY,
 
     /* Triggered a recompilation while placing the arguments to an apply on the stack. */
     REJOIN_CALL_SPLAT,
 
     /* FALLTHROUGH ops which can be implemented as part of an IncOp. */
-    REJOIN_BINDNAME,
     REJOIN_GETTER,
     REJOIN_POS,
     REJOIN_BINARY,
 
     /*
      * For an opcode fused with IFEQ/IFNE, call returns a boolean indicating
      * the result of the comparison and whether to take or not take the branch.
      */
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -1602,26 +1602,25 @@ class ScopeNameCompiler : public PICStub
             return status;
 
         if (!obj->getParent())
             return generateGlobalStub(obj);
 
         return disable("scope object not handled yet");
     }
 
-    bool retrieve(Value *vp, Value *thisvp)
+    bool retrieve(Value *vp, Value *thisvp, PICInfo::Kind kind)
     {
         JSObject *obj = getprop.obj;
         JSObject *holder = getprop.holder;
         const JSProperty *prop = getprop.prop;
 
         if (!prop) {
             /* Kludge to allow (typeof foo == "undefined") tests. */
-            disable("property not found");
-            if (pic.kind == ic::PICInfo::NAME) {
+            if (kind == ic::PICInfo::NAME) {
                 JSOp op2 = js_GetOpcode(cx, f.script(), f.pc() + JSOP_NAME_LENGTH);
                 if (op2 == JSOP_TYPEOF) {
                     vp->setUndefined();
                     return true;
                 }
             }
             ReportAtomNotDefined(cx, atom);
             return false;
@@ -2086,17 +2085,17 @@ ic::XName(VMFrame &f, ic::PICInfo *pic)
 
     ScopeNameCompiler cc(f, script, obj, *pic, pic->atom, DisabledXNameIC);
 
     LookupStatus status = cc.updateForXName();
     if (status == Lookup_Error)
         THROW();
 
     Value rval;
-    if (!cc.retrieve(&rval, NULL))
+    if (!cc.retrieve(&rval, NULL, PICInfo::XNAME))
         THROW();
     f.regs.sp[-1] = rval;
 
     types::TypeScript::Monitor(f.cx, f.script(), f.pc(), rval);
 }
 
 void JS_FASTCALL
 ic::Name(VMFrame &f, ic::PICInfo *pic)
@@ -2105,17 +2104,17 @@ ic::Name(VMFrame &f, ic::PICInfo *pic)
 
     ScopeNameCompiler cc(f, script, &f.fp()->scopeChain(), *pic, pic->atom, DisabledNameIC);
 
     LookupStatus status = cc.updateForName();
     if (status == Lookup_Error)
         THROW();
 
     Value rval;
-    if (!cc.retrieve(&rval, NULL))
+    if (!cc.retrieve(&rval, NULL, PICInfo::NAME))
         THROW();
     f.regs.sp[0] = rval;
 
     types::TypeScript::Monitor(f.cx, f.script(), f.pc(), rval);
 }
 
 static void JS_FASTCALL
 DisabledCallNameIC(VMFrame &f, ic::PICInfo *pic)
@@ -2130,17 +2129,17 @@ ic::CallName(VMFrame &f, ic::PICInfo *pi
 
     ScopeNameCompiler cc(f, script, &f.fp()->scopeChain(), *pic, pic->atom, DisabledCallNameIC);
 
     LookupStatus status = cc.updateForName();
     if (status == Lookup_Error)
         THROW();
 
     Value rval, thisval;
-    if (!cc.retrieve(&rval, &thisval))
+    if (!cc.retrieve(&rval, &thisval, PICInfo::CALLNAME))
         THROW();
 
     f.regs.sp[0] = rval;
     f.regs.sp[1] = thisval;
 
     types::TypeScript::Monitor(f.cx, f.script(), f.pc(), rval);
 }