Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Unified Diff: runtime/vm/intrinsifier_arm.cc

Issue 41573003: Specialize string equality for various string classes. Implement intrinsics for string equal… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/intrinsifier_arm.cc
===================================================================
--- runtime/vm/intrinsifier_arm.cc (revision 29210)
+++ runtime/vm/intrinsifier_arm.cc (working copy)
@@ -1422,7 +1422,7 @@
__ CompareClassId(R0, kTwoByteStringCid, R3);
__ b(&fall_through, NE);
ASSERT(kSmiTagShift == 1);
- __ AddImmediate(R0, OneByteString::data_offset() - kHeapObjectTag);
+ __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
__ ldrh(R0, Address(R0, R1));
__ SmiTag(R0);
__ Ret();
@@ -1654,6 +1654,80 @@
__ Bind(&fall_through);
}
+
+// TODO(srdjan): Add combinations (one-byte/two-byte/external strings).
+void StringEquality(Assembler* assembler, intptr_t string_cid) {
+ Label fall_through, is_true, is_false, loop;
+ __ ldr(R0, Address(SP, 1 * kWordSize)); // This.
+ __ ldr(R1, Address(SP, 0 * kWordSize)); // Other.
+
+ // Are identical?
+ __ cmp(R0, ShifterOperand(R1));
+ __ b(&is_true, EQ);
+
+ // Is other OneByteString?
+ __ tst(R1, ShifterOperand(kSmiTagMask));
+ __ b(&fall_through, EQ);
+ __ CompareClassId(R1, string_cid, R2);
+ __ b(&fall_through, NE);
+
+ // Have same length?
+ __ ldr(R2, FieldAddress(R0, String::length_offset()));
+ __ ldr(R3, FieldAddress(R1, String::length_offset()));
+ __ cmp(R2, ShifterOperand(R3));
+ __ b(&is_false, NE);
+
+ // Check contents, no fall-through possible.
+ ASSERT((string_cid == kOneByteStringCid) ||
+ (string_cid == kTwoByteStringCid));
+ const intptr_t offset = (string_cid == kOneByteStringCid) ?
+ OneByteString::data_offset() : TwoByteString::data_offset();
+ __ AddImmediate(R0, offset - kHeapObjectTag);
+ __ AddImmediate(R1, offset - kHeapObjectTag);
+ __ SmiUntag(R2);
+ __ Bind(&loop);
+ __ AddImmediate(R2, -1);
+ __ cmp(R2, ShifterOperand(0));
+ __ b(&is_true, LT);
+ if (string_cid == kOneByteStringCid) {
+ __ ldrb(R3, Address(R0));
+ __ ldrb(R4, Address(R1));
+ __ AddImmediate(R0, 1);
+ __ AddImmediate(R1, 1);
+ } else if (string_cid == kTwoByteStringCid) {
+ __ ldrh(R3, Address(R0));
+ __ ldrh(R4, Address(R1));
+ __ AddImmediate(R0, 2);
+ __ AddImmediate(R1, 2);
zra 2013/10/24 23:59:46 Forgot that Regis did implement scaled indexes for
srdjan 2013/10/25 00:13:17 Done.
+ } else {
+ UNIMPLEMENTED();
+ }
+ __ cmp(R3, ShifterOperand(R4));
+ __ b(&is_false, NE);
+ __ b(&loop);
+
+ __ Bind(&is_true);
+ __ LoadObject(R0, Bool::True());
+ __ Ret();
+
+ __ Bind(&is_false);
+ __ LoadObject(R0, Bool::False());
+ __ Ret();
+
+ __ Bind(&fall_through);
+}
+
+
+void Intrinsifier::OneByteString_equality(Assembler* assembler) {
+ StringEquality(assembler, kOneByteStringCid);
+}
+
+
+void Intrinsifier::TwoByteString_equality(Assembler* assembler) {
+ StringEquality(assembler, kTwoByteStringCid);
+}
+
+
} // namespace dart
#endif // defined TARGET_ARCH_ARM

Powered by Google App Engine
This is Rietveld 408576698