Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (91279 => 91280)
--- trunk/Source/_javascript_Core/ChangeLog 2011-07-19 18:52:43 UTC (rev 91279)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-07-19 18:55:16 UTC (rev 91280)
@@ -1,3 +1,49 @@
+2011-07-19 Filip Pizlo <[email protected]>
+
+ DFG JIT sometimes emits spill code even when the respective values
+ are never needed.
+ https://bugs.webkit.org/show_bug.cgi?id=64774
+
+ Reviewed by Gavin Barraclough.
+
+ The main high-level change is that it is now easier to call use() on a
+ virtual register. JSValueOperand and its other-typed relatives now have
+ a handy use() method, and jsValueResult() and friends now make it easier to
+ pass UseChildrenCalledExplicitly.
+
+ The rest of this patch hoists the call to use() as high as possible for
+ all of those cases where either flushRegisters() or silentSpillAllRegisters()
+ may be called.
+
+ * dfg/DFGJITCodeGenerator.cpp:
+ (JSC::DFG::JITCodeGenerator::cachedGetById):
+ (JSC::DFG::JITCodeGenerator::cachedGetMethod):
+ (JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeBranch):
+ (JSC::DFG::JITCodeGenerator::nonSpeculativeNonPeepholeCompare):
+ (JSC::DFG::JITCodeGenerator::nonSpeculativeCompare):
+ (JSC::DFG::JITCodeGenerator::nonSpeculativePeepholeStrictEq):
+ (JSC::DFG::JITCodeGenerator::nonSpeculativeNonPeepholeStrictEq):
+ (JSC::DFG::JITCodeGenerator::nonSpeculativeStrictEq):
+ (JSC::DFG::JITCodeGenerator::emitBranch):
+ * dfg/DFGJITCodeGenerator.h:
+ (JSC::DFG::JITCodeGenerator::use):
+ (JSC::DFG::JITCodeGenerator::integerResult):
+ (JSC::DFG::JITCodeGenerator::jsValueResult):
+ (JSC::DFG::IntegerOperand::use):
+ (JSC::DFG::DoubleOperand::use):
+ (JSC::DFG::JSValueOperand::use):
+ * dfg/DFGNonSpeculativeJIT.cpp:
+ (JSC::DFG::NonSpeculativeJIT::valueToNumber):
+ (JSC::DFG::NonSpeculativeJIT::valueToInt32):
+ (JSC::DFG::NonSpeculativeJIT::knownConstantArithOp):
+ (JSC::DFG::NonSpeculativeJIT::basicArithOp):
+ (JSC::DFG::NonSpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculateStrictInt32Operand::use):
+ (JSC::DFG::SpeculateCellOperand::use):
+
2011-07-19 Xan Lopez <[email protected]>
ARMv7 backend broken, lacks 3 parameter rshift32 method
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (91279 => 91280)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-07-19 18:52:43 UTC (rev 91279)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-07-19 18:55:16 UTC (rev 91280)
@@ -391,15 +391,8 @@
|| (node.isConstant() && !valueOfJSConstant(nodeIndex).isInt32());
}
-JITCompiler::Call JITCodeGenerator::cachedGetById(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, NodeType nodeType)
+JITCompiler::Call JITCodeGenerator::cachedGetById(GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, NodeType nodeType)
{
- GPRReg scratchGPR;
-
- if (resultGPR == baseGPR)
- scratchGPR = tryAllocate();
- else
- scratchGPR = resultGPR;
-
JITCompiler::DataLabelPtr structureToCompare;
JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
@@ -511,7 +504,7 @@
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::cachedGetMethod(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget)
+void JITCodeGenerator::cachedGetMethod(GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget)
{
JITCompiler::Call slowCall;
JITCompiler::DataLabelPtr structToCompare, protoObj, protoStructToCompare, putFunction;
@@ -527,7 +520,7 @@
wrongStructure.link(&m_jit);
wrongProtoStructure.link(&m_jit);
- slowCall = cachedGetById(baseGPR, resultGPR, identifierNumber, slowPathTarget, GetMethod);
+ slowCall = cachedGetById(baseGPR, resultGPR, scratchGPR, identifierNumber, slowPathTarget, GetMethod);
done.link(&m_jit);
@@ -653,17 +646,23 @@
JITCompiler::JumpList slowPath;
if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
- flushRegisters();
-
GPRResult result(this);
GPRReg resultGPR = result.gpr();
+ arg1.use();
+ arg2.use();
+
+ flushRegisters();
+
callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
addBranch(m_jit.branchTest8(callResultCondition, resultGPR), taken);
} else {
GPRTemporary result(this, arg2);
GPRReg resultGPR = result.gpr();
+ arg1.use();
+ arg2.use();
+
if (!isKnownInteger(node.child1()))
slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
if (!isKnownInteger(node.child2()))
@@ -701,18 +700,24 @@
JITCompiler::JumpList slowPath;
if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
- flushRegisters();
-
GPRResult result(this);
GPRReg resultGPR = result.gpr();
+ arg1.use();
+ arg2.use();
+
+ flushRegisters();
+
callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
} else {
GPRTemporary result(this, arg2);
GPRReg resultGPR = result.gpr();
+
+ arg1.use();
+ arg2.use();
if (!isKnownInteger(node.child1()))
slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
@@ -740,7 +745,7 @@
m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
}
}
@@ -752,8 +757,6 @@
nonSpeculativePeepholeBranch(node, branchNodeIndex, cond, helperFunction);
- use(node.child1());
- use(node.child2());
m_compileIndex = branchNodeIndex;
return true;
@@ -787,6 +790,9 @@
GPRTemporary result(this);
GPRReg resultGPR = result.gpr();
+ arg1.use();
+ arg2.use();
+
if (isKnownCell(node.child1()) && isKnownCell(node.child2())) {
// see if we get lucky: if the arguments are cells and they reference the same
// cell, then they must be strictly equal.
@@ -839,6 +845,9 @@
GPRTemporary result(this);
GPRReg resultGPR = result.gpr();
+ arg1.use();
+ arg2.use();
+
if (isKnownCell(node.child1()) && isKnownCell(node.child2())) {
// see if we get lucky: if the arguments are cells and they reference the same
// cell, then they must be strictly equal.
@@ -898,7 +907,7 @@
done2.link(&m_jit);
}
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
}
bool JITCodeGenerator::nonSpeculativeStrictEq(Node& node, bool invert)
@@ -912,8 +921,6 @@
nonSpeculativePeepholeStrictEq(node, branchNodeIndex, invert);
- use(node.child1());
- use(node.child2());
m_compileIndex = branchNodeIndex;
return true;
@@ -932,6 +939,8 @@
GPRTemporary result(this);
GPRReg resultGPR = result.gpr();
+ value.use();
+
BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
@@ -951,7 +960,7 @@
if (notTaken != (m_block + 1))
addBranch(m_jit.jump(), notTaken);
- noResult(m_compileIndex);
+ noResult(m_compileIndex, UseChildrenCalledExplicitly);
}
void JITCodeGenerator::emitCall(Node& node)
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (91279 => 91280)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-07-19 18:52:43 UTC (rev 91279)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-07-19 18:55:16 UTC (rev 91280)
@@ -157,6 +157,25 @@
return info.registerFormat() == DataFormatDouble;
}
+ // Called on an operand once it has been consumed by a parent node.
+ void use(NodeIndex nodeIndex)
+ {
+ VirtualRegister virtualRegister = m_jit.graph()[nodeIndex].virtualRegister();
+ GenerationInfo& info = m_generationInfo[virtualRegister];
+
+ // use() returns true when the value becomes dead, and any
+ // associated resources may be freed.
+ if (!info.use())
+ return;
+
+ // Release the associated machine registers.
+ DataFormat registerFormat = info.registerFormat();
+ if (registerFormat == DataFormatDouble)
+ m_fprs.release(info.fpr());
+ else if (registerFormat != DataFormatNone)
+ m_gprs.release(info.gpr());
+ }
+
static void writeBarrier(MacroAssembler&, GPRReg ownerGPR, GPRReg scratchGPR);
static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg)
@@ -357,25 +376,6 @@
return unboxDouble(gpr, fprAllocate());
}
- // Called on an operand once it has been consumed by a parent node.
- void use(NodeIndex nodeIndex)
- {
- VirtualRegister virtualRegister = m_jit.graph()[nodeIndex].virtualRegister();
- GenerationInfo& info = m_generationInfo[virtualRegister];
-
- // use() returns true when the value becomes dead, and any
- // associated resources may be freed.
- if (!info.use())
- return;
-
- // Release the associated machine registers.
- DataFormat registerFormat = info.registerFormat();
- if (registerFormat == DataFormatDouble)
- m_fprs.release(info.fpr());
- else if (registerFormat != DataFormatNone)
- m_gprs.release(info.gpr());
- }
-
// Spill a VirtualRegister to the RegisterFile.
void spill(VirtualRegister spillMe)
{
@@ -559,9 +559,9 @@
return lastNode.op == Branch && lastNode.child1() == m_compileIndex ? lastNodeIndex : NoNode;
}
- JITCompiler::Call cachedGetById(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), NodeType = GetById);
+ JITCompiler::Call cachedGetById(GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), NodeType = GetById);
void cachedPutById(GPRReg baseGPR, GPRReg valueGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
- void cachedGetMethod(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
+ void cachedGetMethod(GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
void nonSpeculativeNonPeepholeCompareNull(NodeIndex operand, bool invert = false);
void nonSpeculativePeepholeBranchNull(NodeIndex operand, NodeIndex branchNodeIndex, bool invert = false);
@@ -612,6 +612,10 @@
info.initJSValue(nodeIndex, node.refCount(), reg, format);
}
}
+ void integerResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode)
+ {
+ integerResult(reg, nodeIndex, DataFormatInteger, mode);
+ }
void noResult(NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
{
if (mode == UseChildrenCalledExplicitly)
@@ -644,6 +648,10 @@
GenerationInfo& info = m_generationInfo[virtualRegister];
info.initJSValue(nodeIndex, node.refCount(), reg, format);
}
+ void jsValueResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode)
+ {
+ jsValueResult(reg, nodeIndex, DataFormatJS, mode);
+ }
void doubleResult(FPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
{
Node& node = m_jit.graph()[nodeIndex];
@@ -995,6 +1003,11 @@
m_gprOrInvalid = m_jit->fillInteger(index(), m_format);
return m_gprOrInvalid;
}
+
+ void use()
+ {
+ m_jit->use(m_index);
+ }
private:
JITCodeGenerator* m_jit;
@@ -1032,6 +1045,11 @@
m_fprOrInvalid = m_jit->fillDouble(index());
return m_fprOrInvalid;
}
+
+ void use()
+ {
+ m_jit->use(m_index);
+ }
private:
JITCodeGenerator* m_jit;
@@ -1068,6 +1086,11 @@
m_gprOrInvalid = m_jit->fillJSValue(index());
return m_gprOrInvalid;
}
+
+ void use()
+ {
+ m_jit->use(m_index);
+ }
private:
JITCodeGenerator* m_jit;
Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (91279 => 91280)
--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-07-19 18:52:43 UTC (rev 91279)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-07-19 18:55:16 UTC (rev 91280)
@@ -59,6 +59,7 @@
void NonSpeculativeJIT::valueToNumber(JSValueOperand& operand, GPRReg gpr)
{
GPRReg jsValueGpr = operand.gpr();
+ operand.use();
JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
JITCompiler::Jump nonNumeric = m_jit.branchTestPtr(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister);
@@ -87,6 +88,7 @@
void NonSpeculativeJIT::valueToInt32(JSValueOperand& operand, GPRReg result)
{
GPRReg jsValueGpr = operand.gpr();
+ operand.use();
JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
@@ -126,6 +128,9 @@
GPRReg regArgGPR = regArg.gpr();
GPRTemporary result(this, regArg);
GPRReg resultGPR = result.gpr();
+
+ regArg.use();
+ use(immChild);
JITCompiler::Jump notInt;
@@ -220,7 +225,7 @@
done.link(&m_jit);
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
}
void NonSpeculativeJIT::basicArithOp(NodeType op, Node &node)
@@ -235,6 +240,9 @@
GPRReg resultGPR = result.gpr();
+ arg1.use();
+ arg2.use();
+
JITCompiler::JumpList slowPath;
if (!isKnownInteger(node.child1()))
@@ -299,7 +307,7 @@
done.link(&m_jit);
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
}
void NonSpeculativeJIT::compile(SpeculationCheckIndexIterator& checkIterator, Node& node)
@@ -447,15 +455,16 @@
if ((childInfo.registerFormat() | DataFormatJS) == DataFormatJSDouble) {
DoubleOperand op1(this, node.child1());
GPRTemporary result(this);
+ op1.use();
numberToInt32(op1.fpr(), result.gpr());
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
break;
}
JSValueOperand op1(this, node.child1());
GPRTemporary result(this, op1);
valueToInt32(op1, result.gpr());
- integerResult(result.gpr(), m_compileIndex);
+ integerResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -474,7 +483,7 @@
JSValueOperand op1(this, node.child1());
GPRTemporary result(this);
valueToNumber(op1, result.gpr());
- jsValueResult(result.gpr(), m_compileIndex);
+ jsValueResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -537,6 +546,9 @@
FPRReg op1FPR = op1Double.fpr();
FPRReg op2FPR = op2Double.fpr();
+
+ op1.use();
+ op2.use();
JITCompiler::Jump firstOpNotInt;
JITCompiler::Jump secondOpNotInt;
@@ -623,17 +635,19 @@
done.link(&m_jit);
- jsValueResult(X86Registers::edx, m_compileIndex);
+ jsValueResult(X86Registers::edx, m_compileIndex, UseChildrenCalledExplicitly);
break;
}
case LogicalNot: {
JSValueOperand arg1(this, node.child1());
GPRTemporary result(this);
-
+
GPRReg arg1GPR = arg1.gpr();
GPRReg resultGPR = result.gpr();
+ arg1.use();
+
m_jit.move(arg1GPR, resultGPR);
m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
JITCompiler::Jump fastCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
@@ -648,7 +662,7 @@
fastCase.link(&m_jit);
m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -703,6 +717,9 @@
GPRReg propertyGPR = property.gpr();
GPRReg storageGPR = storage.gpr();
GPRReg cleanIndexGPR = cleanIndex.gpr();
+
+ base.use();
+ property.use();
JITCompiler::Jump baseNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
@@ -739,7 +756,7 @@
done.link(&m_jit);
- jsValueResult(storageGPR, m_compileIndex);
+ jsValueResult(storageGPR, m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -751,12 +768,15 @@
GPRReg arg1GPR = arg1.gpr();
GPRReg arg2GPR = arg2.gpr();
GPRReg arg3GPR = arg3.gpr();
+
+ arg1.use();
+ arg2.use();
+ arg3.use();
flushRegisters();
- GPRResult result(this);
callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);
- noResult(m_compileIndex);
+ noResult(m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -765,12 +785,20 @@
GPRReg baseGPR = base.gpr();
GPRTemporary result(this, base);
GPRReg resultGPR = result.gpr();
+ GPRReg scratchGPR;
+
+ if (resultGPR == baseGPR)
+ scratchGPR = tryAllocate();
+ else
+ scratchGPR = resultGPR;
+
+ base.use();
JITCompiler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
- cachedGetById(baseGPR, resultGPR, node.identifierNumber(), notCell);
+ cachedGetById(baseGPR, resultGPR, scratchGPR, node.identifierNumber(), notCell);
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -779,12 +807,19 @@
GPRReg baseGPR = base.gpr();
GPRTemporary result(this, base);
GPRReg resultGPR = result.gpr();
+ GPRReg scratchGPR;
+ if (resultGPR == baseGPR)
+ scratchGPR = tryAllocate();
+ else
+ scratchGPR = resultGPR;
+
+ base.use();
JITCompiler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
- cachedGetMethod(baseGPR, resultGPR, node.identifierNumber(), notCell);
+ cachedGetMethod(baseGPR, resultGPR, scratchGPR, node.identifierNumber(), notCell);
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -794,12 +829,16 @@
GPRTemporary scratch(this);
GPRReg valueGPR = value.gpr();
GPRReg baseGPR = base.gpr();
+ GPRReg scratchGPR = scratch.gpr();
+ base.use();
+ value.use();
+
JITCompiler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
- cachedPutById(baseGPR, valueGPR, scratch.gpr(), node.identifierNumber(), NotDirect, notCell);
+ cachedPutById(baseGPR, valueGPR, scratchGPR, node.identifierNumber(), NotDirect, notCell);
- noResult(m_compileIndex);
+ noResult(m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -810,11 +849,14 @@
GPRReg valueGPR = value.gpr();
GPRReg baseGPR = base.gpr();
+ base.use();
+ value.use();
+
JITCompiler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
cachedPutById(baseGPR, valueGPR, scratch.gpr(), node.identifierNumber(), Direct, notCell);
- noResult(m_compileIndex);
+ noResult(m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -924,6 +966,10 @@
GPRReg baseReg = base.gpr();
GPRReg prototypeReg = prototype.gpr();
GPRReg scratchReg = scratch.gpr();
+
+ value.use();
+ base.use();
+ prototype.use();
// Check that operands are cells (base is checked by CheckHasInstance, so we can just assert).
MacroAssembler::Jump valueNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueReg, GPRInfo::tagMaskRegister);
@@ -973,7 +1019,7 @@
wasNotInstance.link(&m_jit);
wasNotDefaultHasInstance.link(&m_jit);
- jsValueResult(scratchReg, m_compileIndex);
+ jsValueResult(scratchReg, m_compileIndex, UseChildrenCalledExplicitly);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (91279 => 91280)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-07-19 18:52:43 UTC (rev 91279)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-07-19 18:55:16 UTC (rev 91280)
@@ -849,6 +849,11 @@
Node& baseNode = m_jit.graph()[node.child1()];
if (baseNode.op != GetLocal || m_jit.graph().getPrediction(baseNode.local()) != PredictArray)
speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
+
+ base.use();
+ property.use();
+ value.use();
+
MacroAssembler::Jump withinArrayBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
// Code to handle put beyond array bounds.
@@ -883,7 +888,7 @@
wasBeyondArrayBounds.link(&m_jit);
- noResult(m_compileIndex);
+ noResult(m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -961,12 +966,21 @@
case GetById: {
SpeculateCellOperand base(this, node.child1());
GPRTemporary result(this, base);
-
+
+ GPRReg baseGPR = base.gpr();
GPRReg resultGPR = result.gpr();
+ GPRReg scratchGPR;
+
+ if (resultGPR == baseGPR)
+ scratchGPR = tryAllocate();
+ else
+ scratchGPR = resultGPR;
+
+ base.use();
- cachedGetById(base.gpr(), resultGPR, node.identifierNumber());
+ cachedGetById(baseGPR, resultGPR, scratchGPR, node.identifierNumber());
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -974,11 +988,20 @@
SpeculateCellOperand base(this, node.child1());
GPRTemporary result(this, base);
+ GPRReg baseGPR = base.gpr();
GPRReg resultGPR = result.gpr();
+ GPRReg scratchGPR;
+
+ if (resultGPR == baseGPR)
+ scratchGPR = tryAllocate();
+ else
+ scratchGPR = resultGPR;
+
+ base.use();
- cachedGetMethod(base.gpr(), resultGPR, node.identifierNumber());
+ cachedGetMethod(baseGPR, resultGPR, scratchGPR, node.identifierNumber());
- jsValueResult(resultGPR, m_compileIndex);
+ jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -986,10 +1009,17 @@
SpeculateCellOperand base(this, node.child1());
JSValueOperand value(this, node.child2());
GPRTemporary scratch(this);
+
+ GPRReg baseGPR = base.gpr();
+ GPRReg valueGPR = value.gpr();
+ GPRReg scratchGPR = scratch.gpr();
+
+ base.use();
+ value.use();
- cachedPutById(base.gpr(), value.gpr(), scratch.gpr(), node.identifierNumber(), NotDirect);
+ cachedPutById(baseGPR, valueGPR, scratchGPR, node.identifierNumber(), NotDirect);
- noResult(m_compileIndex);
+ noResult(m_compileIndex, UseChildrenCalledExplicitly);
break;
}
@@ -997,10 +1027,17 @@
SpeculateCellOperand base(this, node.child1());
JSValueOperand value(this, node.child2());
GPRTemporary scratch(this);
+
+ GPRReg baseGPR = base.gpr();
+ GPRReg valueGPR = value.gpr();
+ GPRReg scratchGPR = scratch.gpr();
+
+ base.use();
+ value.use();
- cachedPutById(base.gpr(), value.gpr(), scratch.gpr(), node.identifierNumber(), Direct);
+ cachedPutById(baseGPR, valueGPR, scratchGPR, node.identifierNumber(), Direct);
- noResult(m_compileIndex);
+ noResult(m_compileIndex, UseChildrenCalledExplicitly);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (91279 => 91280)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-07-19 18:52:43 UTC (rev 91279)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-07-19 18:55:16 UTC (rev 91280)
@@ -293,6 +293,11 @@
m_gprOrInvalid = m_jit->fillSpeculateIntStrict(index());
return m_gprOrInvalid;
}
+
+ void use()
+ {
+ m_jit->use(m_index);
+ }
private:
SpeculativeJIT* m_jit;
@@ -365,6 +370,11 @@
m_gprOrInvalid = m_jit->fillSpeculateCell(index());
return m_gprOrInvalid;
}
+
+ void use()
+ {
+ m_jit->use(m_index);
+ }
private:
SpeculativeJIT* m_jit;