Revision: 16221
Author: [email protected]
Date: Mon Aug 19 13:37:57 2013 UTC
Log: 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
[email protected]
Review URL: https://codereview.chromium.org/23323002
http://code.google.com/p/v8/source/detail?r=16221
Modified:
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Fri Aug 9
13:43:46 2013 UTC
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Mon Aug 19
13:37:57 2013 UTC
@@ -1702,15 +1702,9 @@
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 @@
// 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 @@
}
// 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));
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.