Fix ObjectInitFromCode to do callee frame setup

Change-Id: I70512c85a3a810fd672495b86655c215a07bb977
diff --git a/src/runtime_support.cc b/src/runtime_support.cc
index 5550c2f..ad01f4d 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -40,7 +40,8 @@
   LOG(INFO) << "Info: " << info;
 }
 
-void ObjectInitFromCode(Object* o) {
+extern "C" uint32_t artObjectInitFromCode(Object* o, Thread* self, Method** sp) {
+  FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
   Class* c = o->GetClass();
   if (UNLIKELY(c->IsFinalizable())) {
     Heap::AddFinalizerReference(o);
@@ -50,6 +51,7 @@
    * here and branch to actual compiled object.<init> to handle any
    * breakpoint/logging activites if either is active.
    */
+  return self->IsExceptionPending() ? -1 : 0;
 }
 
 // Return value helper for jobject return types
diff --git a/src/runtime_support.h b/src/runtime_support.h
index ba0b0f1..6350903 100644
--- a/src/runtime_support.h
+++ b/src/runtime_support.h
@@ -36,24 +36,18 @@
 
 #if defined(__arm__)
   /* Compiler helpers */
-  extern "C" void* art_alloc_object_from_code(uint32_t type_idx, void* method);
-  extern "C" void* art_alloc_array_from_code(uint32_t, void*, int32_t);
-  extern "C" void* art_check_and_alloc_array_from_code(uint32_t, void*, int32_t);
-  extern "C" void art_can_put_array_element_from_code(void*, void*);
-  extern "C" void art_check_cast_from_code(void*, void*);
-  extern "C" void art_do_long_jump(uint32_t*, uint32_t*);
-  extern "C" void* art_find_instance_field_from_code(uint32_t, void*);
-  extern "C" void* art_find_static_field_from_code(uint32_t, void*);
-  extern "C" int32_t art_get32_static_from_code(uint32_t, void*);
-  extern "C" int64_t art_get64_static_from_code(uint32_t, void*);
-  extern "C" void* art_get_obj_static_from_code(uint32_t, void*);
-  extern "C" void art_handle_fill_data_from_code(void*, void*);
-  extern "C" void* art_initialize_static_storage_from_code(uint32_t, void*);
-  extern "C" void* art_resolve_string_from_code(void*, uint32_t);
-  extern "C" void art_invoke_interface_trampoline(uint32_t, void*);
   extern "C" int art_set32_static_from_code(uint32_t, void*, int32_t);
   extern "C" int art_set64_static_from_code(uint32_t, void*, int64_t);
   extern "C" int art_set_obj_static_from_code(uint32_t, void*, void*);
+  extern "C" int32_t art_get32_static_from_code(uint32_t, void*);
+  extern "C" int64_t art_get64_static_from_code(uint32_t, void*);
+  extern "C" void art_can_put_array_element_from_code(void*, void*);
+  extern "C" void art_check_cast_from_code(void*, void*);
+  extern "C" void art_do_long_jump(uint32_t*, uint32_t*);
+  extern "C" void art_handle_fill_data_from_code(void*, void*);
+  extern "C" void art_invoke_interface_trampoline(uint32_t, void*);
+  extern "C" void art_lock_object_from_code(void*);
+  extern "C" void art_object_init_from_code(void*);
   extern "C" void art_test_suspend();
   extern "C" void art_throw_array_bounds_from_code(int32_t index, int32_t limit);
   extern "C" void art_throw_div_zero_from_code();
@@ -62,8 +56,15 @@
   extern "C" void art_throw_null_pointer_exception_from_code();
   extern "C" void art_throw_stack_overflow_from_code(void*);
   extern "C" void art_throw_verification_error_from_code(int32_t src1, int32_t ref);
-  extern "C" void art_lock_object_from_code(void*);
   extern "C" void art_unlock_object_from_code(void*);
+  extern "C" void* art_alloc_array_from_code(uint32_t, void*, int32_t);
+  extern "C" void* art_alloc_object_from_code(uint32_t type_idx, void* method);
+  extern "C" void* art_check_and_alloc_array_from_code(uint32_t, void*, int32_t);
+  extern "C" void* art_find_instance_field_from_code(uint32_t, void*);
+  extern "C" void* art_find_static_field_from_code(uint32_t, void*);
+  extern "C" void* art_get_obj_static_from_code(uint32_t, void*);
+  extern "C" void* art_initialize_static_storage_from_code(uint32_t, void*);
+  extern "C" void* art_resolve_string_from_code(void*, uint32_t);
 
   /* Conversions */
   extern "C" float __aeabi_i2f(int op1);             // OP_INT_TO_FLOAT
diff --git a/src/runtime_support_asm.S b/src/runtime_support_asm.S
index 8ef3da8..b3eae57 100644
--- a/src/runtime_support_asm.S
+++ b/src/runtime_support_asm.S
@@ -409,6 +409,23 @@
     bxne   lr                         @ return on success
     DELIVER_PENDING_EXCEPTION
 
+    .global art_object_init_from_code
+    .extern artObjectInitFromCode
+    /*
+     * Entry from managed code to perform Object.<init> string. R0 holds the object to initialize.
+     * On success, 0 is returned. Otherwise there is a pending exception to deliver.
+     */
+art_object_init_from_code:
+    SETUP_REF_ONLY_CALLEE_SAVE_FRAME  @ save callee saves in case of GC
+    mov    r1, r9                     @ pass Thread::Current
+    mov    r2, sp                     @ pass SP
+    @ artObjectInitFromCode(Object* o, Thread*, SP)
+    bl     artObjectInitFromCode
+    RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
+    cmp    r0, #0                     @ success if result is zero
+    bxeq   lr                         @ return on success
+    DELIVER_PENDING_EXCEPTION
+
     .global art_alloc_object_from_code
     .extern artAllocObjectFromCode
     /*
diff --git a/src/thread.cc b/src/thread.cc
index 4401bdb..fbea315 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -88,9 +88,8 @@
   pFmod = fmod;
   pLdivmod = __aeabi_ldivmod;
   pLmul = __aeabi_lmul;
-  pTestSuspendFromCode = art_test_suspend;
-  pAllocObjectFromCode = art_alloc_object_from_code;
   pAllocArrayFromCode = art_alloc_array_from_code;
+  pAllocObjectFromCode = art_alloc_object_from_code;
   pCanPutArrayElementFromCode = art_can_put_array_element_from_code;
   pCheckAndAllocArrayFromCode = art_check_and_alloc_array_from_code;
   pCheckCastFromCode = art_check_cast_from_code;
@@ -100,11 +99,14 @@
   pGetObjStatic = art_get_obj_static_from_code;
   pHandleFillArrayDataFromCode = art_handle_fill_data_from_code;
   pInitializeStaticStorage = art_initialize_static_storage_from_code;
-  pResolveStringFromCode = art_resolve_string_from_code;
   pInvokeInterfaceTrampoline = art_invoke_interface_trampoline;
+  pLockObjectFromCode = art_lock_object_from_code;
+  pObjectInit = art_object_init_from_code;
+  pResolveStringFromCode = art_resolve_string_from_code;
   pSet32Static = art_set32_static_from_code;
   pSet64Static = art_set64_static_from_code;
   pSetObjStatic = art_set_obj_static_from_code;
+  pTestSuspendFromCode = art_test_suspend;
   pThrowArrayBoundsFromCode = art_throw_array_bounds_from_code;
   pThrowDivZeroFromCode = art_throw_div_zero_from_code;
   pThrowNegArraySizeFromCode = art_throw_neg_array_size_from_code;
@@ -112,7 +114,6 @@
   pThrowNullPointerFromCode = art_throw_null_pointer_exception_from_code;
   pThrowStackOverflowFromCode = art_throw_stack_overflow_from_code;
   pThrowVerificationErrorFromCode = art_throw_verification_error_from_code;
-  pLockObjectFromCode = art_lock_object_from_code;
   pUnlockObjectFromCode = art_unlock_object_from_code;
 #endif
   pF2l = F2L;
@@ -125,7 +126,6 @@
   pFindNativeMethod = FindNativeMethod;
   pInitializeTypeFromCode = InitializeTypeFromCode;
   pInstanceofNonTrivialFromCode = IsAssignableFromCode;
-  pObjectInit = ObjectInitFromCode;
   pResolveMethodFromCode = ResolveMethodFromCode;
   pThrowAbstractMethodErrorFromCode = ThrowAbstractMethodErrorFromCode;
   pUnresolvedDirectMethodTrampolineFromCode = UnresolvedDirectMethodTrampolineFromCode;
diff --git a/src/thread.h b/src/thread.h
index d345fdf..a4e0576 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -137,7 +137,7 @@
   void (*pInvokeInterfaceTrampoline)(uint32_t, void*);
   Class* (*pInitializeTypeFromCode)(uint32_t, Method*);
   void (*pLockObjectFromCode)(void*);
-  void (*pObjectInit)(Object*);
+  void (*pObjectInit)(void*);
   void (*pResolveMethodFromCode)(Method*, uint32_t);
   void* (*pResolveStringFromCode)(void*, uint32_t);
   int (*pSet32Static)(uint32_t, void*, int32_t);