Move object allocation in new space to macro assembler
authorsgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 1 Sep 2009 07:36:46 +0000 (07:36 +0000)
committersgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 1 Sep 2009 07:36:46 +0000 (07:36 +0000)
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
src/arm/macro-assembler-arm.cc
src/arm/macro-assembler-arm.h

index 880507d..b94aa10 100644 (file)
@@ -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));
 }
 
 
index 65c2a3e..2ca4898 100644 (file)
@@ -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
index e4758cc..4bbd980 100644 (file)
@@ -188,6 +188,20 @@ class MacroAssembler: public Assembler {
 
 
   // ---------------------------------------------------------------------------
+  // 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.
 
   // Try to get function prototype of a function and puts the value in