Index: src/arm/macro-assembler-arm.cc |
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc |
index 744a9c394b567cfed52f41bb2b41291a894f2045..45fe0cc51fd3f2e980d56d77b7b1470c568e3b55 100644 |
--- a/src/arm/macro-assembler-arm.cc |
+++ b/src/arm/macro-assembler-arm.cc |
@@ -1652,11 +1652,7 @@ void MacroAssembler::Allocate(int object_size, |
return; |
} |
- DCHECK(!result.is(scratch1)); |
- DCHECK(!result.is(scratch2)); |
- DCHECK(!scratch1.is(scratch2)); |
- DCHECK(!scratch1.is(ip)); |
- DCHECK(!scratch2.is(ip)); |
+ DCHECK(!AreAliased(result, scratch1, scratch2, ip)); |
// Make object size into bytes. |
if ((flags & SIZE_IN_WORDS) != 0) { |
@@ -1673,48 +1669,46 @@ 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); |
DCHECK(result.code() < ip.code()); |
// Set up allocation top address register. |
- Register topaddr = scratch1; |
- mov(topaddr, Operand(allocation_top)); |
- |
+ Register top_address = scratch1; |
// This code stores a temporary value in ip. This is OK, as the code below |
// does not need ip for implicit literal generation. |
+ Register alloc_limit = ip; |
+ Register result_end = scratch2; |
+ mov(top_address, Operand(allocation_top)); |
+ |
if ((flags & RESULT_CONTAINS_TOP) == 0) { |
- // Load allocation top into result and allocation limit into ip. |
- ldm(ia, topaddr, result.bit() | ip.bit()); |
+ // Load allocation top into result and allocation limit into alloc_limit. |
+ ldm(ia, top_address, result.bit() | alloc_limit.bit()); |
} else { |
if (emit_debug_code()) { |
- // Assert that result actually contains top on entry. ip is used |
- // immediately below so this use of ip does not cause difference with |
- // respect to register content between debug and release mode. |
- ldr(ip, MemOperand(topaddr)); |
- cmp(result, ip); |
+ // Assert that result actually contains top on entry. |
+ ldr(alloc_limit, MemOperand(top_address)); |
+ cmp(result, alloc_limit); |
Check(eq, kUnexpectedAllocationTop); |
} |
- // Load allocation limit into ip. Result already contains allocation top. |
- ldr(ip, MemOperand(topaddr, limit - top)); |
+ // Load allocation limit. Result already contains allocation top. |
+ ldr(alloc_limit, MemOperand(top_address, limit - top)); |
} |
if ((flags & DOUBLE_ALIGNMENT) != 0) { |
// Align the next allocation. Storing the filler map without checking top is |
// safe in new-space because the limit of the heap is aligned there. |
STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment); |
- and_(scratch2, result, Operand(kDoubleAlignmentMask), SetCC); |
+ and_(result_end, result, Operand(kDoubleAlignmentMask), SetCC); |
Label aligned; |
b(eq, &aligned); |
if ((flags & PRETENURE) != 0) { |
- cmp(result, Operand(ip)); |
+ cmp(result, Operand(alloc_limit)); |
b(hs, gc_required); |
} |
- mov(scratch2, Operand(isolate()->factory()->one_pointer_filler_map())); |
- str(scratch2, MemOperand(result, kDoubleSize / 2, PostIndex)); |
+ mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); |
+ str(result_end, MemOperand(result, kDoubleSize / 2, PostIndex)); |
bind(&aligned); |
} |
@@ -1734,15 +1728,15 @@ void MacroAssembler::Allocate(int object_size, |
shift += 8; |
Operand bits_operand(bits); |
DCHECK(bits_operand.instructions_required(this) == 1); |
- add(scratch2, source, bits_operand, SetCC, cond); |
- source = scratch2; |
+ add(result_end, source, bits_operand, SetCC, cond); |
+ source = result_end; |
cond = cc; |
} |
} |
b(cs, gc_required); |
- cmp(scratch2, Operand(ip)); |
+ cmp(result_end, Operand(alloc_limit)); |
b(hi, gc_required); |
- str(scratch2, MemOperand(topaddr)); |
+ str(result_end, MemOperand(top_address)); |
// Tag object if requested. |
if ((flags & TAG_OBJECT) != 0) { |
@@ -1765,15 +1759,11 @@ void MacroAssembler::Allocate(Register object_size, Register result, |
return; |
} |
- // Assert that the register arguments are different and that none of |
- // them are ip. ip is used explicitly in the code generated below. |
- DCHECK(!result.is(scratch)); |
- DCHECK(!result.is(result_end)); |
- DCHECK(!scratch.is(result_end)); |
- DCHECK(!object_size.is(ip)); |
- DCHECK(!result.is(ip)); |
- DCHECK(!scratch.is(ip)); |
- DCHECK(!result_end.is(ip)); |
+ // |object_size| and |result_end| may overlap if the DOUBLE_ALIGNMENT flag |
+ // is not specified. Other registers must not overlap. |
+ DCHECK(!AreAliased(object_size, result, scratch, ip)); |
+ DCHECK(!AreAliased(result_end, result, scratch, ip)); |
+ DCHECK((flags & DOUBLE_ALIGNMENT) == 0 || !object_size.is(result_end)); |
// Check relative positions of allocation top and limit addresses. |
// The values must be adjacent in memory to allow the use of LDM. |
@@ -1783,33 +1773,30 @@ 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); |
DCHECK(result.code() < ip.code()); |
- // Set up allocation top address. |
- Register topaddr = scratch; |
- mov(topaddr, Operand(allocation_top)); |
- |
+ // Set up allocation top address and allocation limit registers. |
+ Register top_address = scratch; |
// This code stores a temporary value in ip. This is OK, as the code below |
// does not need ip for implicit literal generation. |
+ Register alloc_limit = ip; |
+ mov(top_address, Operand(allocation_top)); |
+ |
if ((flags & RESULT_CONTAINS_TOP) == 0) { |
- // Load allocation top into result and allocation limit into ip. |
- ldm(ia, topaddr, result.bit() | ip.bit()); |
+ // Load allocation top into result and allocation limit into alloc_limit. |
+ ldm(ia, top_address, result.bit() | alloc_limit.bit()); |
} else { |
if (emit_debug_code()) { |
- // Assert that result actually contains top on entry. ip is used |
- // immediately below so this use of ip does not cause difference with |
- // respect to register content between debug and release mode. |
- ldr(ip, MemOperand(topaddr)); |
- cmp(result, ip); |
+ // Assert that result actually contains top on entry. |
+ ldr(alloc_limit, MemOperand(top_address)); |
+ cmp(result, alloc_limit); |
Check(eq, kUnexpectedAllocationTop); |
} |
- // Load allocation limit into ip. Result already contains allocation top. |
- ldr(ip, MemOperand(topaddr, limit - top)); |
+ // Load allocation limit. Result already contains allocation top. |
+ ldr(alloc_limit, MemOperand(top_address, limit - top)); |
} |
if ((flags & DOUBLE_ALIGNMENT) != 0) { |
@@ -1820,7 +1807,7 @@ void MacroAssembler::Allocate(Register object_size, Register result, |
Label aligned; |
b(eq, &aligned); |
if ((flags & PRETENURE) != 0) { |
- cmp(result, Operand(ip)); |
+ cmp(result, Operand(alloc_limit)); |
b(hs, gc_required); |
} |
mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); |
@@ -1837,7 +1824,7 @@ void MacroAssembler::Allocate(Register object_size, Register result, |
add(result_end, result, Operand(object_size), SetCC); |
} |
b(cs, gc_required); |
- cmp(result_end, Operand(ip)); |
+ cmp(result_end, Operand(alloc_limit)); |
b(hi, gc_required); |
// Update allocation top. result temporarily holds the new top. |
@@ -1845,7 +1832,7 @@ void MacroAssembler::Allocate(Register object_size, Register result, |
tst(result_end, Operand(kObjectAlignmentMask)); |
Check(eq, kUnalignedAllocationInNewSpace); |
} |
- str(result_end, MemOperand(topaddr)); |
+ str(result_end, MemOperand(top_address)); |
// Tag object if requested. |
if ((flags & TAG_OBJECT) != 0) { |