Save callee-save registers on alloc helper calls

The allocations helpers may cause a gc, so we need to preserve
all callee save registers that might contain a reference.
Deleted obsolete unit tests.

Change-Id: Ib14f4ca787af94e1d8e036bbb956ffc537eff226
diff --git a/src/object_test.cc b/src/object_test.cc
index c13a19d..6979b75 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -162,29 +162,6 @@
   TestPrimitiveArray<ShortArray>(class_linker_);
 }
 
-extern "C" Object* artAllocObjectFromCode(uint32_t type_idx, Method* method);
-TEST_F(ObjectTest, AllocObjectFromCode) {
-  // pretend we are trying to call 'new String' from Object.toString
-  Class* java_lang_Object = class_linker_->FindSystemClass("Ljava/lang/Object;");
-  Method* toString = java_lang_Object->FindVirtualMethod("toString", "()Ljava/lang/String;");
-  uint32_t type_idx = FindTypeIdxByDescriptor(*java_lang_dex_file_.get(), "Ljava/lang/String;");
-  Object* string = artAllocObjectFromCode(type_idx, toString);
-  EXPECT_TRUE(string->IsString());
-}
-
-extern "C" Array* artAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t component_count);
-TEST_F(ObjectTest, AllocArrayFromCode) {
-  // pretend we are trying to call 'new char[3]' from String.toCharArray
-  Class* java_lang_String = class_linker_->FindSystemClass("Ljava/lang/String;");
-  Method* toCharArray = java_lang_String->FindVirtualMethod("toCharArray", "()[C");
-  uint32_t type_idx = FindTypeIdxByDescriptor(*java_lang_dex_file_.get(), "[C");
-  Object* array = artAllocArrayFromCode(type_idx, toCharArray, 3);
-  EXPECT_TRUE(array->IsArrayInstance());
-  EXPECT_EQ(3, array->AsArray()->GetLength());
-  EXPECT_TRUE(array->GetClass()->IsArrayClass());
-  EXPECT_TRUE(array->GetClass()->GetComponentType()->IsPrimitive());
-}
-
 extern "C" Array* artCheckAndAllocArrayFromCode(uint32_t type_idx, Method* method,
                                                 int32_t component_count);
 TEST_F(ObjectTest, CheckAndAllocArrayFromCode) {
diff --git a/src/runtime_support.cc b/src/runtime_support.cc
index 2bcd7d9..49191b7 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -414,17 +414,22 @@
 
 // Given the context of a calling Method, use its DexCache to resolve a type to a Class. If it
 // cannot be resolved, throw an error. If it can, use it to create an instance.
-extern "C" Object* artAllocObjectFromCode(uint32_t type_idx, Method* method) {
+extern "C" Object* artAllocObjectFromCode(uint32_t type_idx, Method* method, Thread* self, Method** sp) {
+  // Place a special frame at the TOS that will save all callee saves
+  Runtime* runtime = Runtime::Current();
+  *sp = runtime->GetCalleeSaveMethod();
+  self->SetTopOfStack(sp, 0);
+
   Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
   if (klass == NULL) {
-    klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
+    klass = runtime->GetClassLinker()->ResolveType(type_idx, method);
     if (klass == NULL) {
-      DCHECK(Thread::Current()->IsExceptionPending());
+      DCHECK(self->IsExceptionPending());
       return NULL;  // Failure
     }
   }
-  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(klass, true)) {
-    DCHECK(Thread::Current()->IsExceptionPending());
+  if (!runtime->GetClassLinker()->EnsureInitialized(klass, true)) {
+    DCHECK(self->IsExceptionPending());
     return NULL;  // Failure
   }
   return klass->AllocObject();
@@ -465,7 +470,12 @@
 
 // Given the context of a calling Method, use its DexCache to resolve a type to an array Class. If
 // it cannot be resolved, throw an error. If it can, use it to create an array.
-extern "C" Array* artAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t component_count) {
+extern "C" Array* artAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t component_count, Thread* self, Method** sp) {
+  // Place a special frame at the TOS that will save all callee saves
+  Runtime* runtime = Runtime::Current();
+  *sp = runtime->GetCalleeSaveMethod();
+  self->SetTopOfStack(sp, 0);
+
   if (component_count < 0) {
     Thread::Current()->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;", "%d",
                                          component_count);
diff --git a/src/runtime_support_asm.S b/src/runtime_support_asm.S
index 7d4c906..0e73d83 100644
--- a/src/runtime_support_asm.S
+++ b/src/runtime_support_asm.S
@@ -245,13 +245,13 @@
      * Called by managed code to allocate an object
      */
 art_alloc_object_from_code:
-    str    sp, [R9, #THREAD_TOP_OF_MANAGED_STACK_OFFSET]    @ record top of stack and pc in case of
-    str    lr, [R9, #THREAD_TOP_OF_MANAGED_STACK_PC_OFFSET] @ walking stack
-    stmdb  sp!, {lr}               @ Save LR
-    sub    sp, #12                 @ Align stack
-    bl     artAllocObjectFromCode  @ (uint32_t type_idx, Method* method)
-    add    sp, #12
-    ldmia  sp!, {lr}               @ restore LR
+    SETUP_CALLEE_SAVE_FRAME
+    mov    r2, r9                  @ pass Thread::Current
+    mov    r3, sp                  @ pass SP
+    bl     artAllocObjectFromCode  @ (uint32_t type_idx, Method* method, Thread*, SP)
+    add    sp, #16
+    vpop   {s0-s31}
+    pop    {r1-r11, lr}
     cmp    r0, #0                  @ success if result is non-null
     movne  pc, lr                  @ return on success
                                    @ set up for throwing exception
@@ -266,13 +266,13 @@
      * Called by managed code to allocate an array
      */
 art_alloc_array_from_code:
-    str    sp, [R9, #THREAD_TOP_OF_MANAGED_STACK_OFFSET]    @ record top of stack and pc in case of
-    str    lr, [R9, #THREAD_TOP_OF_MANAGED_STACK_PC_OFFSET] @ walking stack
-    stmdb  sp!, {lr}              @ Save LR
-    sub    sp, #12                @ Align stack
-    bl     artAllocArrayFromCode  @ (uint32_t type_idx, Method* method, int32_t component_count)
-    add    sp, #12
-    ldmia  sp!, {lr}              @ restore LR
+    SETUP_CALLEE_SAVE_FRAME
+    mov    r3, r9                 @ pass Thread::Current
+    str    sp, [sp, #0]           @ pass SP
+    bl     artAllocArrayFromCode  @ (uint32_t type_idx, Method* method, int32_t component_count, Thread*, SP)
+    add    sp, #16
+    vpop   {s0-s31}
+    pop    {r1-r11, lr}
     cmp    r0, #0                 @ success if result is non-null
     movne  pc, lr                 @ return on success
                                   @ set up for throwing exception