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