| 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));
|
|
|