diff options
-rw-r--r-- | runtime/arch/arm/quick_entrypoints_arm.S | 198 | ||||
-rw-r--r-- | runtime/arch/arm64/quick_entrypoints_arm64.S | 128 | ||||
-rw-r--r-- | runtime/arch/quick_field_entrypoints.S | 113 | ||||
-rw-r--r-- | runtime/arch/riscv64/quick_entrypoints_riscv64.S | 86 | ||||
-rw-r--r-- | runtime/arch/x86/quick_entrypoints_x86.S | 110 | ||||
-rw-r--r-- | runtime/arch/x86_64/quick_entrypoints_x86_64.S | 85 |
6 files changed, 217 insertions, 503 deletions
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S index 5d378d30d3..eca5c4b042 100644 --- a/runtime/arch/arm/quick_entrypoints_arm.S +++ b/runtime/arch/arm/quick_entrypoints_arm.S @@ -18,6 +18,7 @@ #include "interpreter/cfi_asm_support.h" #include "arch/quick_alloc_entrypoints.S" +#include "arch/quick_field_entrypoints.S" /* Deliver the given exception */ .extern artDeliverExceptionFromCode @@ -134,14 +135,19 @@ .cfi_adjust_cfa_offset -52 .endm -.macro RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION - ldr r1, [rSELF, # THREAD_EXCEPTION_OFFSET] // Get exception field. - cbnz r1, 1f - DEOPT_OR_RETURN r1 // Check if deopt is required +.macro RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION is_ref = 0 + // Use R2 to allow returning 64-bit values in R0-R1. + ldr r2, [rSELF, # THREAD_EXCEPTION_OFFSET] // Get exception field. + cbnz r2, 1f + DEOPT_OR_RETURN r2, \is_ref // Check if deopt is required 1: DELIVER_PENDING_EXCEPTION .endm +.macro RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION /* is_ref= */ 1 +.endm + .macro DEOPT_OR_RETURN temp, is_ref = 0 ldr \temp, [rSELF, #THREAD_DEOPT_CHECK_REQUIRED_OFFSET] cbnz \temp, 2f @@ -214,7 +220,7 @@ ENTRY \c_name END \c_name .endm -.macro RETURN_IF_RESULT_IS_ZERO_OR_DELIVER +.macro RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER cbnz r0, 1f @ result non-zero branch over DEOPT_OR_RETURN r1 1: @@ -223,43 +229,47 @@ END \c_name .macro RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER cbz r0, 1f @ result zero branch over - DEOPT_OR_RETURN r1, /*is_ref=*/1 + DEOPT_OR_RETURN r1, /* is_ref= */ 1 1: DELIVER_PENDING_EXCEPTION .endm // Macros taking opportunity of code similarities for downcalls. -.macro ONE_ARG_REF_DOWNCALL name, entrypoint, return +// Used for field and allocation entrypoints. +.macro N_ARG_DOWNCALL n, name, entrypoint, return .extern \entrypoint ENTRY \name - SETUP_SAVE_REFS_ONLY_FRAME r1 @ save callee saves in case of GC - mov r1, rSELF @ pass Thread::Current - bl \entrypoint @ (uint32_t field_idx, Thread*) + SETUP_SAVE_REFS_ONLY_FRAME r\n @ save callee saves in case of GC + mov r\n, rSELF @ pass Thread::Current + bl \entrypoint @ (<args>, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME REFRESH_MARKING_REGISTER \return END \name .endm -.macro TWO_ARG_REF_DOWNCALL name, entrypoint, return - .extern \entrypoint -ENTRY \name - SETUP_SAVE_REFS_ONLY_FRAME r2 @ save callee saves in case of GC - mov r2, rSELF @ pass Thread::Current - bl \entrypoint @ (field_idx, Object*, Thread*) - RESTORE_SAVE_REFS_ONLY_FRAME - REFRESH_MARKING_REGISTER - \return -END \name +.macro ONE_ARG_DOWNCALL name, entrypoint, return + N_ARG_DOWNCALL 1, \name, \entrypoint, \return +.endm + +.macro TWO_ARG_DOWNCALL name, entrypoint, return + N_ARG_DOWNCALL 2, \name, \entrypoint, \return +.endm + +.macro THREE_ARG_DOWNCALL name, entrypoint, return + N_ARG_DOWNCALL 3, \name, \entrypoint, \return .endm -.macro THREE_ARG_REF_DOWNCALL name, entrypoint, return +// Macro to facilitate adding new allocation entrypoints. +.macro FOUR_ARG_DOWNCALL name, entrypoint, return .extern \entrypoint ENTRY \name - SETUP_SAVE_REFS_ONLY_FRAME r3 @ save callee saves in case of GC - mov r3, rSELF @ pass Thread::Current - bl \entrypoint @ (field_idx, Object*, new_val, Thread*) - RESTORE_SAVE_REFS_ONLY_FRAME @ TODO: we can clearly save an add here + SETUP_SAVE_REFS_ONLY_FRAME r12 @ save callee saves in case of GC + str rSELF, [sp, #-16]! @ expand the frame and pass Thread::Current + .cfi_adjust_cfa_offset 16 + bl \entrypoint @ (<args>, Thread*) + DECREASE_FRAME 16 @ strip the extra frame + RESTORE_SAVE_REFS_ONLY_FRAME REFRESH_MARKING_REGISTER \return END \name @@ -526,7 +536,9 @@ END art_quick_do_long_jump * Entry from managed code that calls artHandleFillArrayDataFromCode and delivers exception on * failure. */ -TWO_ARG_REF_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER +TWO_ARG_DOWNCALL art_quick_handle_fill_data, \ + artHandleFillArrayDataFromCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER /* * Entry from managed code that tries to lock the object in a fast path and @@ -553,7 +565,7 @@ ENTRY art_quick_lock_object_no_inline bl artLockObjectFromCode @ (Object* obj, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME REFRESH_MARKING_REGISTER - RETURN_IF_RESULT_IS_ZERO_OR_DELIVER + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER END art_quick_lock_object_no_inline /* @@ -583,7 +595,7 @@ ENTRY art_quick_unlock_object_no_inline bl artUnlockObjectFromCode @ (Object* obj, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME REFRESH_MARKING_REGISTER - RETURN_IF_RESULT_IS_ZERO_OR_DELIVER + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER END art_quick_unlock_object_no_inline /* @@ -804,62 +816,6 @@ ENTRY art_quick_aput_obj #endif // defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) END art_quick_aput_obj -// Macro to facilitate adding new allocation entrypoints. -.macro ONE_ARG_DOWNCALL name, entrypoint, return - .extern \entrypoint -ENTRY \name - SETUP_SAVE_REFS_ONLY_FRAME r1 @ save callee saves in case of GC - mov r1, rSELF @ pass Thread::Current - bl \entrypoint @ (uint32_t type_idx, Method* method, Thread*) - RESTORE_SAVE_REFS_ONLY_FRAME - REFRESH_MARKING_REGISTER - \return -END \name -.endm - -// Macro to facilitate adding new allocation entrypoints. -.macro TWO_ARG_DOWNCALL name, entrypoint, return - .extern \entrypoint -ENTRY \name - SETUP_SAVE_REFS_ONLY_FRAME r2 @ save callee saves in case of GC - mov r2, rSELF @ pass Thread::Current - bl \entrypoint @ (uint32_t type_idx, Method* method, Thread*) - RESTORE_SAVE_REFS_ONLY_FRAME - REFRESH_MARKING_REGISTER - \return -END \name -.endm - -// Macro to facilitate adding new array allocation entrypoints. -.macro THREE_ARG_DOWNCALL name, entrypoint, return - .extern \entrypoint -ENTRY \name - SETUP_SAVE_REFS_ONLY_FRAME r3 @ save callee saves in case of GC - mov r3, rSELF @ pass Thread::Current - @ (uint32_t type_idx, Method* method, int32_t component_count, Thread*) - bl \entrypoint - RESTORE_SAVE_REFS_ONLY_FRAME - REFRESH_MARKING_REGISTER - \return -END \name -.endm - -// Macro to facilitate adding new allocation entrypoints. -.macro FOUR_ARG_DOWNCALL name, entrypoint, return - .extern \entrypoint -ENTRY \name - SETUP_SAVE_REFS_ONLY_FRAME r12 @ save callee saves in case of GC - str rSELF, [sp, #-16]! @ expand the frame and pass Thread::Current - .cfi_adjust_cfa_offset 16 - bl \entrypoint - add sp, #16 @ strip the extra frame - .cfi_adjust_cfa_offset -16 - RESTORE_SAVE_REFS_ONLY_FRAME - REFRESH_MARKING_REGISTER - \return -END \name -.endm - /* * Macro for resolution and initialization of indexed DEX file * constants such as classes and strings. @@ -892,75 +848,13 @@ ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromC // Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are // defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc. - /* - * Called by managed code to resolve a static field and load a non-wide value. - */ -ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference! -ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION - /* - * Called by managed code to resolve a static field and load a 64-bit primitive value. - */ - .extern artGet64StaticFromCompiledCode -ENTRY art_quick_get64_static - SETUP_SAVE_REFS_ONLY_FRAME r2 @ save callee saves in case of GC - mov r1, rSELF @ pass Thread::Current - bl artGet64StaticFromCompiledCode @ (uint32_t field_idx, Thread*) - ldr r2, [rSELF, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ - RESTORE_SAVE_REFS_ONLY_FRAME - REFRESH_MARKING_REGISTER - cbnz r2, 1f @ success if no exception pending - DEOPT_OR_RETURN r2 @ check if deopt is required or return -1: - DELIVER_PENDING_EXCEPTION -END art_quick_get64_static +GENERATE_STATIC_FIELD_GETTERS - /* - * Called by managed code to resolve an instance field and load a non-wide value. - */ -TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference! -TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION - /* - * Called by managed code to resolve an instance field and load a 64-bit primitive value. - */ - .extern artGet64InstanceFromCompiledCode -ENTRY art_quick_get64_instance - SETUP_SAVE_REFS_ONLY_FRAME r2 @ save callee saves in case of GC - mov r2, rSELF @ pass Thread::Current - bl artGet64InstanceFromCompiledCode @ (field_idx, Object*, Thread*) - ldr r2, [rSELF, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ - RESTORE_SAVE_REFS_ONLY_FRAME - REFRESH_MARKING_REGISTER - cbnz r2, 1f @ success if no exception pending - DEOPT_OR_RETURN r2 @ check if deopt is required or return -1: - DELIVER_PENDING_EXCEPTION -END art_quick_get64_instance +GENERATE_INSTANCE_FIELD_GETTERS - /* - * Called by managed code to resolve a static field and store a value. - */ -TWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER -TWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER -TWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER -TWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER +GENERATE_STATIC_FIELD_SETTERS /* emit64= */ 0 - /* - * Called by managed code to resolve an instance field and store a non-wide value. - */ -THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER -THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER -THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER -THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER +GENERATE_INSTANCE_FIELD_SETTERS /* emit64= */ 0 /* * Called by managed code to resolve an instance field and store a wide value. @@ -976,7 +870,7 @@ ENTRY art_quick_set64_instance .cfi_adjust_cfa_offset -16 RESTORE_SAVE_REFS_ONLY_FRAME @ TODO: we can clearly save an add here REFRESH_MARKING_REGISTER - RETURN_IF_RESULT_IS_ZERO_OR_DELIVER + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER END art_quick_set64_instance .extern artSet64StaticFromCompiledCode @@ -990,7 +884,7 @@ ENTRY art_quick_set64_static .cfi_adjust_cfa_offset -16 RESTORE_SAVE_REFS_ONLY_FRAME @ TODO: we can clearly save an add here REFRESH_MARKING_REGISTER - RETURN_IF_RESULT_IS_ZERO_OR_DELIVER + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER END art_quick_set64_static // Generate the allocation entrypoints for each allocator. diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S index 34f0fdbc11..3c2445ce2c 100644 --- a/runtime/arch/arm64/quick_entrypoints_arm64.S +++ b/runtime/arch/arm64/quick_entrypoints_arm64.S @@ -18,6 +18,7 @@ #include "interpreter/cfi_asm_support.h" #include "arch/quick_alloc_entrypoints.S" +#include "arch/quick_field_entrypoints.S" .macro SAVE_REG_INCREASE_FRAME reg, frame_adjustment str \reg, [sp, #-(\frame_adjustment)]! @@ -195,14 +196,18 @@ RESTORE_SAVE_EVERYTHING_FRAME_KEEP_X0 .endm -.macro RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +.macro RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION is_ref = 0 ldr x1, [xSELF, # THREAD_EXCEPTION_OFFSET] // Get exception field. cbnz x1, 1f - DEOPT_OR_RETURN x1 // Check if deopt is required + DEOPT_OR_RETURN x1, \is_ref // Check if deopt is required 1: // deliver exception on current thread DELIVER_PENDING_EXCEPTION .endm +.macro RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION /* is_ref= */ 1 +.endm + .macro DEOPT_OR_RETURN temp, is_ref = 0 ldr \temp, [xSELF, #THREAD_DEOPT_CHECK_REQUIRED_OFFSET] cbnz \temp, 2f @@ -240,7 +245,7 @@ .endm -.macro RETURN_IF_W0_IS_ZERO_OR_DELIVER +.macro RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER cbnz w0, 1f // result non-zero branch over DEOPT_OR_RETURN x1 1: @@ -849,7 +854,7 @@ ENTRY art_quick_lock_object_no_inline bl artLockObjectFromCode // (Object* obj, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME REFRESH_MARKING_REGISTER - RETURN_IF_W0_IS_ZERO_OR_DELIVER + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER END art_quick_lock_object_no_inline /* @@ -874,7 +879,7 @@ ENTRY art_quick_unlock_object_no_inline bl artUnlockObjectFromCode // (Object* obj, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME REFRESH_MARKING_REGISTER - RETURN_IF_W0_IS_ZERO_OR_DELIVER + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER END art_quick_unlock_object_no_inline /* @@ -1152,43 +1157,6 @@ ENTRY \name END \name .endm -// Macros taking opportunity of code similarities for downcalls. -.macro ONE_ARG_REF_DOWNCALL name, entrypoint, return - .extern \entrypoint -ENTRY \name - SETUP_SAVE_REFS_ONLY_FRAME // save callee saves in case of GC - mov x1, xSELF // pass Thread::Current - bl \entrypoint // (uint32_t type_idx, Thread*) - RESTORE_SAVE_REFS_ONLY_FRAME - REFRESH_MARKING_REGISTER - \return -END \name -.endm - -.macro TWO_ARG_REF_DOWNCALL name, entrypoint, return - .extern \entrypoint -ENTRY \name - SETUP_SAVE_REFS_ONLY_FRAME // save callee saves in case of GC - mov x2, xSELF // pass Thread::Current - bl \entrypoint - RESTORE_SAVE_REFS_ONLY_FRAME - REFRESH_MARKING_REGISTER - \return -END \name -.endm - -.macro THREE_ARG_REF_DOWNCALL name, entrypoint, return - .extern \entrypoint -ENTRY \name - SETUP_SAVE_REFS_ONLY_FRAME // save callee saves in case of GC - mov x3, xSELF // pass Thread::Current - bl \entrypoint - RESTORE_SAVE_REFS_ONLY_FRAME - REFRESH_MARKING_REGISTER - \return -END \name -.endm - /* * Macro for resolution and initialization of indexed DEX file * constants such as classes and strings. @@ -1224,8 +1192,9 @@ END \name * Entry from managed code that calls artHandleFillArrayDataFromCode and delivers exception on * failure. */ -TWO_ARG_REF_DOWNCALL \ - art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER +TWO_ARG_DOWNCALL art_quick_handle_fill_data, \ + artHandleFillArrayDataFromCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER /* * Entry from managed code when uninitialized static storage, this stub will run the class @@ -1241,76 +1210,7 @@ ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_handle, artResolveMeth ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode -// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are -// defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc. - -ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, \ - artGetBooleanStaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, \ - artGetByteStaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_char_static, \ - artGetCharStaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_short_static, \ - artGetShortStaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get32_static, \ - artGet32StaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get64_static, \ - artGet64StaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference! -ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, \ - artGetObjStaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION - -TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, \ - artGetBooleanInstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, \ - artGetByteInstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, \ - artGetCharInstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, \ - artGetShortInstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get32_instance, \ - artGet32InstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get64_instance, \ - artGet64InstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference! -TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, \ - artGetObjInstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION - -TWO_ARG_REF_DOWNCALL \ - art_quick_set8_static, artSet8StaticFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER -TWO_ARG_REF_DOWNCALL \ - art_quick_set16_static, artSet16StaticFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER -TWO_ARG_REF_DOWNCALL \ - art_quick_set32_static, artSet32StaticFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER -TWO_ARG_REF_DOWNCALL \ - art_quick_set64_static, artSet64StaticFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER -TWO_ARG_REF_DOWNCALL \ - art_quick_set_obj_static, artSetObjStaticFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER - -THREE_ARG_REF_DOWNCALL \ - art_quick_set8_instance, artSet8InstanceFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER -THREE_ARG_REF_DOWNCALL \ - art_quick_set16_instance, artSet16InstanceFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER -THREE_ARG_REF_DOWNCALL \ - art_quick_set32_instance, artSet32InstanceFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER -THREE_ARG_REF_DOWNCALL \ - art_quick_set64_instance, artSet64InstanceFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER -THREE_ARG_REF_DOWNCALL \ - art_quick_set_obj_instance, artSetObjInstanceFromCompiledCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER +GENERATE_FIELD_ENTRYPOINTS // Generate the allocation entrypoints for each allocator. GENERATE_ALLOC_ENTRYPOINTS_FOR_NON_TLAB_ALLOCATORS diff --git a/runtime/arch/quick_field_entrypoints.S b/runtime/arch/quick_field_entrypoints.S new file mode 100644 index 0000000000..0bea80340d --- /dev/null +++ b/runtime/arch/quick_field_entrypoints.S @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are +// defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc. + +.macro GENERATE_STATIC_FIELD_GETTERS +ONE_ARG_DOWNCALL art_quick_get_boolean_static, \ + artGetBooleanStaticFromCompiledCode, \ + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_DOWNCALL art_quick_get_byte_static, \ + artGetByteStaticFromCompiledCode, \ + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_DOWNCALL art_quick_get_char_static, \ + artGetCharStaticFromCompiledCode, \ + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_DOWNCALL art_quick_get_short_static, \ + artGetShortStaticFromCompiledCode, \ + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_DOWNCALL art_quick_get32_static, \ + artGet32StaticFromCompiledCode, \ + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_DOWNCALL art_quick_get_obj_static, \ + artGetObjStaticFromCompiledCode, \ + RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_DOWNCALL art_quick_get64_static, \ + artGet64StaticFromCompiledCode, \ + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +.endm + +.macro GENERATE_INSTANCE_FIELD_GETTERS +TWO_ARG_DOWNCALL art_quick_get_boolean_instance, \ + artGetBooleanInstanceFromCompiledCode, \ + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_DOWNCALL art_quick_get_byte_instance, \ + artGetByteInstanceFromCompiledCode, \ + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_DOWNCALL art_quick_get_char_instance, \ + artGetCharInstanceFromCompiledCode, \ + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_DOWNCALL art_quick_get_short_instance, \ + artGetShortInstanceFromCompiledCode, \ + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_DOWNCALL art_quick_get32_instance, \ + artGet32InstanceFromCompiledCode, \ + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_DOWNCALL art_quick_get_obj_instance, \ + artGetObjInstanceFromCompiledCode, \ + RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_DOWNCALL art_quick_get64_instance, \ + artGet64InstanceFromCompiledCode, \ + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +.endm + +.macro GENERATE_STATIC_FIELD_SETTERS emit64 = 1 +TWO_ARG_DOWNCALL art_quick_set8_static, \ + artSet8StaticFromCompiledCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER +TWO_ARG_DOWNCALL art_quick_set16_static, \ + artSet16StaticFromCompiledCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER +TWO_ARG_DOWNCALL art_quick_set32_static, \ + artSet32StaticFromCompiledCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER +TWO_ARG_DOWNCALL art_quick_set_obj_static, \ + artSetObjStaticFromCompiledCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER +.if \emit64 +TWO_ARG_DOWNCALL art_quick_set64_static, \ + artSet64StaticFromCompiledCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER +.endif +.endm + +.macro GENERATE_INSTANCE_FIELD_SETTERS emit64 = 1 +THREE_ARG_DOWNCALL art_quick_set8_instance, \ + artSet8InstanceFromCompiledCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER +THREE_ARG_DOWNCALL art_quick_set16_instance, \ + artSet16InstanceFromCompiledCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER +THREE_ARG_DOWNCALL art_quick_set32_instance, \ + artSet32InstanceFromCompiledCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER +THREE_ARG_DOWNCALL art_quick_set_obj_instance, \ + artSetObjInstanceFromCompiledCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER +.if \emit64 +THREE_ARG_DOWNCALL art_quick_set64_instance, \ + artSet64InstanceFromCompiledCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER +.endif +.endm + +.macro GENERATE_FIELD_ENTRYPOINTS + GENERATE_STATIC_FIELD_GETTERS + GENERATE_INSTANCE_FIELD_GETTERS + GENERATE_STATIC_FIELD_SETTERS + GENERATE_INSTANCE_FIELD_SETTERS +.endm diff --git a/runtime/arch/riscv64/quick_entrypoints_riscv64.S b/runtime/arch/riscv64/quick_entrypoints_riscv64.S index ad506a8096..ccccb2ee85 100644 --- a/runtime/arch/riscv64/quick_entrypoints_riscv64.S +++ b/runtime/arch/riscv64/quick_entrypoints_riscv64.S @@ -18,6 +18,7 @@ #include "interpreter/cfi_asm_support.h" #include "arch/quick_alloc_entrypoints.S" +#include "arch/quick_field_entrypoints.S" // Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding. @@ -561,7 +562,7 @@ END art_quick_do_long_jump .endm -.macro RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER +.macro RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER bnez a0, 1f DEOPT_OR_RETURN a1 1: @@ -620,7 +621,7 @@ ENTRY art_quick_lock_object_no_inline mv a1, xSELF // pass Thread::Current call artLockObjectFromCode // (Object*, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME - RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER END art_quick_lock_object_no_inline @@ -642,7 +643,7 @@ ENTRY art_quick_unlock_object_no_inline mv a1, xSELF // pass Thread::Current call artUnlockObjectFromCode // (Object*, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME - RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER END art_quick_unlock_object_no_inline @@ -1894,84 +1895,7 @@ GENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_tlab, \ COMPUTE_ARRAY_SIZE_64 -// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are -// defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc. - -ONE_ARG_DOWNCALL art_quick_get_boolean_static, \ - artGetBooleanStaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_DOWNCALL art_quick_get_byte_static, \ - artGetByteStaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_DOWNCALL art_quick_get_char_static, \ - artGetCharStaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_DOWNCALL art_quick_get_short_static, \ - artGetShortStaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_DOWNCALL art_quick_get32_static, \ - artGet32StaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_DOWNCALL art_quick_get64_static, \ - artGet64StaticFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_DOWNCALL art_quick_get_obj_static, \ - artGetObjStaticFromCompiledCode, \ - RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION - -TWO_ARG_DOWNCALL art_quick_get_boolean_instance, \ - artGetBooleanInstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_DOWNCALL art_quick_get_byte_instance, \ - artGetByteInstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_DOWNCALL art_quick_get_char_instance, \ - artGetCharInstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_DOWNCALL art_quick_get_short_instance, \ - artGetShortInstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_DOWNCALL art_quick_get32_instance, \ - artGet32InstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_DOWNCALL art_quick_get64_instance, \ - artGet64InstanceFromCompiledCode, \ - RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_DOWNCALL art_quick_get_obj_instance, \ - artGetObjInstanceFromCompiledCode, \ - RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION - -TWO_ARG_DOWNCALL art_quick_set8_static, \ - artSet8StaticFromCompiledCode, \ - RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER -TWO_ARG_DOWNCALL art_quick_set16_static, \ - artSet16StaticFromCompiledCode, \ - RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER -TWO_ARG_DOWNCALL art_quick_set32_static, \ - artSet32StaticFromCompiledCode, \ - RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER -TWO_ARG_DOWNCALL art_quick_set64_static, \ - artSet64StaticFromCompiledCode, \ - RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER -TWO_ARG_DOWNCALL art_quick_set_obj_static, \ - artSetObjStaticFromCompiledCode, \ - RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER - -THREE_ARG_DOWNCALL art_quick_set8_instance, \ - artSet8InstanceFromCompiledCode, \ - RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER -THREE_ARG_DOWNCALL art_quick_set16_instance, \ - artSet16InstanceFromCompiledCode, \ - RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER -THREE_ARG_DOWNCALL art_quick_set32_instance, \ - artSet32InstanceFromCompiledCode, \ - RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER -THREE_ARG_DOWNCALL art_quick_set64_instance, \ - artSet64InstanceFromCompiledCode, \ - RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER -THREE_ARG_DOWNCALL art_quick_set_obj_instance, \ - artSetObjInstanceFromCompiledCode, \ - RETURN_OR_DEOPT_IF_RESULT_IS_ZERO_OR_DELIVER +GENERATE_FIELD_ENTRYPOINTS UNDEFINED art_quick_indexof diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S index da17ed9613..cfc3e4278e 100644 --- a/runtime/arch/x86/quick_entrypoints_x86.S +++ b/runtime/arch/x86/quick_entrypoints_x86.S @@ -18,6 +18,7 @@ #include "interpreter/cfi_asm_support.h" #include "arch/quick_alloc_entrypoints.S" +#include "arch/quick_field_entrypoints.S" // For x86, the CFA is esp+4, the address above the pushed return address on the stack. @@ -709,53 +710,6 @@ MACRO3(FOUR_ARG_DOWNCALL, c_name, cxx_name, return_macro) END_FUNCTION VAR(c_name) END_MACRO -MACRO3(ONE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) - DEFINE_FUNCTION VAR(c_name) - SETUP_SAVE_REFS_ONLY_FRAME ebx // save ref containing registers for GC - // Outgoing argument set up - INCREASE_FRAME 8 // alignment padding - pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() - CFI_ADJUST_CFA_OFFSET(4) - PUSH eax // pass arg1 - call CALLVAR(cxx_name) // cxx_name(arg1, Thread*) - DECREASE_FRAME 16 // pop arguments - RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address - CALL_MACRO(return_macro) // return or deliver exception - END_FUNCTION VAR(c_name) -END_MACRO - -MACRO3(TWO_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) - DEFINE_FUNCTION VAR(c_name) - SETUP_SAVE_REFS_ONLY_FRAME ebx // save ref containing registers for GC - // Outgoing argument set up - PUSH eax // alignment padding - pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() - CFI_ADJUST_CFA_OFFSET(4) - PUSH ecx // pass arg2 - PUSH eax // pass arg1 - call CALLVAR(cxx_name) // cxx_name(arg1, arg2, referrer, Thread*) - DECREASE_FRAME 16 // pop arguments - RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address - CALL_MACRO(return_macro) // return or deliver exception - END_FUNCTION VAR(c_name) -END_MACRO - -MACRO3(THREE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) - DEFINE_FUNCTION VAR(c_name) - SETUP_SAVE_REFS_ONLY_FRAME ebx // save ref containing registers for GC - // Outgoing argument set up - pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() - CFI_ADJUST_CFA_OFFSET(4) - PUSH edx // pass arg3 - PUSH ecx // pass arg2 - PUSH eax // pass arg1 - call CALLVAR(cxx_name) // cxx_name(arg1, arg2, arg3, Thread*) - DECREASE_FRAME 16 // pop arguments - RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address - CALL_MACRO(return_macro) // return or deliver exception - END_FUNCTION VAR(c_name) -END_MACRO - /* * Macro for resolution and initialization of indexed DEX file * constants such as classes and strings. @@ -790,14 +744,18 @@ MACRO0(RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER) DELIVER_PENDING_EXCEPTION END_MACRO -MACRO0(RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION) +MACRO1(RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION, is_ref = 0) cmpl MACRO_LITERAL(0),%fs:THREAD_EXCEPTION_OFFSET // exception field == 0 ? jne 1f // if exception field != 0 goto 1 - DEOPT_OR_RETURN ebx // check if deopt is required + DEOPT_OR_RETURN ebx, \is_ref // check if deopt is required 1: // deliver exception on current thread DELIVER_PENDING_EXCEPTION END_MACRO +MACRO0(RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION) + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION /*is_ref=*/1 +END_MACRO + MACRO2(DEOPT_OR_RETURN, temp, is_ref = 0) cmpl LITERAL(0), %fs:THREAD_DEOPT_CHECK_REQUIRED_OFFSET jne 2f @@ -840,7 +798,7 @@ MACRO2(DEOPT_OR_RESTORE_SAVE_EVERYTHING_FRAME_AND_RETURN_EAX, temp, is_ref = 0) END_MACRO -MACRO0(RETURN_IF_EAX_ZERO) +MACRO0(RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER) testl %eax, %eax // eax == 0 ? jnz 1f // if eax != 0 goto 1 DEOPT_OR_RETURN ebx // check if deopt is needed @@ -1156,7 +1114,9 @@ ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_handle, artResolveMeth ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode -TWO_ARG_REF_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO +TWO_ARG_DOWNCALL art_quick_handle_fill_data, \ + artHandleFillArrayDataFromCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER /* * Entry from managed code that tries to lock the object in a fast path and @@ -1188,7 +1148,7 @@ DEFINE_FUNCTION art_quick_lock_object_no_inline call SYMBOL(artLockObjectFromCode) // artLockObjectFromCode(object, Thread*) DECREASE_FRAME 16 // pop arguments RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address - RETURN_IF_EAX_ZERO + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER END_FUNCTION art_quick_lock_object_no_inline /* @@ -1222,7 +1182,7 @@ DEFINE_FUNCTION art_quick_unlock_object_no_inline call SYMBOL(artUnlockObjectFromCode) // artUnlockObjectFromCode(object, Thread*) DECREASE_FRAME 16 // pop arguments RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address - RETURN_IF_EAX_ZERO + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER END_FUNCTION art_quick_unlock_object_no_inline DEFINE_FUNCTION art_quick_instance_of @@ -1496,37 +1456,17 @@ DEFINE_FUNCTION art_quick_lushr ret END_FUNCTION art_quick_lushr -// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are -// defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc. - -ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference! -ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION - -TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference! -TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION - -TWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCompiledCode, RETURN_IF_EAX_ZERO -TWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCompiledCode, RETURN_IF_EAX_ZERO -TWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCompiledCode, RETURN_IF_EAX_ZERO -TWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCompiledCode, RETURN_IF_EAX_ZERO - -THREE_ARG_REF_DOWNCALL art_quick_set64_static, artSet64StaticFromCompiledCode, RETURN_IF_EAX_ZERO -THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCompiledCode, RETURN_IF_EAX_ZERO -THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCompiledCode, RETURN_IF_EAX_ZERO -THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCompiledCode, RETURN_IF_EAX_ZERO -THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCompiledCode, RETURN_IF_EAX_ZERO +GENERATE_STATIC_FIELD_GETTERS + +GENERATE_INSTANCE_FIELD_GETTERS + +GENERATE_STATIC_FIELD_SETTERS /*emit64=*/0 + +THREE_ARG_DOWNCALL art_quick_set64_static, \ + artSet64StaticFromCompiledCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER + +GENERATE_INSTANCE_FIELD_SETTERS /*emit64=*/0 // Call artSet64InstanceFromCode with 4 word size arguments. DEFINE_FUNCTION art_quick_set64_instance @@ -1546,7 +1486,7 @@ DEFINE_FUNCTION art_quick_set64_instance addl LITERAL(32), %esp // pop arguments CFI_ADJUST_CFA_OFFSET(-32) RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address - RETURN_IF_EAX_ZERO // return or deliver exception + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER // return or deliver exception END_FUNCTION art_quick_set64_instance DEFINE_FUNCTION art_quick_proxy_invoke_handler diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S index 9a60781b7e..7207ab8a3f 100644 --- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S +++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S @@ -18,6 +18,7 @@ #include "interpreter/cfi_asm_support.h" #include "arch/quick_alloc_entrypoints.S" +#include "arch/quick_field_entrypoints.S" MACRO0(ASSERT_USE_READ_BARRIER) #if !defined(USE_READ_BARRIER) @@ -684,39 +685,6 @@ MACRO3(FOUR_ARG_DOWNCALL, c_name, cxx_name, return_macro) END_FUNCTION VAR(c_name) END_MACRO -MACRO3(ONE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) - DEFINE_FUNCTION VAR(c_name) - SETUP_SAVE_REFS_ONLY_FRAME - // arg0 is in rdi - movq %gs:THREAD_SELF_OFFSET, %rsi // pass Thread::Current() - call CALLVAR(cxx_name) // cxx_name(arg0, Thread*) - RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address - CALL_MACRO(return_macro) - END_FUNCTION VAR(c_name) -END_MACRO - -MACRO3(TWO_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) - DEFINE_FUNCTION VAR(c_name) - SETUP_SAVE_REFS_ONLY_FRAME - // arg0 and arg1 are in rdi/rsi - movq %gs:THREAD_SELF_OFFSET, %rdx // pass Thread::Current() - call CALLVAR(cxx_name) // (arg0, arg1, Thread*) - RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address - CALL_MACRO(return_macro) - END_FUNCTION VAR(c_name) -END_MACRO - -MACRO3(THREE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) - DEFINE_FUNCTION VAR(c_name) - SETUP_SAVE_REFS_ONLY_FRAME - // arg0, arg1, and arg2 are in rdi/rsi/rdx - movq %gs:THREAD_SELF_OFFSET, %rcx // pass Thread::Current() - call CALLVAR(cxx_name) // cxx_name(arg0, arg1, arg2, Thread*) - RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address - CALL_MACRO(return_macro) // return or deliver exception - END_FUNCTION VAR(c_name) -END_MACRO - /* * Macro for resolution and initialization of indexed DEX file * constants such as classes and strings. @@ -749,15 +717,19 @@ MACRO0(RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER) END_MACRO -MACRO0(RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION) +MACRO1(RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION, is_ref = 0) movq %gs:THREAD_EXCEPTION_OFFSET, %rcx // get exception field testq %rcx, %rcx // rcx == 0 ? jnz 1f // if rcx != 0 goto 1 - DEOPT_OR_RETURN // Check if deopt is required + DEOPT_OR_RETURN \is_ref // Check if deopt is required 1: // deliver exception on current thread DELIVER_PENDING_EXCEPTION END_MACRO +MACRO0(RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION) + RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION /*is_ref=*/1 +END_MACRO + MACRO1(DEOPT_OR_RETURN, is_ref = 0) cmpl LITERAL(0), %gs:THREAD_DEOPT_CHECK_REQUIRED_OFFSET jne 2f @@ -793,7 +765,7 @@ END_MACRO -MACRO0(RETURN_IF_EAX_ZERO) +MACRO0(RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER) testl %eax, %eax // eax == 0 ? jnz 1f // if eax != 0 goto 1 DEOPT_OR_RETURN // Check if we need a deopt @@ -1103,7 +1075,9 @@ ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_handle, artResolveMeth ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode -TWO_ARG_REF_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO +TWO_ARG_DOWNCALL art_quick_handle_fill_data, \ + artHandleFillArrayDataFromCode, \ + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER /* * Entry from managed code that tries to lock the object in a fast path and @@ -1126,7 +1100,7 @@ DEFINE_FUNCTION art_quick_lock_object_no_inline movq %gs:THREAD_SELF_OFFSET, %rsi // pass Thread::Current() call SYMBOL(artLockObjectFromCode) // artLockObjectFromCode(object, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address - RETURN_IF_EAX_ZERO + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER END_FUNCTION art_quick_lock_object_no_inline /* @@ -1151,7 +1125,7 @@ DEFINE_FUNCTION art_quick_unlock_object_no_inline movq %gs:THREAD_SELF_OFFSET, %rsi // pass Thread::Current() call SYMBOL(artUnlockObjectFromCode) // artUnlockObjectFromCode(object, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address - RETURN_IF_EAX_ZERO + RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER END_FUNCTION art_quick_unlock_object_no_inline DEFINE_FUNCTION art_quick_check_instance_of @@ -1304,38 +1278,7 @@ UNIMPLEMENTED art_quick_lshl UNIMPLEMENTED art_quick_lshr UNIMPLEMENTED art_quick_lushr -// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are -// defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc. - -THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCompiledCode, RETURN_IF_EAX_ZERO -THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCompiledCode, RETURN_IF_EAX_ZERO -THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCompiledCode, RETURN_IF_EAX_ZERO -THREE_ARG_REF_DOWNCALL art_quick_set64_instance, artSet64InstanceFromCompiledCode, RETURN_IF_EAX_ZERO -THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCompiledCode, RETURN_IF_EAX_ZERO - -TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference! -TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION - -TWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCompiledCode, RETURN_IF_EAX_ZERO -TWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCompiledCode, RETURN_IF_EAX_ZERO -TWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCompiledCode, RETURN_IF_EAX_ZERO -TWO_ARG_REF_DOWNCALL art_quick_set64_static, artSet64StaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCompiledCode, RETURN_IF_EAX_ZERO - -ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION -// FIXME: This is passing `is_ref = 0` to `DEOPT_OR_DELIVER` but we have a reference! -ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCompiledCode, RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION +GENERATE_FIELD_ENTRYPOINTS DEFINE_FUNCTION art_quick_proxy_invoke_handler SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_RDI |