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