From d95c49edb50ce994e4a1ca7a6002aa0ecbd7f530 Mon Sep 17 00:00:00 2001 From: "fpizlo@apple.com" Date: Wed, 28 Sep 2011 03:39:36 +0000 Subject: [PATCH] DFG JIT should speculate more aggressively on reads of array.length https://bugs.webkit.org/show_bug.cgi?id=68932 Reviewed by Oliver Hunt. This is a 2% speed-up on Kraken, neutral elsewhere. * dfg/DFGNode.h: * dfg/DFGPropagator.cpp: (JSC::DFG::Propagator::propagateNodePredictions): (JSC::DFG::Propagator::fixupNode): (JSC::DFG::Propagator::performNodeCSE): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compile): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96184 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/JavaScriptCore/ChangeLog | 17 ++++++++++++++ Source/JavaScriptCore/dfg/DFGNode.h | 1 + Source/JavaScriptCore/dfg/DFGPropagator.cpp | 31 +++++++++++++++++++------ Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp | 20 ++++++++++++++++ 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog index 851b192..a691225 100644 --- a/Source/JavaScriptCore/ChangeLog +++ b/Source/JavaScriptCore/ChangeLog @@ -1,3 +1,20 @@ +2011-09-27 Filip Pizlo + + DFG JIT should speculate more aggressively on reads of array.length + https://bugs.webkit.org/show_bug.cgi?id=68932 + + Reviewed by Oliver Hunt. + + This is a 2% speed-up on Kraken, neutral elsewhere. + + * dfg/DFGNode.h: + * dfg/DFGPropagator.cpp: + (JSC::DFG::Propagator::propagateNodePredictions): + (JSC::DFG::Propagator::fixupNode): + (JSC::DFG::Propagator::performNodeCSE): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compile): + 2011-09-27 Gavin Barraclough DFG JIT - merge changes between 95905 - 96175 diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h index 5633c0b..9cd0750 100644 --- a/Source/JavaScriptCore/dfg/DFGNode.h +++ b/Source/JavaScriptCore/dfg/DFGNode.h @@ -266,6 +266,7 @@ static inline const char* arithNodeFlagsAsString(ArithNodeFlags flags) macro(PutByIdDirect, NodeMustGenerate | NodeClobbersWorld) \ macro(CheckStructure, NodeResultStorage | NodeMustGenerate) \ macro(GetByOffset, NodeResultJS) \ + macro(GetArrayLength, NodeResultInt32) \ macro(GetMethod, NodeResultJS | NodeMustGenerate) \ macro(CheckMethod, NodeResultJS | NodeMustGenerate) \ macro(GetScopeChain, NodeResultJS) \ diff --git a/Source/JavaScriptCore/dfg/DFGPropagator.cpp b/Source/JavaScriptCore/dfg/DFGPropagator.cpp index ae299e0..3a00cdc 100644 --- a/Source/JavaScriptCore/dfg/DFGPropagator.cpp +++ b/Source/JavaScriptCore/dfg/DFGPropagator.cpp @@ -375,13 +375,6 @@ private: break; } - case ValueToDouble: { - // This node should never be visible at this stage of compilation. It is - // inserted by fixup(), which follows this phase. - ASSERT_NOT_REACHED(); - break; - } - case ValueAdd: { PredictedType left = m_predictions[node.child1()]; PredictedType right = m_predictions[node.child2()]; @@ -546,6 +539,14 @@ private: break; } + case ValueToDouble: + case GetArrayLength: { + // This node should never be visible at this stage of compilation. It is + // inserted by fixup(), which follows this phase. + ASSERT_NOT_REACHED(); + break; + } + #ifndef NDEBUG // These get ignored because they don't return anything. case PutScopedVar: @@ -681,6 +682,21 @@ private: break; } + case GetById: { + if (!isArrayPrediction(m_predictions[node.child1()])) + break; + if (!isInt32Prediction(m_predictions[m_compileIndex])) + break; + if (m_codeBlock->identifier(node.identifierNumber()) != m_globalData.propertyNames->length) + break; + +#if ENABLE(DFG_DEBUG_PROPAGATION_VERBOSE) + printf(" @%u -> GetArrayLength", nodeIndex); +#endif + node.op = GetArrayLength; + break; + } + default: break; } @@ -1044,6 +1060,7 @@ private: case ArithMax: case ArithSqrt: case GetCallee: + case GetArrayLength: setReplacement(pureCSE(node)); break; diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp index bad3f04..23088a8 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp @@ -1831,6 +1831,26 @@ void SpeculativeJIT::compile(Node& node) jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly); break; } + + case GetArrayLength: { + Node& baseNode = m_jit.graph()[node.child1()]; + SpeculateCellOperand base(this, node.child1()); + GPRTemporary result(this); + + GPRReg baseGPR = base.gpr(); + GPRReg resultGPR = result.gpr(); + + if (baseNode.op != GetLocal || !isArrayPrediction(m_jit.graph().getPrediction(baseNode.local()))) + speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr))); + + m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), resultGPR); + m_jit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), resultGPR); + + speculationCheck(m_jit.branch32(MacroAssembler::LessThan, resultGPR, MacroAssembler::TrustedImm32(0))); + + integerResult(resultGPR, m_compileIndex); + break; + } case CheckStructure: { SpeculateCellOperand base(this, node.child1()); -- 2.7.4