Chromium Code Reviews| Index: runtime/vm/intrinsifier_arm64.cc |
| diff --git a/runtime/vm/intrinsifier_arm64.cc b/runtime/vm/intrinsifier_arm64.cc |
| index f400c02a1fb5b7e2fa1b797be44d72203a37e629..0d1947a3840c740f1de8b0bd4232cf2265ff080c 100644 |
| --- a/runtime/vm/intrinsifier_arm64.cc |
| +++ b/runtime/vm/intrinsifier_arm64.cc |
| @@ -196,8 +196,9 @@ static int GetScaleFactor(intptr_t size) { |
| __ CompareImmediate(R2, max_len); \ |
| __ b(&fall_through, GT); \ |
| __ LslImmediate(R2, R2, scale_shift); \ |
| - const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \ |
| - __ AddImmediate(R2, fixed_size); \ |
| + const intptr_t fixed_size_plus_alignment_padding = \ |
| + sizeof(Raw##type_name) + kObjectAlignment - 1; \ |
| + __ AddImmediate(R2, fixed_size_plus_alignment_padding); \ |
| __ andi(R2, R2, Immediate(~(kObjectAlignment - 1))); \ |
| Heap::Space space = Heap::kNew; \ |
| __ ldr(R3, Address(THR, Thread::heap_offset())); \ |
| @@ -1822,7 +1823,8 @@ void Intrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler) { |
| void Intrinsifier::String_getHashCode(Assembler* assembler) { |
| Label fall_through; |
| __ ldr(R0, Address(SP, 0 * kWordSize)); |
| - __ ldr(R0, FieldAddress(R0, String::hash_offset())); |
| + __ ldr(R0, FieldAddress(R0, String::hash_offset()), kUnsignedWord); |
| + __ SmiTag(R0); |
|
Vyacheslav Egorov (Google)
2017/05/18 06:14:42
if you use something that sets flags for tagging y
erikcorry
2017/05/18 14:28:38
Done.
|
| __ CompareRegisters(R0, ZR); |
| __ b(&fall_through, EQ); |
| __ ret(); |
| @@ -1995,7 +1997,8 @@ void Intrinsifier::StringBaseIsEmpty(Assembler* assembler) { |
| void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) { |
| Label compute_hash; |
| __ ldr(R1, Address(SP, 0 * kWordSize)); // OneByteString object. |
| - __ ldr(R0, FieldAddress(R1, String::hash_offset())); |
| + __ ldr(R0, FieldAddress(R1, String::hash_offset()), kUnsignedWord); |
| + __ SmiTag(R0); |
| __ CompareRegisters(R0, ZR); |
| __ b(&compute_hash, EQ); |
| __ ret(); // Return if already computed. |
| @@ -2046,8 +2049,8 @@ void Intrinsifier::OneByteString_getHashCode(Assembler* assembler) { |
| // return hash_ == 0 ? 1 : hash_; |
| __ Bind(&done); |
| __ csinc(R0, R0, ZR, NE); // R0 <- (R0 != 0) ? R0 : (ZR + 1). |
| + __ str(R0, FieldAddress(R1, String::hash_offset()), kUnsignedWord); |
| __ SmiTag(R0); |
| - __ str(R0, FieldAddress(R1, String::hash_offset())); |
| __ ret(); |
| } |
| @@ -2060,13 +2063,21 @@ static void TryAllocateOnebyteString(Assembler* assembler, |
| Label* ok, |
| Label* failure) { |
| const Register length_reg = R2; |
| - Label fail; |
| + Label fail, not_zero_length; |
| NOT_IN_PRODUCT(__ MaybeTraceAllocation(kOneByteStringCid, R0, failure)); |
| __ mov(R6, length_reg); // Save the length register. |
| // TODO(koda): Protect against negative length and overflow here. |
| - __ SmiUntag(length_reg); |
| - const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1; |
| - __ AddImmediate(length_reg, fixed_size); |
| + __ adds(length_reg, ZR, Operand(length_reg, ASR, kSmiTagSize)); // Smi untag. |
| + // If the length is 0 then we have to make the allocated size a bit bigger, |
| + // otherwise the string takes up less space than an ExternalOneByteString, |
| + // and cannot be externalized. TODO(erikcorry): We should probably just |
| + // return a static zero length string here instead. |
| + __ b(¬_zero_length, NE); |
| + __ AddImmediate(length_reg, 1); |
|
Vyacheslav Egorov (Google)
2017/05/18 06:14:42
maybe conditional add() here instead of branching?
erikcorry
2017/05/18 14:28:38
Done.
|
| + __ Bind(¬_zero_length); |
| + const intptr_t fixed_size_plus_alignment_padding = |
| + sizeof(RawString) + kObjectAlignment - 1; |
| + __ AddImmediate(length_reg, fixed_size_plus_alignment_padding); |
| __ andi(length_reg, length_reg, Immediate(~(kObjectAlignment - 1))); |
| const intptr_t cid = kOneByteStringCid; |
| @@ -2106,6 +2117,7 @@ static void TryAllocateOnebyteString(Assembler* assembler, |
| // Get the class index and insert it into the tags. |
| // R2: size and bit tags. |
| + // This also clears the hash, which is in the high word of the tags. |
| __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid)); |
| __ orr(R2, R2, Operand(TMP)); |
| __ str(R2, FieldAddress(R0, String::tags_offset())); // Store tags. |
| @@ -2114,9 +2126,6 @@ static void TryAllocateOnebyteString(Assembler* assembler, |
| // Set the length field using the saved length (R6). |
| __ StoreIntoObjectNoBarrier(R0, FieldAddress(R0, String::length_offset()), |
| R6); |
| - // Clear hash. |
| - __ mov(TMP, ZR); |
| - __ str(TMP, FieldAddress(R0, String::hash_offset())); |
| __ b(ok); |
| __ Bind(&fail); |