Index: src/mips64/macro-assembler-mips64.cc |
diff --git a/src/mips64/macro-assembler-mips64.cc b/src/mips64/macro-assembler-mips64.cc |
index 5fe691bc5c20466aa52b21a37c50f2008ab63bfc..5af7792120c80186ad5fd15d55b1e66265487b13 100644 |
--- a/src/mips64/macro-assembler-mips64.cc |
+++ b/src/mips64/macro-assembler-mips64.cc |
@@ -3504,12 +3504,7 @@ void MacroAssembler::Allocate(int object_size, |
return; |
} |
- DCHECK(!result.is(scratch1)); |
- DCHECK(!result.is(scratch2)); |
- DCHECK(!scratch1.is(scratch2)); |
- DCHECK(!scratch1.is(t9)); |
- DCHECK(!scratch2.is(t9)); |
- DCHECK(!result.is(t9)); |
+ DCHECK(!AreAliased(result, scratch1, scratch2, t9)); |
// Make object size into bytes. |
if ((flags & SIZE_IN_WORDS) != 0) { |
@@ -3525,34 +3520,35 @@ void MacroAssembler::Allocate(int object_size, |
ExternalReference allocation_limit = |
AllocationUtils::GetAllocationLimitReference(isolate(), flags); |
- intptr_t top = |
- reinterpret_cast<intptr_t>(allocation_top.address()); |
- intptr_t limit = |
- reinterpret_cast<intptr_t>(allocation_limit.address()); |
+ intptr_t top = reinterpret_cast<intptr_t>(allocation_top.address()); |
+ intptr_t limit = reinterpret_cast<intptr_t>(allocation_limit.address()); |
DCHECK((limit - top) == kPointerSize); |
- // Set up allocation top address and object size registers. |
- Register topaddr = scratch1; |
- li(topaddr, Operand(allocation_top)); |
- |
+ // Set up allocation top address and allocation limit registers. |
+ Register top_address = scratch1; |
// This code stores a temporary value in t9. |
+ Register alloc_limit = t9; |
+ Register result_end = scratch2; |
+ li(top_address, Operand(allocation_top)); |
+ |
if ((flags & RESULT_CONTAINS_TOP) == 0) { |
- // Load allocation top into result and allocation limit into t9. |
- ld(result, MemOperand(topaddr)); |
- ld(t9, MemOperand(topaddr, kPointerSize)); |
+ // Load allocation top into result and allocation limit into alloc_limit. |
+ ld(result, MemOperand(top_address)); |
+ ld(alloc_limit, MemOperand(top_address, kPointerSize)); |
} else { |
if (emit_debug_code()) { |
- // Assert that result actually contains top on entry. t9 is used |
- // immediately below so this use of t9 does not cause difference with |
- // respect to register content between debug and release mode. |
- ld(t9, MemOperand(topaddr)); |
- Check(eq, kUnexpectedAllocationTop, result, Operand(t9)); |
+ // Assert that result actually contains top on entry. |
+ ld(alloc_limit, MemOperand(top_address)); |
+ Check(eq, kUnexpectedAllocationTop, result, Operand(alloc_limit)); |
} |
- // Load allocation limit into t9. Result already contains allocation top. |
- ld(t9, MemOperand(topaddr, static_cast<int32_t>(limit - top))); |
+ // Load allocation limit. Result already contains allocation top. |
+ ld(alloc_limit, MemOperand(top_address, static_cast<int32_t>(limit - top))); |
} |
- DCHECK(kPointerSize == kDoubleSize); |
+ // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have |
+ // the same alignment on ARM64. |
+ STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); |
+ |
if (emit_debug_code()) { |
And(at, result, Operand(kDoubleAlignmentMask)); |
Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg)); |
@@ -3560,9 +3556,9 @@ void MacroAssembler::Allocate(int object_size, |
// Calculate new top and bail out if new space is exhausted. Use result |
// to calculate the new top. |
- Daddu(scratch2, result, Operand(object_size)); |
- Branch(gc_required, Ugreater, scratch2, Operand(t9)); |
- sd(scratch2, MemOperand(topaddr)); |
+ Daddu(result_end, result, Operand(object_size)); |
+ Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); |
+ sd(result_end, MemOperand(top_address)); |
// Tag object if requested. |
if ((flags & TAG_OBJECT) != 0) { |
@@ -3585,11 +3581,9 @@ void MacroAssembler::Allocate(Register object_size, Register result, |
return; |
} |
- DCHECK(!result.is(scratch)); |
- DCHECK(!result.is(result_end)); |
- DCHECK(!scratch.is(result_end)); |
- DCHECK(!object_size.is(t9)); |
- DCHECK(!scratch.is(t9) && !result_end.is(t9) && !result.is(t9)); |
+ // |object_size| and |result_end| may overlap, other registers must not. |
+ DCHECK(!AreAliased(object_size, result, scratch, t9)); |
+ DCHECK(!AreAliased(result_end, result, scratch, t9)); |
// Check relative positions of allocation top and limit addresses. |
// ARM adds additional checks to make sure the ldm instruction can be |
@@ -3598,34 +3592,34 @@ void MacroAssembler::Allocate(Register object_size, Register result, |
AllocationUtils::GetAllocationTopReference(isolate(), flags); |
ExternalReference allocation_limit = |
AllocationUtils::GetAllocationLimitReference(isolate(), flags); |
- intptr_t top = |
- reinterpret_cast<intptr_t>(allocation_top.address()); |
- intptr_t limit = |
- reinterpret_cast<intptr_t>(allocation_limit.address()); |
+ intptr_t top = reinterpret_cast<intptr_t>(allocation_top.address()); |
+ intptr_t limit = reinterpret_cast<intptr_t>(allocation_limit.address()); |
DCHECK((limit - top) == kPointerSize); |
// Set up allocation top address and object size registers. |
- Register topaddr = scratch; |
- li(topaddr, Operand(allocation_top)); |
- |
+ Register top_address = scratch; |
// This code stores a temporary value in t9. |
+ Register alloc_limit = t9; |
+ li(top_address, Operand(allocation_top)); |
+ |
if ((flags & RESULT_CONTAINS_TOP) == 0) { |
- // Load allocation top into result and allocation limit into t9. |
- ld(result, MemOperand(topaddr)); |
- ld(t9, MemOperand(topaddr, kPointerSize)); |
+ // Load allocation top into result and allocation limit into alloc_limit. |
+ ld(result, MemOperand(top_address)); |
+ ld(alloc_limit, MemOperand(top_address, kPointerSize)); |
} else { |
if (emit_debug_code()) { |
- // Assert that result actually contains top on entry. t9 is used |
- // immediately below so this use of t9 does not cause difference with |
- // respect to register content between debug and release mode. |
- ld(t9, MemOperand(topaddr)); |
- Check(eq, kUnexpectedAllocationTop, result, Operand(t9)); |
+ // Assert that result actually contains top on entry. |
+ ld(alloc_limit, MemOperand(top_address)); |
+ Check(eq, kUnexpectedAllocationTop, result, Operand(alloc_limit)); |
} |
- // Load allocation limit into t9. Result already contains allocation top. |
- ld(t9, MemOperand(topaddr, static_cast<int32_t>(limit - top))); |
+ // Load allocation limit. Result already contains allocation top. |
+ ld(alloc_limit, MemOperand(top_address, static_cast<int32_t>(limit - top))); |
} |
- DCHECK(kPointerSize == kDoubleSize); |
+ // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have |
+ // the same alignment on ARM64. |
+ STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); |
+ |
if (emit_debug_code()) { |
And(at, result, Operand(kDoubleAlignmentMask)); |
Check(eq, kAllocationIsNotDoubleAligned, at, Operand(zero_reg)); |
@@ -3640,14 +3634,14 @@ void MacroAssembler::Allocate(Register object_size, Register result, |
} else { |
Daddu(result_end, result, Operand(object_size)); |
} |
- Branch(gc_required, Ugreater, result_end, Operand(t9)); |
+ Branch(gc_required, Ugreater, result_end, Operand(alloc_limit)); |
// Update allocation top. result temporarily holds the new top. |
if (emit_debug_code()) { |
- And(t9, result_end, Operand(kObjectAlignmentMask)); |
- Check(eq, kUnalignedAllocationInNewSpace, t9, Operand(zero_reg)); |
+ And(at, result_end, Operand(kObjectAlignmentMask)); |
+ Check(eq, kUnalignedAllocationInNewSpace, at, Operand(zero_reg)); |
} |
- sd(result_end, MemOperand(topaddr)); |
+ sd(result_end, MemOperand(top_address)); |
// Tag object if requested. |
if ((flags & TAG_OBJECT) != 0) { |