Title: [93934] trunk
Revision
93934
Author
barraclo...@apple.com
Date
2011-08-26 21:19:22 -0700 (Fri, 26 Aug 2011)

Log Message

DFG JIT - ArithMod may clobber operands.
https://bugs.webkit.org/show_bug.cgi?id=67085

Reviewed by Sam Weinig.

Source/_javascript_Core: 

unboxDouble must be called on a temporary.

* dfg/DFGJITCodeGenerator.cpp:
(JSC::DFG::JITCodeGenerator::fillDouble):
* dfg/DFGJITCodeGenerator.h:
(JSC::DFG::JITCodeGenerator::boxDouble):
* dfg/DFGNonSpeculativeJIT.cpp:
(JSC::DFG::NonSpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):

LayoutTests: 

Added test case.

* fast/js/mod-crash-expected.txt:
* fast/js/script-tests/mod-crash.js:
(nonSpeculativeModReuseInner):
(nonSpeculativeModReuse):

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (93933 => 93934)


--- trunk/LayoutTests/ChangeLog	2011-08-27 03:51:03 UTC (rev 93933)
+++ trunk/LayoutTests/ChangeLog	2011-08-27 04:19:22 UTC (rev 93934)
@@ -1,3 +1,17 @@
+2011-08-26  Gavin Barraclough  <barraclo...@apple.com>
+
+        DFG JIT - ArithMod may clobber operands.
+        https://bugs.webkit.org/show_bug.cgi?id=67085
+
+        Reviewed by Sam Weinig.
+
+        Added test case.
+
+        * fast/js/mod-crash-expected.txt:
+        * fast/js/script-tests/mod-crash.js:
+        (nonSpeculativeModReuseInner):
+        (nonSpeculativeModReuse):
+
 2011-08-26  Anna Cavender  <ann...@chromium.org>
 
         Cleanup resulting text of media/track tests.

Modified: trunk/LayoutTests/fast/js/mod-crash-expected.txt (93933 => 93934)


--- trunk/LayoutTests/fast/js/mod-crash-expected.txt	2011-08-27 03:51:03 UTC (rev 93933)
+++ trunk/LayoutTests/fast/js/mod-crash-expected.txt	2011-08-27 04:19:22 UTC (rev 93934)
@@ -7,6 +7,7 @@
 PASS n % 0 is NaN
 PASS f() is NaN
 PASS g() is NaN
+PASS nonSpeculativeModReuse(0.5) is 1
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/js/script-tests/mod-crash.js (93933 => 93934)


--- trunk/LayoutTests/fast/js/script-tests/mod-crash.js	2011-08-27 03:51:03 UTC (rev 93933)
+++ trunk/LayoutTests/fast/js/script-tests/mod-crash.js	2011-08-27 04:19:22 UTC (rev 93934)
@@ -22,4 +22,20 @@
 
 shouldBe("g()", "NaN");
 
+// Test that reusing a floating point value after use in a modulus works correctly.
+function nonSpeculativeModReuseInner(argument, o1, o2)
+{
+ 	// The + operator on objects is a reliable way to avoid the speculative JIT path for now at least.
+    o1 + o2;
+
+    var knownDouble = argument - 0;
+    return knownDouble % 1 + knownDouble;
+}
+function nonSpeculativeModReuse(argument)
+{
+    return nonSpeculativeModReuseInner(argument, {}, {});
+}
+
+shouldBe("nonSpeculativeModReuse(0.5)", "1");
+
 var successfullyParsed = true;

Modified: trunk/Source/_javascript_Core/ChangeLog (93933 => 93934)


--- trunk/Source/_javascript_Core/ChangeLog	2011-08-27 03:51:03 UTC (rev 93933)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-08-27 04:19:22 UTC (rev 93934)
@@ -1,3 +1,21 @@
+2011-08-26  Gavin Barraclough  <barraclo...@apple.com>
+
+        DFG JIT - ArithMod may clobber operands.
+        https://bugs.webkit.org/show_bug.cgi?id=67085
+
+        Reviewed by Sam Weinig.
+
+        unboxDouble must be called on a temporary.
+
+        * dfg/DFGJITCodeGenerator.cpp:
+        (JSC::DFG::JITCodeGenerator::fillDouble):
+        * dfg/DFGJITCodeGenerator.h:
+        (JSC::DFG::JITCodeGenerator::boxDouble):
+        * dfg/DFGNonSpeculativeJIT.cpp:
+        (JSC::DFG::NonSpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
+
 2011-08-26  Mark Hahnenberg  <mhahnenb...@apple.com>
 
         Unzip initialization lists and constructors in JSCell hierarchy (2/7)

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (93933 => 93934)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp	2011-08-27 03:51:03 UTC (rev 93933)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp	2011-08-27 04:19:22 UTC (rev 93934)
@@ -198,7 +198,15 @@
     // Unbox the double
     case DataFormatJSDouble: {
         GPRReg gpr = info.gpr();
-        FPRReg fpr = unboxDouble(gpr);
+        FPRReg fpr = fprAllocate();
+        if (m_gprs.isLocked(gpr)) {
+            // Make sure we don't trample gpr if it is in use.
+            GPRReg temp = allocate();
+            m_jit.move(gpr, temp);
+            unboxDouble(temp, fpr);
+            unlock(temp);
+        } else
+            unboxDouble(gpr, fpr);
 
         m_gprs.release(gpr);
         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (93933 => 93934)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-08-27 03:51:03 UTC (rev 93933)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-08-27 04:19:22 UTC (rev 93934)
@@ -367,10 +367,6 @@
     {
         return boxDouble(fpr, allocate());
     }
-    FPRReg unboxDouble(GPRReg gpr)
-    {
-        return unboxDouble(gpr, fprAllocate());
-    }
 
     // Spill a VirtualRegister to the RegisterFile.
     void spill(VirtualRegister spillMe)

Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (93933 => 93934)


--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp	2011-08-27 03:51:03 UTC (rev 93933)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp	2011-08-27 04:19:22 UTC (rev 93934)
@@ -674,12 +674,19 @@
         op2.use();
     
         GPRReg temp2 = InvalidGPRReg;
+        GPRReg unboxGPR;
         if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) {
             temp2 = allocate();
             m_jit.move(op2GPR, temp2);
             op2GPR = temp2;
-        }
-    
+            unboxGPR = temp2;
+        } else if (op1GPR == X86Registers::eax)
+            unboxGPR = X86Registers::edx;
+        else
+            unboxGPR = X86Registers::eax;
+        ASSERT(unboxGPR != op1.gpr());
+        ASSERT(unboxGPR != op2.gpr());
+
         JITCompiler::Jump firstOpNotInt;
         JITCompiler::Jump secondOpNotInt;
         JITCompiler::JumpList done;
@@ -724,12 +731,14 @@
                 secondOpNotInt2.link(&m_jit);
             
                 // first op is a double, second op is a double.
-                unboxDouble(op2GPR, op2FPR);
+                m_jit.move(op2GPR, unboxGPR);
+                unboxDouble(unboxGPR, op2FPR);
             
                 gotSecondOp.link(&m_jit);
             }
         
-            unboxDouble(op1GPR, op1FPR);
+            m_jit.move(op1GPR, unboxGPR);
+            unboxDouble(unboxGPR, op1FPR);
         
             gotDoubleArgs = m_jit.jump();
         }
@@ -739,7 +748,8 @@
         
             // we know that the first op is an int, and the second is a double
             m_jit.convertInt32ToDouble(op1GPR, op1FPR);
-            unboxDouble(op2GPR, op2FPR);
+            m_jit.move(op2GPR, unboxGPR);
+            unboxDouble(unboxGPR, op2FPR);
         }
     
         if (!isKnownInteger(node.child1()))

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (93933 => 93934)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-08-27 03:51:03 UTC (rev 93933)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-08-27 04:19:22 UTC (rev 93934)
@@ -271,7 +271,15 @@
     // Unbox the double
     case DataFormatJSDouble: {
         GPRReg gpr = info.gpr();
-        FPRReg fpr = unboxDouble(gpr);
+        FPRReg fpr = fprAllocate();
+        if (m_gprs.isLocked(gpr)) {
+            // Make sure we don't trample gpr if it is in use.
+            GPRReg temp = allocate();
+            m_jit.move(gpr, temp);
+            unboxDouble(temp, fpr);
+            unlock(temp);
+        } else
+            unboxDouble(gpr, fpr);
 
         m_gprs.release(gpr);
         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to