Bug 1357024 - Fix fixupAliasedInputs to not leave an unusable register on 32-bit platforms. r=h4writer, a=gchang
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 25 Apr 2017 13:51:03 +0200
changeset 393765 dbdaa649ec554f92804becbab17743791cab3ad6
parent 393764 4c630b9a7d2f7bce143ea7ffcd9a42b44de59d2c
child 393766 2adccdb8d0de0547a5873b7b17d4b119020c6809
push id7253
push userryanvm@gmail.com
push dateMon, 01 May 2017 17:09:40 +0000
treeherdermozilla-beta@bd22c9a6d586 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersh4writer, gchang
bugs1357024
milestone54.0
Bug 1357024 - Fix fixupAliasedInputs to not leave an unusable register on 32-bit platforms. r=h4writer, a=gchang
js/src/jit-test/tests/cacheir/bug1357024.js
js/src/jit/CacheIRCompiler.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/cacheir/bug1357024.js
@@ -0,0 +1,12 @@
+function f() {
+    var o = {};
+    for (var j = 0; j < 15; j++) {
+        try {
+            o.__proto__ = o || j;
+        } catch(e) {
+            continue;
+        }
+        throw "Fail";
+    }
+}
+f();
--- a/js/src/jit/CacheIRCompiler.cpp
+++ b/js/src/jit/CacheIRCompiler.cpp
@@ -454,25 +454,29 @@ CacheRegisterAllocator::fixupAliasedInpu
         if (!loc1.isInRegister())
             continue;
 
         for (size_t j = 0; j < i; j++) {
             OperandLocation& loc2 = operandLocations_[j];
             if (!loc1.aliasesReg(loc2))
                 continue;
 
+            // loc1 and loc2 alias so we spill one of them. If one is a
+            // ValueReg and the other is a PayloadReg, we have to spill the
+            // PayloadReg: spilling the ValueReg instead would leave its type
+            // register unallocated on 32-bit platforms.
             if (loc1.kind() == OperandLocation::ValueReg) {
                 MOZ_ASSERT_IF(loc2.kind() == OperandLocation::ValueReg,
                               loc1 == loc2);
+                spillOperandToStack(masm, &loc2);
+            } else {
+                MOZ_ASSERT(loc1.kind() == OperandLocation::PayloadReg);
                 spillOperandToStack(masm, &loc1);
-                break;
+                break; // Spilled loc1, so nothing else will alias it.
             }
-
-            MOZ_ASSERT(loc1.kind() == OperandLocation::PayloadReg);
-            spillOperandToStack(masm, &loc2);
         }
     }
 }
 
 GeneralRegisterSet
 CacheRegisterAllocator::inputRegisterSet() const
 {
     MOZ_ASSERT(origInputLocations_.length() == writer_.numInputOperands());