Fix and clean up field get/set entrypoints.
Fix `is_ref` argument for `*get_obj*` deoptimization.
Test: m test-art-host-gtest # x86, x86-64
Test: testrunner.py --host --optimizing # x86, x86-64
Test: testrunner.py --target --optimizing # arm, arm64, riscv64
Bug: 283082089
Change-Id: I1f0c5e6233cb14c8b3c2149a756e8f72e84379e0
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index 5d378d3..eca5c4b 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 @@
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 @@
.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 THREE_ARG_REF_DOWNCALL name, entrypoint, return
+.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 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 @@
* 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 @@
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 @@
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 @@
#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 @@
// 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 @@
.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 @@
.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 34f0fdb..3c2445c 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 @@
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 @@
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 @@
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 @@
* 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_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 0000000..0bea803
--- /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 ad506a8..ccccb2e 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 @@
.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 @@
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 @@
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 @@
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 da17ed9..cfc3e42 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 @@
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 @@
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 @@
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_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 @@
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 @@
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 @@
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.
+GENERATE_STATIC_FIELD_GETTERS
-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
+GENERATE_INSTANCE_FIELD_GETTERS
-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
+GENERATE_STATIC_FIELD_SETTERS /*emit64=*/0
-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_DOWNCALL art_quick_set64_static, \
+ artSet64StaticFromCompiledCode, \
+ RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER
-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_INSTANCE_FIELD_SETTERS /*emit64=*/0
// Call artSet64InstanceFromCode with 4 word size arguments.
DEFINE_FUNCTION art_quick_set64_instance
@@ -1546,7 +1486,7 @@
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 9a60781..7207ab8 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 @@
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 @@
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 @@
-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_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 @@
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 @@
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_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