diff options
| author | 2011-10-08 16:10:57 -0700 | |
|---|---|---|
| committer | 2011-10-08 16:10:57 -0700 | |
| commit | 4a14bc2e374add8f7df8232b3af3d8881eb4c84b (patch) | |
| tree | 2b49ca069ccbc433127709d1c471438893f89a84 | |
| parent | bb7d7730e553438d86ae45003e15ed8bf99d88d6 (diff) | |
| parent | ce9eca6de042f26e9eebc41c9bee8b4d14f753aa (diff) | |
Merge "Move from code field routines to runtime support." into dalvik-dev
| -rw-r--r-- | src/asm_support.h | 2 | ||||
| -rw-r--r-- | src/class_linker_test.cc | 3 | ||||
| -rw-r--r-- | src/object.cc | 54 | ||||
| -rw-r--r-- | src/object.h | 33 | ||||
| -rw-r--r-- | src/object_test.cc | 16 | ||||
| -rw-r--r-- | src/runtime_support.cc | 143 | ||||
| -rw-r--r-- | src/runtime_support.h | 13 | ||||
| -rw-r--r-- | src/runtime_support_asm.S | 170 | ||||
| -rw-r--r-- | src/thread.cc | 14 | ||||
| -rw-r--r-- | src/thread.h | 42 | ||||
| -rw-r--r-- | src/thread_arm.cc | 1 |
11 files changed, 328 insertions, 163 deletions
diff --git a/src/asm_support.h b/src/asm_support.h index 305e17d660..19a930d70f 100644 --- a/src/asm_support.h +++ b/src/asm_support.h @@ -10,6 +10,8 @@ #define SUSPEND_CHECK_INTERVAL (1000) // Offset of field Thread::suspend_count_ verified in InitCpu #define THREAD_SUSPEND_COUNT_OFFSET 388 +// Offset of field Thread::suspend_count_ verified in InitCpu +#define THREAD_EXCEPTION_OFFSET 384 #elif defined(__i386__) // Offset of field Thread::self_ verified in InitCpu diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc index 025f9e3b65..264b669155 100644 --- a/src/class_linker_test.cc +++ b/src/class_linker_test.cc @@ -9,6 +9,7 @@ #include "dex_cache.h" #include "dex_file.h" #include "heap.h" +#include "runtime_support.h" namespace art { @@ -924,8 +925,6 @@ TEST_F(ClassLinkerTest, Interfaces) { EXPECT_EQ(Aj2, A->FindVirtualMethodForVirtualOrInterface(Jj2)); } -extern Class* InitializeStaticStorage(uint32_t type_idx, const Method* referrer, Thread* self); - TEST_F(ClassLinkerTest, InitializeStaticStorageFromCode) { // pretend we are trying to get the static storage for the StaticsFromCode class. diff --git a/src/object.cc b/src/object.cc index 9f225d766d..58ffa6bac9 100644 --- a/src/object.cc +++ b/src/object.cc @@ -123,60 +123,6 @@ void Field::InitJavaFieldsLocked() { GetType(); // Sets type_ as a side-effect. May throw. } -Field* Field::FindInstanceFieldFromCode(uint32_t field_idx, const Method* referrer) { - return FindFieldFromCode(field_idx, referrer, false); -} - -Field* Field::FindStaticFieldFromCode(uint32_t field_idx, const Method* referrer) { - return FindFieldFromCode(field_idx, referrer, true); -} - -Field* Field::FindFieldFromCode(uint32_t field_idx, const Method* referrer, bool is_static) { - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - Field* f = class_linker->ResolveField(field_idx, referrer, is_static); - if (f != NULL) { - Class* c = f->GetDeclaringClass(); - // If the class is already initializing, we must be inside <clinit>, or - // we'd still be waiting for the lock. - if (c->GetStatus() == Class::kStatusInitializing || class_linker->EnsureInitialized(c, true)) { - return f; - } - } - UNIMPLEMENTED(FATAL) << "throw an error and unwind"; - return NULL; -} - -uint32_t Field::Get32StaticFromCode(uint32_t field_idx, const Method* referrer) { - Field* field = FindStaticFieldFromCode(field_idx, referrer); - DCHECK(field->GetType()->PrimitiveSize() == sizeof(int32_t)); - return field->Get32(NULL); -} -void Field::Set32StaticFromCode(uint32_t field_idx, const Method* referrer, uint32_t new_value) { - Field* field = FindStaticFieldFromCode(field_idx, referrer); - DCHECK(field->GetType()->PrimitiveSize() == sizeof(int32_t)); - field->Set32(NULL, new_value); -} -uint64_t Field::Get64StaticFromCode(uint32_t field_idx, const Method* referrer) { - Field* field = FindStaticFieldFromCode(field_idx, referrer); - DCHECK(field->GetType()->PrimitiveSize() == sizeof(int64_t)); - return field->Get64(NULL); -} -void Field::Set64StaticFromCode(uint32_t field_idx, const Method* referrer, uint64_t new_value) { - Field* field = FindStaticFieldFromCode(field_idx, referrer); - DCHECK(field->GetType()->PrimitiveSize() == sizeof(int64_t)); - field->Set64(NULL, new_value); -} -Object* Field::GetObjStaticFromCode(uint32_t field_idx, const Method* referrer) { - Field* field = FindStaticFieldFromCode(field_idx, referrer); - DCHECK(!field->GetType()->IsPrimitive()); - return field->GetObj(NULL); -} -void Field::SetObjStaticFromCode(uint32_t field_idx, const Method* referrer, Object* new_value) { - Field* field = FindStaticFieldFromCode(field_idx, referrer); - DCHECK(!field->GetType()->IsPrimitive()); - field->SetObj(NULL, new_value); -} - uint32_t Field::Get32(const Object* object) const { CHECK((object == NULL) == IsStatic()); if (IsStatic()) { diff --git a/src/object.h b/src/object.h index d8eb179ce1..80a4ce92d1 100644 --- a/src/object.h +++ b/src/object.h @@ -471,10 +471,6 @@ class MANAGED Field : public AccessibleObject { return MemberOffset(OFFSETOF_MEMBER(Field, offset_)); } - static Field* FindInstanceFieldFromCode(uint32_t field_idx, const Method* referrer); - static Field* FindStaticFieldFromCode(uint32_t field_idx, const Method* referrer); - static Field* FindFieldFromCode(uint32_t field_idx, const Method* referrer, bool is_static); - MemberOffset GetOffsetDuringLinking() const; void SetOffset(MemberOffset num_bytes); @@ -499,20 +495,13 @@ class MANAGED Field : public AccessibleObject { Object* GetObject(const Object* object) const; void SetObject(Object* object, const Object* l) const; - // Slow path routines for static field access when field was unresolved at - // compile time - static uint32_t Get32StaticFromCode(uint32_t field_idx, - const Method* referrer); - static void Set32StaticFromCode(uint32_t field_idx, const Method* referrer, - uint32_t new_value); - static uint64_t Get64StaticFromCode(uint32_t field_idx, - const Method* referrer); - static void Set64StaticFromCode(uint32_t field_idx, const Method* referrer, - uint64_t new_value); - static Object* GetObjStaticFromCode(uint32_t field_idx, - const Method* referrer); - static void SetObjStaticFromCode(uint32_t field_idx, const Method* referrer, - Object* new_value); + // raw field accesses + uint32_t Get32(const Object* object) const; + void Set32(Object* object, uint32_t new_value) const; + uint64_t Get64(const Object* object) const; + void Set64(Object* object, uint64_t new_value) const; + Object* GetObj(const Object* object) const; + void SetObj(Object* object, const Object* new_value) const; static Class* GetJavaLangReflectField() { DCHECK(java_lang_reflect_Field_ != NULL); @@ -529,14 +518,6 @@ class MANAGED Field : public AccessibleObject { void InitJavaFields(); private: - // private implementation of field access using raw data - uint32_t Get32(const Object* object) const; - void Set32(Object* object, uint32_t new_value) const; - uint64_t Get64(const Object* object) const; - void Set64(Object* object, uint64_t new_value) const; - Object* GetObj(const Object* object) const; - void SetObj(Object* object, const Object* new_value) const; - void InitJavaFieldsLocked(); // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". diff --git a/src/object_test.cc b/src/object_test.cc index 6979b75327..6b1f818327 100644 --- a/src/object_test.cc +++ b/src/object_test.cc @@ -10,6 +10,7 @@ #include "common_test.h" #include "dex_file.h" #include "heap.h" +#include "runtime_support.h" namespace art { @@ -162,14 +163,12 @@ TEST_F(ObjectTest, PrimitiveArray_Short_Alloc) { TestPrimitiveArray<ShortArray>(class_linker_); } -extern "C" Array* artCheckAndAllocArrayFromCode(uint32_t type_idx, Method* method, - int32_t component_count); TEST_F(ObjectTest, CheckAndAllocArrayFromCode) { // pretend we are trying to call 'new char[3]' from String.toCharArray Class* java_util_Arrays = class_linker_->FindSystemClass("Ljava/util/Arrays;"); Method* sort = java_util_Arrays->FindDirectMethod("sort", "([I)V"); uint32_t type_idx = FindTypeIdxByDescriptor(*java_lang_dex_file_.get(), "[I"); - Object* array = artCheckAndAllocArrayFromCode(type_idx, sort, 3); + Object* array = CheckAndAllocArrayFromCode(type_idx, sort, 3, Thread::Current()); EXPECT_TRUE(array->IsArrayInstance()); EXPECT_EQ(3, array->AsArray()->GetLength()); EXPECT_TRUE(array->GetClass()->IsArrayClass()); @@ -185,15 +184,16 @@ TEST_F(ObjectTest, StaticFieldFromCode) { Class* klass = class_linker_->FindClass("LStaticsFromCode;", class_loader); Method* clinit = klass->FindDirectMethod("<clinit>", "()V"); uint32_t field_idx = FindFieldIdxByDescriptorAndName(*dex_file, "LStaticsFromCode;", "s0"); - Object* s0 = Field::GetObjStaticFromCode(field_idx, clinit); + Field* field = FindFieldFromCode(field_idx, clinit, true); + Object* s0 = field->GetObj(NULL); EXPECT_EQ(NULL, s0); CharArray* char_array = CharArray::Alloc(0); - Field::SetObjStaticFromCode(field_idx, clinit, char_array); - EXPECT_EQ(char_array, Field::GetObjStaticFromCode(field_idx, clinit)); + field->SetObj(NULL, char_array); + EXPECT_EQ(char_array, field->GetObj(NULL)); - Field::SetObjStaticFromCode(field_idx, clinit, NULL); - EXPECT_EQ(NULL, Field::GetObjStaticFromCode(field_idx, clinit)); + field->SetObj(NULL, NULL); + EXPECT_EQ(NULL, field->GetObj(NULL)); // TODO: more exhaustive tests of all 6 cases of Field::*FromCode } diff --git a/src/runtime_support.cc b/src/runtime_support.cc index 6a11e11b47..db6cbf06e2 100644 --- a/src/runtime_support.cc +++ b/src/runtime_support.cc @@ -22,6 +22,7 @@ namespace art { // Place a special frame at the TOS that will save the callee saves for the given type static void FinishCalleeSaveFrameSetup(Thread* self, Method** sp, Runtime::CalleeSaveType type) { + // Be aware the store below may well stomp on an incoming argument *sp = Runtime::Current()->GetCalleeSaveMethod(type); self->SetTopOfStack(sp, 0); } @@ -398,10 +399,135 @@ void ResolveMethodFromCode(Method* method, uint32_t method_idx) { */ } +Field* FindFieldFromCode(uint32_t field_idx, const Method* referrer, bool is_static) { + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + Field* f = class_linker->ResolveField(field_idx, referrer, is_static); + if (f != NULL) { + Class* c = f->GetDeclaringClass(); + // If the class is already initializing, we must be inside <clinit>, or + // we'd still be waiting for the lock. + if (c->GetStatus() == Class::kStatusInitializing || class_linker->EnsureInitialized(c, true)) { + return f; + } + } + DCHECK(Thread::Current()->IsExceptionPending()); // Throw exception and unwind + return NULL; +} + +extern "C" Field* artFindInstanceFieldFromCode(uint32_t field_idx, const Method* referrer, + Thread* self, Method** sp) { + FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); + return FindFieldFromCode(field_idx, referrer, false); +} + +extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx, const Method* referrer, + Thread* self, Method** sp) { + FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); + Field* field = FindFieldFromCode(field_idx, referrer, true); + if (field != NULL) { + Class* type = field->GetType(); + if (!type->IsPrimitive() || type->PrimitiveSize() != sizeof(int64_t)) { + self->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;", + "Attempted read of 32-bit primitive on field '%s'", + PrettyField(field, true).c_str()); + } else { + return field->Get32(NULL); + } + } + return 0; // Will throw exception by checking with Thread::Current +} + +extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx, const Method* referrer, + Thread* self, Method** sp) { + FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); + Field* field = FindFieldFromCode(field_idx, referrer, true); + if (field != NULL) { + Class* type = field->GetType(); + if (!type->IsPrimitive() || type->PrimitiveSize() != sizeof(int64_t)) { + self->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;", + "Attempted read of 64-bit primitive on field '%s'", + PrettyField(field, true).c_str()); + } else { + return field->Get64(NULL); + } + } + return 0; // Will throw exception by checking with Thread::Current +} + +extern "C" Object* artGetObjStaticFromCode(uint32_t field_idx, const Method* referrer, + Thread* self, Method** sp) { + FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); + Field* field = FindFieldFromCode(field_idx, referrer, true); + if (field != NULL) { + Class* type = field->GetType(); + if (type->IsPrimitive()) { + self->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;", + "Attempted read of reference on primitive field '%s'", + PrettyField(field, true).c_str()); + } else { + return field->GetObj(NULL); + } + } + return NULL; // Will throw exception by checking with Thread::Current +} + +extern "C" int artSet32StaticFromCode(uint32_t field_idx, const Method* referrer, + uint32_t new_value, Thread* self, Method** sp) { + FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); + Field* field = FindFieldFromCode(field_idx, referrer, true); + if (field != NULL) { + Class* type = field->GetType(); + if (!type->IsPrimitive() || type->PrimitiveSize() != sizeof(int32_t)) { + self->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;", + "Attempted write of 32-bit primitive to field '%s'", + PrettyField(field, true).c_str()); + } else { + field->Set32(NULL, new_value); + return 0; // success + } + } + return -1; // failure +} + +extern "C" int artSet64StaticFromCode(uint32_t field_idx, const Method* referrer, + uint64_t new_value, Thread* self, Method** sp) { + FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); + Field* field = FindFieldFromCode(field_idx, referrer, true); + if (field != NULL) { + Class* type = field->GetType(); + if (!type->IsPrimitive() || type->PrimitiveSize() != sizeof(int64_t)) { + self->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;", + "Attempted write of 64-bit primitive to field '%s'", + PrettyField(field, true).c_str()); + } else { + field->Set64(NULL, new_value); + return 0; // success + } + } + return -1; // failure +} + +extern "C" int artSetObjStaticFromCode(uint32_t field_idx, const Method* referrer, + Object* new_value, Thread* self, Method** sp) { + FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); + Field* field = FindFieldFromCode(field_idx, referrer, true); + if (field != NULL) { + Class* type = field->GetType(); + if (type->IsPrimitive()) { + self->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;", + "Attempted write of reference to primitive field '%s'", + PrettyField(field, true).c_str()); + } else { + field->SetObj(NULL, new_value); + return 0; // success + } + } + return -1; // failure +} + // 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, Thread* self, Method** sp) { - // Place a special frame at the TOS that will save all callee saves FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx); Runtime* runtime = Runtime::Current(); @@ -419,12 +545,10 @@ extern "C" Object* artAllocObjectFromCode(uint32_t type_idx, Method* method, Thr return klass->AllocObject(); } -// Helper function to alloc array for OP_FILLED_NEW_ARRAY -extern "C" Array* artCheckAndAllocArrayFromCode(uint32_t type_idx, Method* method, - int32_t component_count, Thread* self, Method** sp) { +Array* CheckAndAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t component_count, + Thread* self) { if (component_count < 0) { - Thread::Current()->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;", "%d", - component_count); + self->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;", "%d", component_count); return NULL; // Failure } Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx); @@ -452,6 +576,13 @@ extern "C" Array* artCheckAndAllocArrayFromCode(uint32_t type_idx, Method* metho } } +// Helper function to alloc array for OP_FILLED_NEW_ARRAY +extern "C" Array* artCheckAndAllocArrayFromCode(uint32_t type_idx, Method* method, + int32_t component_count, Thread* self, Method** sp) { + FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly); + return CheckAndAllocArrayFromCode(type_idx, method, component_count, self); +} + // 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, diff --git a/src/runtime_support.h b/src/runtime_support.h index 0a70c61472..d05ece0b96 100644 --- a/src/runtime_support.h +++ b/src/runtime_support.h @@ -10,11 +10,15 @@ namespace art { +extern Array* CheckAndAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t component_count, + Thread* self); extern void DebugMe(Method* method, uint32_t info); extern Object* DecodeJObjectInThread(Thread* thread, jobject obj); +extern Field* FindFieldFromCode(uint32_t field_idx, const Method* referrer, bool is_static); extern void* FindNativeMethod(Thread* thread); extern void ThrowAbstractMethodErrorFromCode(Method* method, Thread* thread, Method** sp); void* UnresolvedDirectMethodTrampolineFromCode(int32_t, void*, Thread*, Runtime::TrampolineType); +extern Class* InitializeStaticStorage(uint32_t type_idx, const Method* referrer, Thread* self); extern Class* InitializeTypeFromCode(uint32_t type_idx, Method* method); extern void ResolveMethodFromCode(Method* method, uint32_t method_idx); extern void LockObjectFromCode(Thread* thread, Object* obj); @@ -23,7 +27,6 @@ extern int64_t D2L(double d); extern int64_t F2L(float f); } // namespace art - /* Helper for both JNI and regular compiled code */ extern "C" void art_deliver_exception_from_code(void*); @@ -34,9 +37,17 @@ extern "C" void art_deliver_exception_from_code(void*); 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_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_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" 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(); diff --git a/src/runtime_support_asm.S b/src/runtime_support_asm.S index 5b70fb7610..d86d1fb2bf 100644 --- a/src/runtime_support_asm.S +++ b/src/runtime_support_asm.S @@ -52,6 +52,17 @@ pop {r1-r3, r5-r8, r10-r11, lr} @ 10 words of callee saves .endm + /* + * Macro that set calls through to artDeliverPendingExceptionFromCode, where the pending + * exception is Thread::Current()->exception_ + */ +.macro DELIVER_PENDING_EXCEPTION + SETUP_CALLEE_SAVE_FRAME @ save callee saves for throw + mov r0, r9 @ pass Thread::Current + mov r1, sp @ pass SP + b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) +.endm + .global art_deliver_exception_from_code /* * Called by managed code, saves mosts registers (forms basis of long jump context) and passes @@ -156,10 +167,7 @@ art_invoke_interface_trampoline: RESTORE_REF_AND_ARGS_CALLEE_SAVE_FRAME cmp r0, #0 @ did we find the target? bxne r12 @ tail call to target if so - SETUP_CALLEE_SAVE_FRAME @ set up for throwing exception - mov r0, r9 @ pass Thread::Current - mov r1, sp @ pass SP - b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + DELIVER_PENDING_EXCEPTION .global art_handle_fill_data_from_code .extern artHandleFillArrayDataFromCode @@ -175,10 +183,7 @@ art_handle_fill_data_from_code: RESTORE_REF_ONLY_CALLEE_SAVE_FRAME cmp r0, #0 @ success? moveq pc, lr @ return on success - SETUP_CALLEE_SAVE_FRAME @ set up for throwing exception - mov r0, r9 @ pass Thread::Current - mov r1, sp @ pass SP - b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + DELIVER_PENDING_EXCEPTION .global art_lock_object_from_code .extern artLockObjectFromCode @@ -205,10 +210,7 @@ art_unlock_object_from_code: RESTORE_REF_ONLY_CALLEE_SAVE_FRAME cmp r0, #0 @ success? moveq pc, lr @ return on success - SETUP_CALLEE_SAVE_FRAME @ set up for throwing exception - mov r0, r9 @ pass Thread::Current - mov r1, sp @ pass SP - b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + DELIVER_PENDING_EXCEPTION .global art_check_cast_from_code .extern artCheckCastFromCode @@ -223,10 +225,7 @@ art_check_cast_from_code: RESTORE_REF_ONLY_CALLEE_SAVE_FRAME cmp r0, #0 @ success? moveq pc, lr @ return on success - SETUP_CALLEE_SAVE_FRAME @ set up for throwing exception - mov r0, r9 @ pass Thread::Current - mov r1, sp @ pass SP - b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + DELIVER_PENDING_EXCEPTION .global art_can_put_array_element_from_code .extern artCanPutArrayElementFromCode @@ -244,10 +243,7 @@ art_can_put_array_element_from_code: RESTORE_REF_ONLY_CALLEE_SAVE_FRAME cmp r0, #0 @ success? moveq pc, lr @ return on success - SETUP_CALLEE_SAVE_FRAME @ set up for throwing exception - mov r0, r9 @ pass Thread::Current - mov r1, sp @ pass SP - b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + DELIVER_PENDING_EXCEPTION .global art_initialize_static_storage_from_code .extern artInitializeStaticStorageFromCode @@ -265,10 +261,117 @@ art_initialize_static_storage_from_code: RESTORE_REF_ONLY_CALLEE_SAVE_FRAME cmp r0, #0 @ success if result is non-null movne pc, lr @ return on success - SETUP_CALLEE_SAVE_FRAME @ set up for throwing exception - mov r0, r9 @ pass Thread::Current - mov r1, sp @ pass SP - b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + DELIVER_PENDING_EXCEPTION + + .global art_find_instance_field_from_code + .extern artFindInstanceFieldFromCode + /* + * Called by managed code to resolve a field of an object + */ +art_find_instance_field_from_code: + SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC + mov r2, r9 @ pass Thread::Current + mov r3, sp @ pass SP + bl artFindInstanceFieldFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP) + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME + cmp r0, #0 @ success if result is non-null + movne pc, lr @ return on success + DELIVER_PENDING_EXCEPTION + + .global art_get32_static_from_code + .extern artGet32StaticFromCode + /* + * Called by managed code to resolve a static field and load a 32-bit primitive value + */ +art_get32_static_from_code: + SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC + mov r2, r9 @ pass Thread::Current + mov r3, sp @ pass SP + bl artGet32StaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP) + ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME + cmp r12, #0 @ success if no exception is pending + moveq pc, lr @ return on success + DELIVER_PENDING_EXCEPTION + + .global art_get64_static_from_code + .extern artGet64StaticFromCode + /* + * Called by managed code to resolve a static field and load a 64-bit primitive value + */ +art_get64_static_from_code: + SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC + mov r2, r9 @ pass Thread::Current + mov r3, sp @ pass SP + bl artGet64StaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP) + ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME + cmp r12, #0 @ success if no exception is pending + moveq pc, lr @ return on success + DELIVER_PENDING_EXCEPTION + + .global art_get_obj_static_from_code + .extern artGetObjStaticFromCode + /* + * Called by managed code to resolve a static field and load an object reference + */ +art_get_obj_static_from_code: + SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC + mov r2, r9 @ pass Thread::Current + mov r3, sp @ pass SP + bl artGetObjStaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP) + ldr r12, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME + cmp r12, #0 @ success if no exception is pending + moveq pc, lr @ return on success + DELIVER_PENDING_EXCEPTION + + .global art_set32_static_from_code + .extern artSet32StaticFromCode + /* + * Called by managed code to resolve a static field and store a 32-bit primitive value + */ +art_set32_static_from_code: + SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC + mov r3, r9 @ pass Thread::Current + str sp, [sp, #0] @ pass SP + bl artSet32StaticFromCode @ (field_idx, referrer, new_val, Thread*, SP) + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME + cmp r0, #0 @ success if result is 0 + moveq pc, lr @ return on success + DELIVER_PENDING_EXCEPTION + + .global art_set64_static_from_code + .extern artSet32StaticFromCode + /* + * Called by managed code to resolve a static field and store a 64-bit primitive value + */ +art_set64_static_from_code: + SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC + mov r12, sp @ save SP + sub sp, #8 @ grow frame for alignment with stack args + push {r9, r12} @ pass Thread::Current and SP + bl artSet64StaticFromCode @ (field_idx, referrer, new_val, Thread*, SP) + add sp, #16 @ release out args + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME @ TODO: we can clearly save an add here + cmp r0, #0 @ success if result is 0 + moveq pc, lr @ return on success + DELIVER_PENDING_EXCEPTION + + .global art_set_obj_static_from_code + .extern artSetObjStaticFromCode + /* + * Called by managed code to resolve a static field and store an object reference + */ +art_set_obj_static_from_code: + SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC + mov r3, r9 @ pass Thread::Current + str sp, [sp, #0] @ pass SP + bl artSetObjStaticFromCode @ (field_idx, referrer, new_val, Thread*, SP) + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME + cmp r0, #0 @ success if result is 0 + moveq pc, lr @ return on success + DELIVER_PENDING_EXCEPTION .global art_alloc_object_from_code .extern artAllocObjectFromCode @@ -283,10 +386,7 @@ art_alloc_object_from_code: RESTORE_REF_ONLY_CALLEE_SAVE_FRAME cmp r0, #0 @ success if result is non-null movne pc, lr @ return on success - SETUP_CALLEE_SAVE_FRAME @ set up for throwing exception - mov r0, r9 @ pass Thread::Current - mov r1, sp @ pass SP - b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + DELIVER_PENDING_EXCEPTION .global art_alloc_array_from_code .extern artAllocArrayFromCode @@ -302,10 +402,7 @@ art_alloc_array_from_code: RESTORE_REF_ONLY_CALLEE_SAVE_FRAME cmp r0, #0 @ success if result is non-null movne pc, lr @ return on success - SETUP_CALLEE_SAVE_FRAME @ set up for throwing exception - mov r0, r9 @ pass Thread::Current - mov r1, sp @ pass SP - b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + DELIVER_PENDING_EXCEPTION .global art_check_and_alloc_array_from_code .extern artCheckAndAllocArrayFromCode @@ -319,12 +416,9 @@ art_check_and_alloc_array_from_code: @ artCheckAndAllocArrayFromCode(uint32_t type_idx, Method* method, int32_t count, Thread* , SP) bl artCheckAndAllocArrayFromCode RESTORE_REF_ONLY_CALLEE_SAVE_FRAME - cmp r0, #0 @ success if result is non-null - movne pc, lr @ return on success - SETUP_CALLEE_SAVE_FRAME @ set up for throwing exception - mov r0, r9 @ pass Thread::Current - mov r1, sp @ pass SP - b artDeliverPendingExceptionFromCode @ artDeliverPendingExceptionFromCode(Thread*, SP) + cmp r0, #0 @ success if result is non-null + movne pc, lr @ return on success + DELIVER_PENDING_EXCEPTION .global art_test_suspend .extern artCheckSuspendFromCode diff --git a/src/thread.cc b/src/thread.cc index b3dbcb69ed..079954b5e6 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -110,9 +110,16 @@ void Thread::InitFunctionPointers() { pCanPutArrayElementFromCode = art_can_put_array_element_from_code; pCheckAndAllocArrayFromCode = art_check_and_alloc_array_from_code; pCheckCastFromCode = art_check_cast_from_code; + pFindInstanceFieldFromCode = art_find_instance_field_from_code; + pGet32Static = art_get32_static_from_code; + pGet64Static = art_get64_static_from_code; + pGetObjStatic = art_get_obj_static_from_code; pHandleFillArrayDataFromCode = art_handle_fill_data_from_code; pInitializeStaticStorage = art_initialize_static_storage_from_code; pInvokeInterfaceTrampoline = art_invoke_interface_trampoline; + 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; @@ -130,16 +137,9 @@ void Thread::InitFunctionPointers() { pF2l = F2L; pD2l = D2L; pMemcpy = memcpy; - pGet32Static = Field::Get32StaticFromCode; - pSet32Static = Field::Set32StaticFromCode; - pGet64Static = Field::Get64StaticFromCode; - pSet64Static = Field::Set64StaticFromCode; - pGetObjStatic = Field::GetObjStaticFromCode; - pSetObjStatic = Field::SetObjStaticFromCode; pInitializeTypeFromCode = InitializeTypeFromCode; pResolveMethodFromCode = ResolveMethodFromCode; pInstanceofNonTrivialFromCode = Class::IsAssignableFromCode; - pFindInstanceFieldFromCode = Field::FindInstanceFieldFromCode; pCheckSuspendFromCode = artCheckSuspendFromJni; pFindNativeMethod = FindNativeMethod; pDecodeJObjectInThread = DecodeJObjectInThread; diff --git a/src/thread.h b/src/thread.h index c66e77e520..12302adc5d 100644 --- a/src/thread.h +++ b/src/thread.h @@ -116,31 +116,32 @@ class PACKED Thread { int (*pIdiv)(int, int); long long (*pLmul)(long long, long long); long long (*pLdivmod)(long long, long long); - void* (*pUnresolvedDirectMethodTrampolineFromCode)(int32_t, void*, Thread*, - Runtime::TrampolineType); void* (*pAllocObjectFromCode)(uint32_t, void*); void* (*pAllocArrayFromCode)(uint32_t, void*, int32_t); - void* (*pCheckAndAllocArrayFromCode)(uint32_t, void*, int32_t); - uint32_t (*pGet32Static)(uint32_t, const Method*); - void (*pSet32Static)(uint32_t, const Method*, uint32_t); - uint64_t (*pGet64Static)(uint32_t, const Method*); - void (*pSet64Static)(uint32_t, const Method*, uint64_t); - Object* (*pGetObjStatic)(uint32_t, const Method*); - void (*pSetObjStatic)(uint32_t, const Method*, Object*); void (*pCanPutArrayElementFromCode)(void*, void*); - uint32_t (*pInstanceofNonTrivialFromCode) (const Class*, const Class*); + void* (*pCheckAndAllocArrayFromCode)(uint32_t, void*, int32_t); void (*pCheckCastFromCode) (void*, void*); - Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*); - void (*pUnlockObjectFromCode)(void*); - void (*pLockObjectFromCode)(void*); + void (*pCheckSuspendFromCode)(Thread*); + Object* (*pDecodeJObjectInThread)(Thread* thread, jobject obj); void (*pDeliverException)(void*); + void* (*pFindInstanceFieldFromCode)(uint32_t, void*); + Method* (*pFindInterfaceMethodInCache)(Class*, uint32_t, const Method*, struct DvmDex*); + void* (*pFindNativeMethod)(Thread* thread); + int32_t (*pGet32Static)(uint32_t, void*); + int64_t (*pGet64Static)(uint32_t, void*); + void* (*pGetObjStatic)(uint32_t, void*); void (*pHandleFillArrayDataFromCode)(void*, void*); + void* (*pInitializeStaticStorage)(uint32_t, void*); + uint32_t (*pInstanceofNonTrivialFromCode) (const Class*, const Class*); + void (*pInvokeInterfaceTrampoline)(uint32_t, void*); Class* (*pInitializeTypeFromCode)(uint32_t, Method*); + void (*pLockObjectFromCode)(void*); + void (*pObjectInit)(Object*); void (*pResolveMethodFromCode)(Method*, uint32_t); - void (*pInvokeInterfaceTrampoline)(uint32_t, void*); - void* (*pInitializeStaticStorage)(uint32_t, void*); - Field* (*pFindInstanceFieldFromCode)(uint32_t, const Method*); - void (*pCheckSuspendFromCode)(Thread*); + String* (*pResolveStringFromCode)(Method*, int32_t); + int (*pSet32Static)(uint32_t, void*, int32_t); + int (*pSet64Static)(uint32_t, void*, int64_t); + int (*pSetObjStatic)(uint32_t, void*, void*); void (*pTestSuspendFromCode)(); void (*pThrowStackOverflowFromCode)(void*); void (*pThrowNullPointerFromCode)(); @@ -150,10 +151,9 @@ class PACKED Thread { void (*pThrowNegArraySizeFromCode)(int32_t); void (*pThrowNoSuchMethodFromCode)(int32_t); void (*pThrowAbstractMethodErrorFromCode)(Method* method, Thread* thread, Method** sp); - void* (*pFindNativeMethod)(Thread* thread); - Object* (*pDecodeJObjectInThread)(Thread* thread, jobject obj); - String* (*pResolveStringFromCode)(Method*, int32_t); - void (*pObjectInit)(Object*); + void (*pUnlockObjectFromCode)(void*); + void* (*pUnresolvedDirectMethodTrampolineFromCode)(int32_t, void*, Thread*, + Runtime::TrampolineType); class StackVisitor { public: diff --git a/src/thread_arm.cc b/src/thread_arm.cc index a7efc1a5ac..0196eb8970 100644 --- a/src/thread_arm.cc +++ b/src/thread_arm.cc @@ -9,6 +9,7 @@ namespace art { void Thread::InitCpu() { CHECK_EQ(THREAD_SUSPEND_COUNT_OFFSET, OFFSETOF_MEMBER(Thread, suspend_count_)); + CHECK_EQ(THREAD_EXCEPTION_OFFSET, OFFSETOF_MEMBER(Thread, exception_)); } } // namespace art |