Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (96982 => 96983)
--- trunk/Source/_javascript_Core/ChangeLog 2011-10-07 22:00:18 UTC (rev 96982)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-10-07 22:11:51 UTC (rev 96983)
@@ -1,3 +1,26 @@
+2011-10-07 Oliver Hunt <oli...@apple.com>
+
+ Support string indexing in the DFG
+ https://bugs.webkit.org/show_bug.cgi?id=69671
+
+ Reviewed by Gavin Barraclough.
+
+ Emit code to support inline indexing of strings
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
+ Shared code to perform string indexing.
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ Use compileGetByValOnString if we predict that the base object
+ is a string in GetByVal.
+ * runtime/JSString.h:
+ (JSC::JSString::offsetOfFiberCount):
+ (JSC::JSString::offsetOfValue):
+
2011-10-07 Filip Pizlo <fpi...@apple.com>
DFG ConvertThis speculation logic is wrong
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (96982 => 96983)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-10-07 22:00:18 UTC (rev 96982)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-10-07 22:11:51 UTC (rev 96983)
@@ -528,6 +528,42 @@
}
}
+void SpeculativeJIT::compileGetByValOnString(Node& node)
+{
+ ASSERT(node.child3() == NoNode);
+ SpeculateCellOperand base(this, node.child1());
+ SpeculateStrictInt32Operand property(this, node.child2());
+
+ GPRReg baseReg = base.gpr();
+ GPRReg propertyReg = property.gpr();
+
+ if (!isKnownString(node.child1()))
+ speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
+
+ // unsigned comparison so we can filter out negative indices and indices that are too large
+ speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSString::offsetOfLength())));
+
+ // Speculate that we're not accessing a rope
+ speculationCheck(m_jit.branchTest32(MacroAssembler::NonZero, MacroAssembler::Address(baseReg, JSString::offsetOfFiberCount())));
+
+ GPRTemporary scratch(this);
+ GPRReg scratchReg = scratch.gpr();
+
+ // Load the character into scratchReg
+ m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), scratchReg);
+ m_jit.loadPtr(MacroAssembler::Address(scratchReg, StringImpl::dataOffset()), scratchReg);
+ m_jit.load16(MacroAssembler::BaseIndex(scratchReg, propertyReg, MacroAssembler::TimesTwo, 0), scratchReg);
+
+ // We only support ascii characters
+ speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, scratchReg, TrustedImm32(0x100)));
+ GPRTemporary smallStrings(this);
+ GPRReg smallStringsReg = smallStrings.gpr();
+ m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalData()->smallStrings.singleCharacterStrings()), smallStringsReg);
+ m_jit.loadPtr(MacroAssembler::BaseIndex(smallStringsReg, scratchReg, MacroAssembler::ScalePtr, 0), scratchReg);
+ speculationCheck(m_jit.branchTest32(MacroAssembler::Zero, scratchReg));
+ cellResult(scratchReg, m_compileIndex);
+}
+
} } // namespace JSC::DFG
#endif
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (96982 => 96983)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-10-07 22:00:18 UTC (rev 96982)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-10-07 22:11:51 UTC (rev 96983)
@@ -456,6 +456,8 @@
void emitObjectOrOtherBranch(NodeIndex value, BlockIndex taken, BlockIndex notTaken, void *vptr);
void emitBranch(Node&);
+ void compileGetByValOnString(Node&);
+
// It is acceptable to have structure be equal to scratch, so long as you're fine
// with the structure GPR being clobbered.
template<typename T>
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (96982 => 96983)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2011-10-07 22:00:18 UTC (rev 96982)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2011-10-07 22:11:51 UTC (rev 96983)
@@ -1260,6 +1260,13 @@
break;
case GetByVal: {
+ if (at(node.child1()).prediction() == PredictString) {
+ compileGetByValOnString(node);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
+
ASSERT(node.child3() == NoNode);
SpeculateCellOperand base(this, node.child1());
SpeculateStrictInt32Operand property(this, node.child2());
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (96982 => 96983)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2011-10-07 22:00:18 UTC (rev 96982)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2011-10-07 22:11:51 UTC (rev 96983)
@@ -1378,6 +1378,13 @@
break;
case GetByVal: {
+ if (at(node.child1()).prediction() == PredictString) {
+ compileGetByValOnString(node);
+ if (!m_compileOkay)
+ return;
+ break;
+ }
+
ASSERT(node.child3() == NoNode);
SpeculateCellOperand base(this, node.child1());
SpeculateStrictInt32Operand property(this, node.child2());
Modified: trunk/Source/_javascript_Core/runtime/JSString.h (96982 => 96983)
--- trunk/Source/_javascript_Core/runtime/JSString.h 2011-10-07 22:00:18 UTC (rev 96982)
+++ trunk/Source/_javascript_Core/runtime/JSString.h 2011-10-07 22:11:51 UTC (rev 96983)
@@ -447,6 +447,8 @@
}
static size_t offsetOfLength() { return OBJECT_OFFSETOF(JSString, m_length); }
+ static size_t offsetOfFiberCount() { return OBJECT_OFFSETOF(JSString, m_fiberCount); }
+ static size_t offsetOfValue() { return OBJECT_OFFSETOF(JSString, m_value); }
static const ClassInfo s_info;