diff options
author | Ian Rogers <irogers@google.com> | 2013-10-04 11:17:26 -0700 |
---|---|---|
committer | Ian Rogers <irogers@google.com> | 2013-10-08 15:54:54 -0700 |
commit | a9a8254c920ce8e22210abfc16c9842ce0aea28f (patch) | |
tree | 56614ee997940e8e3b88fef43b890e8a33e78112 /runtime/arch/arm | |
parent | 34633b22f74393344987a50b8aaee548a9dadc18 (diff) | |
download | art-a9a8254c920ce8e22210abfc16c9842ce0aea28f.zip art-a9a8254c920ce8e22210abfc16c9842ce0aea28f.tar.gz art-a9a8254c920ce8e22210abfc16c9842ce0aea28f.tar.bz2 |
Improve quick codegen for aput-object.
1) don't type check known null.
2) if we know types in verify don't check at runtime.
3) if we're runtime checking then move all the code out-of-line.
Also, don't set up a callee-save frame for check-cast, do an instance-of test
then throw an exception if that fails.
Tidy quick entry point of Ldivmod to Lmod which it is on x86 and mips.
Fix monitor-enter/exit NPE for MIPS.
Fix benign bug in mirror::Class::CannotBeAssignedFromOtherTypes, a byte[]
cannot be assigned to from other types.
Change-Id: I9cb3859ec70cca71ed79331ec8df5bec969d6745
Diffstat (limited to 'runtime/arch/arm')
-rw-r--r-- | runtime/arch/arm/asm_support_arm.h | 2 | ||||
-rw-r--r-- | runtime/arch/arm/entrypoints_init_arm.cc | 14 | ||||
-rw-r--r-- | runtime/arch/arm/quick_entrypoints_arm.S | 107 | ||||
-rw-r--r-- | runtime/arch/arm/thread_arm.cc | 1 |
4 files changed, 98 insertions, 26 deletions
diff --git a/runtime/arch/arm/asm_support_arm.h b/runtime/arch/arm/asm_support_arm.h index 69fb9c3..cfffbea 100644 --- a/runtime/arch/arm/asm_support_arm.h +++ b/runtime/arch/arm/asm_support_arm.h @@ -25,6 +25,8 @@ #define rSELF r9 // Offset of field Thread::suspend_count_ verified in InitCpu #define THREAD_FLAGS_OFFSET 0 +// Offset of field Thread::card_table_ verified in InitCpu +#define THREAD_CARD_TABLE_OFFSET 8 // Offset of field Thread::exception_ verified in InitCpu #define THREAD_EXCEPTION_OFFSET 12 // Offset of field Thread::thin_lock_thread_id_ verified in InitCpu diff --git a/runtime/arch/arm/entrypoints_init_arm.cc b/runtime/arch/arm/entrypoints_init_arm.cc index e6e13be..352982f 100644 --- a/runtime/arch/arm/entrypoints_init_arm.cc +++ b/runtime/arch/arm/entrypoints_init_arm.cc @@ -52,7 +52,6 @@ extern "C" void* art_quick_check_and_alloc_array_with_access_check_instrumented( // Cast entrypoints. extern "C" uint32_t artIsAssignableFromCode(const mirror::Class* klass, const mirror::Class* ref_class); -extern "C" void art_quick_can_put_array_element(void*, void*); extern "C" void art_quick_check_cast(void*, void*); // DexCache entrypoints. @@ -78,7 +77,10 @@ extern "C" int64_t art_quick_get64_static(uint32_t); extern "C" void* art_quick_get_obj_instance(uint32_t, void*); extern "C" void* art_quick_get_obj_static(uint32_t); -// FillArray entrypoint. +// Array entrypoints. +extern "C" void art_quick_aput_obj_with_null_and_bound_check(void*, uint32_t, void*); +extern "C" void art_quick_aput_obj_with_bound_check(void*, uint32_t, void*); +extern "C" void art_quick_aput_obj(void*, uint32_t, void*); extern "C" void art_quick_handle_fill_data(void*, void*); // Lock entrypoints. @@ -182,7 +184,6 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints, // Cast qpoints->pInstanceofNonTrivial = artIsAssignableFromCode; - qpoints->pCanPutArrayElement = art_quick_can_put_array_element; qpoints->pCheckCast = art_quick_check_cast; // DexCache @@ -205,7 +206,10 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints, qpoints->pGet64Static = art_quick_get64_static; qpoints->pGetObjStatic = art_quick_get_obj_static; - // FillArray + // Array + qpoints->pAputObjectWithNullAndBoundCheck = art_quick_aput_obj_with_null_and_bound_check; + qpoints->pAputObjectWithBoundCheck = art_quick_aput_obj_with_bound_check; + qpoints->pAputObject = art_quick_aput_obj; qpoints->pHandleFillArrayData = art_quick_handle_fill_data; // JNI @@ -236,7 +240,7 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints, qpoints->pD2l = art_d2l; qpoints->pF2l = art_f2l; qpoints->pLdiv = __aeabi_ldivmod; - qpoints->pLdivmod = __aeabi_ldivmod; // result returned in r2:r3 + qpoints->pLmod = __aeabi_ldivmod; // result returned in r2:r3 qpoints->pLmul = art_quick_mul_long; qpoints->pShlLong = art_quick_shl_long; qpoints->pShrLong = art_quick_shr_long; diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S index cb61698..d073177 100644 --- a/runtime/arch/arm/quick_entrypoints_arm.S +++ b/runtime/arch/arm/quick_entrypoints_arm.S @@ -152,6 +152,7 @@ ENTRY \c_name mov r1, r9 @ pass Thread::Current mov r2, sp @ pass SP b \cxx_name @ \cxx_name(Thread*, SP) + bkpt END \c_name .endm @@ -162,6 +163,7 @@ ENTRY \c_name mov r2, r9 @ pass Thread::Current mov r3, sp @ pass SP b \cxx_name @ \cxx_name(Thread*, SP) + bkpt END \c_name .endm @@ -389,33 +391,96 @@ slow_unlock: END art_quick_unlock_object /* - * Entry from managed code that calls artCheckCastFromCode and delivers exception on failure. + * Entry from managed code that calls artIsAssignableFromCode and on failure calls + * artThrowClassCastException. */ - .extern artCheckCastFromCode + .extern artThrowClassCastException ENTRY art_quick_check_cast - SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case exception allocation triggers GC - mov r2, r9 @ pass Thread::Current - mov r3, sp @ pass SP - bl artCheckCastFromCode @ (Class* a, Class* b, Thread*, SP) - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME - RETURN_IF_RESULT_IS_ZERO - DELIVER_PENDING_EXCEPTION + push {r0-r1, lr} @ save arguments, link register and pad + .save {r0-r1, lr} + .cfi_adjust_cfa_offset 12 + .cfi_rel_offset r0, 0 + .cfi_rel_offset r1, 4 + .cfi_rel_offset lr, 8 + sub sp, #4 + .pad #4 + .cfi_adjust_cfa_offset 4 + bl artIsAssignableFromCode + cbz r0, throw_class_cast_exception + add sp, #4 + .cfi_adjust_cfa_offset -4 + pop {r0-r1, pc} +throw_class_cast_exception: + add sp, #4 + .cfi_adjust_cfa_offset -4 + pop {r0-r1, lr} + SETUP_SAVE_ALL_CALLEE_SAVE_FRAME // save all registers as basis for long jump context + mov r2, r9 @ pass Thread::Current + mov r3, sp @ pass SP + b artThrowClassCastException @ (Class*, Class*, Thread*, SP) + bkpt END art_quick_check_cast /* - * Entry from managed code that calls artCanPutArrayElementFromCode and delivers exception on - * failure. + * Entry from managed code for array put operations of objects where the value being stored + * needs to be checked for compatibility. + * r0 = array, r1 = index, r2 = value */ - .extern artCanPutArrayElementFromCode -ENTRY art_quick_can_put_array_element - SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case exception allocation triggers GC - mov r2, r9 @ pass Thread::Current - mov r3, sp @ pass SP - bl artCanPutArrayElementFromCode @ (Object* element, Class* array_class, Thread*, SP) - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME - RETURN_IF_RESULT_IS_ZERO - DELIVER_PENDING_EXCEPTION -END art_quick_can_put_array_element +ENTRY art_quick_aput_obj_with_null_and_bound_check + tst r0, r0 + bne art_quick_aput_obj_with_bound_check + b art_quick_throw_null_pointer_exception +END art_quick_aput_obj_with_null_and_bound_check + +ENTRY art_quick_aput_obj_with_bound_check + ldr r3, [r0, #ARRAY_LENGTH_OFFSET] + cmp r3, r1 + bhi art_quick_aput_obj + mov r0, r1 + mov r1, r3 + b art_quick_throw_array_bounds +END art_quick_aput_obj_with_bound_check + +ENTRY art_quick_aput_obj + cbz r2, do_aput_null + ldr r3, [r0, #CLASS_OFFSET] + ldr ip, [r2, #CLASS_OFFSET] + ldr r3, [r3, #CLASS_COMPONENT_TYPE_OFFSET] + cmp r3, ip @ value's type == array's component type - trivial assignability + bne check_assignability +do_aput: + add r3, r0, #OBJECT_ARRAY_DATA_OFFSET + str r2, [r3, r1, lsl #2] + ldr r3, [r9, #THREAD_CARD_TABLE_OFFSET] + lsr r0, r0, #7 + strb r3, [r3, r0] + blx lr +do_aput_null: + add r3, r0, #OBJECT_ARRAY_DATA_OFFSET + str r2, [r3, r1, lsl #2] + blx lr +check_assignability: + push {r0-r2, lr} @ save arguments + mov r1, ip + mov r0, r3 + bl artIsAssignableFromCode + cbz r0, throw_array_store_exception + pop {r0-r2, lr} + add r3, r0, #OBJECT_ARRAY_DATA_OFFSET + str r2, [r3, r1, lsl #2] + ldr r3, [r9, #THREAD_CARD_TABLE_OFFSET] + lsr r0, r0, #7 + strb r3, [r3, r0] + blx lr +throw_array_store_exception: + pop {r0-r2, lr} + SETUP_SAVE_ALL_CALLEE_SAVE_FRAME + mov r1, r2 + mov r2, r9 @ pass Thread::Current + mov r3, sp @ pass SP + b artThrowArrayStoreException @ (Class*, Class*, Thread*, SP) + bkpt @ unreached +END art_quick_aput_obj /* * Entry from managed code when uninitialized static storage, this stub will run the class diff --git a/runtime/arch/arm/thread_arm.cc b/runtime/arch/arm/thread_arm.cc index 75eef60..8c1efeb 100644 --- a/runtime/arch/arm/thread_arm.cc +++ b/runtime/arch/arm/thread_arm.cc @@ -23,6 +23,7 @@ namespace art { void Thread::InitCpu() { CHECK_EQ(THREAD_FLAGS_OFFSET, OFFSETOF_MEMBER(Thread, state_and_flags_)); + CHECK_EQ(THREAD_CARD_TABLE_OFFSET, OFFSETOF_MEMBER(Thread, card_table_)); CHECK_EQ(THREAD_EXCEPTION_OFFSET, OFFSETOF_MEMBER(Thread, exception_)); CHECK_EQ(THREAD_ID_OFFSET, OFFSETOF_MEMBER(Thread, thin_lock_thread_id_)); } |