Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (90501 => 90502)
--- trunk/Source/_javascript_Core/ChangeLog 2011-07-06 21:39:19 UTC (rev 90501)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-07-06 21:40:11 UTC (rev 90502)
@@ -1,5 +1,25 @@
2011-07-06 Filip Pizlo <[email protected]>
+ DFG JIT op_call implementation will flush registers even when those registers are dead
+ https://bugs.webkit.org/show_bug.cgi?id=64023
+
+ Reviewed by Gavin Barraclough.
+
+ * dfg/DFGJITCodeGenerator.cpp:
+ (JSC::DFG::JITCodeGenerator::emitCall):
+ * dfg/DFGJITCodeGenerator.h:
+ (JSC::DFG::JITCodeGenerator::integerResult):
+ (JSC::DFG::JITCodeGenerator::noResult):
+ (JSC::DFG::JITCodeGenerator::cellResult):
+ (JSC::DFG::JITCodeGenerator::jsValueResult):
+ (JSC::DFG::JITCodeGenerator::doubleResult):
+ * dfg/DFGNonSpeculativeJIT.cpp:
+ (JSC::DFG::NonSpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2011-07-06 Filip Pizlo <[email protected]>
+
DFG speculative JIT may crash when speculating int on a non-int JSConstant.
https://bugs.webkit.org/show_bug.cgi?id=64017
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (90501 => 90502)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-07-06 21:39:19 UTC (rev 90501)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-07-06 21:40:11 UTC (rev 90502)
@@ -430,8 +430,13 @@
m_jit.addPropertyAccess(functionCall, checkImmToCall, callToCheck, callToStore, callToSlowCase, callToDone, static_cast<int8_t>(baseGPR), static_cast<int8_t>(valueGPR), static_cast<int8_t>(scratchGPR));
}
-void JITCodeGenerator::emitCall(Node& node, GPRReg targetGPR)
+void JITCodeGenerator::emitCall(Node& node)
{
+ NodeIndex calleeNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild()];
+ JSValueOperand callee(this, calleeNodeIndex);
+ GPRReg calleeGPR = callee.gpr();
+ use(calleeNodeIndex);
+
// the call instruction's first child is either the function (normal call) or the
// receiver (method call). subsequent children are the arguments.
int numArgs = node.numChildren() - 1;
@@ -450,15 +455,17 @@
m_jit.storePtr(GPRInfo::callFrameRegister, addressOfCallData(RegisterFile::CallerFrame));
for (int argIdx = 0; argIdx < numArgs; argIdx++) {
- JSValueOperand arg(this, m_jit.graph().m_varArgChildren[node.firstChild() + 1 + argIdx]);
+ NodeIndex argNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + argIdx];
+ JSValueOperand arg(this, argNodeIndex);
GPRReg argGPR = arg.gpr();
+ use(argNodeIndex);
m_jit.storePtr(argGPR, addressOfCallData(-callDataSize + argIdx));
}
switch (node.op) {
case Call:
- m_jit.storePtr(targetGPR, addressOfCallData(RegisterFile::Callee));
+ m_jit.storePtr(calleeGPR, addressOfCallData(RegisterFile::Callee));
break;
default:
@@ -475,8 +482,8 @@
switch (node.op) {
case Call:
- slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, targetGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue())));
- m_jit.loadPtr(MacroAssembler::Address(targetGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR);
+ slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue())));
+ m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR);
m_jit.storePtr(resultGPR, addressOfCallData(RegisterFile::ScopeChain));
break;
@@ -503,7 +510,7 @@
m_jit.move(GPRInfo::returnValueGPR, resultGPR);
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, m_compileIndex, DataFormatJS, UseChildrenCalledExplicitly);
m_jit.addJSCall(fastCall, slowCall, targetToCheck, true, m_jit.graph()[m_compileIndex].exceptionInfo);
}
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (90501 => 90502)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-07-06 21:39:19 UTC (rev 90501)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-07-06 21:40:11 UTC (rev 90502)
@@ -64,6 +64,8 @@
SpillOrderInteger = 5, // needs spill and box
SpillOrderDouble = 6, // needs spill and convert
};
+
+ enum UseChildrenMode { CallUseChildren, UseChildrenCalledExplicitly };
public:
@@ -528,7 +530,7 @@
return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + idx) * static_cast<int>(sizeof(Register)));
}
- void emitCall(Node&, GPRReg targetGPR);
+ void emitCall(Node&);
// Called once a node has completed code generation but prior to setting
// its result, to free up its children. (This must happen prior to setting
@@ -538,10 +540,11 @@
// These method called to initialize the the GenerationInfo
// to describe the result of an operation.
- void integerResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatInteger)
+ void integerResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatInteger, UseChildrenMode mode = CallUseChildren)
{
Node& node = m_jit.graph()[nodeIndex];
- useChildren(node);
+ if (mode == CallUseChildren)
+ useChildren(node);
VirtualRegister virtualRegister = node.virtualRegister();
GenerationInfo& info = m_generationInfo[virtualRegister];
@@ -557,38 +560,43 @@
info.initJSValue(nodeIndex, node.refCount(), reg, format);
}
}
- void noResult(NodeIndex nodeIndex)
+ void noResult(NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
{
+ if (mode == UseChildrenCalledExplicitly)
+ return;
Node& node = m_jit.graph()[nodeIndex];
useChildren(node);
}
- void cellResult(GPRReg reg, NodeIndex nodeIndex)
+ void cellResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
{
Node& node = m_jit.graph()[nodeIndex];
- useChildren(node);
+ if (mode == CallUseChildren)
+ useChildren(node);
VirtualRegister virtualRegister = node.virtualRegister();
m_gprs.retain(reg, virtualRegister, SpillOrderCell);
GenerationInfo& info = m_generationInfo[virtualRegister];
info.initCell(nodeIndex, node.refCount(), reg);
}
- void jsValueResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatJS)
+ void jsValueResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
{
if (format == DataFormatJSInteger)
m_jit.jitAssertIsJSInt32(reg);
Node& node = m_jit.graph()[nodeIndex];
- useChildren(node);
+ if (mode == CallUseChildren)
+ useChildren(node);
VirtualRegister virtualRegister = node.virtualRegister();
m_gprs.retain(reg, virtualRegister, SpillOrderJS);
GenerationInfo& info = m_generationInfo[virtualRegister];
info.initJSValue(nodeIndex, node.refCount(), reg, format);
}
- void doubleResult(FPRReg reg, NodeIndex nodeIndex)
+ void doubleResult(FPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
{
Node& node = m_jit.graph()[nodeIndex];
- useChildren(node);
+ if (mode == CallUseChildren)
+ useChildren(node);
VirtualRegister virtualRegister = node.virtualRegister();
m_fprs.retain(reg, virtualRegister, SpillOrderDouble);
Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (90501 => 90502)
--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-07-06 21:39:19 UTC (rev 90501)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-07-06 21:40:11 UTC (rev 90502)
@@ -1054,9 +1054,7 @@
break;
case Call:
- JSValueOperand callee(this, m_jit.graph().m_varArgChildren[node.firstChild()]);
- GPRReg calleeGPR = callee.gpr();
- emitCall(node, calleeGPR);
+ emitCall(node);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (90501 => 90502)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-07-06 21:39:19 UTC (rev 90501)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-07-06 21:40:11 UTC (rev 90502)
@@ -1133,9 +1133,7 @@
break;
case Call:
- JSValueOperand callee(this, m_jit.graph().m_varArgChildren[node.firstChild()]);
- GPRReg calleeGPR = callee.gpr();
- emitCall(node, calleeGPR);
+ emitCall(node);
break;
}