Title: [91894] trunk/Source/_javascript_Core
Revision
91894
Author
commit-qu...@webkit.org
Date
2011-07-27 20:25:19 -0700 (Wed, 27 Jul 2011)

Log Message

DFG graph has no notion of double prediction.
https://bugs.webkit.org/show_bug.cgi?id=65234

Patch by Filip Pizlo <fpi...@apple.com> on 2011-07-27
Reviewed by Gavin Barraclough.

Added the notion of PredictDouble, and PredictNumber, which is the least
upper bound of PredictInt32 and PredictDouble.  Least upper bound is
defined as the bitwise-or of two predictions.  Bottom is defined as 0,
and Top is defined as all bits being set.  Added the ability to explicitly
distinguish between a node having had a prediction associated with it,
and that prediction still being valid (i.e. no conflicting predictions
have also been added).  Used this to guard the speculative JIT from
speculating Int32 in cases where the graph knows that the value is
double, which currently only happens for GetLocal nodes on arguments
which were double at compile-time.

* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::predictArgumentTypes):
* dfg/DFGGraph.h:
(JSC::DFG::isCellPrediction):
(JSC::DFG::isArrayPrediction):
(JSC::DFG::isInt32Prediction):
(JSC::DFG::isDoublePrediction):
(JSC::DFG::isNumberPrediction):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::checkArgumentTypes):
(JSC::DFG::SpeculativeJIT::initializeVariableTypes):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::isRegisterDataFormatDouble):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (91893 => 91894)


--- trunk/Source/_javascript_Core/ChangeLog	2011-07-28 03:00:54 UTC (rev 91893)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-07-28 03:25:19 UTC (rev 91894)
@@ -1,3 +1,36 @@
+2011-07-27  Filip Pizlo  <fpi...@apple.com>
+
+        DFG graph has no notion of double prediction.
+        https://bugs.webkit.org/show_bug.cgi?id=65234
+
+        Reviewed by Gavin Barraclough.
+        
+        Added the notion of PredictDouble, and PredictNumber, which is the least
+        upper bound of PredictInt32 and PredictDouble.  Least upper bound is
+        defined as the bitwise-or of two predictions.  Bottom is defined as 0,
+        and Top is defined as all bits being set.  Added the ability to explicitly
+        distinguish between a node having had a prediction associated with it,
+        and that prediction still being valid (i.e. no conflicting predictions
+        have also been added).  Used this to guard the speculative JIT from
+        speculating Int32 in cases where the graph knows that the value is
+        double, which currently only happens for GetLocal nodes on arguments
+        which were double at compile-time.
+
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::predictArgumentTypes):
+        * dfg/DFGGraph.h:
+        (JSC::DFG::isCellPrediction):
+        (JSC::DFG::isArrayPrediction):
+        (JSC::DFG::isInt32Prediction):
+        (JSC::DFG::isDoublePrediction):
+        (JSC::DFG::isNumberPrediction):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
+        (JSC::DFG::SpeculativeJIT::initializeVariableTypes):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::isRegisterDataFormatDouble):
+
 2011-07-27  Gavin Barraclough  <barraclo...@apple.com>
 
         https://bugs.webkit.org/show_bug.cgi?id=65294

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (91893 => 91894)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2011-07-28 03:00:54 UTC (rev 91893)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp	2011-07-28 03:25:19 UTC (rev 91894)
@@ -181,8 +181,11 @@
     size_t numberOfArguments = std::min(exec->argumentCountIncludingThis(), m_argumentPredictions.size());
 
     for (size_t arg = 1; arg < numberOfArguments; ++arg) {
-        if (exec->argument(arg - 1).isInt32())
+        JSValue argumentValue = exec->argument(arg - 1);
+        if (argumentValue.isInt32())
             m_argumentPredictions[arg].m_value |= PredictInt32;
+        else if (argumentValue.isDouble())
+            m_argumentPredictions[arg].m_value |= PredictDouble;
     }
 }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (91893 => 91894)


--- trunk/Source/_javascript_Core/dfg/DFGGraph.h	2011-07-28 03:00:54 UTC (rev 91893)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h	2011-07-28 03:25:19 UTC (rev 91894)
@@ -44,11 +44,38 @@
 inline bool operandIsArgument(int operand) { return operand < 0; }
 
 typedef uint8_t PredictedType;
-static const PredictedType PredictNone  = 0;
-static const PredictedType PredictCell  = 0x01;
-static const PredictedType PredictArray = 0x03;
-static const PredictedType PredictInt32 = 0x04;
+static const PredictedType PredictNone   = 0;
+static const PredictedType PredictCell   = 0x01;
+static const PredictedType PredictArray  = 0x03;
+static const PredictedType PredictInt32  = 0x04;
+static const PredictedType PredictDouble = 0x08;
+static const PredictedType PredictNumber = 0x0c;
 
+inline bool isCellPrediction(PredictedType value)
+{
+    return (value & PredictCell) == PredictCell && !(value & ~PredictArray);
+}
+
+inline bool isArrayPrediction(PredictedType value)
+{
+    return value == PredictArray;
+}
+
+inline bool isInt32Prediction(PredictedType value)
+{
+    return value == PredictInt32;
+}
+
+inline bool isDoublePrediction(PredictedType value)
+{
+    return value == PredictDouble;
+}
+
+inline bool isNumberPrediction(PredictedType value)
+{
+    return !!(value & PredictNumber) && !(value & ~PredictNumber);
+}
+
 struct PredictionSlot {
 public:
     PredictionSlot()

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (91893 => 91894)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-07-28 03:00:54 UTC (rev 91893)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-07-28 03:25:19 UTC (rev 91894)
@@ -537,7 +537,7 @@
     case GetLocal: {
         GPRTemporary result(this);
         PredictedType prediction = m_jit.graph().getPrediction(node.local());
-        if (prediction == PredictInt32) {
+        if (isInt32Prediction(prediction)) {
             m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
 
             // Like integerResult, but don't useChildren - our children are phi nodes,
@@ -552,35 +552,28 @@
             // and don't represent values within this dataflow with virtual registers.
             VirtualRegister virtualRegister = node.virtualRegister();
             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
-            m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), (prediction == PredictArray) ? DataFormatJSCell : DataFormatJS);
+            m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), isArrayPrediction(prediction) ? DataFormatJSCell : DataFormatJS);
         }
         break;
     }
 
     case SetLocal: {
-        switch (m_jit.graph().getPrediction(node.local())) {
-        case PredictInt32: {
+        PredictedType predictedType = m_jit.graph().getPrediction(node.local());
+        if (isInt32Prediction(predictedType)) {
             SpeculateIntegerOperand value(this, node.child1());
             m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
             noResult(m_compileIndex);
-            break;
-        }
-        case PredictArray: {
+        } else if (isArrayPrediction(predictedType)) {
             SpeculateCellOperand cell(this, node.child1());
             GPRReg cellGPR = cell.gpr();
             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
             m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local()));
             noResult(m_compileIndex);
-            break;
-        }
-
-        default: {
+        } else {
             JSValueOperand value(this, node.child1());
             m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local()));
             noResult(m_compileIndex);
-            break;
         }
-        }
         break;
     }
 
@@ -918,7 +911,7 @@
         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
         // If we have predicted the base to be type array, we can skip the check.
         Node& baseNode = m_jit.graph()[node.child1()];
-        if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray)
+        if (baseNode.op != GetLocal || !isArrayPrediction(m_jit.graph().getPrediction(baseNode.local())))
             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
         speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
 
@@ -953,7 +946,7 @@
         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
         // If we have predicted the base to be type array, we can skip the check.
         Node& baseNode = m_jit.graph()[node.child1()];
-        if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray)
+        if (baseNode.op != GetLocal || isArrayPrediction(m_jit.graph().getPrediction(baseNode.local())))
             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
 
         base.use();
@@ -1305,22 +1298,15 @@
     ASSERT(!m_compileIndex);
     for (int i = 0; i < m_jit.codeBlock()->m_numParameters; ++i) {
         VirtualRegister virtualRegister = (VirtualRegister)(m_jit.codeBlock()->thisRegister() + i);
-        switch (m_jit.graph().getPrediction(virtualRegister)) {
-        case PredictInt32:
+        PredictedType predictedType = m_jit.graph().getPrediction(virtualRegister);
+        if (isInt32Prediction(predictedType))
             speculationCheck(m_jit.branchPtr(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister));
-            break;
-
-        case PredictArray: {
+        else if (isArrayPrediction(predictedType)) {
             GPRTemporary temp(this);
             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
             speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
-            break;
         }
-
-        default:
-            break;
-        }
     }
 }
 
@@ -1332,7 +1318,7 @@
 {
     ASSERT(!m_compileIndex);
     for (int var = 0; var < m_jit.codeBlock()->m_numVars; ++var) {
-        if (m_jit.graph().getPrediction(var) == PredictInt32)
+        if (isInt32Prediction(m_jit.graph().getPrediction(var)))
             m_jit.storePtr(GPRInfo::tagTypeNumberRegister, JITCompiler::addressFor((VirtualRegister)var));
     }
 }

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (91893 => 91894)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2011-07-28 03:00:54 UTC (rev 91893)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2011-07-28 03:25:19 UTC (rev 91894)
@@ -162,7 +162,14 @@
         VirtualRegister virtualRegister = node.virtualRegister();
         GenerationInfo& info = m_generationInfo[virtualRegister];
 
-        return (info.registerFormat() | DataFormatJS) == DataFormatJSDouble;
+        if ((info.registerFormat() | DataFormatJS) == DataFormatJSDouble
+            || (info.spillFormat() | DataFormatJS) == DataFormatJSDouble)
+            return true;
+        
+        if (node.op == GetLocal && isDoublePrediction(m_jit.graph().getPrediction(node.local())))
+            return true;
+        
+        return false;
     }
     
     bool shouldSpeculateInteger(NodeIndex op1, NodeIndex op2)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to