Commit c1707fca authored by oliver@apple.com's avatar 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):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96461 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 45bbd9db
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
......@@ -1070,7 +1070,6 @@
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>"; };
......@@ -1542,7 +1541,6 @@
0867D691FE84028FC02AAC07 /* JavaScriptCore */ = {
isa = PBXGroup;
children = (
86880F311434FFAF00B08D42 /* ChangeLog */,
651122E5140469BA002B101D /* testRegExp.cpp */,
A718F8211178EB4B002465A7 /* create_regex_tables */,
937B63CC09E766D200A671DD /* DerivedSources.make */,
......
......@@ -319,6 +319,7 @@ static inline const char* arithNodeFlagsAsString(ArithNodeFlags flags)
macro(GetByOffset, NodeResultJS) \
macro(PutByOffset, NodeMustGenerate | NodeClobbersWorld) \
macro(GetArrayLength, NodeResultInt32) \
macro(GetStringLength, NodeResultInt32) \
macro(GetMethod, NodeResultJS | NodeMustGenerate) \
macro(CheckMethod, NodeResultJS | NodeMustGenerate) \
macro(GetScopeChain, NodeResultJS) \
......
......@@ -559,7 +559,8 @@ private:
}
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();
......@@ -706,7 +707,9 @@ private:
}
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;
......@@ -714,9 +717,9 @@ private:
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;
}
......@@ -1189,6 +1192,7 @@ private:
case ArithSqrt:
case GetCallee:
case GetArrayLength:
case GetStringLength:
setReplacement(pureCSE(node));
break;
......
......@@ -579,6 +579,18 @@ private:
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);
......
......@@ -1655,6 +1655,22 @@ void SpeculativeJIT::compile(Node& node)
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());
......
......@@ -1715,6 +1715,22 @@ void SpeculativeJIT::compile(Node& node)
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());
......
......@@ -445,7 +445,9 @@ namespace JSC {
{
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:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment