- Revision
- 200897
- Author
- [email protected]
- Date
- 2016-05-13 16:45:15 -0700 (Fri, 13 May 2016)
Log Message
[JSC] Move the CheckTierUp function calls out of the main path
https://bugs.webkit.org/show_bug.cgi?id=157668
Patch by Benjamin Poulain <[email protected]> on 2016-05-13
Reviewed by Mark Lam.
If you have a tiny tiny loop (for example, Sunspider's bits-in-byte),
the size of CheckTierUp is a problem.
On multi-issue CPUs, the node is so big that we do not
get to run anything from the loop in the instruction fetch.
On x86, having a bigger loop also pushes us out of the LSD.
This is a 6% improvement on bits-in-byte. Other Sunspider tests
only improves marginally.
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::addSlowPathGenerator):
(JSC::DFG::SpeculativeJIT::runSlowPathGenerators):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::silentSpill):
(JSC::DFG::SpeculativeJIT::silentFill):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (200896 => 200897)
--- trunk/Source/_javascript_Core/ChangeLog 2016-05-13 23:44:31 UTC (rev 200896)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-05-13 23:45:15 UTC (rev 200897)
@@ -1,5 +1,32 @@
2016-05-13 Benjamin Poulain <[email protected]>
+ [JSC] Move the CheckTierUp function calls out of the main path
+ https://bugs.webkit.org/show_bug.cgi?id=157668
+
+ Reviewed by Mark Lam.
+
+ If you have a tiny tiny loop (for example, Sunspider's bits-in-byte),
+ the size of CheckTierUp is a problem.
+
+ On multi-issue CPUs, the node is so big that we do not
+ get to run anything from the loop in the instruction fetch.
+
+ On x86, having a bigger loop also pushes us out of the LSD.
+
+ This is a 6% improvement on bits-in-byte. Other Sunspider tests
+ only improves marginally.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::addSlowPathGenerator):
+ (JSC::DFG::SpeculativeJIT::runSlowPathGenerators):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::silentSpill):
+ (JSC::DFG::SpeculativeJIT::silentFill):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2016-05-13 Benjamin Poulain <[email protected]>
+
[JSC] Emit the loads of emitLoadWithStructureCheck() in the order they are used
https://bugs.webkit.org/show_bug.cgi?id=157671
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (200896 => 200897)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2016-05-13 23:44:31 UTC (rev 200896)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2016-05-13 23:45:15 UTC (rev 200897)
@@ -354,12 +354,21 @@
m_slowPathGenerators.append(WTFMove(slowPathGenerator));
}
+void SpeculativeJIT::addSlowPathGenerator(std::function<void()> lambda)
+{
+ m_slowPathLambdas.append(std::make_pair(lambda, m_origin.semantic));
+}
+
void SpeculativeJIT::runSlowPathGenerators(PCToCodeOriginMapBuilder& pcToCodeOriginMapBuilder)
{
- for (unsigned i = 0; i < m_slowPathGenerators.size(); ++i) {
- pcToCodeOriginMapBuilder.appendItem(m_jit.label(), m_slowPathGenerators[i]->origin().semantic);
- m_slowPathGenerators[i]->generate(this);
+ for (auto& slowPathGenerator : m_slowPathGenerators) {
+ pcToCodeOriginMapBuilder.appendItem(m_jit.label(), slowPathGenerator->origin().semantic);
+ slowPathGenerator->generate(this);
}
+ for (auto& generatorPair : m_slowPathLambdas) {
+ pcToCodeOriginMapBuilder.appendItem(m_jit.label(), generatorPair.second);
+ generatorPair.first();
+ }
}
void SpeculativeJIT::clearGenerationInfo()
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (200896 => 200897)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2016-05-13 23:44:31 UTC (rev 200896)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2016-05-13 23:45:15 UTC (rev 200897)
@@ -319,6 +319,7 @@
GeneratedOperandType checkGeneratedTypeForToInt32(Node*);
void addSlowPathGenerator(std::unique_ptr<SlowPathGenerator>);
+ void addSlowPathGenerator(std::function<void()>);
void runSlowPathGenerators(PCToCodeOriginMapBuilder&);
void compile(Node*);
@@ -339,8 +340,23 @@
SilentRegisterSavePlan silentSavePlanForFPR(VirtualRegister spillMe, FPRReg source);
void silentSpill(const SilentRegisterSavePlan&);
void silentFill(const SilentRegisterSavePlan&, GPRReg canTrample);
-
+
template<typename CollectionType>
+ void silentSpill(const CollectionType& savePlans)
+ {
+ for (unsigned i = 0; i < savePlans.size(); ++i)
+ silentSpill(savePlans[i]);
+ }
+
+ template<typename CollectionType>
+ void silentFill(const CollectionType& savePlans, GPRReg exclude = InvalidGPRReg)
+ {
+ GPRReg canTrample = SpeculativeJIT::pickCanTrample(exclude);
+ for (unsigned i = savePlans.size(); i--;)
+ silentFill(savePlans[i], canTrample);
+ }
+
+ template<typename CollectionType>
void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg)
{
ASSERT(plans.isEmpty());
@@ -2812,6 +2828,7 @@
MinifiedGraph* m_minifiedGraph;
Vector<std::unique_ptr<SlowPathGenerator>, 8> m_slowPathGenerators;
+ Vector<std::pair<std::function<void()>, CodeOrigin>, 8> m_slowPathLambdas;
Vector<SilentRegisterSavePlan> m_plans;
unsigned m_outOfLineStreamIndex { UINT_MAX };
};
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (200896 => 200897)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2016-05-13 23:44:31 UTC (rev 200896)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2016-05-13 23:45:15 UTC (rev 200897)
@@ -5166,18 +5166,27 @@
#if ENABLE(FTL_JIT)
case CheckTierUpInLoop: {
- MacroAssembler::Jump done = m_jit.branchAdd32(
- MacroAssembler::Signed,
+ MacroAssembler::Jump callTierUp = m_jit.branchAdd32(
+ MacroAssembler::PositiveOrZero,
TrustedImm32(Options::ftlTierUpCounterIncrementForLoop()),
MacroAssembler::AbsoluteAddress(&m_jit.jitCode()->tierUpCounter.m_counter));
-
- silentSpillAllRegisters(InvalidGPRReg);
- m_jit.setupArgumentsWithExecState(
- TrustedImm32(node->origin.semantic.bytecodeIndex));
- appendCall(triggerTierUpNowInLoop);
- silentFillAllRegisters(InvalidGPRReg);
-
- done.link(&m_jit);
+
+ MacroAssembler::Label toNextOperation = m_jit.label();
+
+ Vector<SilentRegisterSavePlan> savePlans;
+ silentSpillAllRegistersImpl(false, savePlans, InvalidGPRReg);
+ unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex;
+
+ addSlowPathGenerator([=]() {
+ callTierUp.link(&m_jit);
+
+ silentSpill(savePlans);
+ m_jit.setupArgumentsWithExecState(TrustedImm32(bytecodeIndex));
+ appendCall(triggerTierUpNowInLoop);
+ silentFill(savePlans);
+
+ m_jit.jump().linkTo(toNextOperation, &m_jit);
+ });
break;
}
@@ -5198,7 +5207,7 @@
case CheckTierUpAndOSREnter: {
ASSERT(!node->origin.semantic.inlineCallFrame);
-
+
GPRTemporary temp(this);
GPRReg tempGPR = temp.gpr();
@@ -5206,26 +5215,39 @@
auto triggerIterator = m_jit.jitCode()->tierUpEntryTriggers.find(bytecodeIndex);
RELEASE_ASSERT(triggerIterator != m_jit.jitCode()->tierUpEntryTriggers.end());
uint8_t* forceEntryTrigger = &(m_jit.jitCode()->tierUpEntryTriggers.find(bytecodeIndex)->value);
+
MacroAssembler::Jump forceOSREntry = m_jit.branchTest8(MacroAssembler::NonZero, MacroAssembler::AbsoluteAddress(forceEntryTrigger));
-
- MacroAssembler::Jump done = m_jit.branchAdd32(
- MacroAssembler::Signed,
+ MacroAssembler::Jump overflowedCounter = m_jit.branchAdd32(
+ MacroAssembler::PositiveOrZero,
TrustedImm32(Options::ftlTierUpCounterIncrementForLoop()),
MacroAssembler::AbsoluteAddress(&m_jit.jitCode()->tierUpCounter.m_counter));
+ MacroAssembler::Label toNextOperation = m_jit.label();
- forceOSREntry.link(&m_jit);
- silentSpillAllRegisters(tempGPR);
+ Vector<SilentRegisterSavePlan> savePlans;
+ silentSpillAllRegistersImpl(false, savePlans, tempGPR);
+
unsigned streamIndex = m_stream->size();
m_jit.jitCode()->bytecodeIndexToStreamIndex.add(bytecodeIndex, streamIndex);
- m_jit.setupArgumentsWithExecState(TrustedImm32(bytecodeIndex));
- appendCallSetResult(triggerOSREntryNow, tempGPR);
- MacroAssembler::Jump dontEnter = m_jit.branchTestPtr(MacroAssembler::Zero, tempGPR);
- m_jit.emitRestoreCalleeSaves();
- m_jit.jump(tempGPR);
- dontEnter.link(&m_jit);
- silentFillAllRegisters(tempGPR);
-
- done.link(&m_jit);
+
+ addSlowPathGenerator([=]() {
+ forceOSREntry.link(&m_jit);
+ overflowedCounter.link(&m_jit);
+
+ silentSpill(savePlans);
+ m_jit.setupArgumentsWithExecState(TrustedImm32(bytecodeIndex));
+ appendCallSetResult(triggerOSREntryNow, tempGPR);
+
+ if (savePlans.isEmpty())
+ m_jit.branchTestPtr(MacroAssembler::Zero, tempGPR).linkTo(toNextOperation, &m_jit);
+ else {
+ MacroAssembler::Jump osrEnter = m_jit.branchTestPtr(MacroAssembler::NonZero, tempGPR);
+ silentFill(savePlans);
+ m_jit.jump().linkTo(toNextOperation, &m_jit);
+ osrEnter.link(&m_jit);
+ }
+ m_jit.emitRestoreCalleeSaves();
+ m_jit.jump(tempGPR);
+ });
break;
}
#else // ENABLE(FTL_JIT)