Improve code generated for AllocInNewSpace. This is a commit of http://codereview.chromium.org/5512004 for Rodolph Perfetta.
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5917 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
fb93e5bc36
commit
bca83462d8
@ -920,6 +920,7 @@ void MacroAssembler::AllocateInNewSpace(int object_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(!result.is(scratch1));
|
ASSERT(!result.is(scratch1));
|
||||||
|
ASSERT(!result.is(scratch2));
|
||||||
ASSERT(!scratch1.is(scratch2));
|
ASSERT(!scratch1.is(scratch2));
|
||||||
|
|
||||||
// Make object size into bytes.
|
// Make object size into bytes.
|
||||||
@ -928,38 +929,55 @@ void MacroAssembler::AllocateInNewSpace(int object_size,
|
|||||||
}
|
}
|
||||||
ASSERT_EQ(0, object_size & kObjectAlignmentMask);
|
ASSERT_EQ(0, object_size & kObjectAlignmentMask);
|
||||||
|
|
||||||
// Load address of new object into result and allocation top address into
|
// Check relative positions of allocation top and limit addresses.
|
||||||
// scratch1.
|
// The values must be adjacent in memory to allow the use of LDM.
|
||||||
|
// Also, assert that the registers are numbered such that the values
|
||||||
|
// are loaded in the correct order.
|
||||||
ExternalReference new_space_allocation_top =
|
ExternalReference new_space_allocation_top =
|
||||||
ExternalReference::new_space_allocation_top_address();
|
ExternalReference::new_space_allocation_top_address();
|
||||||
mov(scratch1, Operand(new_space_allocation_top));
|
ExternalReference new_space_allocation_limit =
|
||||||
|
ExternalReference::new_space_allocation_limit_address();
|
||||||
|
intptr_t top =
|
||||||
|
reinterpret_cast<intptr_t>(new_space_allocation_top.address());
|
||||||
|
intptr_t limit =
|
||||||
|
reinterpret_cast<intptr_t>(new_space_allocation_limit.address());
|
||||||
|
ASSERT((limit - top) == kPointerSize);
|
||||||
|
ASSERT(result.code() < ip.code());
|
||||||
|
|
||||||
|
// Set up allocation top address and object size registers.
|
||||||
|
Register topaddr = scratch1;
|
||||||
|
Register obj_size_reg = scratch2;
|
||||||
|
mov(topaddr, Operand(new_space_allocation_top));
|
||||||
|
mov(obj_size_reg, Operand(object_size));
|
||||||
|
|
||||||
|
// This code stores a temporary value in ip. This is OK, as the code below
|
||||||
|
// does not need ip for implicit literal generation.
|
||||||
if ((flags & RESULT_CONTAINS_TOP) == 0) {
|
if ((flags & RESULT_CONTAINS_TOP) == 0) {
|
||||||
ldr(result, MemOperand(scratch1));
|
// Load allocation top into result and allocation limit into ip.
|
||||||
} else if (FLAG_debug_code) {
|
ldm(ia, topaddr, result.bit() | ip.bit());
|
||||||
// Assert that result actually contains top on entry. scratch2 is used
|
} else {
|
||||||
// immediately below so this use of scratch2 does not cause difference with
|
if (FLAG_debug_code) {
|
||||||
|
// Assert that result actually contains top on entry. ip is used
|
||||||
|
// immediately below so this use of ip does not cause difference with
|
||||||
// respect to register content between debug and release mode.
|
// respect to register content between debug and release mode.
|
||||||
ldr(scratch2, MemOperand(scratch1));
|
ldr(ip, MemOperand(topaddr));
|
||||||
cmp(result, scratch2);
|
cmp(result, ip);
|
||||||
Check(eq, "Unexpected allocation top");
|
Check(eq, "Unexpected allocation top");
|
||||||
}
|
}
|
||||||
|
// Load allocation limit into ip. Result already contains allocation top.
|
||||||
|
ldr(ip, MemOperand(topaddr, limit - top));
|
||||||
|
}
|
||||||
|
|
||||||
// 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.
|
||||||
ExternalReference new_space_allocation_limit =
|
add(scratch2, result, Operand(obj_size_reg));
|
||||||
ExternalReference::new_space_allocation_limit_address();
|
cmp(scratch2, Operand(ip));
|
||||||
mov(scratch2, Operand(new_space_allocation_limit));
|
|
||||||
ldr(scratch2, MemOperand(scratch2));
|
|
||||||
add(result, result, Operand(object_size));
|
|
||||||
cmp(result, Operand(scratch2));
|
|
||||||
b(hi, gc_required);
|
b(hi, gc_required);
|
||||||
str(result, MemOperand(scratch1));
|
str(scratch2, MemOperand(topaddr));
|
||||||
|
|
||||||
// Tag and adjust back to start of new object.
|
// Tag object if requested.
|
||||||
if ((flags & TAG_OBJECT) != 0) {
|
if ((flags & TAG_OBJECT) != 0) {
|
||||||
sub(result, result, Operand(object_size - kHeapObjectTag));
|
add(result, result, Operand(kHeapObjectTag));
|
||||||
} else {
|
|
||||||
sub(result, result, Operand(object_size));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -982,52 +1000,63 @@ void MacroAssembler::AllocateInNewSpace(Register object_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(!result.is(scratch1));
|
ASSERT(!result.is(scratch1));
|
||||||
|
ASSERT(!result.is(scratch2));
|
||||||
ASSERT(!scratch1.is(scratch2));
|
ASSERT(!scratch1.is(scratch2));
|
||||||
|
|
||||||
// Load address of new object into result and allocation top address into
|
// Check relative positions of allocation top and limit addresses.
|
||||||
// scratch1.
|
// The values must be adjacent in memory to allow the use of LDM.
|
||||||
|
// Also, assert that the registers are numbered such that the values
|
||||||
|
// are loaded in the correct order.
|
||||||
ExternalReference new_space_allocation_top =
|
ExternalReference new_space_allocation_top =
|
||||||
ExternalReference::new_space_allocation_top_address();
|
ExternalReference::new_space_allocation_top_address();
|
||||||
mov(scratch1, Operand(new_space_allocation_top));
|
ExternalReference new_space_allocation_limit =
|
||||||
|
ExternalReference::new_space_allocation_limit_address();
|
||||||
|
intptr_t top =
|
||||||
|
reinterpret_cast<intptr_t>(new_space_allocation_top.address());
|
||||||
|
intptr_t limit =
|
||||||
|
reinterpret_cast<intptr_t>(new_space_allocation_limit.address());
|
||||||
|
ASSERT((limit - top) == kPointerSize);
|
||||||
|
ASSERT(result.code() < ip.code());
|
||||||
|
|
||||||
|
// Set up allocation top address.
|
||||||
|
Register topaddr = scratch1;
|
||||||
|
mov(topaddr, Operand(new_space_allocation_top));
|
||||||
|
|
||||||
|
// This code stores a temporary value in ip. This is OK, as the code below
|
||||||
|
// does not need ip for implicit literal generation.
|
||||||
if ((flags & RESULT_CONTAINS_TOP) == 0) {
|
if ((flags & RESULT_CONTAINS_TOP) == 0) {
|
||||||
ldr(result, MemOperand(scratch1));
|
// Load allocation top into result and allocation limit into ip.
|
||||||
} else if (FLAG_debug_code) {
|
ldm(ia, topaddr, result.bit() | ip.bit());
|
||||||
// Assert that result actually contains top on entry. scratch2 is used
|
} else {
|
||||||
// immediately below so this use of scratch2 does not cause difference with
|
if (FLAG_debug_code) {
|
||||||
|
// Assert that result actually contains top on entry. ip is used
|
||||||
|
// immediately below so this use of ip does not cause difference with
|
||||||
// respect to register content between debug and release mode.
|
// respect to register content between debug and release mode.
|
||||||
ldr(scratch2, MemOperand(scratch1));
|
ldr(ip, MemOperand(topaddr));
|
||||||
cmp(result, scratch2);
|
cmp(result, ip);
|
||||||
Check(eq, "Unexpected allocation top");
|
Check(eq, "Unexpected allocation top");
|
||||||
}
|
}
|
||||||
|
// Load allocation limit into ip. Result already contains allocation top.
|
||||||
|
ldr(ip, MemOperand(topaddr, limit - top));
|
||||||
|
}
|
||||||
|
|
||||||
// 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. Object size is in words so a shift is required to
|
// to calculate the new top. Object size may be in words so a shift is
|
||||||
// get the number of bytes
|
// required to get the number of bytes.
|
||||||
ExternalReference new_space_allocation_limit =
|
|
||||||
ExternalReference::new_space_allocation_limit_address();
|
|
||||||
mov(scratch2, Operand(new_space_allocation_limit));
|
|
||||||
ldr(scratch2, MemOperand(scratch2));
|
|
||||||
if ((flags & SIZE_IN_WORDS) != 0) {
|
if ((flags & SIZE_IN_WORDS) != 0) {
|
||||||
add(result, result, Operand(object_size, LSL, kPointerSizeLog2));
|
add(scratch2, result, Operand(object_size, LSL, kPointerSizeLog2));
|
||||||
} else {
|
} else {
|
||||||
add(result, result, Operand(object_size));
|
add(scratch2, result, Operand(object_size));
|
||||||
}
|
}
|
||||||
cmp(result, Operand(scratch2));
|
cmp(scratch2, Operand(ip));
|
||||||
b(hi, gc_required);
|
b(hi, gc_required);
|
||||||
|
|
||||||
// Update allocation top. result temporarily holds the new top.
|
// Update allocation top. result temporarily holds the new top.
|
||||||
if (FLAG_debug_code) {
|
if (FLAG_debug_code) {
|
||||||
tst(result, Operand(kObjectAlignmentMask));
|
tst(scratch2, Operand(kObjectAlignmentMask));
|
||||||
Check(eq, "Unaligned allocation in new space");
|
Check(eq, "Unaligned allocation in new space");
|
||||||
}
|
}
|
||||||
str(result, MemOperand(scratch1));
|
str(scratch2, MemOperand(topaddr));
|
||||||
|
|
||||||
// Adjust back to start of new object.
|
|
||||||
if ((flags & SIZE_IN_WORDS) != 0) {
|
|
||||||
sub(result, result, Operand(object_size, LSL, kPointerSizeLog2));
|
|
||||||
} else {
|
|
||||||
sub(result, result, Operand(object_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tag object if requested.
|
// Tag object if requested.
|
||||||
if ((flags & TAG_OBJECT) != 0) {
|
if ((flags & TAG_OBJECT) != 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user