Chromium Code Reviews| Index: runtime/vm/intrinsifier_x64.cc |
| =================================================================== |
| --- runtime/vm/intrinsifier_x64.cc (revision 22374) |
| +++ 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) { |
| + __ movl(RDI, length_reg); |
|
siva
2013/05/03 23:05:01
movq instead of movl.
srdjan
2013/05/03 23:36:37
Done.
|
| + } |
| + 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 |