Commit 62e9956c authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Move object allocation in new space to macro assembler

Currently allocation in generated code on ARM is only used for allocating heap numbers. This change factors this out for use in upcomming changes.
Review URL: http://codereview.chromium.org/173625

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2789 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 90abdd28
......@@ -4945,36 +4945,21 @@ void CompareStub::Generate(MacroAssembler* masm) {
static void AllocateHeapNumber(
MacroAssembler* masm,
Label* need_gc, // Jump here if young space is full.
Register result_reg, // The tagged address of the new heap number.
Register allocation_top_addr_reg, // A scratch register.
Register result, // The tagged address of the new heap number.
Register scratch1, // A scratch register.
Register scratch2) { // Another scratch register.
ExternalReference allocation_top =
ExternalReference::new_space_allocation_top_address();
ExternalReference allocation_limit =
ExternalReference::new_space_allocation_limit_address();
// allocat := the address of the allocation top variable.
__ mov(allocation_top_addr_reg, Operand(allocation_top));
// result_reg := the old allocation top.
__ ldr(result_reg, MemOperand(allocation_top_addr_reg));
// scratch2 := the address of the allocation limit.
__ mov(scratch2, Operand(allocation_limit));
// scratch2 := the allocation limit.
__ ldr(scratch2, MemOperand(scratch2));
// result_reg := the new allocation top.
__ add(result_reg, result_reg, Operand(HeapNumber::kSize));
// Compare new new allocation top and limit.
__ cmp(result_reg, Operand(scratch2));
// Branch if out of space in young generation.
__ b(hi, need_gc);
// Store new allocation top.
__ str(result_reg, MemOperand(allocation_top_addr_reg)); // store new top
// Tag and adjust back to start of new object.
__ sub(result_reg, result_reg, Operand(HeapNumber::kSize - kHeapObjectTag));
// Get heap number map into scratch2.
__ LoadRoot(scratch2, Heap::kHeapNumberMapRootIndex);
// Store heap number map in new object.
__ str(scratch2, FieldMemOperand(result_reg, HeapObject::kMapOffset));
// Allocate an object in the heap for the heap number and tag it as a heap
// object.
__ AllocateObjectInNewSpace(HeapNumber::kSize,
result,
scratch1,
scratch2,
need_gc,
true);
// Get heap number map and store it in the allocated object.
__ LoadRoot(scratch1, Heap::kHeapNumberMapRootIndex);
__ str(scratch1, FieldMemOperand(result, HeapObject::kMapOffset));
}
......
......@@ -768,6 +768,44 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
}
void MacroAssembler::AllocateObjectInNewSpace(int object_size,
Register result,
Register scratch1,
Register scratch2,
Label* gc_required,
bool tag_allocated_object) {
ASSERT(!result.is(scratch1));
ASSERT(!scratch1.is(scratch2));
// Load address of new object into result and allocation top address into
// scratch1.
ExternalReference new_space_allocation_top =
ExternalReference::new_space_allocation_top_address();
mov(scratch1, Operand(new_space_allocation_top));
ldr(result, MemOperand(scratch1));
// Calculate new top and bail out if new space is exhausted. Use result
// to calculate the new top.
ExternalReference new_space_allocation_limit =
ExternalReference::new_space_allocation_limit_address();
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);
// Update allocation top. result temporarily holds the new top,
str(result, MemOperand(scratch1));
// Tag and adjust back to start of new object.
if (tag_allocated_object) {
sub(result, result, Operand(object_size - kHeapObjectTag));
} else {
sub(result, result, Operand(object_size));
}
}
void MacroAssembler::CompareObjectType(Register function,
Register map,
Register type_reg,
......@@ -1022,4 +1060,5 @@ void MacroAssembler::Abort(const char* msg) {
// will not return here
}
} } // namespace v8::internal
......@@ -187,6 +187,20 @@ class MacroAssembler: public Assembler {
Label* miss);
// ---------------------------------------------------------------------------
// Allocation support
// Allocate an object in new space. If the new space is exhausted control
// continues at the gc_required label. The allocated object is returned in
// result. If the flag tag_allocated_object is true the result is tagged as
// as a heap object.
void AllocateObjectInNewSpace(int object_size,
Register result,
Register scratch1,
Register scratch2,
Label* gc_required,
bool tag_allocated_object);
// ---------------------------------------------------------------------------
// Support functions.
......
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