Bug 921035 - Dont phi-eliminate scopeChain object in heavyweight functions if it may be neede for argsobj construction later. r=h4writer
☠☠ backed out by 062d17374196 ☠ ☠
authorKannan Vijayan <kvijayan@mozilla.com>
Wed, 16 Oct 2013 11:43:26 -0400
changeset 164784 b158656d754e6cc4af1e51e2ea843d265572110d
parent 164783 7652896ed115b66594fa131a969475ca326107c0
child 164785 d189b37b6877be1cd51b7cbd5dd8f462517cee71
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [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,12 @@
+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;
         }
     }