From 62e9956c91ea0f4c3e2f499c708096efd5c09cee Mon Sep 17 00:00:00 2001 From: "sgjesse@chromium.org" Date: Tue, 1 Sep 2009 07:36:46 +0000 Subject: [PATCH] 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 --- src/arm/codegen-arm.cc | 43 +++++++++++----------------------- src/arm/macro-assembler-arm.cc | 39 ++++++++++++++++++++++++++++++ src/arm/macro-assembler-arm.h | 14 +++++++++++ 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc index 880507d06..b94aa10bd 100644 --- a/src/arm/codegen-arm.cc +++ b/src/arm/codegen-arm.cc @@ -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)); } diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc index 65c2a3ebd..2ca489868 100644 --- a/src/arm/macro-assembler-arm.cc +++ b/src/arm/macro-assembler-arm.cc @@ -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 diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h index e4758cc39..4bbd9802f 100644 --- a/src/arm/macro-assembler-arm.h +++ b/src/arm/macro-assembler-arm.h @@ -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. -- 2.34.1