Commit a0449051 authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

ARM: Fix register misuse bug in Allocate().

The bug is triggered if flags contains DOUBLE_ALIGNMENT and the
object_size is not an ARM immediate value. In this case, the code
for DOUBLE_ALIGNMENT uses the scratch2 register, which is aliased
to obj_size_reg containing the object_size.

Instead of pre-loading the object_size, which is difficult since
we are out of registers here, we simply generate a non-empty
sequence of add instructions for the addition of the constant
object_size (carefully handling possible overflow in each step).

Also turn static ASSERT into STATIC_ASSERT in Allocate().

BUG=v8:2851
R=svenpanne@chromium.org

Review URL: https://codereview.chromium.org/23323002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16221 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 665a6d8a
......@@ -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));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment