Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (91009 => 91010)
--- trunk/Source/_javascript_Core/ChangeLog 2011-07-14 17:24:13 UTC (rev 91009)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-07-14 17:32:13 UTC (rev 91010)
@@ -1,3 +1,44 @@
+2011-07-14 Filip Pizlo <[email protected]>
+
+ DFG JIT unnecessarily boxes and unboxes values during silent spilling.
+ https://bugs.webkit.org/show_bug.cgi?id=64068
+
+ Reviewed by Gavin Barraclough.
+
+ Silent spilling and filling of registers is done during slow-path C
+ function calls. The silent spill/fill logic does not affect register
+ allocation on paths that don't involve the C function call.
+
+ This changes the silent spilling code to spill in unboxed form. The
+ silent fill will refill in whatever form the register was spilled in.
+ For example, the silent spill code may choose not to spill the register
+ because it was already spilled previously, which would imply that it
+ was spilled in boxed form. The filling code detects this and either
+ unboxes, or not, depending on what is appropriate.
+
+ This change also results in a simplification of the silent spill/fill
+ API: silent spilling no longer needs to know about the set of registers
+ that cannot be trampled, since it never does boxing and hence does not
+ need a temporary register.
+
+ * dfg/DFGJITCodeGenerator.cpp:
+ (JSC::DFG::JITCodeGenerator::cachedGetById):
+ (JSC::DFG::JITCodeGenerator::cachedPutById):
+ * dfg/DFGJITCodeGenerator.h:
+ (JSC::DFG::JITCodeGenerator::silentSpillGPR):
+ (JSC::DFG::JITCodeGenerator::silentSpillFPR):
+ (JSC::DFG::JITCodeGenerator::silentFillFPR):
+ (JSC::DFG::JITCodeGenerator::silentSpillAllRegisters):
+ * dfg/DFGNonSpeculativeJIT.cpp:
+ (JSC::DFG::NonSpeculativeJIT::valueToNumber):
+ (JSC::DFG::NonSpeculativeJIT::valueToInt32):
+ (JSC::DFG::NonSpeculativeJIT::knownConstantArithOp):
+ (JSC::DFG::NonSpeculativeJIT::basicArithOp):
+ (JSC::DFG::NonSpeculativeJIT::compare):
+ (JSC::DFG::NonSpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
2011-07-13 Michael Saboff <[email protected]>
https://bugs.webkit.org/show_bug.cgi?id=64202
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (91009 => 91010)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-07-14 17:24:13 UTC (rev 91009)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-07-14 17:32:13 UTC (rev 91010)
@@ -349,7 +349,7 @@
JITCompiler::Label slowCase = m_jit.label();
- silentSpillAllRegisters(resultGPR, baseGPR);
+ silentSpillAllRegisters(resultGPR);
m_jit.move(baseGPR, GPRInfo::argumentGPR1);
m_jit.move(JITCompiler::ImmPtr(identifier(identifierNumber)), GPRInfo::argumentGPR2);
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
@@ -414,7 +414,7 @@
JITCompiler::Label slowCase = m_jit.label();
- silentSpillAllRegisters(InvalidGPRReg, baseGPR, valueGPR);
+ silentSpillAllRegisters(InvalidGPRReg);
setupTwoStubArgs<GPRInfo::argumentGPR1, GPRInfo::argumentGPR2>(valueGPR, baseGPR);
m_jit.move(JITCompiler::ImmPtr(identifier(identifierNumber)), GPRInfo::argumentGPR3);
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (91009 => 91010)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-07-14 17:24:13 UTC (rev 91009)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-07-14 17:32:13 UTC (rev 91010)
@@ -188,7 +188,7 @@
// they spill all live values to the appropriate
// slots in the RegisterFile without changing any state
// in the GenerationInfo.
- void silentSpillGPR(VirtualRegister spillMe, GPRReg canTrample, GPRReg exclude = InvalidGPRReg)
+ void silentSpillGPR(VirtualRegister spillMe, GPRReg exclude = InvalidGPRReg)
{
GenerationInfo& info = m_generationInfo[spillMe];
ASSERT(info.registerFormat() != DataFormatNone);
@@ -200,23 +200,30 @@
DataFormat registerFormat = info.registerFormat();
if (registerFormat == DataFormatInteger) {
- m_jit.orPtr(GPRInfo::tagTypeNumberRegister, info.gpr(), canTrample);
- m_jit.storePtr(canTrample, JITCompiler::addressFor(spillMe));
+ m_jit.store32(info.gpr(), JITCompiler::addressFor(spillMe));
} else {
ASSERT(registerFormat & DataFormatJS || registerFormat == DataFormatCell);
m_jit.storePtr(info.gpr(), JITCompiler::addressFor(spillMe));
}
}
- void silentSpillFPR(VirtualRegister spillMe, GPRReg canTrample, FPRReg exclude = InvalidFPRReg)
+ void silentSpillFPR(VirtualRegister spillMe, FPRReg exclude = InvalidFPRReg)
{
GenerationInfo& info = m_generationInfo[spillMe];
ASSERT(info.registerFormat() == DataFormatDouble);
- if (!info.needsSpill() || (info.fpr() == exclude))
+ if (info.fpr() == exclude)
return;
+ if (!info.needsSpill()) {
+ // it's either a constant or it's already been spilled
+ ASSERT(m_jit.graph()[info.nodeIndex()].isConstant() || info.spillFormat() != DataFormatNone);
+ return;
+ }
+
+ // it's neither a constant nor has it been spilled.
+ ASSERT(!m_jit.graph()[info.nodeIndex()].isConstant());
+ ASSERT(info.spillFormat() == DataFormatNone);
- boxDouble(info.fpr(), canTrample);
- m_jit.storePtr(canTrample, JITCompiler::addressFor(spillMe));
+ m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe));
}
void silentFillGPR(VirtualRegister spillMe, GPRReg exclude = InvalidGPRReg)
@@ -261,38 +268,40 @@
ASSERT(isDoubleConstant(nodeIndex));
m_jit.move(JITCompiler::ImmPtr(bitwise_cast<void*>(valueOfDoubleConstant(nodeIndex))), canTrample);
m_jit.movePtrToDouble(canTrample, info.fpr());
- } else {
+ return;
+ }
+
+ if (info.spillFormat() != DataFormatNone) {
+ // it was already spilled previously, which means we need unboxing.
+ ASSERT(info.spillFormat() & DataFormatJS);
m_jit.loadPtr(JITCompiler::addressFor(spillMe), canTrample);
unboxDouble(canTrample, info.fpr());
+ return;
}
+
+ m_jit.loadDouble(JITCompiler::addressFor(spillMe), info.fpr());
}
- void silentSpillAllRegisters(GPRReg exclude, GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg)
+ void silentSpillAllRegisters(GPRReg exclude)
{
- GPRReg canTrample = selectScratchGPR(preserve1, preserve2, preserve3);
-
for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
if (iter.name() != InvalidVirtualRegister)
- silentSpillGPR(iter.name(), canTrample, exclude);
+ silentSpillGPR(iter.name(), exclude);
}
for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
if (iter.name() != InvalidVirtualRegister)
- silentSpillFPR(iter.name(), canTrample);
+ silentSpillFPR(iter.name());
}
}
- void silentSpillAllRegisters(FPRReg exclude, GPRReg preserve = InvalidGPRReg)
+ void silentSpillAllRegisters(FPRReg exclude)
{
- GPRReg canTrample = GPRInfo::regT0;
- if (preserve == GPRInfo::regT0)
- canTrample = GPRInfo::regT1;
-
for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
if (iter.name() != InvalidVirtualRegister)
- silentSpillGPR(iter.name(), canTrample);
+ silentSpillGPR(iter.name());
}
for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
if (iter.name() != InvalidVirtualRegister)
- silentSpillFPR(iter.name(), canTrample, exclude);
+ silentSpillFPR(iter.name(), exclude);
}
}
void silentFillAllRegisters(GPRReg exclude)
Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (91009 => 91010)
--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-07-14 17:24:13 UTC (rev 91009)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-07-14 17:32:13 UTC (rev 91010)
@@ -69,7 +69,7 @@
// Next handle cells (& other JS immediates)
nonNumeric.link(&m_jit);
- silentSpillAllRegisters(gpr, jsValueGpr);
+ silentSpillAllRegisters(gpr);
m_jit.move(jsValueGpr, GPRInfo::argumentGPR1);
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
appendCallWithExceptionCheck(dfgConvertJSValueToNumber);
@@ -91,7 +91,7 @@
JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
// First handle non-integers
- silentSpillAllRegisters(result, jsValueGpr);
+ silentSpillAllRegisters(result);
m_jit.move(jsValueGpr, GPRInfo::argumentGPR1);
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
appendCallWithExceptionCheck(dfgConvertJSValueToInt32);
@@ -220,7 +220,7 @@
if (!isKnownInteger(regChild))
notInt.link(&m_jit);
- silentSpillAllRegisters(resultGPR, regArgGPR);
+ silentSpillAllRegisters(resultGPR);
switch (op) {
case ValueAdd:
if (commute) {
@@ -310,7 +310,7 @@
slowPath.link(&m_jit);
- silentSpillAllRegisters(resultGPR, arg1GPR, arg2GPR);
+ silentSpillAllRegisters(resultGPR);
if (op == ValueAdd) {
setupStubArguments(arg1GPR, arg2GPR);
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
@@ -367,7 +367,7 @@
slowPath.link(&m_jit);
- silentSpillAllRegisters(resultGPR, arg1GPR, arg2GPR);
+ silentSpillAllRegisters(resultGPR);
setupStubArguments(arg1GPR, arg2GPR);
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
appendCallWithExceptionCheck(helperFunction);
@@ -718,7 +718,7 @@
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)));
- silentSpillAllRegisters(resultGPR, arg1GPR);
+ silentSpillAllRegisters(resultGPR);
m_jit.move(arg1GPR, GPRInfo::argumentGPR1);
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
@@ -794,7 +794,7 @@
outOfBounds.link(&m_jit);
loadFailed.link(&m_jit);
- silentSpillAllRegisters(storageGPR, baseGPR, propertyGPR);
+ silentSpillAllRegisters(storageGPR);
setupStubArguments(baseGPR, propertyGPR);
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
appendCallWithExceptionCheck(operationGetByVal);
@@ -1038,7 +1038,7 @@
notDefaultHasInstance.link(&m_jit);
protoNotObject.link(&m_jit);
- silentSpillAllRegisters(scratchReg, valueReg, baseReg, prototypeReg);
+ silentSpillAllRegisters(scratchReg);
setupStubArguments(valueReg, baseReg, prototypeReg);
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
appendCallWithExceptionCheck(operationInstanceOf);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (91009 => 91010)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-07-14 17:24:13 UTC (rev 91009)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-07-14 17:32:13 UTC (rev 91010)
@@ -876,7 +876,7 @@
MacroAssembler::Jump withinArrayBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
// Code to handle put beyond array bounds.
- silentSpillAllRegisters(scratchReg, baseReg, propertyReg, valueReg);
+ silentSpillAllRegisters(scratchReg);
setupStubArguments(baseReg, propertyReg, valueReg);
m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
JITCompiler::Call functionCall = appendCallWithExceptionCheck(operationPutByValBeyondArrayBounds);