[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 77409 723b6c2995741f3c3c68aa83571834a8e7f8db20
parent 77408 cc17967ae10b11d746e69e1b1687c885d14f2239
child 77410 4e4822ab5a03a68257863f8c34601ddd77bd3b0f
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs676764
milestone8.0a1
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
[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);
 }