diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/object.cc | 14 | ||||
| -rw-r--r-- | src/object.h | 5 | ||||
| -rw-r--r-- | src/object_test.cc | 3 | ||||
| -rw-r--r-- | src/runtime_support.S | 22 | ||||
| -rw-r--r-- | src/runtime_support.h | 1 | ||||
| -rw-r--r-- | src/thread.cc | 16 | ||||
| -rw-r--r-- | src/thread.h | 2 |
7 files changed, 43 insertions, 20 deletions
diff --git a/src/object.cc b/src/object.cc index 29eac7736e..7b47d9f80f 100644 --- a/src/object.cc +++ b/src/object.cc @@ -774,20 +774,10 @@ void Class::SetDexCache(DexCache* new_dex_cache) { new_dex_cache, false); } -Object* Class::AllocObjectFromCode(uint32_t type_idx, Method* method) { - Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx); - if (klass == NULL) { - klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method); - if (klass == NULL) { - UNIMPLEMENTED(FATAL) << "throw an error"; - return NULL; - } - } - return klass->AllocObject(); -} - Object* Class::AllocObject() { DCHECK(!IsAbstract()); + DCHECK(!IsInterface()); + DCHECK(!IsPrimitive()); return Heap::AllocObject(this, this->object_size_); } diff --git a/src/object.h b/src/object.h index 09788be867..69f8c14f6e 100644 --- a/src/object.h +++ b/src/object.h @@ -1422,11 +1422,6 @@ class MANAGED Class : public StaticStorageBase { return !IsPrimitive() && GetSuperClass() == NULL; } - // 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. - static Object* AllocObjectFromCode(uint32_t type_idx, Method* method); - // Creates a raw object instance but does not invoke the default constructor. Object* AllocObject(); diff --git a/src/object_test.cc b/src/object_test.cc index 9a5777b6aa..d6705d7e24 100644 --- a/src/object_test.cc +++ b/src/object_test.cc @@ -162,12 +162,13 @@ TEST_F(ObjectTest, PrimitiveArray_Short_Alloc) { 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 = Class::AllocObjectFromCode(type_idx, toString); + Object* string = artAllocObjectFromCode(type_idx, toString); EXPECT_TRUE(string->IsString()); } diff --git a/src/runtime_support.S b/src/runtime_support.S index 9cfb3ab74c..4a50344305 100644 --- a/src/runtime_support.S +++ b/src/runtime_support.S @@ -219,6 +219,28 @@ art_initialize_static_storage_from_code: mov r1, sp @ pass SP b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + .global art_alloc_object_from_code + .extern artAllocObjectFromCode + /* + * 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 + cmp r0, #0 @ success if result is non-null + movne pc, lr @ return on success + @ set up for throwing exception + stmdb sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr} + sub sp, #16 @ 4 words of space, bottom word will hold Method* + mov r0, r9 @ pass Thread::Current + mov r1, sp @ pass SP + b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + .global art_array_alloc_from_code .extern artArrayAllocFromCode /* diff --git a/src/runtime_support.h b/src/runtime_support.h index 20ca1d4d5e..d9cc36421f 100644 --- a/src/runtime_support.h +++ b/src/runtime_support.h @@ -8,6 +8,7 @@ extern "C" void art_deliver_exception_from_code(void*); #if defined(__arm__) /* Compiler helpers */ + extern "C" void* art_alloc_object_from_code(uint32_t type_idx, void* method); extern "C" void* art_array_alloc_from_code(uint32_t, void*, int32_t); extern "C" void* art_check_and_array_alloc_from_code(uint32_t, void*, int32_t); extern "C" void art_can_put_array_element_from_code(void*, void*); diff --git a/src/thread.cc b/src/thread.cc index 69dec9439b..22495be9c2 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -191,6 +191,20 @@ void ResolveMethodFromCode(Method* method, uint32_t method_idx) { */ } +// 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) { + Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx); + if (klass == NULL) { + klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method); + if (klass == NULL) { + DCHECK(Thread::Current()->IsExceptionPending()); + return NULL; // Failure + } + } + return klass->AllocObject(); +} + // Helper function to alloc array for OP_FILLED_NEW_ARRAY extern "C" Array* artCheckAndArrayAllocFromCode(uint32_t type_idx, Method* method, int32_t component_count) { @@ -418,6 +432,7 @@ void Thread::InitFunctionPointers() { pFmod = fmod; pLdivmod = __aeabi_ldivmod; pLmul = __aeabi_lmul; + pAllocObjectFromCode = art_alloc_object_from_code; pArrayAllocFromCode = art_array_alloc_from_code; pCanPutArrayElementFromCode = art_can_put_array_element_from_code; pCheckAndArrayAllocFromCode = art_check_and_array_alloc_from_code; @@ -435,7 +450,6 @@ void Thread::InitFunctionPointers() { pDeliverException = art_deliver_exception_from_code; pF2l = F2L; pD2l = D2L; - pAllocObjectFromCode = Class::AllocObjectFromCode; pMemcpy = memcpy; pGet32Static = Field::Get32StaticFromCode; pSet32Static = Field::Set32StaticFromCode; diff --git a/src/thread.h b/src/thread.h index 945d3379f0..fe7900d114 100644 --- a/src/thread.h +++ b/src/thread.h @@ -202,9 +202,9 @@ class PACKED Thread { int (*pIdiv)(int, int); long long (*pLmul)(long long, long long); long long (*pLdivmod)(long long, long long); + void* (*pAllocObjectFromCode)(uint32_t, void*); void* (*pArrayAllocFromCode)(uint32_t, void*, int32_t); void* (*pCheckAndArrayAllocFromCode)(uint32_t, void*, int32_t); - Object* (*pAllocObjectFromCode)(uint32_t, Method*); uint32_t (*pGet32Static)(uint32_t, const Method*); void (*pSet32Static)(uint32_t, const Method*, uint32_t); uint64_t (*pGet64Static)(uint32_t, const Method*); |