Modified: trunk/Source/_javascript_Core/ChangeLog (110660 => 110661)
--- trunk/Source/_javascript_Core/ChangeLog 2012-03-14 02:47:48 UTC (rev 110660)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-03-14 02:54:58 UTC (rev 110661)
@@ -1,3 +1,24 @@
+2012-03-13 Filip Pizlo <[email protected]>
+
+ ValueToInt32 speculation will cause OSR exits even when it does not have to
+ https://bugs.webkit.org/show_bug.cgi?id=81068
+ <rdar://problem/11043926>
+
+ Reviewed by Anders Carlsson.
+
+ Two related changes:
+ 1) ValueToInt32 will now always just defer to the non-speculative path, instead
+ of exiting, if it doesn't know what speculations to perform.
+ 2) ValueToInt32 will speculate boolean if it sees this to be profitable.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::shouldSpeculateBoolean):
+ (Node):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileValueToInt32):
+
2012-03-13 Mark Hahnenberg <[email protected]>
More Windows build fixing
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp (110660 => 110661)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2012-03-14 02:47:48 UTC (rev 110660)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2012-03-14 02:54:58 UTC (rev 110661)
@@ -291,11 +291,12 @@
break;
case ValueToInt32:
- if (m_graph[node.child1()].shouldNotSpeculateInteger()) {
- if (m_graph[node.child1()].shouldSpeculateDouble())
- forNode(node.child1()).filter(PredictNumber);
- } else
+ if (m_graph[node.child1()].shouldSpeculateInteger())
forNode(node.child1()).filter(PredictInt32);
+ else if (m_graph[node.child1()].shouldSpeculateNumber())
+ forNode(node.child1()).filter(PredictNumber);
+ else if (m_graph[node.child1()].shouldSpeculateBoolean())
+ forNode(node.child1()).filter(PredictBoolean);
forNode(nodeIndex).set(PredictInt32);
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (110660 => 110661)
--- trunk/Source/_javascript_Core/dfg/DFGNode.h 2012-03-14 02:47:48 UTC (rev 110660)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h 2012-03-14 02:54:58 UTC (rev 110661)
@@ -700,6 +700,11 @@
return !!(prediction() & PredictDouble);
}
+ bool shouldSpeculateBoolean()
+ {
+ return isBooleanPrediction(prediction());
+ }
+
bool shouldSpeculateFinalObject()
{
return isFinalObjectPrediction(prediction());
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (110660 => 110661)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2012-03-14 02:47:48 UTC (rev 110660)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2012-03-14 02:54:58 UTC (rev 110661)
@@ -1490,31 +1490,43 @@
void SpeculativeJIT::compileValueToInt32(Node& node)
{
- if (at(node.child1()).shouldNotSpeculateInteger()) {
- if (at(node.child1()).shouldSpeculateDouble()) {
- SpeculateDoubleOperand op1(this, node.child1());
- GPRTemporary result(this);
- FPRReg fpr = op1.fpr();
- GPRReg gpr = result.gpr();
- JITCompiler::Jump truncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateSuccessful);
-
- silentSpillAllRegisters(gpr);
- callOperation(toInt32, gpr, fpr);
- silentFillAllRegisters(gpr);
-
- truncatedToInteger.link(&m_jit);
- integerResult(gpr, m_compileIndex);
- return;
- }
- // Do it the safe way.
- nonSpeculativeValueToInt32(node);
+ if (at(node.child1()).shouldSpeculateInteger()) {
+ SpeculateIntegerOperand op1(this, node.child1());
+ GPRTemporary result(this, op1);
+ m_jit.move(op1.gpr(), result.gpr());
+ integerResult(result.gpr(), m_compileIndex, op1.format());
return;
}
- SpeculateIntegerOperand op1(this, node.child1());
- GPRTemporary result(this, op1);
- m_jit.move(op1.gpr(), result.gpr());
- integerResult(result.gpr(), m_compileIndex, op1.format());
+ if (at(node.child1()).shouldSpeculateNumber()) {
+ SpeculateDoubleOperand op1(this, node.child1());
+ GPRTemporary result(this);
+ FPRReg fpr = op1.fpr();
+ GPRReg gpr = result.gpr();
+ JITCompiler::Jump truncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateSuccessful);
+
+ silentSpillAllRegisters(gpr);
+ callOperation(toInt32, gpr, fpr);
+ silentFillAllRegisters(gpr);
+
+ truncatedToInteger.link(&m_jit);
+ integerResult(gpr, m_compileIndex);
+ return;
+ }
+
+ if (at(node.child1()).shouldSpeculateBoolean()) {
+ SpeculateBooleanOperand op1(this, node.child1());
+ GPRTemporary result(this, op1);
+
+ m_jit.and32(JITCompiler::TrustedImm32(1), op1.gpr());
+
+ integerResult(op1.gpr(), m_compileIndex);
+ return;
+ }
+
+ // Do it the safe way.
+ nonSpeculativeValueToInt32(node);
+ return;
}
void SpeculativeJIT::compileUInt32ToNumber(Node& node)