Modified: trunk/Source/_javascript_Core/ChangeLog (89956 => 89957)
--- trunk/Source/_javascript_Core/ChangeLog 2011-06-28 20:47:58 UTC (rev 89956)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-06-28 21:06:49 UTC (rev 89957)
@@ -1,3 +1,20 @@
+2011-06-28 Gavin Barraclough <[email protected]>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=63561
+ DFG JIT - don't always assume integer in relational compare
+
+ If neither operand is known integer, or either is in double representation,
+ then at least use a function call (don't bail off the speculative path).
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compilePeepHoleCall):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::isDataFormatDouble):
+ (JSC::DFG::SpeculativeJIT::compareIsInteger):
+
2011-06-28 Oliver Hunt <[email protected]>
Reviewed by Gavin Barraclough.
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (89956 => 89957)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-06-28 20:47:58 UTC (rev 89956)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-06-28 21:06:49 UTC (rev 89957)
@@ -267,7 +267,7 @@
addBranch(m_jit.jump(), notTaken);
}
-void SpeculativeJIT::compilePeepHoleEq(Node& node, NodeIndex branchNodeIndex)
+void SpeculativeJIT::compilePeepHoleCall(Node& node, NodeIndex branchNodeIndex, Z_DFGOperation_EJJ operation)
{
Node& branchNode = m_jit.graph()[branchNodeIndex];
BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset());
@@ -290,7 +290,7 @@
flushRegisters();
GPRResult result(this);
- callOperation(operationCompareEq, result.gpr(), op1GPR, op2GPR);
+ callOperation(operation, result.gpr(), op1GPR, op2GPR);
addBranch(m_jit.branchTest8(condition, result.gpr()), taken);
// Check for fall through, otherwise we need to jump.
@@ -569,7 +569,10 @@
// so can be no intervening nodes to also reference the compare.
ASSERT(node.adjustedRefCount() == 1);
- compilePeepHoleIntegerBranch(node, branchNodeIndex, JITCompiler::LessThan);
+ if (compareIsInteger(node.child1, node.child2))
+ compilePeepHoleIntegerBranch(node, branchNodeIndex, JITCompiler::LessThan);
+ else
+ compilePeepHoleCall(node, branchNodeIndex, operationCompareLess);
use(node.child1);
use(node.child2);
@@ -598,7 +601,10 @@
// so can be no intervening nodes to also reference the compare.
ASSERT(node.adjustedRefCount() == 1);
- compilePeepHoleIntegerBranch(node, branchNodeIndex, JITCompiler::LessThanOrEqual);
+ if (compareIsInteger(node.child1, node.child2))
+ compilePeepHoleIntegerBranch(node, branchNodeIndex, JITCompiler::LessThanOrEqual);
+ else
+ compilePeepHoleCall(node, branchNodeIndex, operationCompareLessEq);
use(node.child1);
use(node.child2);
@@ -627,10 +633,10 @@
// so can be no intervening nodes to also reference the compare.
ASSERT(node.adjustedRefCount() == 1);
- if (isInteger(node.child1) || isInteger(node.child2))
+ if (compareIsInteger(node.child1, node.child2))
compilePeepHoleIntegerBranch(node, branchNodeIndex, JITCompiler::Equal);
else
- compilePeepHoleEq(node, branchNodeIndex);
+ compilePeepHoleCall(node, branchNodeIndex, operationCompareEq);
use(node.child1);
use(node.child2);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (89956 => 89957)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-06-28 20:47:58 UTC (rev 89956)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-06-28 21:06:49 UTC (rev 89957)
@@ -169,8 +169,22 @@
return (info.registerFormat() | DataFormatJS) == DataFormatJSInteger;
}
+ bool isDataFormatDouble(NodeIndex nodeIndex)
+ {
+ Node& node = m_jit.graph()[nodeIndex];
+ VirtualRegister virtualRegister = node.virtualRegister();
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+
+ return (info.registerFormat() | DataFormatJS) == DataFormatJSDouble;
+ }
+
+ bool compareIsInteger(NodeIndex op1, NodeIndex op2)
+ {
+ return !(isDataFormatDouble(op1) || isDataFormatDouble(op2)) && (isInteger(op1) || isInteger(op2));
+ }
+
void compilePeepHoleIntegerBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition);
- void compilePeepHoleEq(Node&, NodeIndex branchNodeIndex);
+ void compilePeepHoleCall(Node&, NodeIndex branchNodeIndex, Z_DFGOperation_EJJ);
// Add a speculation check without additional recovery.
void speculationCheck(MacroAssembler::Jump jumpToFail)