Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (89642 => 89643)
--- trunk/Source/_javascript_Core/ChangeLog 2011-06-24 00:33:42 UTC (rev 89642)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-06-24 00:40:18 UTC (rev 89643)
@@ -1,3 +1,18 @@
+2011-06-23 Filip Pizlo <[email protected]>
+
+ Reviewed by Gavin Barraclough.
+
+ DFG non-speculative JIT should have obvious optimizations for GetById and GetByVal
+ https://bugs.webkit.org/show_bug.cgi?id=63173
+
+ * dfg/DFGJITCodeGenerator.cpp:
+ (JSC::DFG::JITCodeGenerator::cachedGetById):
+ * dfg/DFGJITCodeGenerator.h:
+ * dfg/DFGNonSpeculativeJIT.cpp:
+ (JSC::DFG::NonSpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+
2011-06-23 Oliver Hunt <[email protected]>
Fix Qt again.
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (89642 => 89643)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-06-24 00:33:42 UTC (rev 89642)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-06-24 00:40:18 UTC (rev 89643)
@@ -320,6 +320,36 @@
use(child3);
}
+void JITCodeGenerator::cachedGetById(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget)
+{
+ JITCompiler::DataLabelPtr structureToCompare;
+ JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::Equal, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
+
+ if (slowPathTarget.isSet())
+ slowPathTarget.link(&m_jit);
+
+ silentSpillAllRegisters(resultGPR, baseGPR);
+ m_jit.move(baseGPR, GPRInfo::argumentGPR1);
+ m_jit.move(JITCompiler::ImmPtr(identifier(identifierNumber)), GPRInfo::argumentGPR2);
+ m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+ JITCompiler::Call functionCall = appendCallWithExceptionCheck(operationGetByIdOptimize);
+ m_jit.move(GPRInfo::returnValueGPR, resultGPR);
+ silentFillAllRegisters(resultGPR);
+
+ JITCompiler::Jump handledByC = m_jit.jump();
+ structureCheck.link(&m_jit);
+
+ m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
+ JITCompiler::DataLabelCompact loadWithPatch = m_jit.loadPtrWithCompactAddressOffsetPatch(JITCompiler::Address(resultGPR, 0), resultGPR);
+
+ intptr_t checkToCall = m_jit.differenceBetween(structureToCompare, functionCall);
+ intptr_t callToLoad = m_jit.differenceBetween(functionCall, loadWithPatch);
+
+ handledByC.link(&m_jit);
+
+ m_jit.addPropertyAccess(functionCall, checkToCall, callToLoad);
+}
+
#ifndef NDEBUG
static const char* dataFormatString(DataFormat format)
{
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (89642 => 89643)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-06-24 00:33:42 UTC (rev 89642)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-06-24 00:40:18 UTC (rev 89643)
@@ -500,6 +500,8 @@
}
}
+ void cachedGetById(GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
+
// 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
// the nodes result, since the node may have the same VirtualRegister as
Modified: trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp (89642 => 89643)
--- trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-06-24 00:33:42 UTC (rev 89642)
+++ trunk/Source/_javascript_Core/dfg/DFGNonSpeculativeJIT.cpp 2011-06-24 00:40:18 UTC (rev 89643)
@@ -493,16 +493,53 @@
}
case GetByVal: {
- JSValueOperand arg1(this, node.child1);
- JSValueOperand arg2(this, node.child2);
- GPRReg arg1GPR = arg1.gpr();
- GPRReg arg2GPR = arg2.gpr();
- flushRegisters();
+ JSValueOperand base(this, node.child1);
+ JSValueOperand property(this, node.child2);
- GPRResult result(this);
- callOperation(operationGetByVal, result.gpr(), arg1GPR, arg2GPR);
+ GPRTemporary storage(this);
+ GPRTemporary cleanIndex(this);
- jsValueResult(result.gpr(), m_compileIndex);
+ GPRReg baseGPR = base.gpr();
+ GPRReg propertyGPR = property.gpr();
+ GPRReg storageGPR = storage.gpr();
+ GPRReg cleanIndexGPR = cleanIndex.gpr();
+
+ JITCompiler::Jump baseNotCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
+
+ JITCompiler::Jump propertyNotInt = m_jit.branchPtr(MacroAssembler::Below, propertyGPR, GPRInfo::tagTypeNumberRegister);
+
+ // Get the array storage. We haven't yet checked this is a JSArray, so this is only safe if
+ // an access with offset JSArray::storageOffset() is valid for all JSCells!
+ m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR);
+
+ JITCompiler::Jump baseNotArray = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr));
+
+ m_jit.zeroExtend32ToPtr(propertyGPR, cleanIndexGPR);
+
+ JITCompiler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, cleanIndexGPR, MacroAssembler::Address(baseGPR, JSArray::vectorLengthOffset()));
+
+ m_jit.loadPtr(MacroAssembler::BaseIndex(storageGPR, cleanIndexGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), storageGPR);
+
+ JITCompiler::Jump loadFailed = m_jit.branchTestPtr(MacroAssembler::Zero, storageGPR);
+
+ JITCompiler::Jump done = m_jit.jump();
+
+ baseNotCell.link(&m_jit);
+ propertyNotInt.link(&m_jit);
+ baseNotArray.link(&m_jit);
+ outOfBounds.link(&m_jit);
+ loadFailed.link(&m_jit);
+
+ silentSpillAllRegisters(storageGPR, baseGPR, propertyGPR);
+ setupStubArguments(baseGPR, propertyGPR);
+ m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+ appendCallWithExceptionCheck(operationGetByVal);
+ m_jit.move(GPRInfo::returnValueGPR, storageGPR);
+ silentFillAllRegisters(storageGPR);
+
+ done.link(&m_jit);
+
+ jsValueResult(storageGPR, m_compileIndex);
break;
}
@@ -526,11 +563,14 @@
case GetById: {
JSValueOperand base(this, node.child1);
GPRReg baseGPR = base.gpr();
- flushRegisters();
+ GPRTemporary result(this, base);
+ GPRReg resultGPR = result.gpr();
- GPRResult result(this);
- callOperation(operationGetById, result.gpr(), baseGPR, identifier(node.identifierNumber()));
- jsValueResult(result.gpr(), m_compileIndex);
+ JITCompiler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
+
+ cachedGetById(baseGPR, resultGPR, node.identifierNumber(), notCell);
+
+ jsValueResult(resultGPR, m_compileIndex);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (89642 => 89643)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-06-24 00:33:42 UTC (rev 89642)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-06-24 00:40:18 UTC (rev 89643)
@@ -854,33 +854,10 @@
SpeculateCellOperand base(this, node.child1);
GPRTemporary result(this, base);
- GPRReg baseGPR = base.gpr();
GPRReg resultGPR = result.gpr();
- JITCompiler::DataLabelPtr structureToCompare;
- JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::Equal, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
+ cachedGetById(base.gpr(), resultGPR, node.identifierNumber());
- silentSpillAllRegisters(resultGPR, baseGPR);
- m_jit.move(baseGPR, GPRInfo::argumentGPR1);
- m_jit.move(JITCompiler::ImmPtr(identifier(node.identifierNumber())), GPRInfo::argumentGPR2);
- m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
- JITCompiler::Call functionCall = appendCallWithExceptionCheck(operationGetByIdOptimize);
- m_jit.move(GPRInfo::returnValueGPR, resultGPR);
- silentFillAllRegisters(resultGPR);
-
- JITCompiler::Jump handledByC = m_jit.jump();
- structureCheck.link(&m_jit);
-
- m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
- JITCompiler::DataLabelCompact loadWithPatch = m_jit.loadPtrWithCompactAddressOffsetPatch(JITCompiler::Address(resultGPR, 0), resultGPR);
-
- intptr_t checkToCall = m_jit.differenceBetween(structureToCompare, functionCall);
- intptr_t callToLoad = m_jit.differenceBetween(functionCall, loadWithPatch);
-
- handledByC.link(&m_jit);
-
- m_jit.addPropertyAccess(functionCall, checkToCall, callToLoad);
-
jsValueResult(resultGPR, m_compileIndex);
break;
}