Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (95146 => 95147)
--- trunk/Source/_javascript_Core/ChangeLog 2011-09-15 01:22:47 UTC (rev 95146)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-09-15 01:24:39 UTC (rev 95147)
@@ -1,3 +1,23 @@
+2011-09-12 Filip Pizlo <fpi...@apple.com>
+
+ DFG JIT always speculates that ValueAdd is a numeric addition
+ https://bugs.webkit.org/show_bug.cgi?id=67956
+
+ Reviewed by Geoffrey Garen.
+
+ * dfg/DFGJITCodeGenerator.cpp:
+ (JSC::DFG::JITCodeGenerator::isKnownNotNumber):
+ * dfg/DFGJITCodeGenerator.h:
+ * dfg/DFGNonSpeculativeJIT.cpp:
+ (JSC::DFG::NonSpeculativeJIT::knownConstantArithOp):
+ (JSC::DFG::NonSpeculativeJIT::basicArithOp):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::shouldSpeculateNumber):
+
2011-09-14 Anders Carlsson <ander...@apple.com>
Stop building BinarySemaphore to see if that's what's breaking the GTK+ build.
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (95146 => 95147)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-09-15 01:22:47 UTC (rev 95146)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-09-15 01:24:39 UTC (rev 95147)
@@ -395,6 +395,16 @@
|| (node.isConstant() && !valueOfJSConstant(nodeIndex).isInt32());
}
+bool JITCodeGenerator::isKnownNotNumber(NodeIndex nodeIndex)
+{
+ Node& node = m_jit.graph()[nodeIndex];
+ VirtualRegister virtualRegister = node.virtualRegister();
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+
+ return (!info.isJSDouble() && !info.isJSInteger())
+ || (node.isConstant() && !isNumberConstant(nodeIndex));
+}
+
bool JITCodeGenerator::isKnownBoolean(NodeIndex nodeIndex)
{
Node& node = m_jit.graph()[nodeIndex];
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (95146 => 95147)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-09-15 01:22:47 UTC (rev 95146)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-09-15 01:24:39 UTC (rev 95147)
@@ -413,6 +413,7 @@
bool isKnownCell(NodeIndex);
bool isKnownNotInteger(NodeIndex);
+ bool isKnownNotNumber(NodeIndex);
bool isKnownBoolean(NodeIndex);
Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (95146 => 95147)
--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-09-15 01:22:47 UTC (rev 95146)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-09-15 01:24:39 UTC (rev 95147)
@@ -240,7 +240,7 @@
m_jit.move(MacroAssembler::ImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm)))), GPRInfo::argumentGPR2);
}
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- appendCallWithExceptionCheck(operationValueAdd);
+ appendCallWithExceptionCheck(operationValueAddNotNumber);
m_jit.move(GPRInfo::returnValueGPR, resultGPR);
silentFillAllRegisters(resultGPR);
@@ -418,7 +418,7 @@
silentSpillAllRegisters(resultGPR);
setupStubArguments(arg1GPR, arg2GPR);
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- appendCallWithExceptionCheck(operationValueAdd);
+ appendCallWithExceptionCheck(operationValueAddNotNumber);
m_jit.move(GPRInfo::returnValueGPR, resultGPR);
silentFillAllRegisters(resultGPR);
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (95146 => 95147)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2011-09-15 01:22:47 UTC (rev 95146)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2011-09-15 01:24:39 UTC (rev 95147)
@@ -124,7 +124,21 @@
JSValue op1 = JSValue::decode(encodedOp1);
JSValue op2 = JSValue::decode(encodedOp2);
+ return JSValue::encode(jsAdd(exec, op1, op2));
+}
+
+EncodedJSValue operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
+{
+ JSValue op1 = JSValue::decode(encodedOp1);
+ JSValue op2 = JSValue::decode(encodedOp2);
+
ASSERT(!op1.isNumber() || !op2.isNumber());
+
+ if (op1.isString()) {
+ if (op2.isString())
+ return JSValue::encode(jsString(exec, asString(op1), asString(op2)));
+ return JSValue::encode(jsString(exec, asString(op1), op2.toPrimitiveString(exec)));
+ }
return JSValue::encode(jsAddSlowCase(exec, op1, op2));
}
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (95146 => 95147)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.h 2011-09-15 01:22:47 UTC (rev 95146)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h 2011-09-15 01:24:39 UTC (rev 95147)
@@ -57,6 +57,7 @@
// These routines are provide callbacks out to C++ implementations of operations too complex to JIT.
EncodedJSValue operationConvertThis(ExecState*, EncodedJSValue encodedOp1);
EncodedJSValue operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2);
+EncodedJSValue operationValueAddNotNumber(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2);
EncodedJSValue operationArithAdd(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2);
EncodedJSValue operationArithSub(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2);
EncodedJSValue operationArithMul(EncodedJSValue encodedOp1, EncodedJSValue encodedOp2);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (95146 => 95147)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-09-15 01:22:47 UTC (rev 95146)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-09-15 01:24:39 UTC (rev 95147)
@@ -923,15 +923,36 @@
break;
}
- SpeculateDoubleOperand op1(this, node.child1());
- SpeculateDoubleOperand op2(this, node.child2());
- FPRTemporary result(this, op1, op2);
-
- FPRReg reg1 = op1.fpr();
- FPRReg reg2 = op2.fpr();
- m_jit.addDouble(reg1, reg2, result.fpr());
-
- doubleResult(result.fpr(), m_compileIndex);
+ if (shouldSpeculateNumber(node.child1(), node.child2())) {
+ SpeculateDoubleOperand op1(this, node.child1());
+ SpeculateDoubleOperand op2(this, node.child2());
+ FPRTemporary result(this, op1, op2);
+
+ FPRReg reg1 = op1.fpr();
+ FPRReg reg2 = op2.fpr();
+ m_jit.addDouble(reg1, reg2, result.fpr());
+
+ doubleResult(result.fpr(), m_compileIndex);
+ break;
+ }
+
+ ASSERT(op == ValueAdd);
+
+ JSValueOperand op1(this, node.child1());
+ JSValueOperand op2(this, node.child2());
+
+ GPRReg op1GPR = op1.gpr();
+ GPRReg op2GPR = op2.gpr();
+
+ flushRegisters();
+
+ GPRResult result(this);
+ if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
+ callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
+ else
+ callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
+
+ jsValueResult(result.gpr(), m_compileIndex);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (95146 => 95147)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-09-15 01:22:47 UTC (rev 95146)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-09-15 01:24:39 UTC (rev 95147)
@@ -384,6 +384,30 @@
return false;
}
+ bool shouldSpeculateNumber(NodeIndex nodeIndex)
+ {
+ Node& node = m_jit.graph()[nodeIndex];
+
+ if (node.hasNumberResult())
+ return true;
+
+ if (isNumberConstant(nodeIndex))
+ return true;
+
+ VirtualRegister virtualRegister = node.virtualRegister();
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+
+ if (info.isJSInteger() || info.isJSDouble())
+ return true;
+
+ PredictedType prediction = m_jit.graph().getPrediction(node);
+
+ if (isNumberPrediction(prediction) || prediction == PredictNone)
+ return true;
+
+ return false;
+ }
+
bool shouldNotSpeculateInteger(NodeIndex nodeIndex)
{
if (isDoubleConstant(nodeIndex))
@@ -407,6 +431,11 @@
{
return !(shouldNotSpeculateInteger(op1) || shouldNotSpeculateInteger(op2)) && (shouldSpeculateInteger(op1) || shouldSpeculateInteger(op2));
}
+
+ bool shouldSpeculateNumber(NodeIndex op1, NodeIndex op2)
+ {
+ return shouldSpeculateNumber(op1) && shouldSpeculateNumber(op2);
+ }
bool compare(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, Z_DFGOperation_EJJ);
void compilePeepHoleIntegerBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition);