Index: src/arm/macro-assembler-arm.cc |
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc |
index a56744bf597a245a0afed0b4b1a64b38d1a4cd0c..4e280215851b6f29ad075c1ab9883f3f5f939807 100644 |
--- a/src/arm/macro-assembler-arm.cc |
+++ b/src/arm/macro-assembler-arm.cc |
@@ -1702,15 +1702,9 @@ void MacroAssembler::Allocate(int object_size, |
ASSERT((limit - top) == kPointerSize); |
ASSERT(result.code() < ip.code()); |
- // Set up allocation top address and object size registers. |
+ // Set up allocation top address register. |
Register topaddr = scratch1; |
- Register obj_size_reg = scratch2; |
mov(topaddr, Operand(allocation_top)); |
- Operand obj_size_operand = Operand(object_size); |
- if (!obj_size_operand.is_single_instruction(this)) { |
- // We are about to steal IP, so we need to load this value first |
- mov(obj_size_reg, obj_size_operand); |
- } |
// This code stores a temporary value in ip. This is OK, as the code below |
// does not need ip for implicit literal generation. |
@@ -1734,7 +1728,7 @@ void MacroAssembler::Allocate(int object_size, |
// Align the next allocation. Storing the filler map without checking top is |
// always safe because the limit of the heap is always aligned. |
ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); |
- ASSERT(kPointerAlignment * 2 == kDoubleAlignment); |
+ STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment); |
and_(scratch2, result, Operand(kDoubleAlignmentMask), SetCC); |
Label aligned; |
b(eq, &aligned); |
@@ -1744,13 +1738,25 @@ void MacroAssembler::Allocate(int object_size, |
} |
// Calculate new top and bail out if new space is exhausted. Use result |
- // to calculate the new top. |
- if (obj_size_operand.is_single_instruction(this)) { |
- // We can add the size as an immediate |
- add(scratch2, result, obj_size_operand, SetCC); |
- } else { |
- // Doesn't fit in an immediate, we have to use the register |
- add(scratch2, result, obj_size_reg, SetCC); |
+ // to calculate the new top. We must preserve the ip register at this |
+ // point, so we cannot just use add(). |
+ ASSERT(object_size > 0); |
+ Register source = result; |
+ Condition cond = al; |
+ int shift = 0; |
+ while (object_size != 0) { |
+ if (((object_size >> shift) & 0x03) == 0) { |
+ shift += 2; |
+ } else { |
+ int bits = object_size & (0xff << shift); |
+ object_size -= bits; |
+ shift += 8; |
+ Operand bits_operand(bits); |
+ ASSERT(bits_operand.is_single_instruction(this)); |
+ add(scratch2, source, bits_operand, SetCC, cond); |
+ source = scratch2; |
+ cond = cc; |
+ } |
} |
b(cs, gc_required); |
cmp(scratch2, Operand(ip)); |