Bug 921035 - Dont phi-eliminate scopeChain object in heavyweight functions if it may be neede for argsobj construction later. r=h4writer
authorKannan Vijayan <kvijayan@mozilla.com>
Wed, 16 Oct 2013 16:20:10 -0400
changeset 165843 e41c12eedc22bf947a2c247ec2779cf577c756b9
parent 165842 1850054aca10e97833160551b7c5726609c20262
child 165844 af90be9858824e59ea1dc874dfe5a51e1b420213
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersh4writer
bugs921035
milestone27.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
Bug 921035 - Dont phi-eliminate scopeChain object in heavyweight functions if it may be neede for argsobj construction later. r=h4writer
js/src/jit-test/tests/ion/bug921035.js
js/src/jit/IonAnalysis.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug921035.js
@@ -0,0 +1,14 @@
+// |jit-test| error: TypeError
+
+function $ERROR() {}
+function testMultipleArgumentsObjects() {
+    var testargs = arguments;
+    var f = function (which) {
+        var args = [ testargs ];
+        return args[which][0];
+    };
+    var arr = [0, 0, 0, 0, 1];
+    for (var i = 0; i < arr.length; i++)
+        $ERROR[i] = f(arr[i]);
+}
+testMultipleArgumentsObjects()
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -206,26 +206,35 @@ IsPhiObservable(MPhi *phi, Observability
         for (MUseIterator iter(phi->usesBegin()); iter != phi->usesEnd(); iter++) {
             if (!iter->consumer()->isDefinition() ||
                 !iter->consumer()->toDefinition()->isPhi())
                 return true;
         }
         break;
     }
 
-    // If the Phi is of the |this| value, it must always be observable.
     uint32_t slot = phi->slot();
     CompileInfo &info = phi->block()->info();
-    if (info.fun() && slot == info.thisSlot())
+    JSFunction *fun = info.fun();
+
+    // If the Phi is of the |this| value, it must always be observable.
+    if (fun && slot == info.thisSlot())
+        return true;
+
+    // If the function is heavyweight, and the Phi is of the |scopeChain|
+    // value, and the function may need an arguments object, then make sure
+    // to preserve the scope chain, because it may be needed to construct the
+    // arguments object during bailout.
+    if (fun && fun->isHeavyweight() && info.hasArguments() && slot == info.scopeChainSlot())
         return true;
 
     // If the Phi is one of the formal argument, and we are using an argument
     // object in the function. The phi might be observable after a bailout.
     // For inlined frames this is not needed, as they are captured in the inlineResumePoint.
-    if (info.fun() && info.hasArguments()) {
+    if (fun && info.hasArguments()) {
         uint32_t first = info.firstArgSlot();
         if (first <= slot && slot - first < info.nargs()) {
             // If arguments obj aliases formals, then the arg slots will never be used.
             if (info.argsObjAliasesFormals())
                 return false;
             return true;
         }
     }