ParseInt intrinsic in DFG backend doesn't properly flush its operands
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 15 Apr 2017 02:13:11 +0000 (02:13 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 15 Apr 2017 02:13:11 +0000 (02:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170865

Reviewed by Mark Lam and Geoffrey Garen.

JSTests:

* stress/parse-int-intrinsic-dfg-backend-flush.js: Added.
(assert):
(foo):

Source/JavaScriptCore:

The DFG backend code needed to first call .gpr()/.jsValueRegs()
before calling flushRegisters(), or the input JSValueOperand would
not be flushed.

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileParseInt):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@215387 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JSTests/ChangeLog
JSTests/stress/parse-int-intrinsic-dfg-backend-flush.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

index 439e090..ac9d27c 100644 (file)
@@ -1,3 +1,14 @@
+2017-04-14  Saam Barati  <sbarati@apple.com>
+
+        ParseInt intrinsic in DFG backend doesn't properly flush its operands
+        https://bugs.webkit.org/show_bug.cgi?id=170865
+
+        Reviewed by Mark Lam and Geoffrey Garen.
+
+        * stress/parse-int-intrinsic-dfg-backend-flush.js: Added.
+        (assert):
+        (foo):
+
 2017-04-14  Caitlin Potter  <caitp@igalia.com>
 
         [JSC] use ExpressionErrorClassifier for AwaitExpression operand
diff --git a/JSTests/stress/parse-int-intrinsic-dfg-backend-flush.js b/JSTests/stress/parse-int-intrinsic-dfg-backend-flush.js
new file mode 100644 (file)
index 0000000..b66057c
--- /dev/null
@@ -0,0 +1,14 @@
+function assert(b) {
+    if (!b)
+        throw new Error("Bad")
+}
+
+function foo(x) {
+    return x === parseInt(x, 10);
+}
+noInline(foo);
+
+for (let i = 0; i < 10000; i++) {
+    assert(!foo(`${i}`));
+    assert(foo(i));
+}
index 7958c1d..816d19d 100644 (file)
@@ -1,3 +1,17 @@
+2017-04-14  Saam Barati  <sbarati@apple.com>
+
+        ParseInt intrinsic in DFG backend doesn't properly flush its operands
+        https://bugs.webkit.org/show_bug.cgi?id=170865
+
+        Reviewed by Mark Lam and Geoffrey Garen.
+
+        The DFG backend code needed to first call .gpr()/.jsValueRegs()
+        before calling flushRegisters(), or the input JSValueOperand would
+        not be flushed.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileParseInt):
+
 2017-04-14  Mark Lam  <mark.lam@apple.com>
 
         Update architectures in xcconfig files.
index 2b34ce3..5c4e92f 100644 (file)
@@ -3153,37 +3153,44 @@ void SpeculativeJIT::compileParseInt(Node* node)
         GPRReg radixGPR = radix.gpr();
         if (node->child1().useKind() == UntypedUse) {
             JSValueOperand value(this, node->child1());
-
-            flushRegisters();
 #if USE(JSVALUE64)
-            callOperation(operationParseIntGeneric, resultRegs.gpr(), value.gpr(), radixGPR);
+            auto result = resultRegs.gpr();
+            auto valueReg = value.gpr();
 #else
-            callOperation(operationParseIntGeneric, resultRegs, value.jsValueRegs(), radixGPR);
+            auto result = resultRegs;
+            auto valueReg = value.jsValueRegs();
 #endif
+
+            flushRegisters();
+            callOperation(operationParseIntGeneric, result, valueReg, radixGPR);
             m_jit.exceptionCheck();
         } else {
             SpeculateCellOperand value(this, node->child1());
             GPRReg valueGPR = value.gpr();
             speculateString(node->child1(), valueGPR);
 
-            flushRegisters();
 #if USE(JSVALUE64)
-            callOperation(operationParseIntString, resultRegs.gpr(), valueGPR, radixGPR);
+            auto result = resultRegs.gpr();
 #else
-            callOperation(operationParseIntString, resultRegs, valueGPR, radixGPR);
+            auto result = resultRegs;
 #endif
+
+            flushRegisters();
+            callOperation(operationParseIntString, result, valueGPR, radixGPR);
             m_jit.exceptionCheck();
         }
     } else {
         if (node->child1().useKind() == UntypedUse) {
             JSValueOperand value(this, node->child1());
-
-            flushRegisters();
 #if USE(JSVALUE64)
-            callOperation(operationParseIntNoRadixGeneric, resultRegs.gpr(), value.jsValueRegs());
+            auto result = resultRegs.gpr();
 #else
-            callOperation(operationParseIntNoRadixGeneric, resultRegs, value.jsValueRegs());
+            auto result = resultRegs;
 #endif
+            JSValueRegs valueRegs = value.jsValueRegs();
+
+            flushRegisters();
+            callOperation(operationParseIntNoRadixGeneric, result, valueRegs);
             m_jit.exceptionCheck();
         } else {
             SpeculateCellOperand value(this, node->child1());