- Revision
- 91041
- Author
- [email protected]
- Date
- 2011-07-14 19:06:10 -0700 (Thu, 14 Jul 2011)
Log Message
DFG JIT does not optimize Branch as well as it could.
https://bugs.webkit.org/show_bug.cgi?id=64574
Patch by Filip Pizlo <[email protected]> on 2011-07-14
Reviewed by Gavin Barraclough.
This creates a common code path for emitting unfused branches, which does
no speculation, and only performs a slow call if absolutely necessary.
* dfg/DFGJITCodeGenerator.cpp:
(JSC::DFG::JITCodeGenerator::emitBranch):
* dfg/DFGJITCodeGenerator.h:
* dfg/DFGNonSpeculativeJIT.cpp:
(JSC::DFG::NonSpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compile):
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (91040 => 91041)
--- trunk/Source/_javascript_Core/ChangeLog 2011-07-15 01:51:45 UTC (rev 91040)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-07-15 02:06:10 UTC (rev 91041)
@@ -1,5 +1,23 @@
2011-07-14 Filip Pizlo <[email protected]>
+ DFG JIT does not optimize Branch as well as it could.
+ https://bugs.webkit.org/show_bug.cgi?id=64574
+
+ Reviewed by Gavin Barraclough.
+
+ This creates a common code path for emitting unfused branches, which does
+ no speculation, and only performs a slow call if absolutely necessary.
+
+ * dfg/DFGJITCodeGenerator.cpp:
+ (JSC::DFG::JITCodeGenerator::emitBranch):
+ * dfg/DFGJITCodeGenerator.h:
+ * dfg/DFGNonSpeculativeJIT.cpp:
+ (JSC::DFG::NonSpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
+2011-07-14 Filip Pizlo <[email protected]>
+
GC allocation fast path has too many operations.
https://bugs.webkit.org/show_bug.cgi?id=64493
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (91040 => 91041)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-07-15 01:51:45 UTC (rev 91040)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-07-15 02:06:10 UTC (rev 91041)
@@ -468,6 +468,36 @@
m_jit.addMethodGet(slowCall, structToCompare, protoObj, protoStructToCompare, putFunction);
}
+void JITCodeGenerator::emitBranch(Node& node)
+{
+ JSValueOperand value(this, node.child1());
+ GPRReg valueGPR = value.gpr();
+
+ GPRTemporary result(this);
+ GPRReg resultGPR = result.gpr();
+
+ BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
+ BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
+
+ addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsNumber(0)))), notTaken);
+ addBranch(m_jit.branchPtr(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister), taken);
+ addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken);
+ addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken);
+
+ silentSpillAllRegisters(resultGPR);
+ m_jit.move(valueGPR, GPRInfo::argumentGPR1);
+ m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+ appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
+ m_jit.move(GPRInfo::returnValueGPR, resultGPR);
+ silentFillAllRegisters(resultGPR);
+
+ addBranch(m_jit.branchTest8(MacroAssembler::NonZero, resultGPR), taken);
+ if (notTaken != (m_block + 1))
+ addBranch(m_jit.jump(), notTaken);
+
+ noResult(m_compileIndex);
+}
+
void JITCodeGenerator::emitCall(Node& node)
{
P_DFGOperation_E slowCallFunction;
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (91040 => 91041)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-07-15 01:51:45 UTC (rev 91040)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-07-15 02:06:10 UTC (rev 91041)
@@ -535,6 +535,8 @@
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 emitBranch(Node&);
+
MacroAssembler::Address addressOfCallData(int idx)
{
return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + idx) * static_cast<int>(sizeof(Register)));
Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (91040 => 91041)
--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-07-15 01:51:45 UTC (rev 91040)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-07-15 02:06:10 UTC (rev 91041)
@@ -920,24 +920,9 @@
break;
}
- case Branch: {
- JSValueOperand value(this, node.child1());
- GPRReg valueGPR = value.gpr();
- flushRegisters();
-
- GPRResult result(this);
- callOperation(dfgConvertJSValueToBoolean, result.gpr(), valueGPR);
-
- BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
- BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
-
- addBranch(m_jit.branchTest8(MacroAssembler::NonZero, result.gpr()), taken);
- if (notTaken != (m_block + 1))
- addBranch(m_jit.jump(), notTaken);
-
- noResult(m_compileIndex);
+ case Branch:
+ emitBranch(node);
break;
- }
case Return: {
ASSERT(GPRInfo::callFrameRegister != GPRInfo::regT1);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (91040 => 91041)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-07-15 01:51:45 UTC (rev 91040)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-07-15 02:06:10 UTC (rev 91041)
@@ -943,31 +943,9 @@
break;
}
- case Branch: {
- JSValueOperand value(this, node.child1());
- GPRReg valueReg = value.gpr();
-
- BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
- BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
-
- // Integers
- addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueReg, MacroAssembler::ImmPtr(JSValue::encode(jsNumber(0)))), notTaken);
- MacroAssembler::Jump isNonZeroInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, valueReg, GPRInfo::tagTypeNumberRegister);
-
- // Booleans
- addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueReg, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken);
- speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, valueReg, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))));
-
- if (taken == (m_block + 1))
- isNonZeroInteger.link(&m_jit);
- else {
- addBranch(isNonZeroInteger, taken);
- addBranch(m_jit.jump(), taken);
- }
-
- noResult(m_compileIndex);
+ case Branch:
+ emitBranch(node);
break;
- }
case Return: {
ASSERT(GPRInfo::callFrameRegister != GPRInfo::regT1);