[INFER] Add recompilation rejoin points for GETELEM/CALLELEM, bug 642405.
authorBrian Hackett <bhackett1024@gmail.com>
Thu, 17 Mar 2011 12:07:48 -0700
changeset 74801 e65266e60e1f9d7cdd8efb1296391b36a7074249
parent 74800 8b5eb3c09698e37b25071fd3820491e20ec0465e
child 74802 7085463508eeede7eaa016f28f27e2f584c5112b
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs642405
milestone2.0b13pre
[INFER] Add recompilation rejoin points for GETELEM/CALLELEM, bug 642405.
js/src/jit-test/tests/jaeger/recompile/bug642405.js
js/src/methodjit/Compiler.cpp
js/src/methodjit/FastOps.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/recompile/bug642405.js
@@ -0,0 +1,13 @@
+function startTest() {};
+try {
+}
+catch(ex)
+{
+  actual = ex + '';
+}
+var actual = 'no error';
+var prefValue;
+DESCRIPTION = "var class = true";
+EXPECTED = "error";
+foo(EXPECTED[prefValue], DESCRIPTION[prefValue], startTest[prefValue]);
+function foo() {}
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -3222,17 +3222,17 @@ mjit::Compiler::inlineCallHelper(uint32 
 /*
  * This function must be called immediately after any instruction which could
  * cause a new JSStackFrame to be pushed and could lead to a new debug trap
  * being set. This includes any API callbacks and any scripted or native call.
  */
 void
 mjit::Compiler::addCallSite(const InternalCallSite &site)
 {
-#if 0 /* Expensive assertion on some tests. */
+#if 1 /* Expensive assertion on some tests. */
     for (unsigned i = 0; i < callSites.length(); i++)
         JS_ASSERT(site.pc != callSites[i].pc || site.id != callSites[i].id);
 #endif
     callSites.append(site);
 }
 
 void
 mjit::Compiler::restoreFrameRegs(Assembler &masm)
@@ -5034,16 +5034,21 @@ mjit::Compiler::jsop_setelem_slow()
 
 void
 mjit::Compiler::jsop_getelem_slow()
 {
     prepareStubCall(Uses(2));
     INLINE_STUBCALL(stubs::GetElem);
     frame.popn(2);
     pushSyncedEntry(0);
+
+    if (recompiling) {
+        OOL_STUBCALL(ic::GetElement);
+        stubcc.rejoin(Changes(1));
+    }
 }
 
 void
 mjit::Compiler::jsop_unbrand()
 {
     prepareStubCall(Uses(1));
     INLINE_STUBCALL(stubs::Unbrand);
 }
@@ -5593,16 +5598,21 @@ mjit::Compiler::jsop_tableswitch(jsbytec
 void
 mjit::Compiler::jsop_callelem_slow()
 {
     prepareStubCall(Uses(2));
     INLINE_STUBCALL(stubs::CallElem);
     frame.popn(2);
     pushSyncedEntry(0);
     pushSyncedEntry(1);
+
+    if (recompiling) {
+        OOL_STUBCALL(ic::CallElement);
+        stubcc.rejoin(Changes(2));
+    }
 }
 
 void
 mjit::Compiler::jsop_forprop(JSAtom *atom)
 {
     // Before: ITER OBJ
     // After:  ITER OBJ ITER
     frame.dupAt(-2);
--- a/js/src/methodjit/FastOps.cpp
+++ b/js/src/methodjit/FastOps.cpp
@@ -1494,16 +1494,21 @@ mjit::Compiler::jsop_getelem_dense(bool 
             stubcc.linkExitDirect(holeCheck, stubcc.masm.label());
         JS_ASSERT(type == JSVAL_TYPE_UNKNOWN || type == JSVAL_TYPE_UNDEFINED);
         if (type == JSVAL_TYPE_UNDEFINED)
             stubcc.masm.loadValuePayload(UndefinedValue(), dataReg);
         else
             stubcc.masm.loadValueAsComponents(UndefinedValue(), typeReg.reg(), dataReg);
         stubcc.linkRejoin(stubcc.masm.jump());
     }
+
+    if (recompiling) {
+        OOL_STUBCALL(ic::GetElement);
+        stubcc.rejoin(Changes(1));
+    }
 }
 
 bool
 mjit::Compiler::jsop_getelem(bool isCall)
 {
     FrameEntry *obj = frame.peek(-2);
     FrameEntry *id = frame.peek(-1);