https://bugs.webkit.org/show_bug.cgi?id=69215
Reviewed by Geoff Garen.
Adds a GetStringLength node to the DFG so that we can support
string.length inline.
* dfg/DFGNode.h:
* dfg/DFGPropagator.cpp:
(JSC::DFG::Propagator::propagateNodePredictions):
(JSC::DFG::Propagator::fixupNode):
(JSC::DFG::Propagator::performNodeCSE):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::isKnownString):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* runtime/JSString.h:
(JSC::JSString::offsetOfLength):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96461
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2011-10-01 Oliver Hunt <oliver@apple.com>
+
+ Support string length in the DFG
+ https://bugs.webkit.org/show_bug.cgi?id=69215
+
+ Reviewed by Geoff Garen.
+
+ Adds a GetStringLength node to the DFG so that we can support
+ string.length inline.
+
+ * dfg/DFGNode.h:
+ * dfg/DFGPropagator.cpp:
+ (JSC::DFG::Propagator::propagateNodePredictions):
+ (JSC::DFG::Propagator::fixupNode):
+ (JSC::DFG::Propagator::performNodeCSE):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::isKnownString):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * runtime/JSString.h:
+ (JSC::JSString::offsetOfLength):
+
2011-10-01 Yuqiang Xian <yuqiang.xian@intel.com>
JSVALUE32_64 DFG JIT - unboxed integers and cells in register file must be reboxed before exiting from DFG JIT
86880F1914328BB900B08D42 /* DFGJITCompiler32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGJITCompiler32_64.cpp; path = dfg/DFGJITCompiler32_64.cpp; sourceTree = "<group>"; };
86880F1A14328BB900B08D42 /* DFGJITCompilerInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGJITCompilerInlineMethods.h; path = dfg/DFGJITCompilerInlineMethods.h; sourceTree = "<group>"; };
86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSpeculativeJIT32_64.cpp; path = dfg/DFGSpeculativeJIT32_64.cpp; sourceTree = "<group>"; };
- 86880F311434FFAF00B08D42 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
86880F43143531A700B08D42 /* DFGJITCodeGenerator64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGJITCodeGenerator64.cpp; path = dfg/DFGJITCodeGenerator64.cpp; sourceTree = "<group>"; };
86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSpeculativeJIT64.cpp; path = dfg/DFGSpeculativeJIT64.cpp; sourceTree = "<group>"; };
868BFA00117CEFD100B908B1 /* AtomicString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AtomicString.cpp; path = text/AtomicString.cpp; sourceTree = "<group>"; };
0867D691FE84028FC02AAC07 /* JavaScriptCore */ = {
isa = PBXGroup;
children = (
- 86880F311434FFAF00B08D42 /* ChangeLog */,
651122E5140469BA002B101D /* testRegExp.cpp */,
A718F8211178EB4B002465A7 /* create_regex_tables */,
937B63CC09E766D200A671DD /* DerivedSources.make */,
macro(GetByOffset, NodeResultJS) \
macro(PutByOffset, NodeMustGenerate | NodeClobbersWorld) \
macro(GetArrayLength, NodeResultInt32) \
+ macro(GetStringLength, NodeResultInt32) \
macro(GetMethod, NodeResultJS | NodeMustGenerate) \
macro(CheckMethod, NodeResultJS | NodeMustGenerate) \
macro(GetScopeChain, NodeResultJS) \
}
case ValueToDouble:
- case GetArrayLength: {
+ case GetArrayLength:
+ case GetStringLength: {
// This node should never be visible at this stage of compilation. It is
// inserted by fixup(), which follows this phase.
ASSERT_NOT_REACHED();
}
case GetById: {
- if (!isArrayPrediction(m_predictions[node.child1()]))
+ bool isArray = isArrayPrediction(m_predictions[node.child1()]);
+ bool isString = isStringPrediction(m_predictions[node.child1()]);
+ if (!isArray && !isString)
break;
if (!isInt32Prediction(m_predictions[m_compileIndex]))
break;
break;
#if ENABLE(DFG_DEBUG_PROPAGATION_VERBOSE)
- printf(" @%u -> GetArrayLength", nodeIndex);
+ printf(" @%u -> %s", nodeIndex, isArray ? "GetArrayLength" : "GetStringLength");
#endif
- node.op = GetArrayLength;
+ node.op = isArray ? GetArrayLength : GetStringLength;
break;
}
case ArithSqrt:
case GetCallee:
case GetArrayLength:
+ case GetStringLength:
setReplacement(pureCSE(node));
break;
return false;
}
}
+
+ bool isKnownString(NodeIndex op1)
+ {
+ Node& node = m_jit.graph()[op1];
+ switch (node.op) {
+ case GetLocal:
+ return isStringPrediction(node.variableAccessData()->prediction());
+
+ default:
+ return false;
+ }
+ }
bool compare(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, Z_DFGOperation_EJJ);
bool compilePeepHoleBranch(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, Z_DFGOperation_EJJ);
break;
}
+ case GetStringLength: {
+ SpeculateCellOperand base(this, node.child1());
+ GPRTemporary result(this);
+
+ GPRReg baseGPR = base.gpr();
+ GPRReg resultGPR = result.gpr();
+
+ if (!isKnownString(node.child1()))
+ speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
+
+ m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
+
+ integerResult(resultGPR, m_compileIndex);
+ break;
+ }
+
case CheckStructure: {
SpeculateCellOperand base(this, node.child1());
break;
}
+ case GetStringLength: {
+ SpeculateCellOperand base(this, node.child1());
+ GPRTemporary result(this);
+
+ GPRReg baseGPR = base.gpr();
+ GPRReg resultGPR = result.gpr();
+
+ if (!isKnownString(node.child1()))
+ speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
+
+ m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
+
+ integerResult(resultGPR, m_compileIndex);
+ break;
+ }
+
case CheckStructure: {
SpeculateCellOperand base(this, node.child1());
{
return Structure::create(globalData, globalObject, proto, TypeInfo(StringType, OverridesGetOwnPropertySlot), &s_info);
}
-
+
+ static size_t offsetOfLength() { return OBJECT_OFFSETOF(JSString, m_length); }
+
static const ClassInfo s_info;
private: