| Index: runtime/vm/intrinsifier_x64.cc
|
| ===================================================================
|
| --- runtime/vm/intrinsifier_x64.cc (revision 22398)
|
| +++ runtime/vm/intrinsifier_x64.cc (working copy)
|
| @@ -1488,15 +1488,19 @@
|
|
|
|
|
| // Allocates one-byte string of length 'end - start'. The content is not
|
| -// initialized.
|
| +// initialized. 'length-reg' contains tagged length.
|
| +// Returns new string as tagged pointer in EAX.
|
| static void TryAllocateOnebyteString(Assembler* assembler,
|
| + Label* ok,
|
| Label* failure,
|
| - intptr_t start_index_offset,
|
| - intptr_t end_index_offset) {
|
| - __ movq(RDI, Address(RSP, + end_index_offset));
|
| - __ subq(RDI, Address(RSP, + start_index_offset));
|
| + Register length_reg) {
|
| + if (length_reg != RDI) {
|
| + __ movq(RDI, length_reg);
|
| + }
|
| + Label pop_and_fail;
|
| + __ pushq(RDI); // Preserve length.
|
| + __ SmiUntag(RDI);
|
| const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
|
| - __ SmiUntag(RDI);
|
| __ leaq(RDI, Address(RDI, TIMES_1, fixed_size)); // RDI is a Smi.
|
| __ andq(RDI, Immediate(-kObjectAlignment));
|
|
|
| @@ -1509,7 +1513,7 @@
|
| // RDI: allocation size.
|
| __ movq(RCX, RAX);
|
| __ addq(RCX, RDI);
|
| - __ j(CARRY, failure);
|
| + __ j(CARRY, &pop_and_fail);
|
|
|
| // Check if the allocation fits into the remaining space.
|
| // RAX: potential new object start.
|
| @@ -1517,7 +1521,7 @@
|
| // RDI: allocation size.
|
| __ movq(R13, Immediate(heap->EndAddress()));
|
| __ cmpq(RCX, Address(R13, 0));
|
| - __ j(ABOVE_EQUAL, failure);
|
| + __ j(ABOVE_EQUAL, &pop_and_fail);
|
|
|
| // Successfully allocated the object(s), now update top to point to
|
| // next object start and initialize the object.
|
| @@ -1547,13 +1551,17 @@
|
| }
|
|
|
| // Set the length field.
|
| - __ movq(RDI, Address(RSP, + end_index_offset));
|
| - __ subq(RDI, Address(RSP, + start_index_offset)); // Length.
|
| + __ popq(RDI);
|
| __ StoreIntoObjectNoBarrier(RAX,
|
| FieldAddress(RAX, String::length_offset()),
|
| RDI);
|
| // Clear hash.
|
| __ movq(FieldAddress(RAX, String::hash_offset()), Immediate(0));
|
| + __ jmp(ok, Assembler::kNearJump);
|
| +
|
| + __ Bind(&pop_and_fail);
|
| + __ popq(RDI);
|
| + __ jmp(failure);
|
| }
|
|
|
|
|
| @@ -1565,9 +1573,11 @@
|
| const intptr_t kStringOffset = 3 * kWordSize;
|
| const intptr_t kStartIndexOffset = 2 * kWordSize;
|
| const intptr_t kEndIndexOffset = 1 * kWordSize;
|
| - Label fall_through;
|
| - TryAllocateOnebyteString(
|
| - assembler, &fall_through, kStartIndexOffset, kEndIndexOffset);
|
| + Label fall_through, ok;
|
| + __ movq(RDI, Address(RSP, + kEndIndexOffset));
|
| + __ subq(RDI, Address(RSP, + kStartIndexOffset));
|
| + TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI);
|
| + __ Bind(&ok);
|
| // RAX: new string as tagged pointer.
|
| // Copy string.
|
| __ movq(RSI, Address(RSP, + kStringOffset));
|
| @@ -1600,6 +1610,32 @@
|
| }
|
|
|
|
|
| +bool Intrinsifier::OneByteString_setAt(Assembler* assembler) {
|
| + __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Value.
|
| + __ movq(RBX, Address(RSP, + 2 * kWordSize)); // Index.
|
| + __ movq(RAX, Address(RSP, + 3 * kWordSize)); // OneByteString.
|
| + __ SmiUntag(RBX);
|
| + __ SmiUntag(RCX);
|
| + __ movb(FieldAddress(RAX, RBX, TIMES_1, OneByteString::data_offset()), RCX);
|
| + __ ret();
|
| + return true;
|
| +}
|
| +
|
| +
|
| +bool Intrinsifier::OneByteString_allocate(Assembler* assembler) {
|
| + __ movq(RDI, Address(RSP, + 1 * kWordSize)); // Length.v=
|
| + Label fall_through, ok;
|
| + TryAllocateOnebyteString(assembler, &ok, &fall_through, RDI);
|
| + // EDI: Start address to copy from (untagged).
|
| +
|
| + __ Bind(&ok);
|
| + __ ret();
|
| +
|
| + __ Bind(&fall_through);
|
| + return false;
|
| +}
|
| +
|
| +
|
| #undef __
|
|
|
| } // namespace dart
|
|
|