Bug 909743 - Save live ForkJoinSlice register in the fast string concat stub. (r=jandem)
authorShu-yu Guo <shu@rfrn.org>
Thu, 10 Oct 2013 20:02:30 -0700
changeset 150421 d64b073e736edd1a59c96ec096f58f69ae15710b
parent 150420 027a7386406ff2ce0fc59e6afda43fd1d5c78179
child 150422 f422b59826c1767d44b52f9467c18b5561f8cfe5
push id2993
push usercbook@mozilla.com
push dateFri, 11 Oct 2013 09:22:00 +0000
treeherderfx-team@fe160ec1e0ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs909743
milestone27.0a1
Bug 909743 - Save live ForkJoinSlice register in the fast string concat stub. (r=jandem)
js/src/jit-test/tests/parallel/bug909743.js
js/src/jit/CodeGenerator.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/parallel/bug909743.js
@@ -0,0 +1,21 @@
+if (getBuildConfiguration().parallelJS) {
+  function assertParallelExecSucceeds(opFunction) {
+    for (var i = 0; i < 100; ++i) {
+      opFunction({mode:"compile"});
+    }
+  }
+  function assertArraySeqParResultsEq(arr, op, func) {
+    assertParallelExecSucceeds(
+      function (m) { 
+        return arr[op + "Par"].apply(arr, [func, m]); 
+      }
+    );
+  }
+  function range(n, m) {
+    var result = [];
+    for (var i = n; i < m; i++)
+      result.push(i);
+    return result;
+  }
+  assertArraySeqParResultsEq(range(0, 512), "map", function(e) { return e+'x'; });
+}
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -4452,25 +4452,36 @@ IonCompartment::generateStringConcatStub
     masm.lshiftPtr(Imm32(JSString::LENGTH_SHIFT), temp2);
     masm.orPtr(Imm32(JSString::FIXED_FLAGS), temp2);
     masm.storePtr(temp2, Address(output, JSString::offsetOfLengthAndFlags()));
 
     // Set chars pointer, keep in temp2 for copy loop below.
     masm.computeEffectiveAddress(Address(output, JSShortString::offsetOfInlineStorage()), temp2);
     masm.storePtr(temp2, Address(output, JSShortString::offsetOfChars()));
 
-    // Copy lhs chars. Temp1 still holds the lhs length. Note that this
-    // advances temp2 to point to the next char.
-    masm.loadPtr(Address(lhs, JSString::offsetOfChars()), temp3);
-    CopyStringChars(masm, temp2, temp3, temp1, temp4);
-
-    // Copy rhs chars.
-    masm.loadPtr(Address(rhs, JSString::offsetOfChars()), temp3);
-    masm.loadStringLength(rhs, temp1);
-    CopyStringChars(masm, temp2, temp3, temp1, temp4);
+    {
+        // We use temp4 in this block, which in parallel execution also holds
+        // a live ForkJoinSlice pointer. If we are compiling for parallel
+        // execution, be sure to save and restore the ForkJoinSlice.
+        if (mode == ParallelExecution)
+            masm.push(temp4);
+
+        // Copy lhs chars. Temp1 still holds the lhs length. Note that this
+        // advances temp2 to point to the next char.
+        masm.loadPtr(Address(lhs, JSString::offsetOfChars()), temp3);
+        CopyStringChars(masm, temp2, temp3, temp1, temp4);
+
+        // Copy rhs chars.
+        masm.loadPtr(Address(rhs, JSString::offsetOfChars()), temp3);
+        masm.loadStringLength(rhs, temp1);
+        CopyStringChars(masm, temp2, temp3, temp1, temp4);
+
+        if (mode == ParallelExecution)
+            masm.pop(temp4);
+    }
 
     // Null-terminate.
     masm.store16(Imm32(0), Address(temp2, 0));
     masm.ret();
 
     masm.bind(&failurePopTemps);
     masm.pop(temp2);
     masm.pop(temp1);