diff options
author | Fred Shih <ffred@google.com> | 2014-07-16 18:38:08 -0700 |
---|---|---|
committer | Fred Shih <ffred@google.com> | 2014-08-25 11:16:53 -0700 |
commit | 37f05ef45e0393de812d51261dc293240c17294d (patch) | |
tree | 7c7793862efa52e1deb42babbdcb652c245ab941 /runtime/arch | |
parent | e25826e28ea65d9c1aa23f84788a091c677b20c7 (diff) | |
download | android_art-37f05ef45e0393de812d51261dc293240c17294d.tar.gz android_art-37f05ef45e0393de812d51261dc293240c17294d.tar.bz2 android_art-37f05ef45e0393de812d51261dc293240c17294d.zip |
Reduced memory usage of primitive fields smaller than 4-bytes
Reduced memory used by byte and boolean fields from 4 bytes down to a
single byte and shorts and chars down to two bytes. Fields are now
arranged as Reference followed by decreasing component sizes, with
fields shuffled forward as needed.
Bug: 8135266
Change-Id: I65eaf31ed27e5bd5ba0c7d4606454b720b074752
Diffstat (limited to 'runtime/arch')
-rw-r--r-- | runtime/arch/arm/entrypoints_init_arm.cc | 24 | ||||
-rw-r--r-- | runtime/arch/arm/quick_entrypoints_arm.S | 255 | ||||
-rw-r--r-- | runtime/arch/arm64/entrypoints_init_arm64.cc | 24 | ||||
-rw-r--r-- | runtime/arch/arm64/quick_entrypoints_arm64.S | 12 | ||||
-rw-r--r-- | runtime/arch/mips/entrypoints_init_mips.cc | 24 | ||||
-rw-r--r-- | runtime/arch/mips/quick_entrypoints_mips.S | 167 | ||||
-rw-r--r-- | runtime/arch/stub_test.cc | 349 | ||||
-rw-r--r-- | runtime/arch/x86/entrypoints_init_x86.cc | 24 | ||||
-rw-r--r-- | runtime/arch/x86/quick_entrypoints_x86.S | 171 | ||||
-rw-r--r-- | runtime/arch/x86_64/entrypoints_init_x86_64.cc | 24 | ||||
-rw-r--r-- | runtime/arch/x86_64/quick_entrypoints_x86_64.S | 12 |
11 files changed, 864 insertions, 222 deletions
diff --git a/runtime/arch/arm/entrypoints_init_arm.cc b/runtime/arch/arm/entrypoints_init_arm.cc index 8c6afd66bd..38a88c574c 100644 --- a/runtime/arch/arm/entrypoints_init_arm.cc +++ b/runtime/arch/arm/entrypoints_init_arm.cc @@ -48,12 +48,24 @@ extern "C" void* art_quick_initialize_type_and_verify_access(uint32_t, void*); extern "C" void* art_quick_resolve_string(void*, uint32_t); // Field entrypoints. +extern "C" int art_quick_set8_instance(uint32_t, void*, int8_t); +extern "C" int art_quick_set8_static(uint32_t, int8_t); +extern "C" int art_quick_set16_instance(uint32_t, void*, int16_t); +extern "C" int art_quick_set16_static(uint32_t, int16_t); extern "C" int art_quick_set32_instance(uint32_t, void*, int32_t); extern "C" int art_quick_set32_static(uint32_t, int32_t); extern "C" int art_quick_set64_instance(uint32_t, void*, int64_t); extern "C" int art_quick_set64_static(uint32_t, int64_t); extern "C" int art_quick_set_obj_instance(uint32_t, void*, void*); extern "C" int art_quick_set_obj_static(uint32_t, void*); +extern "C" int8_t art_quick_get_byte_instance(uint32_t, void*); +extern "C" uint8_t art_quick_get_boolean_instance(uint32_t, void*); +extern "C" int8_t art_quick_get_byte_static(uint32_t); +extern "C" uint8_t art_quick_get_boolean_static(uint32_t); +extern "C" int16_t art_quick_get_short_instance(uint32_t, void*); +extern "C" uint16_t art_quick_get_char_instance(uint32_t, void*); +extern "C" int16_t art_quick_get_short_static(uint32_t); +extern "C" uint16_t art_quick_get_char_static(uint32_t); extern "C" int32_t art_quick_get32_instance(uint32_t, void*); extern "C" int32_t art_quick_get32_static(uint32_t); extern "C" int64_t art_quick_get64_instance(uint32_t, void*); @@ -154,15 +166,27 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints, qpoints->pResolveString = art_quick_resolve_string; // Field + qpoints->pSet8Instance = art_quick_set8_instance; + qpoints->pSet8Static = art_quick_set8_static; + qpoints->pSet16Instance = art_quick_set16_instance; + qpoints->pSet16Static = art_quick_set16_static; qpoints->pSet32Instance = art_quick_set32_instance; qpoints->pSet32Static = art_quick_set32_static; qpoints->pSet64Instance = art_quick_set64_instance; qpoints->pSet64Static = art_quick_set64_static; qpoints->pSetObjInstance = art_quick_set_obj_instance; qpoints->pSetObjStatic = art_quick_set_obj_static; + qpoints->pGetByteInstance = art_quick_get_byte_instance; + qpoints->pGetBooleanInstance = art_quick_get_boolean_instance; + qpoints->pGetShortInstance = art_quick_get_short_instance; + qpoints->pGetCharInstance = art_quick_get_char_instance; qpoints->pGet32Instance = art_quick_get32_instance; qpoints->pGet64Instance = art_quick_get64_instance; qpoints->pGetObjInstance = art_quick_get_obj_instance; + qpoints->pGetByteStatic = art_quick_get_byte_static; + qpoints->pGetBooleanStatic = art_quick_get_boolean_static; + qpoints->pGetShortStatic = art_quick_get_short_static; + qpoints->pGetCharStatic = art_quick_get_char_static; qpoints->pGet32Static = art_quick_get32_static; qpoints->pGet64Static = art_quick_get64_static; qpoints->pGetObjStatic = art_quick_get_obj_static; diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S index 1b30c9cca2..51bcd3c654 100644 --- a/runtime/arch/arm/quick_entrypoints_arm.S +++ b/runtime/arch/arm/quick_entrypoints_arm.S @@ -203,6 +203,77 @@ ENTRY \c_name END \c_name .endm +.macro RETURN_OR_DELIVER_PENDING_EXCEPTION_REG reg + ldr \reg, [r9, #THREAD_EXCEPTION_OFFSET] // Get exception field. + cbnz \reg, 1f + bx lr +1: + DELIVER_PENDING_EXCEPTION +.endm + +.macro RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 + RETURN_OR_DELIVER_PENDING_EXCEPTION_REG r1 +.endm + +.macro RETURN_IF_RESULT_IS_ZERO_OR_DELIVER + RETURN_IF_RESULT_IS_ZERO + DELIVER_PENDING_EXCEPTION +.endm + +// Macros taking opportunity of code similarities for downcalls with referrer for non-wide fields. +.macro ONE_ARG_REF_DOWNCALL name, entrypoint, return + .extern \entrypoint +ENTRY \name + SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC + ldr r1, [sp, #32] @ pass referrer + mov r2, r9 @ pass Thread::Current + mov r3, sp @ pass SP + bl \entrypoint @ (uint32_t field_idx, const Method* referrer, Thread*, SP) + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME + \return +END \name +.endm + +.macro TWO_ARG_REF_DOWNCALL name, entrypoint, return + .extern \entrypoint +ENTRY \name + SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC + ldr r2, [sp, #32] @ pass referrer + mov r3, r9 @ pass Thread::Current + mov r12, sp + str r12, [sp, #-16]! @ expand the frame and pass SP + .pad #16 + .cfi_adjust_cfa_offset 16 + bl \entrypoint @ (field_idx, Object*, referrer, Thread*, SP) + add sp, #16 @ strip the extra frame + .cfi_adjust_cfa_offset -16 + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME + \return +END \name +.endm + +.macro THREE_ARG_REF_DOWNCALL name, entrypoint, return + .extern \entrypoint +ENTRY \name + SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC + ldr r3, [sp, #32] @ pass referrer + mov r12, sp @ save SP + sub sp, #8 @ grow frame for alignment with stack args + .pad #8 + .cfi_adjust_cfa_offset 8 + push {r9, r12} @ pass Thread::Current and SP + .save {r9, r12} + .cfi_adjust_cfa_offset 8 + .cfi_rel_offset r9, 0 + .cfi_rel_offset r12, 4 + bl \entrypoint @ (field_idx, Object*, new_val, referrer, Thread*, SP) + add sp, #16 @ release out args + .cfi_adjust_cfa_offset -16 + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME @ TODO: we can clearly save an add here + \return +END \name +.endm + /* * Called by managed code, saves callee saves and then calls artThrowException * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception. @@ -601,23 +672,14 @@ ENTRY art_quick_initialize_type_and_verify_access END art_quick_initialize_type_and_verify_access /* - * Called by managed code to resolve a static field and load a 32-bit primitive value. + * Called by managed code to resolve a static field and load a non-wide value. */ - .extern artGet32StaticFromCode -ENTRY art_quick_get32_static - SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC - ldr r1, [sp, #32] @ pass referrer - mov r2, r9 @ pass Thread::Current - mov r3, sp @ pass SP - bl artGet32StaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP) - ldr r1, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME - cbnz r1, 1f @ success if no exception pending - bx lr @ return on success -1: - DELIVER_PENDING_EXCEPTION -END art_quick_get32_static - +ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 /* * Called by managed code to resolve a static field and load a 64-bit primitive value. */ @@ -637,43 +699,14 @@ ENTRY art_quick_get64_static END art_quick_get64_static /* - * Called by managed code to resolve a static field and load an object reference. + * Called by managed code to resolve an instance field and load a non-wide value. */ - .extern artGetObjStaticFromCode -ENTRY art_quick_get_obj_static - SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC - ldr r1, [sp, #32] @ pass referrer - mov r2, r9 @ pass Thread::Current - mov r3, sp @ pass SP - bl artGetObjStaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP) - ldr r1, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME - cbnz r1, 1f @ success if no exception pending - bx lr @ return on success -1: - DELIVER_PENDING_EXCEPTION -END art_quick_get_obj_static - - /* - * Called by managed code to resolve an instance field and load a 32-bit primitive value. - */ - .extern artGet32InstanceFromCode -ENTRY art_quick_get32_instance - SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC - ldr r2, [sp, #32] @ pass referrer - mov r3, r9 @ pass Thread::Current - mov r12, sp - str r12, [sp, #-16]! @ expand the frame and pass SP - bl artGet32InstanceFromCode @ (field_idx, Object*, referrer, Thread*, SP) - add sp, #16 @ strip the extra frame - ldr r1, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME - cbnz r1, 1f @ success if no exception pending - bx lr @ return on success -1: - DELIVER_PENDING_EXCEPTION -END art_quick_get32_instance - +TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 /* * Called by managed code to resolve an instance field and load a 64-bit primitive value. */ @@ -698,48 +731,12 @@ ENTRY art_quick_get64_instance END art_quick_get64_instance /* - * Called by managed code to resolve an instance field and load an object reference. - */ - .extern artGetObjInstanceFromCode -ENTRY art_quick_get_obj_instance - SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC - ldr r2, [sp, #32] @ pass referrer - mov r3, r9 @ pass Thread::Current - mov r12, sp - str r12, [sp, #-16]! @ expand the frame and pass SP - .pad #16 - .cfi_adjust_cfa_offset 16 - bl artGetObjInstanceFromCode @ (field_idx, Object*, referrer, Thread*, SP) - add sp, #16 @ strip the extra frame - .cfi_adjust_cfa_offset -16 - ldr r1, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME - cbnz r1, 1f @ success if no exception pending - bx lr @ return on success -1: - DELIVER_PENDING_EXCEPTION -END art_quick_get_obj_instance - - /* - * Called by managed code to resolve a static field and store a 32-bit primitive value. + * Called by managed code to resolve a static field and store a non-wide value. */ - .extern artSet32StaticFromCode -ENTRY art_quick_set32_static - SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC - ldr r2, [sp, #32] @ pass referrer - mov r3, r9 @ pass Thread::Current - mov r12, sp - str r12, [sp, #-16]! @ expand the frame and pass SP - .pad #16 - .cfi_adjust_cfa_offset 16 - bl artSet32StaticFromCode @ (field_idx, new_val, referrer, Thread*, SP) - add sp, #16 @ strip the extra frame - .cfi_adjust_cfa_offset -16 - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME - RETURN_IF_RESULT_IS_ZERO - DELIVER_PENDING_EXCEPTION -END art_quick_set32_static - +TWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER +TWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER +TWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER +TWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER /* * Called by managed code to resolve a static field and store a 64-bit primitive value. * On entry r0 holds field index, r1:r2 hold new_val @@ -767,53 +764,16 @@ ENTRY art_quick_set64_static END art_quick_set64_static /* - * Called by managed code to resolve a static field and store an object reference. - */ - .extern artSetObjStaticFromCode -ENTRY art_quick_set_obj_static - SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC - ldr r2, [sp, #32] @ pass referrer - mov r3, r9 @ pass Thread::Current - mov r12, sp - str r12, [sp, #-16]! @ expand the frame and pass SP - .pad #16 - .cfi_adjust_cfa_offset 16 - bl artSetObjStaticFromCode @ (field_idx, new_val, referrer, Thread*, SP) - add sp, #16 @ strip the extra frame - .cfi_adjust_cfa_offset -16 - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME - RETURN_IF_RESULT_IS_ZERO - DELIVER_PENDING_EXCEPTION -END art_quick_set_obj_static - - /* - * Called by managed code to resolve an instance field and store a 32-bit primitive value. + * Called by managed code to resolve an instance field and store a non-wide value. */ - .extern artSet32InstanceFromCode -ENTRY art_quick_set32_instance - SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC - ldr r3, [sp, #32] @ pass referrer - mov r12, sp @ save SP - sub sp, #8 @ grow frame for alignment with stack args - .pad #8 - .cfi_adjust_cfa_offset 8 - push {r9, r12} @ pass Thread::Current and SP - .save {r9, r12} - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset r9, 0 - .cfi_rel_offset r12, 4 - bl artSet32InstanceFromCode @ (field_idx, Object*, new_val, referrer, Thread*, SP) - add sp, #16 @ release out args - .cfi_adjust_cfa_offset -16 - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME @ TODO: we can clearly save an add here - RETURN_IF_RESULT_IS_ZERO - DELIVER_PENDING_EXCEPTION -END art_quick_set32_instance - +THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER +THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER +THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER +THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER /* * Called by managed code to resolve an instance field and store a 64-bit primitive value. */ - .extern artSet32InstanceFromCode + .extern artSet64InstanceFromCode ENTRY art_quick_set64_instance SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC mov r12, sp @ save SP @@ -833,29 +793,6 @@ ENTRY art_quick_set64_instance END art_quick_set64_instance /* - * Called by managed code to resolve an instance field and store an object reference. - */ - .extern artSetObjInstanceFromCode -ENTRY art_quick_set_obj_instance - SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC - ldr r3, [sp, #32] @ pass referrer - mov r12, sp @ save SP - sub sp, #8 @ grow frame for alignment with stack args - .pad #8 - .cfi_adjust_cfa_offset 8 - push {r9, r12} @ pass Thread::Current and SP - .save {r9, r12} - .cfi_adjust_cfa_offset 8 - .cfi_rel_offset r9, 0 - bl artSetObjInstanceFromCode @ (field_idx, Object*, new_val, referrer, Thread*, SP) - add sp, #16 @ release out args - .cfi_adjust_cfa_offset -16 - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME @ TODO: we can clearly save an add here - RETURN_IF_RESULT_IS_ZERO - DELIVER_PENDING_EXCEPTION -END art_quick_set_obj_instance - - /* * Entry from managed code to resolve a string, this stub will allocate a String and deliver an * exception on error. On success the String is returned. R0 holds the referring method, * R1 holds the string index. The fast path check for hit in strings cache has already been diff --git a/runtime/arch/arm64/entrypoints_init_arm64.cc b/runtime/arch/arm64/entrypoints_init_arm64.cc index 0c33d9ce83..70e93b3051 100644 --- a/runtime/arch/arm64/entrypoints_init_arm64.cc +++ b/runtime/arch/arm64/entrypoints_init_arm64.cc @@ -47,12 +47,24 @@ extern "C" void* art_quick_initialize_type_and_verify_access(uint32_t, void*); extern "C" void* art_quick_resolve_string(void*, uint32_t); // Field entrypoints. +extern "C" int art_quick_set8_instance(uint32_t, void*, int8_t); +extern "C" int art_quick_set8_static(uint32_t, int8_t); +extern "C" int art_quick_set16_instance(uint32_t, void*, int16_t); +extern "C" int art_quick_set16_static(uint32_t, int16_t); extern "C" int art_quick_set32_instance(uint32_t, void*, int32_t); extern "C" int art_quick_set32_static(uint32_t, int32_t); extern "C" int art_quick_set64_instance(uint32_t, void*, int64_t); extern "C" int art_quick_set64_static(uint32_t, int64_t); extern "C" int art_quick_set_obj_instance(uint32_t, void*, void*); extern "C" int art_quick_set_obj_static(uint32_t, void*); +extern "C" uint8_t art_quick_get_boolean_instance(uint32_t, void*); +extern "C" int8_t art_quick_get_byte_instance(uint32_t, void*); +extern "C" uint8_t art_quick_get_boolean_static(uint32_t); +extern "C" int8_t art_quick_get_byte_static(uint32_t); +extern "C" uint16_t art_quick_get_char_instance(uint32_t, void*); +extern "C" int16_t art_quick_get_short_instance(uint32_t, void*); +extern "C" uint16_t art_quick_get_char_static(uint32_t); +extern "C" int16_t art_quick_get_short_static(uint32_t); extern "C" int32_t art_quick_get32_instance(uint32_t, void*); extern "C" int32_t art_quick_get32_static(uint32_t); extern "C" int64_t art_quick_get64_instance(uint32_t, void*); @@ -136,15 +148,27 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints, qpoints->pResolveString = art_quick_resolve_string; // Field + qpoints->pSet8Instance = art_quick_set8_instance; + qpoints->pSet8Static = art_quick_set8_static; + qpoints->pSet16Instance = art_quick_set16_instance; + qpoints->pSet16Static = art_quick_set16_static; qpoints->pSet32Instance = art_quick_set32_instance; qpoints->pSet32Static = art_quick_set32_static; qpoints->pSet64Instance = art_quick_set64_instance; qpoints->pSet64Static = art_quick_set64_static; qpoints->pSetObjInstance = art_quick_set_obj_instance; qpoints->pSetObjStatic = art_quick_set_obj_static; + qpoints->pGetBooleanInstance = art_quick_get_boolean_instance; + qpoints->pGetByteInstance = art_quick_get_byte_instance; + qpoints->pGetCharInstance = art_quick_get_char_instance; + qpoints->pGetShortInstance = art_quick_get_short_instance; qpoints->pGet32Instance = art_quick_get32_instance; qpoints->pGet64Instance = art_quick_get64_instance; qpoints->pGetObjInstance = art_quick_get_obj_instance; + qpoints->pGetBooleanStatic = art_quick_get_boolean_static; + qpoints->pGetByteStatic = art_quick_get_byte_static; + qpoints->pGetCharStatic = art_quick_get_char_static; + qpoints->pGetShortStatic = art_quick_get_short_static; qpoints->pGet32Static = art_quick_get32_static; qpoints->pGet64Static = art_quick_get64_static; qpoints->pGetObjStatic = art_quick_get_obj_static; diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S index 2a19e27b04..606816a181 100644 --- a/runtime/arch/arm64/quick_entrypoints_arm64.S +++ b/runtime/arch/arm64/quick_entrypoints_arm64.S @@ -1266,17 +1266,29 @@ TWO_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorage TWO_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_RESULT_IS_NON_ZERO TWO_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_RESULT_IS_NON_ZERO +ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 TWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +TWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER +TWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER TWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER TWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER +THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER +THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER THREE_ARG_DOWNCALL art_quick_set64_instance, artSet64InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER diff --git a/runtime/arch/mips/entrypoints_init_mips.cc b/runtime/arch/mips/entrypoints_init_mips.cc index d3e7d5e904..25e911d765 100644 --- a/runtime/arch/mips/entrypoints_init_mips.cc +++ b/runtime/arch/mips/entrypoints_init_mips.cc @@ -49,12 +49,24 @@ extern "C" void* art_quick_initialize_type_and_verify_access(uint32_t, void*); extern "C" void* art_quick_resolve_string(void*, uint32_t); // Field entrypoints. +extern "C" int art_quick_set8_instance(uint32_t, void*, int8_t); +extern "C" int art_quick_set8_static(uint32_t, int8_t); +extern "C" int art_quick_set16_instance(uint32_t, void*, int16_t); +extern "C" int art_quick_set16_static(uint32_t, int16_t); extern "C" int art_quick_set32_instance(uint32_t, void*, int32_t); extern "C" int art_quick_set32_static(uint32_t, int32_t); extern "C" int art_quick_set64_instance(uint32_t, void*, int64_t); extern "C" int art_quick_set64_static(uint32_t, int64_t); extern "C" int art_quick_set_obj_instance(uint32_t, void*, void*); extern "C" int art_quick_set_obj_static(uint32_t, void*); +extern "C" uint8_t art_quick_get_boolean_instance(uint32_t, void*); +extern "C" int8_t art_quick_get_byte_instance(uint32_t, void*); +extern "C" uint8_t art_quick_get_boolean_static(uint32_t); +extern "C" int8_t art_quick_get_byte_static(uint32_t); +extern "C" uint16_t art_quick_get_char_instance(uint32_t, void*); +extern "C" int16_t art_quick_get_short_instance(uint32_t, void*); +extern "C" uint16_t art_quick_get_char_static(uint32_t); +extern "C" int16_t art_quick_get_short_static(uint32_t); extern "C" int32_t art_quick_get32_instance(uint32_t, void*); extern "C" int32_t art_quick_get32_static(uint32_t); extern "C" int64_t art_quick_get64_instance(uint32_t, void*); @@ -159,15 +171,27 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints, qpoints->pResolveString = art_quick_resolve_string; // Field + qpoints->pSet8Instance = art_quick_set8_instance; + qpoints->pSet8Static = art_quick_set8_static; + qpoints->pSet16Instance = art_quick_set16_instance; + qpoints->pSet16Static = art_quick_set16_static; qpoints->pSet32Instance = art_quick_set32_instance; qpoints->pSet32Static = art_quick_set32_static; qpoints->pSet64Instance = art_quick_set64_instance; qpoints->pSet64Static = art_quick_set64_static; qpoints->pSetObjInstance = art_quick_set_obj_instance; qpoints->pSetObjStatic = art_quick_set_obj_static; + qpoints->pGetBooleanInstance = art_quick_get_boolean_instance; + qpoints->pGetByteInstance = art_quick_get_byte_instance; + qpoints->pGetCharInstance = art_quick_get_char_instance; + qpoints->pGetShortInstance = art_quick_get_short_instance; qpoints->pGet32Instance = art_quick_get32_instance; qpoints->pGet64Instance = art_quick_get64_instance; qpoints->pGetObjInstance = art_quick_get_obj_instance; + qpoints->pGetBooleanStatic = art_quick_get_boolean_static; + qpoints->pGetByteStatic = art_quick_get_byte_static; + qpoints->pGetCharStatic = art_quick_get_char_static; + qpoints->pGetShortStatic = art_quick_get_short_static; qpoints->pGet32Static = art_quick_get32_static; qpoints->pGet64Static = art_quick_get64_static; qpoints->pGetObjStatic = art_quick_get_obj_static; diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S index 8786222250..9e9e5236af 100644 --- a/runtime/arch/mips/quick_entrypoints_mips.S +++ b/runtime/arch/mips/quick_entrypoints_mips.S @@ -739,6 +739,59 @@ ENTRY art_quick_initialize_type_and_verify_access move $a3, $sp # pass $sp RETURN_IF_RESULT_IS_NON_ZERO END art_quick_initialize_type_and_verify_access + /* + * Called by managed code to resolve a static field and load a boolean primitive value. + */ + .extern artGetBooleanStaticFromCode +ENTRY art_quick_get_boolean_static + GENERATE_GLOBAL_POINTER + SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC + lw $a1, 64($sp) # pass referrer's Method* + move $a2, rSELF # pass Thread::Current + jal artGetBooleanStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp) + move $a3, $sp # pass $sp + RETURN_IF_NO_EXCEPTION +END art_quick_get_boolean_static + /* + * Called by managed code to resolve a static field and load a byte primitive value. + */ + .extern artGetByteStaticFromCode +ENTRY art_quick_get_byte_static + GENERATE_GLOBAL_POINTER + SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC + lw $a1, 64($sp) # pass referrer's Method* + move $a2, rSELF # pass Thread::Current + jal artGetByteStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp) + move $a3, $sp # pass $sp + RETURN_IF_NO_EXCEPTION +END art_quick_get_byte_static + + /* + * Called by managed code to resolve a static field and load a char primitive value. + */ + .extern artGetCharStaticFromCode +ENTRY art_quick_get_char_static + GENERATE_GLOBAL_POINTER + SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC + lw $a1, 64($sp) # pass referrer's Method* + move $a2, rSELF # pass Thread::Current + jal artGetCharStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp) + move $a3, $sp # pass $sp + RETURN_IF_NO_EXCEPTION +END art_quick_get_char_static + /* + * Called by managed code to resolve a static field and load a short primitive value. + */ + .extern artGetShortStaticFromCode +ENTRY art_quick_get_short_static + GENERATE_GLOBAL_POINTER + SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC + lw $a1, 64($sp) # pass referrer's Method* + move $a2, rSELF # pass Thread::Current + jal artGetShortStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp) + move $a3, $sp # pass $sp + RETURN_IF_NO_EXCEPTION +END art_quick_get_short_static /* * Called by managed code to resolve a static field and load a 32-bit primitive value. @@ -783,6 +836,60 @@ ENTRY art_quick_get_obj_static END art_quick_get_obj_static /* + * Called by managed code to resolve an instance field and load a boolean primitive value. + */ + .extern artGetBooleanInstanceFromCode +ENTRY art_quick_get_boolean_instance + GENERATE_GLOBAL_POINTER + SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC + lw $a2, 64($sp) # pass referrer's Method* + move $a3, rSELF # pass Thread::Current + jal artGetBooleanInstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp) + sw $sp, 16($sp) # pass $sp + RETURN_IF_NO_EXCEPTION +END art_quick_get_boolean_instance + /* + * Called by managed code to resolve an instance field and load a byte primitive value. + */ + .extern artGetByteInstanceFromCode +ENTRY art_quick_get_byte_instance + GENERATE_GLOBAL_POINTER + SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC + lw $a2, 64($sp) # pass referrer's Method* + move $a3, rSELF # pass Thread::Current + jal artGetByteInstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp) + sw $sp, 16($sp) # pass $sp + RETURN_IF_NO_EXCEPTION +END art_quick_get_byte_instance + + /* + * Called by managed code to resolve an instance field and load a char primitive value. + */ + .extern artGetCharInstanceFromCode +ENTRY art_quick_get_char_instance + GENERATE_GLOBAL_POINTER + SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC + lw $a2, 64($sp) # pass referrer's Method* + move $a3, rSELF # pass Thread::Current + jal artGetCharInstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp) + sw $sp, 16($sp) # pass $sp + RETURN_IF_NO_EXCEPTION +END art_quick_get_char_instance + /* + * Called by managed code to resolve an instance field and load a short primitive value. + */ + .extern artGetShortInstanceFromCode +ENTRY art_quick_get_short_instance + GENERATE_GLOBAL_POINTER + SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC + lw $a2, 64($sp) # pass referrer's Method* + move $a3, rSELF # pass Thread::Current + jal artGetShortInstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp) + sw $sp, 16($sp) # pass $sp + RETURN_IF_NO_EXCEPTION +END art_quick_get_short_instance + + /* * Called by managed code to resolve an instance field and load a 32-bit primitive value. */ .extern artGet32InstanceFromCode @@ -825,6 +932,34 @@ ENTRY art_quick_get_obj_instance END art_quick_get_obj_instance /* + * Called by managed code to resolve a static field and store a 8-bit primitive value. + */ + .extern artSet8StaticFromCode +ENTRY art_quick_set8_static + GENERATE_GLOBAL_POINTER + SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC + lw $a2, 64($sp) # pass referrer's Method* + move $a3, rSELF # pass Thread::Current + jal artSet8StaticFromCode # (field_idx, new_val, referrer, Thread*, $sp) + sw $sp, 16($sp) # pass $sp + RETURN_IF_ZERO +END art_quick_set8_static + + /* + * Called by managed code to resolve a static field and store a 16-bit primitive value. + */ + .extern artSet16StaticFromCode +ENTRY art_quick_set16_static + GENERATE_GLOBAL_POINTER + SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC + lw $a2, 64($sp) # pass referrer's Method* + move $a3, rSELF # pass Thread::Current + jal artSet16StaticFromCode # (field_idx, new_val, referrer, Thread*, $sp) + sw $sp, 16($sp) # pass $sp + RETURN_IF_ZERO +END art_quick_set16_static + + /* * Called by managed code to resolve a static field and store a 32-bit primitive value. */ .extern artSet32StaticFromCode @@ -841,7 +976,7 @@ END art_quick_set32_static /* * Called by managed code to resolve a static field and store a 64-bit primitive value. */ - .extern artSet32StaticFromCode + .extern artSet64StaticFromCode ENTRY art_quick_set64_static GENERATE_GLOBAL_POINTER SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC @@ -867,6 +1002,34 @@ ENTRY art_quick_set_obj_static END art_quick_set_obj_static /* + * Called by managed code to resolve an instance field and store a 8-bit primitive value. + */ + .extern artSet8InstanceFromCode +ENTRY art_quick_set8_instance + GENERATE_GLOBAL_POINTER + SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC + lw $a3, 64($sp) # pass referrer's Method* + sw rSELF, 16($sp) # pass Thread::Current + jal artSet8InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*, $sp) + sw $sp, 20($sp) # pass $sp + RETURN_IF_ZERO +END art_quick_set8_instance + + /* + * Called by managed code to resolve an instance field and store a 16-bit primitive value. + */ + .extern artSet16InstanceFromCode +ENTRY art_quick_set16_instance + GENERATE_GLOBAL_POINTER + SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC + lw $a3, 64($sp) # pass referrer's Method* + sw rSELF, 16($sp) # pass Thread::Current + jal artSet16InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*, $sp) + sw $sp, 20($sp) # pass $sp + RETURN_IF_ZERO +END art_quick_set16_instance + + /* * Called by managed code to resolve an instance field and store a 32-bit primitive value. */ .extern artSet32InstanceFromCode @@ -883,7 +1046,7 @@ END art_quick_set32_instance /* * Called by managed code to resolve an instance field and store a 64-bit primitive value. */ - .extern artSet32InstanceFromCode + .extern artSet64InstanceFromCode ENTRY art_quick_set64_instance GENERATE_GLOBAL_POINTER SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc index 864e3f7ad0..1215d8b322 100644 --- a/runtime/arch/stub_test.cc +++ b/runtime/arch/stub_test.cc @@ -1306,6 +1306,288 @@ TEST_F(StubTest, StringCompareTo) { } +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) +extern "C" void art_quick_set8_static(void); +extern "C" void art_quick_get_byte_static(void); +extern "C" void art_quick_get_boolean_static(void); +#endif + +static void GetSetBooleanStatic(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self, + mirror::ArtMethod* referrer, StubTest* test) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) + constexpr size_t num_values = 5; + uint8_t values[num_values] = { 0, 1, 2, 128, 0xFF }; + + for (size_t i = 0; i < num_values; ++i) { + test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + static_cast<size_t>(values[i]), + 0U, + StubTest::GetEntrypoint(self, kQuickSet8Static), + self, + referrer); + + size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + 0U, 0U, + StubTest::GetEntrypoint(self, kQuickGetBooleanStatic), + self, + referrer); + // Boolean currently stores bools as uint8_t, be more zealous about asserting correct writes/gets. + EXPECT_EQ(values[i], static_cast<uint8_t>(res)) << "Iteration " << i; + } +#else + LOG(INFO) << "Skipping set_boolean_static as I don't know how to do that on " << kRuntimeISA; + // Force-print to std::cout so it's also outside the logcat. + std::cout << "Skipping set_boolean_static as I don't know how to do that on " << kRuntimeISA << std::endl; +#endif +} +static void GetSetByteStatic(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self, + mirror::ArtMethod* referrer, StubTest* test) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) + constexpr size_t num_values = 5; + int8_t values[num_values] = { -128, -64, 0, 64, 127 }; + + for (size_t i = 0; i < num_values; ++i) { + test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + static_cast<size_t>(values[i]), + 0U, + StubTest::GetEntrypoint(self, kQuickSet8Static), + self, + referrer); + + size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + 0U, 0U, + StubTest::GetEntrypoint(self, kQuickGetByteStatic), + self, + referrer); + EXPECT_EQ(values[i], static_cast<int8_t>(res)) << "Iteration " << i; + } +#else + LOG(INFO) << "Skipping set_byte_static as I don't know how to do that on " << kRuntimeISA; + // Force-print to std::cout so it's also outside the logcat. + std::cout << "Skipping set_byte_static as I don't know how to do that on " << kRuntimeISA << std::endl; +#endif +} + + +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) +extern "C" void art_quick_set8_instance(void); +extern "C" void art_quick_get_byte_instance(void); +extern "C" void art_quick_get_boolean_instance(void); +#endif + +static void GetSetBooleanInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, + Thread* self, mirror::ArtMethod* referrer, StubTest* test) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) + constexpr size_t num_values = 5; + uint8_t values[num_values] = { 0, true, 2, 128, 0xFF }; + + for (size_t i = 0; i < num_values; ++i) { + test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + reinterpret_cast<size_t>(obj->Get()), + static_cast<size_t>(values[i]), + StubTest::GetEntrypoint(self, kQuickSet8Instance), + self, + referrer); + + uint8_t res = f->Get()->GetBoolean(obj->Get()); + EXPECT_EQ(values[i], res) << "Iteration " << i; + + f->Get()->SetBoolean<false>(obj->Get(), res); + + size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + reinterpret_cast<size_t>(obj->Get()), + 0U, + StubTest::GetEntrypoint(self, kQuickGetBooleanInstance), + self, + referrer); + EXPECT_EQ(res, static_cast<uint8_t>(res2)); + } +#else + LOG(INFO) << "Skipping set_boolean_instance as I don't know how to do that on " << kRuntimeISA; + // Force-print to std::cout so it's also outside the logcat. + std::cout << "Skipping set_boolean_instance as I don't know how to do that on " << kRuntimeISA << std::endl; +#endif +} +static void GetSetByteInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, + Thread* self, mirror::ArtMethod* referrer, StubTest* test) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) + constexpr size_t num_values = 5; + int8_t values[num_values] = { -128, -64, 0, 64, 127 }; + + for (size_t i = 0; i < num_values; ++i) { + test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + reinterpret_cast<size_t>(obj->Get()), + static_cast<size_t>(values[i]), + StubTest::GetEntrypoint(self, kQuickSet8Instance), + self, + referrer); + + int8_t res = f->Get()->GetByte(obj->Get()); + EXPECT_EQ(res, values[i]) << "Iteration " << i; + f->Get()->SetByte<false>(obj->Get(), ++res); + + size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + reinterpret_cast<size_t>(obj->Get()), + 0U, + StubTest::GetEntrypoint(self, kQuickGetByteInstance), + self, + referrer); + EXPECT_EQ(res, static_cast<int8_t>(res2)); + } +#else + LOG(INFO) << "Skipping set_byte_instance as I don't know how to do that on " << kRuntimeISA; + // Force-print to std::cout so it's also outside the logcat. + std::cout << "Skipping set_byte_instance as I don't know how to do that on " << kRuntimeISA << std::endl; +#endif +} + +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) +extern "C" void art_quick_set16_static(void); +extern "C" void art_quick_get_short_static(void); +extern "C" void art_quick_get_char_static(void); +#endif + +static void GetSetCharStatic(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self, + mirror::ArtMethod* referrer, StubTest* test) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) + constexpr size_t num_values = 6; + uint16_t values[num_values] = { 0, 1, 2, 255, 32768, 0xFFFF }; + + for (size_t i = 0; i < num_values; ++i) { + test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + static_cast<size_t>(values[i]), + 0U, + StubTest::GetEntrypoint(self, kQuickSet16Static), + self, + referrer); + + size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + 0U, 0U, + StubTest::GetEntrypoint(self, kQuickGetCharStatic), + self, + referrer); + + EXPECT_EQ(values[i], static_cast<uint16_t>(res)) << "Iteration " << i; + } +#else + LOG(INFO) << "Skipping set_char_static as I don't know how to do that on " << kRuntimeISA; + // Force-print to std::cout so it's also outside the logcat. + std::cout << "Skipping set_char_static as I don't know how to do that on " << kRuntimeISA << std::endl; +#endif +} +static void GetSetShortStatic(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self, + mirror::ArtMethod* referrer, StubTest* test) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) + constexpr size_t num_values = 6; + int16_t values[num_values] = { -0x7FFF, -32768, 0, 255, 32767, 0x7FFE }; + + for (size_t i = 0; i < num_values; ++i) { + test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + static_cast<size_t>(values[i]), + 0U, + StubTest::GetEntrypoint(self, kQuickSet16Static), + self, + referrer); + + size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + 0U, 0U, + StubTest::GetEntrypoint(self, kQuickGetShortStatic), + self, + referrer); + + EXPECT_EQ(static_cast<int16_t>(res), values[i]) << "Iteration " << i; + } +#else + LOG(INFO) << "Skipping set_short_static as I don't know how to do that on " << kRuntimeISA; + // Force-print to std::cout so it's also outside the logcat. + std::cout << "Skipping set_short_static as I don't know how to do that on " << kRuntimeISA << std::endl; +#endif +} + +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) +extern "C" void art_quick_set16_instance(void); +extern "C" void art_quick_get_short_instance(void); +extern "C" void art_quick_get_char_instance(void); +#endif + +static void GetSetCharInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, + Thread* self, mirror::ArtMethod* referrer, StubTest* test) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) + constexpr size_t num_values = 6; + uint16_t values[num_values] = { 0, 1, 2, 255, 32768, 0xFFFF }; + + for (size_t i = 0; i < num_values; ++i) { + test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + reinterpret_cast<size_t>(obj->Get()), + static_cast<size_t>(values[i]), + StubTest::GetEntrypoint(self, kQuickSet16Instance), + self, + referrer); + + uint16_t res = f->Get()->GetChar(obj->Get()); + EXPECT_EQ(res, values[i]) << "Iteration " << i; + f->Get()->SetChar<false>(obj->Get(), ++res); + + size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + reinterpret_cast<size_t>(obj->Get()), + 0U, + StubTest::GetEntrypoint(self, kQuickGetCharInstance), + self, + referrer); + EXPECT_EQ(res, static_cast<uint16_t>(res2)); + } +#else + LOG(INFO) << "Skipping set_char_instance as I don't know how to do that on " << kRuntimeISA; + // Force-print to std::cout so it's also outside the logcat. + std::cout << "Skipping set_char_instance as I don't know how to do that on " << kRuntimeISA << std::endl; +#endif +} +static void GetSetShortInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, + Thread* self, mirror::ArtMethod* referrer, StubTest* test) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) + constexpr size_t num_values = 6; + int16_t values[num_values] = { -0x7FFF, -32768, 0, 255, 32767, 0x7FFE }; + + for (size_t i = 0; i < num_values; ++i) { + test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + reinterpret_cast<size_t>(obj->Get()), + static_cast<size_t>(values[i]), + StubTest::GetEntrypoint(self, kQuickSet16Instance), + self, + referrer); + + int16_t res = f->Get()->GetShort(obj->Get()); + EXPECT_EQ(res, values[i]) << "Iteration " << i; + f->Get()->SetShort<false>(obj->Get(), ++res); + + size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()), + reinterpret_cast<size_t>(obj->Get()), + 0U, + StubTest::GetEntrypoint(self, kQuickGetShortInstance), + self, + referrer); + EXPECT_EQ(res, static_cast<int16_t>(res2)); + } +#else + LOG(INFO) << "Skipping set_short_instance as I don't know how to do that on " << kRuntimeISA; + // Force-print to std::cout so it's also outside the logcat. + std::cout << "Skipping set_short_instance as I don't know how to do that on " << kRuntimeISA << std::endl; +#endif +} + +#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__)) +extern "C" void art_quick_set32_static(void); +extern "C" void art_quick_get32_static(void); +#endif + static void GetSet32Static(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self, mirror::ArtMethod* referrer, StubTest* test) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { @@ -1555,6 +1837,26 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type) Primitive::Type type = f->GetTypeAsPrimitiveType(); switch (type) { + case Primitive::Type::kPrimBoolean: + if (test_type == type) { + GetSetBooleanStatic(&obj, &f, self, m.Get(), test); + } + break; + case Primitive::Type::kPrimByte: + if (test_type == type) { + GetSetByteStatic(&obj, &f, self, m.Get(), test); + } + break; + case Primitive::Type::kPrimChar: + if (test_type == type) { + GetSetCharStatic(&obj, &f, self, m.Get(), test); + } + break; + case Primitive::Type::kPrimShort: + if (test_type == type) { + GetSetShortStatic(&obj, &f, self, m.Get(), test); + } + break; case Primitive::Type::kPrimInt: if (test_type == type) { GetSet32Static(&obj, &f, self, m.Get(), test); @@ -1590,6 +1892,26 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type) Primitive::Type type = f->GetTypeAsPrimitiveType(); switch (type) { + case Primitive::Type::kPrimBoolean: + if (test_type == type) { + GetSetBooleanInstance(&obj, &f, self, m.Get(), test); + } + break; + case Primitive::Type::kPrimByte: + if (test_type == type) { + GetSetByteInstance(&obj, &f, self, m.Get(), test); + } + break; + case Primitive::Type::kPrimChar: + if (test_type == type) { + GetSetCharInstance(&obj, &f, self, m.Get(), test); + } + break; + case Primitive::Type::kPrimShort: + if (test_type == type) { + GetSetShortInstance(&obj, &f, self, m.Get(), test); + } + break; case Primitive::Type::kPrimInt: if (test_type == type) { GetSet32Instance(&obj, &f, self, m.Get(), test); @@ -1618,6 +1940,33 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type) // TODO: Deallocate things. } +TEST_F(StubTest, Fields8) { + TEST_DISABLED_FOR_HEAP_REFERENCE_POISONING(); + + Thread* self = Thread::Current(); + + self->TransitionFromSuspendedToRunnable(); + LoadDex("AllFields"); + bool started = runtime_->Start(); + CHECK(started); + + TestFields(self, this, Primitive::Type::kPrimBoolean); + TestFields(self, this, Primitive::Type::kPrimByte); +} + +TEST_F(StubTest, Fields16) { + TEST_DISABLED_FOR_HEAP_REFERENCE_POISONING(); + + Thread* self = Thread::Current(); + + self->TransitionFromSuspendedToRunnable(); + LoadDex("AllFields"); + bool started = runtime_->Start(); + CHECK(started); + + TestFields(self, this, Primitive::Type::kPrimChar); + TestFields(self, this, Primitive::Type::kPrimShort); +} TEST_F(StubTest, Fields32) { TEST_DISABLED_FOR_HEAP_REFERENCE_POISONING(); diff --git a/runtime/arch/x86/entrypoints_init_x86.cc b/runtime/arch/x86/entrypoints_init_x86.cc index a072996504..682c5021ce 100644 --- a/runtime/arch/x86/entrypoints_init_x86.cc +++ b/runtime/arch/x86/entrypoints_init_x86.cc @@ -47,12 +47,24 @@ extern "C" void* art_quick_initialize_type_and_verify_access(uint32_t, void*); extern "C" void* art_quick_resolve_string(void*, uint32_t); // Field entrypoints. +extern "C" int art_quick_set8_instance(uint32_t, void*, int8_t); +extern "C" int art_quick_set8_static(uint32_t, int8_t); +extern "C" int art_quick_set16_instance(uint32_t, void*, int16_t); +extern "C" int art_quick_set16_static(uint32_t, int16_t); extern "C" int art_quick_set32_instance(uint32_t, void*, int32_t); extern "C" int art_quick_set32_static(uint32_t, int32_t); extern "C" int art_quick_set64_instance(uint32_t, void*, int64_t); extern "C" int art_quick_set64_static(uint32_t, int64_t); extern "C" int art_quick_set_obj_instance(uint32_t, void*, void*); extern "C" int art_quick_set_obj_static(uint32_t, void*); +extern "C" int8_t art_quick_get_byte_instance(uint32_t, void*); +extern "C" uint8_t art_quick_get_boolean_instance(uint32_t, void*); +extern "C" int8_t art_quick_get_byte_static(uint32_t); +extern "C" uint8_t art_quick_get_boolean_static(uint32_t); +extern "C" int16_t art_quick_get_short_instance(uint32_t, void*); +extern "C" uint16_t art_quick_get_char_instance(uint32_t, void*); +extern "C" int16_t art_quick_get_short_static(uint32_t); +extern "C" uint16_t art_quick_get_char_static(uint32_t); extern "C" int32_t art_quick_get32_instance(uint32_t, void*); extern "C" int32_t art_quick_get32_static(uint32_t); extern "C" int64_t art_quick_get64_instance(uint32_t, void*); @@ -137,15 +149,27 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints, qpoints->pResolveString = art_quick_resolve_string; // Field + qpoints->pSet8Instance = art_quick_set8_instance; + qpoints->pSet8Static = art_quick_set8_static; + qpoints->pSet16Instance = art_quick_set16_instance; + qpoints->pSet16Static = art_quick_set16_static; qpoints->pSet32Instance = art_quick_set32_instance; qpoints->pSet32Static = art_quick_set32_static; qpoints->pSet64Instance = art_quick_set64_instance; qpoints->pSet64Static = art_quick_set64_static; qpoints->pSetObjInstance = art_quick_set_obj_instance; qpoints->pSetObjStatic = art_quick_set_obj_static; + qpoints->pGetByteInstance = art_quick_get_byte_instance; + qpoints->pGetBooleanInstance = art_quick_get_boolean_instance; + qpoints->pGetShortInstance = art_quick_get_short_instance; + qpoints->pGetCharInstance = art_quick_get_char_instance; qpoints->pGet32Instance = art_quick_get32_instance; qpoints->pGet64Instance = art_quick_get64_instance; qpoints->pGetObjInstance = art_quick_get_obj_instance; + qpoints->pGetByteStatic = art_quick_get_byte_static; + qpoints->pGetBooleanStatic = art_quick_get_boolean_static; + qpoints->pGetShortStatic = art_quick_get_short_static; + qpoints->pGetCharStatic = art_quick_get_char_static; qpoints->pGet32Static = art_quick_get32_static; qpoints->pGet64Static = art_quick_get64_static; qpoints->pGetObjStatic = art_quick_get_obj_static; diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S index c6e704a9cd..6166cb5cd5 100644 --- a/runtime/arch/x86/quick_entrypoints_x86.S +++ b/runtime/arch/x86/quick_entrypoints_x86.S @@ -384,6 +384,48 @@ MACRO3(THREE_ARG_DOWNCALL, c_name, cxx_name, return_macro) END_FUNCTION RAW_VAR(c_name, 0) END_MACRO +MACRO3(ONE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) + DEFINE_FUNCTION RAW_VAR(c_name, 0) + SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC + mov %esp, %edx // remember SP + mov 32(%esp), %ecx // get referrer + // Outgoing argument set up + PUSH edx // pass SP + pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() + CFI_ADJUST_CFA_OFFSET(4) + PUSH ecx // pass referrer + PUSH eax // pass arg1 + call VAR(cxx_name, 1) // cxx_name(arg1, referrer, Thread*, SP) + addl MACRO_LITERAL(16), %esp // pop arguments + CFI_ADJUST_CFA_OFFSET(-16) + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address + CALL_MACRO(return_macro, 2) // return or deliver exception + END_FUNCTION RAW_VAR(c_name, 0) +END_MACRO + +MACRO3(TWO_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) + DEFINE_FUNCTION RAW_VAR(c_name, 0) + SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC + mov %esp, %ebx // remember SP + mov 32(%esp), %edx // get referrer + subl LITERAL(12), %esp // alignment padding + CFI_ADJUST_CFA_OFFSET(12) + PUSH ebx // pass SP + pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() + CFI_ADJUST_CFA_OFFSET(4) + // Outgoing argument set up + PUSH edx // pass referrer + PUSH ecx // pass arg2 + PUSH eax // pass arg1 + call VAR(cxx_name, 1) // cxx_name(arg1, arg2, referrer, Thread*, SP) + addl LITERAL(32), %esp // pop arguments + CFI_ADJUST_CFA_OFFSET(-32) + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address + CALL_MACRO(return_macro, 2) // return or deliver exception + END_FUNCTION RAW_VAR(c_name, 0) +END_MACRO + + MACRO0(RETURN_IF_RESULT_IS_NON_ZERO) testl %eax, %eax // eax == 0 ? jz 1f // if eax == 0 goto 1 @@ -814,6 +856,46 @@ DEFINE_FUNCTION art_quick_lushr ret END_FUNCTION art_quick_lushr +DEFINE_FUNCTION art_quick_set8_instance + SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC + mov %esp, %ebx // remember SP + subl LITERAL(8), %esp // alignment padding + CFI_ADJUST_CFA_OFFSET(8) + PUSH ebx // pass SP + pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() + CFI_ADJUST_CFA_OFFSET(4) + mov 32(%ebx), %ebx // get referrer + PUSH ebx // pass referrer + PUSH edx // pass new_val + PUSH ecx // pass object + PUSH eax // pass field_idx + call PLT_SYMBOL(artSet8InstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*, SP) + addl LITERAL(32), %esp // pop arguments + CFI_ADJUST_CFA_OFFSET(-32) + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address + RETURN_IF_EAX_ZERO // return or deliver exception +END_FUNCTION art_quick_set8_instance + +DEFINE_FUNCTION art_quick_set16_instance + SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC + mov %esp, %ebx // remember SP + subl LITERAL(8), %esp // alignment padding + CFI_ADJUST_CFA_OFFSET(8) + PUSH ebx // pass SP + pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() + CFI_ADJUST_CFA_OFFSET(4) + mov 32(%ebx), %ebx // get referrer + PUSH ebx // pass referrer + PUSH edx // pass new_val + PUSH ecx // pass object + PUSH eax // pass field_idx + call PLT_SYMBOL(artSet16InstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*, SP) + addl LITERAL(32), %esp // pop arguments + CFI_ADJUST_CFA_OFFSET(-32) + RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address + RETURN_IF_EAX_ZERO // return or deliver exception +END_FUNCTION art_quick_set16_instance + DEFINE_FUNCTION art_quick_set32_instance SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC mov %esp, %ebx // remember SP @@ -873,8 +955,15 @@ DEFINE_FUNCTION art_quick_set_obj_instance RETURN_IF_EAX_ZERO // return or deliver exception END_FUNCTION art_quick_set_obj_instance -DEFINE_FUNCTION art_quick_get32_instance - SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC +TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION + +DEFINE_FUNCTION art_quick_get64_instance + SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC mov %esp, %ebx // remember SP mov 32(%esp), %edx // get referrer subl LITERAL(12), %esp // alignment padding @@ -885,14 +974,14 @@ DEFINE_FUNCTION art_quick_get32_instance PUSH edx // pass referrer PUSH ecx // pass object PUSH eax // pass field_idx - call SYMBOL(artGet32InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP) + call SYMBOL(artGet64InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP) addl LITERAL(32), %esp // pop arguments CFI_ADJUST_CFA_OFFSET(-32) RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception -END_FUNCTION art_quick_get32_instance +END_FUNCTION art_quick_get64_instance -DEFINE_FUNCTION art_quick_get64_instance +DEFINE_FUNCTION art_quick_set8_static SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC mov %esp, %ebx // remember SP mov 32(%esp), %edx // get referrer @@ -902,16 +991,16 @@ DEFINE_FUNCTION art_quick_get64_instance pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() CFI_ADJUST_CFA_OFFSET(4) PUSH edx // pass referrer - PUSH ecx // pass object + PUSH ecx // pass new_val PUSH eax // pass field_idx - call SYMBOL(artGet64InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP) + call SYMBOL(artSet8StaticFromCode) // (field_idx, new_val, referrer, Thread*, SP) addl LITERAL(32), %esp // pop arguments CFI_ADJUST_CFA_OFFSET(-32) RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address - RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception -END_FUNCTION art_quick_get64_instance + RETURN_IF_EAX_ZERO // return or deliver exception +END_FUNCTION art_quick_set8_static -DEFINE_FUNCTION art_quick_get_obj_instance +DEFINE_FUNCTION art_quick_set16_static SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC mov %esp, %ebx // remember SP mov 32(%esp), %edx // get referrer @@ -921,14 +1010,14 @@ DEFINE_FUNCTION art_quick_get_obj_instance pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() CFI_ADJUST_CFA_OFFSET(4) PUSH edx // pass referrer - PUSH ecx // pass object + PUSH ecx // pass new_val PUSH eax // pass field_idx - call SYMBOL(artGetObjInstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP) + call SYMBOL(artSet16StaticFromCode) // (field_idx, new_val, referrer, Thread*, SP) addl LITERAL(32), %esp // pop arguments CFI_ADJUST_CFA_OFFSET(-32) RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address - RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception -END_FUNCTION art_quick_get_obj_instance + RETURN_IF_EAX_ZERO // return or deliver exception +END_FUNCTION art_quick_set16_static DEFINE_FUNCTION art_quick_set32_static SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC @@ -987,53 +1076,13 @@ DEFINE_FUNCTION art_quick_set_obj_static RETURN_IF_EAX_ZERO // return or deliver exception END_FUNCTION art_quick_set_obj_static -DEFINE_FUNCTION art_quick_get32_static - SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC - mov %esp, %edx // remember SP - mov 32(%esp), %ecx // get referrer - PUSH edx // pass SP - pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() - CFI_ADJUST_CFA_OFFSET(4) - PUSH ecx // pass referrer - PUSH eax // pass field_idx - call SYMBOL(artGet32StaticFromCode) // (field_idx, referrer, Thread*, SP) - addl LITERAL(16), %esp // pop arguments - CFI_ADJUST_CFA_OFFSET(-16) - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address - RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception -END_FUNCTION art_quick_get32_static - -DEFINE_FUNCTION art_quick_get64_static - SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC - mov %esp, %edx // remember SP - mov 32(%esp), %ecx // get referrer - PUSH edx // pass SP - pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() - CFI_ADJUST_CFA_OFFSET(4) - PUSH ecx // pass referrer - PUSH eax // pass field_idx - call SYMBOL(artGet64StaticFromCode) // (field_idx, referrer, Thread*, SP) - addl LITERAL(16), %esp // pop arguments - CFI_ADJUST_CFA_OFFSET(-16) - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address - RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception -END_FUNCTION art_quick_get64_static - -DEFINE_FUNCTION art_quick_get_obj_static - SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC - mov %esp, %edx // remember SP - mov 32(%esp), %ecx // get referrer - PUSH edx // pass SP - pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() - CFI_ADJUST_CFA_OFFSET(4) - PUSH ecx // pass referrer - PUSH eax // pass field_idx - call SYMBOL(artGetObjStaticFromCode) // (field_idx, referrer, Thread*, SP) - addl LITERAL(16), %esp // pop arguments - CFI_ADJUST_CFA_OFFSET(-16) - RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address - RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception -END_FUNCTION art_quick_get_obj_static +ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCode RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCode RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION DEFINE_FUNCTION art_quick_proxy_invoke_handler SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame and Method* diff --git a/runtime/arch/x86_64/entrypoints_init_x86_64.cc b/runtime/arch/x86_64/entrypoints_init_x86_64.cc index 35a0cf4f2c..c9028e1355 100644 --- a/runtime/arch/x86_64/entrypoints_init_x86_64.cc +++ b/runtime/arch/x86_64/entrypoints_init_x86_64.cc @@ -48,12 +48,24 @@ extern "C" void* art_quick_initialize_type_and_verify_access(uint32_t, void*); extern "C" void* art_quick_resolve_string(void*, uint32_t); // Field entrypoints. +extern "C" int art_quick_set8_instance(uint32_t, void*, int8_t); +extern "C" int art_quick_set8_static(uint32_t, int8_t); +extern "C" int art_quick_set16_instance(uint32_t, void*, int16_t); +extern "C" int art_quick_set16_static(uint32_t, int16_t); extern "C" int art_quick_set32_instance(uint32_t, void*, int32_t); extern "C" int art_quick_set32_static(uint32_t, int32_t); extern "C" int art_quick_set64_instance(uint32_t, void*, int64_t); extern "C" int art_quick_set64_static(uint32_t, int64_t); extern "C" int art_quick_set_obj_instance(uint32_t, void*, void*); extern "C" int art_quick_set_obj_static(uint32_t, void*); +extern "C" int8_t art_quick_get_byte_instance(uint32_t, void*); +extern "C" uint8_t art_quick_get_boolean_instance(uint32_t, void*); +extern "C" int8_t art_quick_get_byte_static(uint32_t); +extern "C" uint8_t art_quick_get_boolean_static(uint32_t); +extern "C" int16_t art_quick_get_short_instance(uint32_t, void*); +extern "C" uint16_t art_quick_get_char_instance(uint32_t, void*); +extern "C" int16_t art_quick_get_short_static(uint32_t); +extern "C" uint16_t art_quick_get_char_static(uint32_t); extern "C" int32_t art_quick_get32_instance(uint32_t, void*); extern "C" int32_t art_quick_get32_static(uint32_t); extern "C" int64_t art_quick_get64_instance(uint32_t, void*); @@ -141,15 +153,27 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints, qpoints->pResolveString = art_quick_resolve_string; // Field + qpoints->pSet8Instance = art_quick_set8_instance; + qpoints->pSet8Static = art_quick_set8_static; + qpoints->pSet16Instance = art_quick_set16_instance; + qpoints->pSet16Static = art_quick_set16_static; qpoints->pSet32Instance = art_quick_set32_instance; qpoints->pSet32Static = art_quick_set32_static; qpoints->pSet64Instance = art_quick_set64_instance; qpoints->pSet64Static = art_quick_set64_static; qpoints->pSetObjInstance = art_quick_set_obj_instance; qpoints->pSetObjStatic = art_quick_set_obj_static; + qpoints->pGetByteInstance = art_quick_get_byte_instance; + qpoints->pGetBooleanInstance = art_quick_get_boolean_instance; + qpoints->pGetShortInstance = art_quick_get_short_instance; + qpoints->pGetCharInstance = art_quick_get_char_instance; qpoints->pGet32Instance = art_quick_get32_instance; qpoints->pGet64Instance = art_quick_get64_instance; qpoints->pGetObjInstance = art_quick_get_obj_instance; + qpoints->pGetByteStatic = art_quick_get_byte_static; + qpoints->pGetBooleanStatic = art_quick_get_boolean_static; + qpoints->pGetShortStatic = art_quick_get_short_static; + qpoints->pGetCharStatic = art_quick_get_char_static; qpoints->pGet32Static = art_quick_get32_static; qpoints->pGet64Static = art_quick_get64_static; qpoints->pGetObjStatic = art_quick_get_obj_static; diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S index f95bd22e9f..e9b5a7274b 100644 --- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S +++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S @@ -1076,17 +1076,29 @@ UNIMPLEMENTED art_quick_lshl UNIMPLEMENTED art_quick_lshr UNIMPLEMENTED art_quick_lushr +THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCode, RETURN_IF_EAX_ZERO +THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCode, RETURN_IF_EAX_ZERO THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCode, RETURN_IF_EAX_ZERO THREE_ARG_DOWNCALL art_quick_set64_instance, artSet64InstanceFromCode, RETURN_IF_EAX_ZERO THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCode, RETURN_IF_EAX_ZERO +TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION TWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCode, RETURN_IF_EAX_ZERO +TWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCode, RETURN_IF_EAX_ZERO TWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCode, RETURN_IF_EAX_ZERO TWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCode, RETURN_IF_EAX_ZERO +ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION |