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

Unified Diff: runtime/vm/intrinsifier_ia32.cc

Issue 13964002: Intrinsify OnebyteString's substringUnchecked. Significant performance improvement on Json benchmar… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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
« no previous file with comments | « runtime/vm/intrinsifier_arm.cc ('k') | runtime/vm/intrinsifier_mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intrinsifier_ia32.cc
===================================================================
--- runtime/vm/intrinsifier_ia32.cc (revision 21228)
+++ runtime/vm/intrinsifier_ia32.cc (working copy)
@@ -1498,6 +1498,118 @@
return true;
}
+
+// Allocates one-byte string of length 'end - start'. The content is not
+// initialized.
+static void TryAllocateOnebyteString(Assembler* assembler,
+ Label* failure,
+ intptr_t start_index_offset,
+ intptr_t end_index_offset) {
+ __ movl(EDI, Address(ESP, + end_index_offset));
+ __ subl(EDI, Address(ESP, + start_index_offset));
+ const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
+ __ SmiUntag(EDI);
+ __ leal(EDI, Address(EDI, TIMES_1, fixed_size)); // EDI is a Smi.
+ __ andl(EDI, Immediate(-kObjectAlignment));
+
+ Isolate* isolate = Isolate::Current();
+ Heap* heap = isolate->heap();
+
+ __ movl(EAX, Address::Absolute(heap->TopAddress()));
+ __ movl(EBX, EAX);
+
+ // EDI: allocation size.
+ __ addl(EBX, EDI);
+ __ j(CARRY, failure);
+
+ // Check if the allocation fits into the remaining space.
+ // EAX: potential new object start.
+ // EBX: potential next object start.
+ // EDI: allocation size.
+ __ cmpl(EBX, Address::Absolute(heap->EndAddress()));
+ __ j(ABOVE_EQUAL, failure);
+
+ // Successfully allocated the object(s), now update top to point to
+ // next object start and initialize the object.
+ __ movl(Address::Absolute(heap->TopAddress()), EBX);
+ __ addl(EAX, Immediate(kHeapObjectTag));
+
+ // Initialize the tags.
+ // EAX: new object start as a tagged pointer.
+ // EBX: new object end address.
+ // EDI: allocation size.
+ {
+ Label size_tag_overflow, done;
+ __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag));
+ __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+ __ shll(EDI, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2));
+ __ jmp(&done, Assembler::kNearJump);
+
+ __ Bind(&size_tag_overflow);
+ __ xorl(EDI, EDI);
+ __ Bind(&done);
+
+ // Get the class index and insert it into the tags.
+ const Class& cls =
+ Class::Handle(isolate->object_store()->one_byte_string_class());
+ __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cls.id())));
+ __ movl(FieldAddress(EAX, String::tags_offset()), EDI); // Tags.
+ }
+
+ // Set the length field.
+ __ movl(EDI, Address(ESP, + end_index_offset));
+ __ subl(EDI, Address(ESP, + start_index_offset)); // Length.
+ __ StoreIntoObjectNoBarrier(EAX,
+ FieldAddress(EAX, String::length_offset()),
+ EDI);
+ // Clear hash.
+ __ movl(FieldAddress(EAX, String::hash_offset()), Immediate(0));
+}
+
+
+// Arg0: Onebyte String
+// Arg1: Start index as Smi.
+// Arg2: End index as Smi.
+// The indexes must be valid.
+bool Intrinsifier::OneByteString_substringUnchecked(Assembler* assembler) {
+ const intptr_t kStringOffset = 3 * kWordSize;
+ const intptr_t kStartIndexOffset = 2 * kWordSize;
+ const intptr_t kEndIndexOffset = 1 * kWordSize;
+ Label fall_through, done;
+ TryAllocateOnebyteString(
+ assembler, &fall_through, kStartIndexOffset, kEndIndexOffset);
+ // EAX: new string as tagged pointer.
+ // Copy string.
+ __ movl(EDI, Address(ESP, + kStringOffset));
+ __ movl(EBX, Address(ESP, + kStartIndexOffset));
+ __ SmiUntag(EBX);
+ __ leal(EDI, FieldAddress(EDI, EBX, TIMES_1, OneByteString::data_offset()));
+ // EDI: Start address to copy from (untagged).
+ __ movl(EDX, Address(ESP, + kEndIndexOffset));
+ __ SmiUntag(EDX);
+ __ subl(EDX, EBX);
+ __ xorl(ECX, ECX);
+ // EDX: Number of bytes to copy.
+ // ECX: Loop counter.
+ // TODO(srdjan): For large substrings it could be better if we would group
+ // the byte copies into word copies or even call memcpy.
+ Label loop, check;
+ // TODO(srdjan): Use rep movsb instead.
+ __ jmp(&check, Assembler::kNearJump);
+ __ Bind(&loop);
+ __ movzxb(EBX, Address(EDI, ECX, TIMES_1, 0));
+ __ movb(FieldAddress(EAX, ECX, TIMES_1, OneByteString::data_offset()), BL);
+ __ incl(ECX);
+ __ Bind(&check);
+ __ cmpl(ECX, EDX);
+ __ j(LESS, &loop, Assembler::kNearJump);
+
+ __ Bind(&done);
+ __ ret();
+ __ Bind(&fall_through);
+ return false;
+}
+
#undef __
} // namespace dart
« no previous file with comments | « runtime/vm/intrinsifier_arm.cc ('k') | runtime/vm/intrinsifier_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698