From: Nicolas Geoffray Date: Thu, 19 Jan 2017 14:22:26 +0000 (+0000) Subject: Refactor code for unresolved field entrypoint. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=5b3c6c0fcca76d82a4c9acb03f7714457ae53dd9;p=android-x86%2Fart.git Refactor code for unresolved field entrypoint. - Do macro magic to avoid source code duplication. - Do not fetch the referrer from the assembly, but from the C entrypoint instead. Test: test-art-host test-art-target Change-Id: Ib139c94bc8f74686640cad538ba75dc56fa00e1d --- diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h index 52d18575f..b38c9155e 100644 --- a/compiler/optimizing/code_generator_arm.h +++ b/compiler/optimizing/code_generator_arm.h @@ -128,7 +128,9 @@ class FieldAccessCallingConventionARM : public FieldAccessCallingConvention { } Location GetSetValueLocation(Primitive::Type type, bool is_instance) const OVERRIDE { return Primitive::Is64BitType(type) - ? Location::RegisterPairLocation(R2, R3) + ? (is_instance + ? Location::RegisterPairLocation(R2, R3) + : Location::RegisterPairLocation(R1, R2)) : (is_instance ? Location::RegisterLocation(R2) : Location::RegisterLocation(R1)); diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h index a9dca9298..224f17072 100644 --- a/compiler/optimizing/code_generator_arm64.h +++ b/compiler/optimizing/code_generator_arm64.h @@ -210,12 +210,11 @@ class FieldAccessCallingConventionARM64 : public FieldAccessCallingConvention { Location GetReturnLocation(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE { return helpers::LocationFrom(vixl::aarch64::x0); } - Location GetSetValueLocation(Primitive::Type type, bool is_instance) const OVERRIDE { - return Primitive::Is64BitType(type) + Location GetSetValueLocation(Primitive::Type type ATTRIBUTE_UNUSED, + bool is_instance) const OVERRIDE { + return is_instance ? helpers::LocationFrom(vixl::aarch64::x2) - : (is_instance - ? helpers::LocationFrom(vixl::aarch64::x2) - : helpers::LocationFrom(vixl::aarch64::x1)); + : helpers::LocationFrom(vixl::aarch64::x1); } Location GetFpuLocation(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE { return helpers::LocationFrom(vixl::aarch64::d0); diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h index be653535e..719604c7b 100644 --- a/compiler/optimizing/code_generator_arm_vixl.h +++ b/compiler/optimizing/code_generator_arm_vixl.h @@ -199,7 +199,9 @@ class FieldAccessCallingConventionARMVIXL : public FieldAccessCallingConvention } Location GetSetValueLocation(Primitive::Type type, bool is_instance) const OVERRIDE { return Primitive::Is64BitType(type) - ? helpers::LocationFrom(vixl::aarch32::r2, vixl::aarch32::r3) + ? (is_instance + ? helpers::LocationFrom(vixl::aarch32::r2, vixl::aarch32::r3) + : helpers::LocationFrom(vixl::aarch32::r1, vixl::aarch32::r2)) : (is_instance ? helpers::LocationFrom(vixl::aarch32::r2) : helpers::LocationFrom(vixl::aarch32::r1)); diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index 9eb97658d..285a3fecc 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -110,7 +110,9 @@ class FieldAccessCallingConventionX86 : public FieldAccessCallingConvention { } Location GetSetValueLocation(Primitive::Type type, bool is_instance) const OVERRIDE { return Primitive::Is64BitType(type) - ? Location::RegisterPairLocation(EDX, EBX) + ? (is_instance + ? Location::RegisterPairLocation(EDX, EBX) + : Location::RegisterPairLocation(ECX, EDX)) : (is_instance ? Location::RegisterLocation(EDX) : Location::RegisterLocation(ECX)); diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h index 3438b8159..3a83731b3 100644 --- a/compiler/optimizing/code_generator_x86_64.h +++ b/compiler/optimizing/code_generator_x86_64.h @@ -92,12 +92,11 @@ class FieldAccessCallingConventionX86_64 : public FieldAccessCallingConvention { Location GetReturnLocation(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE { return Location::RegisterLocation(RAX); } - Location GetSetValueLocation(Primitive::Type type, bool is_instance) const OVERRIDE { - return Primitive::Is64BitType(type) + Location GetSetValueLocation(Primitive::Type type ATTRIBUTE_UNUSED, bool is_instance) + const OVERRIDE { + return is_instance ? Location::RegisterLocation(RDX) - : (is_instance - ? Location::RegisterLocation(RDX) - : Location::RegisterLocation(RSI)); + : Location::RegisterLocation(RSI); } Location GetFpuLocation(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE { return Location::FpuRegisterLocation(XMM0); diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S index db1cad670..d1225b323 100644 --- a/runtime/arch/arm/quick_entrypoints_arm.S +++ b/runtime/arch/arm/quick_entrypoints_arm.S @@ -351,14 +351,13 @@ END \c_name DELIVER_PENDING_EXCEPTION .endm -// Macros taking opportunity of code similarities for downcalls with referrer for non-wide fields. +// 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 r1 @ save callee saves in case of GC - ldr r1, [sp, #FRAME_SIZE_SAVE_REFS_ONLY] @ pass referrer - mov r2, r9 @ pass Thread::Current - bl \entrypoint @ (uint32_t field_idx, const Method* referrer, Thread*) + mov r1, r9 @ pass Thread::Current + bl \entrypoint @ (uint32_t field_idx, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME \return END \name @@ -368,9 +367,8 @@ END \name .extern \entrypoint ENTRY \name SETUP_SAVE_REFS_ONLY_FRAME r2 @ save callee saves in case of GC - ldr r2, [sp, #FRAME_SIZE_SAVE_REFS_ONLY] @ pass referrer - mov r3, r9 @ pass Thread::Current - bl \entrypoint @ (field_idx, Object*, referrer, Thread*) + mov r2, r9 @ pass Thread::Current + bl \entrypoint @ (field_idx, Object*, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME \return END \name @@ -380,12 +378,8 @@ END \name .extern \entrypoint ENTRY \name SETUP_SAVE_REFS_ONLY_FRAME r3 @ save callee saves in case of GC - ldr r3, [sp, #FRAME_SIZE_SAVE_REFS_ONLY] @ pass referrer - str r9, [sp, #-16]! @ expand the frame and pass Thread::Current - .cfi_adjust_cfa_offset 16 - bl \entrypoint @ (field_idx, Object*, new_val, referrer, Thread*) - add sp, #16 @ release out args - .cfi_adjust_cfa_offset -16 + mov r3, r9 @ pass Thread::Current + bl \entrypoint @ (field_idx, Object*, new_val, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME @ TODO: we can clearly save an add here \return END \name @@ -978,21 +972,20 @@ ONE_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeA /* * Called by managed code to resolve a static field and load a non-wide value. */ -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 +ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 /* * Called by managed code to resolve a static field and load a 64-bit primitive value. */ - .extern artGet64StaticFromCode + .extern artGet64StaticFromCompiledCode ENTRY art_quick_get64_static SETUP_SAVE_REFS_ONLY_FRAME r2 @ save callee saves in case of GC - ldr r1, [sp, #FRAME_SIZE_SAVE_REFS_ONLY] @ pass referrer - mov r2, r9 @ pass Thread::Current - bl artGet64StaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*) + mov r1, r9 @ pass Thread::Current + bl artGet64StaticFromCompiledCode @ (uint32_t field_idx, Thread*) ldr r2, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ RESTORE_SAVE_REFS_ONLY_FRAME cbnz r2, 1f @ success if no exception pending @@ -1004,21 +997,20 @@ END art_quick_get64_static /* * Called by managed code to resolve an instance field and load a non-wide value. */ -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 +TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 +TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1 /* * Called by managed code to resolve an instance field and load a 64-bit primitive value. */ - .extern artGet64InstanceFromCode + .extern artGet64InstanceFromCompiledCode ENTRY art_quick_get64_instance SETUP_SAVE_REFS_ONLY_FRAME r2 @ save callee saves in case of GC - ldr r2, [sp, #FRAME_SIZE_SAVE_REFS_ONLY] @ pass referrer - mov r3, r9 @ pass Thread::Current - bl artGet64InstanceFromCode @ (field_idx, Object*, referrer, Thread*) + mov r2, r9 @ pass Thread::Current + bl artGet64InstanceFromCompiledCode @ (field_idx, Object*, Thread*) ldr r2, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ RESTORE_SAVE_REFS_ONLY_FRAME cbnz r2, 1f @ success if no exception pending @@ -1028,51 +1020,32 @@ ENTRY art_quick_get64_instance END art_quick_get64_instance /* - * Called by managed code to resolve a static field and store a non-wide value. + * Called by managed code to resolve a static field and store a value. */ -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, r2:r3 hold new_val - */ - .extern artSet64StaticFromCode -ENTRY art_quick_set64_static - SETUP_SAVE_REFS_ONLY_FRAME r1 @ save callee saves in case of GC - @ r2:r3 contain the wide argument - ldr r1, [sp, #FRAME_SIZE_SAVE_REFS_ONLY] @ pass referrer - str r9, [sp, #-16]! @ expand the frame and pass Thread::Current - .cfi_adjust_cfa_offset 16 - bl artSet64StaticFromCode @ (field_idx, referrer, new_val, Thread*) - add sp, #16 @ release out args - .cfi_adjust_cfa_offset -16 - RESTORE_SAVE_REFS_ONLY_FRAME @ TODO: we can clearly save an add here - RETURN_IF_RESULT_IS_ZERO - DELIVER_PENDING_EXCEPTION -END art_quick_set64_static +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 +THREE_ARG_REF_DOWNCALL art_quick_set64_static, artSet64StaticFromCompiledCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER /* * Called by managed code to resolve an instance field and store a non-wide value. */ -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 +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 + /* - * Called by managed code to resolve an instance field and store a 64-bit primitive value. + * Called by managed code to resolve an instance field and store a wide value. */ - .extern artSet64InstanceFromCode + .extern artSet64InstanceFromCompiledCode ENTRY art_quick_set64_instance SETUP_SAVE_REFS_ONLY_FRAME r12 @ save callee saves in case of GC @ r2:r3 contain the wide argument - ldr r12, [sp, #FRAME_SIZE_SAVE_REFS_ONLY] @ pass referrer - str r9, [sp, #-12]! @ expand the frame and pass Thread::Current - .cfi_adjust_cfa_offset 12 - str r12, [sp, #-4]! @ expand the frame and pass the referrer - .cfi_adjust_cfa_offset 4 - bl artSet64InstanceFromCode @ (field_idx, Object*, new_val, Method* referrer, Thread*) + str r9, [sp, #-16]! @ expand the frame and pass Thread::Current + .cfi_adjust_cfa_offset 16 + bl artSet64InstanceFromCompiledCode @ (field_idx, Object*, new_val, Thread*) add sp, #16 @ release out args .cfi_adjust_cfa_offset -16 RESTORE_SAVE_REFS_ONLY_FRAME @ TODO: we can clearly save an add here diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S index 00518e16b..a84e553e7 100644 --- a/runtime/arch/arm64/quick_entrypoints_arm64.S +++ b/runtime/arch/arm64/quick_entrypoints_arm64.S @@ -1519,14 +1519,13 @@ ENTRY \name END \name .endm -// Macros taking opportunity of code similarities for downcalls with referrer. +// 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 - ldr x1, [sp, #FRAME_SIZE_SAVE_REFS_ONLY] // Load referrer - mov x2, xSELF // pass Thread::Current - bl \entrypoint // (uint32_t type_idx, Method* method, Thread*, SP) + mov x1, xSELF // pass Thread::Current + bl \entrypoint // (uint32_t type_idx, Thread*) RESTORE_SAVE_REFS_ONLY_FRAME \return END \name @@ -1536,8 +1535,7 @@ END \name .extern \entrypoint ENTRY \name SETUP_SAVE_REFS_ONLY_FRAME // save callee saves in case of GC - ldr x2, [sp, #FRAME_SIZE_SAVE_REFS_ONLY] // Load referrer - mov x3, xSELF // pass Thread::Current + mov x2, xSELF // pass Thread::Current bl \entrypoint RESTORE_SAVE_REFS_ONLY_FRAME \return @@ -1548,8 +1546,7 @@ END \name .extern \entrypoint ENTRY \name SETUP_SAVE_REFS_ONLY_FRAME // save callee saves in case of GC - ldr x3, [sp, #FRAME_SIZE_SAVE_REFS_ONLY] // Load referrer - mov x4, xSELF // pass Thread::Current + mov x3, xSELF // pass Thread::Current bl \entrypoint RESTORE_SAVE_REFS_ONLY_FRAME \return @@ -1579,44 +1576,33 @@ ONE_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorage ONE_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER ONE_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_RESULT_IS_NON_ZERO_OR_DELIVER -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_REF_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 - -// This is separated out as the argument order is different. - .extern artSet64StaticFromCode -ENTRY art_quick_set64_static - SETUP_SAVE_REFS_ONLY_FRAME // save callee saves in case of GC - ldr x1, [sp, #FRAME_SIZE_SAVE_REFS_ONLY] // Load referrer - // x2 contains the parameter - mov x3, xSELF // pass Thread::Current - bl artSet64StaticFromCode - RESTORE_SAVE_REFS_ONLY_FRAME - RETURN_IF_W0_IS_ZERO_OR_DELIVER -END art_quick_set64_static +ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 + +TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +TWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 +TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1 + +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 /* * Entry from managed code to resolve a string, this stub will diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc index 547b57ee1..9e75cbabd 100644 --- a/runtime/arch/stub_test.cc +++ b/runtime/arch/stub_test.cc @@ -1610,8 +1610,8 @@ static void GetSet64Static(ArtField* f, Thread* self, ArtMethod* referrer, for (size_t i = 0; i < arraysize(values); ++i) { // 64 bit FieldSet stores the set value in the second register. test->Invoke3WithReferrer(static_cast(f->GetDexFieldIndex()), - 0U, values[i], + 0U, StubTest::GetEntrypoint(self, kQuickSet64Static), self, referrer); diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S index c4202596f..1d81b7d1e 100644 --- a/runtime/arch/x86/quick_entrypoints_x86.S +++ b/runtime/arch/x86/quick_entrypoints_x86.S @@ -875,13 +875,12 @@ MACRO3(ONE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) DEFINE_FUNCTION VAR(c_name) SETUP_SAVE_REFS_ONLY_FRAME ebx, ebx // save ref containing registers for GC // Outgoing argument set up - mov FRAME_SIZE_SAVE_REFS_ONLY(%esp), %ecx // get referrer - PUSH eax // push padding + subl MACRO_LITERAL(8), %esp // alignment padding + CFI_ADJUST_CFA_OFFSET(8) pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() CFI_ADJUST_CFA_OFFSET(4) - PUSH ecx // pass referrer PUSH eax // pass arg1 - call CALLVAR(cxx_name) // cxx_name(arg1, referrer, Thread*) + call CALLVAR(cxx_name) // cxx_name(arg1, Thread*) addl MACRO_LITERAL(16), %esp // pop arguments CFI_ADJUST_CFA_OFFSET(-16) RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address @@ -893,10 +892,9 @@ MACRO3(TWO_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) DEFINE_FUNCTION VAR(c_name) SETUP_SAVE_REFS_ONLY_FRAME ebx, ebx // save ref containing registers for GC // Outgoing argument set up - mov FRAME_SIZE_SAVE_REFS_ONLY(%esp), %edx // get referrer + PUSH eax // alignment padding pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() CFI_ADJUST_CFA_OFFSET(4) - PUSH edx // pass referrer PUSH ecx // pass arg2 PUSH eax // pass arg1 call CALLVAR(cxx_name) // cxx_name(arg1, arg2, referrer, Thread*) @@ -911,18 +909,13 @@ MACRO3(THREE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) DEFINE_FUNCTION VAR(c_name) SETUP_SAVE_REFS_ONLY_FRAME ebx, ebx // save ref containing registers for GC // Outgoing argument set up - mov FRAME_SIZE_SAVE_REFS_ONLY(%esp), %ebx // get referrer - subl MACRO_LITERAL(12), %esp // alignment padding - CFI_ADJUST_CFA_OFFSET(12) pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() CFI_ADJUST_CFA_OFFSET(4) - PUSH ebx // pass referrer PUSH edx // pass arg3 PUSH ecx // pass arg2 PUSH eax // pass arg1 - call CALLVAR(cxx_name) // cxx_name(arg1, arg2, arg3, referrer, - // Thread*) - addl LITERAL(32), %esp // pop arguments + call CALLVAR(cxx_name) // cxx_name(arg1, arg2, arg3, Thread*) + addl LITERAL(16), %esp // pop arguments CFI_ADJUST_CFA_OFFSET(-32) RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address CALL_MACRO(return_macro) // return or deliver exception @@ -1556,78 +1549,53 @@ DEFINE_FUNCTION art_quick_lushr ret END_FUNCTION art_quick_lushr -ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION -ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCode, 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_get_short_static, artGetShortStaticFromCode, 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 - -TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION -TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCode, 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_get_short_instance, artGetShortInstanceFromCode, 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 - -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_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCode, RETURN_IF_EAX_ZERO - -// Call artSet64InstanceFromCode with 4 word size arguments and the referrer. +ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION + +TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCompiledCode, RETURN_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 + +// Call artSet64InstanceFromCode with 4 word size arguments. DEFINE_FUNCTION art_quick_set64_instance movd %ebx, %xmm0 SETUP_SAVE_REFS_ONLY_FRAME ebx, ebx // save ref containing registers for GC movd %xmm0, %ebx // Outgoing argument set up - subl LITERAL(8), %esp // alignment padding - CFI_ADJUST_CFA_OFFSET(8) + PUSH eax // alignment padding pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() CFI_ADJUST_CFA_OFFSET(4) - pushl (FRAME_SIZE_SAVE_REFS_ONLY+12)(%esp) // pass referrer - CFI_ADJUST_CFA_OFFSET(4) PUSH ebx // pass high half of new_val PUSH edx // pass low half of new_val PUSH ecx // pass object PUSH eax // pass field_idx - call SYMBOL(artSet64InstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*) + call SYMBOL(artSet64InstanceFromCode) // (field_idx, Object*, new_val, Thread*) 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 END_FUNCTION art_quick_set64_instance -// Call artSet64StaticFromCode with 3 word size arguments plus with the referrer in the 2nd position -// so that new_val is aligned on even registers were we passing arguments in registers. -DEFINE_FUNCTION art_quick_set64_static - // TODO: Implement SETUP_GOT_NOSAVE for got_reg = ecx to avoid moving around the registers. - movd %ebx, %xmm0 - SETUP_SAVE_REFS_ONLY_FRAME ebx, ebx // save ref containing registers for GC - movd %xmm0, %ebx - mov FRAME_SIZE_SAVE_REFS_ONLY(%esp), %ecx // get referrer - subl LITERAL(12), %esp // alignment padding - CFI_ADJUST_CFA_OFFSET(12) - pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() - CFI_ADJUST_CFA_OFFSET(4) - PUSH ebx // pass high half of new_val - PUSH edx // pass low half of new_val - PUSH ecx // pass referrer - PUSH eax // pass field_idx - call SYMBOL(artSet64StaticFromCode) // (field_idx, referrer, new_val, Thread*) - 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 -END_FUNCTION art_quick_set64_static - DEFINE_FUNCTION art_quick_proxy_invoke_handler SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_EAX PUSH esp // pass SP diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S index 46bee399f..544e3eacd 100644 --- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S +++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S @@ -919,11 +919,10 @@ END_MACRO MACRO3(ONE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) DEFINE_FUNCTION VAR(c_name) - movq 8(%rsp), %rsi // pass referrer SETUP_SAVE_REFS_ONLY_FRAME // arg0 is in rdi - movq %gs:THREAD_SELF_OFFSET, %rdx // pass Thread::Current() - call CALLVAR(cxx_name) // cxx_name(arg0, referrer, Thread*) + 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) @@ -931,11 +930,10 @@ END_MACRO MACRO3(TWO_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) DEFINE_FUNCTION VAR(c_name) - movq 8(%rsp), %rdx // pass referrer SETUP_SAVE_REFS_ONLY_FRAME // arg0 and arg1 are in rdi/rsi - movq %gs:THREAD_SELF_OFFSET, %rcx // pass Thread::Current() - call CALLVAR(cxx_name) // (arg0, arg1, referrer, Thread*) + 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) @@ -943,11 +941,10 @@ END_MACRO MACRO3(THREE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro) DEFINE_FUNCTION VAR(c_name) - movq 8(%rsp), %rcx // pass referrer SETUP_SAVE_REFS_ONLY_FRAME // arg0, arg1, and arg2 are in rdi/rsi/rdx - movq %gs:THREAD_SELF_OFFSET, %r8 // pass Thread::Current() - call CALLVAR(cxx_name) // cxx_name(arg0, arg1, arg2, referrer, Thread*) + 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) @@ -1239,7 +1236,7 @@ DEFINE_FUNCTION art_quick_resolve_string // Outgoing argument set up movl %eax, %edi // pass string index movq %gs:THREAD_SELF_OFFSET, %rsi // pass Thread::Current() - call SYMBOL(artResolveStringFromCode) // artResolveStringFromCode(arg0, referrer, Thread*) + call SYMBOL(artResolveStringFromCode) // artResolveStringFromCode(arg0, Thread*) testl %eax, %eax // If result is null, deliver the OOME. jz 1f @@ -1551,45 +1548,33 @@ 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_REF_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 - -// This is singled out as the argument order is different. -DEFINE_FUNCTION art_quick_set64_static - // new_val is already in %rdx - movq 8(%rsp), %rsi // pass referrer - SETUP_SAVE_REFS_ONLY_FRAME - // field_idx is in rdi - movq %gs:THREAD_SELF_OFFSET, %rcx // pass Thread::Current() - call SYMBOL(artSet64StaticFromCode) // (field_idx, referrer, new_val, Thread*) - RESTORE_SAVE_REFS_ONLY_FRAME // restore frame up to return address - RETURN_IF_EAX_ZERO // return or deliver exception -END_FUNCTION art_quick_set64_static - +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_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCompiledCode, RETURN_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_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_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION +ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCompiledCode, RETURN_OR_DELIVER_PENDING_EXCEPTION DEFINE_FUNCTION art_quick_proxy_invoke_handler SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_RDI diff --git a/runtime/art_field-inl.h b/runtime/art_field-inl.h index b9f688de5..ea02027b5 100644 --- a/runtime/art_field-inl.h +++ b/runtime/art_field-inl.h @@ -132,7 +132,6 @@ inline void ArtField::SetObj(ObjPtr object, ObjPtrGetField ## type(GetOffset()); #define FIELD_SET(object, type, value) \ - DCHECK_EQ(Primitive::kPrim ## type, GetTypeAsPrimitiveType()) << PrettyField(); \ DCHECK((object) != nullptr) << PrettyField(); \ DCHECK(!IsStatic() || ((object) == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \ if (UNLIKELY(IsVolatile())) { \ @@ -147,6 +146,12 @@ inline uint8_t ArtField::GetBoolean(ObjPtr object) { template inline void ArtField::SetBoolean(ObjPtr object, uint8_t z) { + if (kIsDebugBuild) { + // For simplicity, this method is being called by the compiler entrypoint for + // both boolean and byte fields. + Primitive::Type type = GetTypeAsPrimitiveType(); + DCHECK(type == Primitive::kPrimBoolean || type == Primitive::kPrimByte) << PrettyField(); + } FIELD_SET(object, Boolean, z); } @@ -156,6 +161,7 @@ inline int8_t ArtField::GetByte(ObjPtr object) { template inline void ArtField::SetByte(ObjPtr object, int8_t b) { + DCHECK_EQ(Primitive::kPrimByte, GetTypeAsPrimitiveType()) << PrettyField(); FIELD_SET(object, Byte, b); } @@ -165,6 +171,12 @@ inline uint16_t ArtField::GetChar(ObjPtr object) { template inline void ArtField::SetChar(ObjPtr object, uint16_t c) { + if (kIsDebugBuild) { + // For simplicity, this method is being called by the compiler entrypoint for + // both char and short fields. + Primitive::Type type = GetTypeAsPrimitiveType(); + DCHECK(type == Primitive::kPrimChar || type == Primitive::kPrimShort) << PrettyField(); + } FIELD_SET(object, Char, c); } @@ -174,6 +186,7 @@ inline int16_t ArtField::GetShort(ObjPtr object) { template inline void ArtField::SetShort(ObjPtr object, int16_t s) { + DCHECK_EQ(Primitive::kPrimShort, GetTypeAsPrimitiveType()) << PrettyField(); FIELD_SET(object, Short, s); } @@ -182,6 +195,8 @@ inline void ArtField::SetShort(ObjPtr object, int16_t s) { inline int32_t ArtField::GetInt(ObjPtr object) { if (kIsDebugBuild) { + // For simplicity, this method is being called by the compiler entrypoint for + // both int and float fields. Primitive::Type type = GetTypeAsPrimitiveType(); CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(); } @@ -191,6 +206,8 @@ inline int32_t ArtField::GetInt(ObjPtr object) { template inline void ArtField::SetInt(ObjPtr object, int32_t i) { if (kIsDebugBuild) { + // For simplicity, this method is being called by the compiler entrypoint for + // both int and float fields. Primitive::Type type = GetTypeAsPrimitiveType(); CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(); } @@ -199,6 +216,8 @@ inline void ArtField::SetInt(ObjPtr object, int32_t i) { inline int64_t ArtField::GetLong(ObjPtr object) { if (kIsDebugBuild) { + // For simplicity, this method is being called by the compiler entrypoint for + // both long and double fields. Primitive::Type type = GetTypeAsPrimitiveType(); CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(); } @@ -208,6 +227,8 @@ inline int64_t ArtField::GetLong(ObjPtr object) { template inline void ArtField::SetLong(ObjPtr object, int64_t j) { if (kIsDebugBuild) { + // For simplicity, this method is being called by the compiler entrypoint for + // both long and double fields. Primitive::Type type = GetTypeAsPrimitiveType(); CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(); } diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc index 25fd72796..06c11f510 100644 --- a/runtime/entrypoints/entrypoint_utils.cc +++ b/runtime/entrypoints/entrypoint_utils.cc @@ -254,5 +254,10 @@ CallerAndOuterMethod GetCalleeSaveMethodCallerAndOuterMethod(Thread* self, return result; } +ArtMethod* GetCalleeSaveOuterMethod(Thread* self, Runtime::CalleeSaveType type) { + ScopedAssertNoThreadSuspension ants(__FUNCTION__); + ArtMethod** sp = self->GetManagedStack()->GetTopQuickFrame(); + return DoGetCalleeSaveMethodOuterCallerAndPc(sp, type).first; +} } // namespace art diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h index 6a04f20f3..69ee3ebe7 100644 --- a/runtime/entrypoints/entrypoint_utils.h +++ b/runtime/entrypoints/entrypoint_utils.h @@ -191,6 +191,9 @@ CallerAndOuterMethod GetCalleeSaveMethodCallerAndOuterMethod(Thread* self, Runtime::CalleeSaveType type) REQUIRES_SHARED(Locks::mutator_lock_); +ArtMethod* GetCalleeSaveOuterMethod(Thread* self, Runtime::CalleeSaveType type) + REQUIRES_SHARED(Locks::mutator_lock_); + } // namespace art #endif // ART_RUNTIME_ENTRYPOINTS_ENTRYPOINT_UTILS_H_ diff --git a/runtime/entrypoints/quick/quick_field_entrypoints.cc b/runtime/entrypoints/quick/quick_field_entrypoints.cc index 6d17000dd..4544aef14 100644 --- a/runtime/entrypoints/quick/quick_field_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc @@ -55,261 +55,207 @@ ALWAYS_INLINE static inline ArtField* FindInstanceField(uint32_t field_idx, return field; } -extern "C" ssize_t artGetByteStaticFromCode(uint32_t field_idx, ArtMethod* referrer, Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int8_t)); - if (LIKELY(field != nullptr)) { - return field->GetByte(field->GetDeclaringClass()); - } - field = FindFieldFromCode(field_idx, referrer, self, sizeof(int8_t)); - if (LIKELY(field != nullptr)) { - return field->GetByte(field->GetDeclaringClass()); - } - return 0; // Will throw exception by checking with Thread::Current. -} - -extern "C" size_t artGetBooleanStaticFromCode(uint32_t field_idx, ArtMethod* referrer, Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int8_t)); - if (LIKELY(field != nullptr)) { - return field->GetBoolean(field->GetDeclaringClass()); - } - field = FindFieldFromCode(field_idx, referrer, self, sizeof(int8_t)); - if (LIKELY(field != nullptr)) { - return field->GetBoolean(field->GetDeclaringClass()); - } - return 0; // Will throw exception by checking with Thread::Current. -} - -extern "C" ssize_t artGetShortStaticFromCode(uint32_t field_idx, ArtMethod* referrer, Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int16_t)); - if (LIKELY(field != nullptr)) { - return field->GetShort(field->GetDeclaringClass()); - } - field = FindFieldFromCode(field_idx, referrer, self, sizeof(int16_t)); - if (LIKELY(field != nullptr)) { - return field->GetShort(field->GetDeclaringClass()); - } - return 0; // Will throw exception by checking with Thread::Current. -} - -extern "C" size_t artGetCharStaticFromCode(uint32_t field_idx, ArtMethod* referrer, Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int16_t)); - if (LIKELY(field != nullptr)) { - return field->GetChar(field->GetDeclaringClass()); - } - field = FindFieldFromCode(field_idx, referrer, self, sizeof(int16_t)); - if (LIKELY(field != nullptr)) { - return field->GetChar(field->GetDeclaringClass()); - } - return 0; // Will throw exception by checking with Thread::Current. -} - -extern "C" size_t artGet32StaticFromCode(uint32_t field_idx, ArtMethod* referrer, Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int32_t)); - if (LIKELY(field != nullptr)) { - return field->Get32(field->GetDeclaringClass()); - } - field = FindFieldFromCode(field_idx, referrer, self, sizeof(int32_t)); - if (LIKELY(field != nullptr)) { - return field->Get32(field->GetDeclaringClass()); - } - return 0; // Will throw exception by checking with Thread::Current. -} - -extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx, - ArtMethod* referrer, - Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int64_t)); - if (LIKELY(field != nullptr)) { - return field->Get64(field->GetDeclaringClass()); - } - field = FindFieldFromCode(field_idx, referrer, self, sizeof(int64_t)); - if (LIKELY(field != nullptr)) { - return field->Get64(field->GetDeclaringClass()); +static ArtMethod* GetReferrer(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { + if (kIsDebugBuild) { + // stub_test doesn't call this code with a proper frame, so get the outer, and if + // it does not have compiled code return it. + ArtMethod* outer = GetCalleeSaveOuterMethod(self, Runtime::kSaveRefsOnly); + if (outer->GetEntryPointFromQuickCompiledCode() == nullptr) { + return outer; + } } - return 0; // Will throw exception by checking with Thread::Current. + return GetCalleeSaveMethodCallerAndOuterMethod(self, Runtime::kSaveRefsOnly).caller; } -extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx, - ArtMethod* referrer, - Thread* self) +#define ART_GET_FIELD_FROM_CODE(Kind, PrimitiveType, RetType, SetType, \ + PrimitiveOrObject, IsObject, Ptr) \ + extern "C" RetType artGet ## Kind ## StaticFromCode(uint32_t field_idx, \ + ArtMethod* referrer, \ + Thread* self) \ + REQUIRES_SHARED(Locks::mutator_lock_) { \ + ScopedQuickEntrypointChecks sqec(self); \ + ArtField* field = FindFieldFast( \ + field_idx, referrer, Static ## PrimitiveOrObject ## Read, \ + sizeof(PrimitiveType)); \ + if (LIKELY(field != nullptr)) { \ + return field->Get ## Kind (field->GetDeclaringClass())Ptr; \ + } \ + field = FindFieldFromCode( \ + field_idx, referrer, self, sizeof(PrimitiveType)); \ + if (LIKELY(field != nullptr)) { \ + return field->Get ## Kind (field->GetDeclaringClass())Ptr; \ + } \ + /* Will throw exception by checking with Thread::Current. */ \ + return 0; \ + } \ + \ + extern "C" RetType artGet ## Kind ## InstanceFromCode(uint32_t field_idx, \ + mirror::Object* obj, \ + ArtMethod* referrer, \ + Thread* self) \ + REQUIRES_SHARED(Locks::mutator_lock_) { \ + ScopedQuickEntrypointChecks sqec(self); \ + ArtField* field = FindFieldFast( \ + field_idx, referrer, Instance ## PrimitiveOrObject ## Read, \ + sizeof(PrimitiveType)); \ + if (LIKELY(field != nullptr) && obj != nullptr) { \ + return field->Get ## Kind (obj)Ptr; \ + } \ + field = FindInstanceField( \ + field_idx, referrer, self, sizeof(PrimitiveType), &obj); \ + if (LIKELY(field != nullptr)) { \ + return field->Get ## Kind (obj)Ptr; \ + } \ + /* Will throw exception by checking with Thread::Current. */ \ + return 0; \ + } \ + \ + extern "C" int artSet ## Kind ## StaticFromCode(uint32_t field_idx, \ + SetType new_value, \ + ArtMethod* referrer, \ + Thread* self) \ + REQUIRES_SHARED(Locks::mutator_lock_) { \ + ScopedQuickEntrypointChecks sqec(self); \ + ArtField* field = FindFieldFast( \ + field_idx, referrer, Static ## PrimitiveOrObject ## Write, \ + sizeof(PrimitiveType)); \ + if (LIKELY(field != nullptr)) { \ + field->Set ## Kind (field->GetDeclaringClass(), new_value); \ + return 0; \ + } \ + if (IsObject) { \ + StackHandleScope<1> hs(self); \ + HandleWrapper h_obj(hs.NewHandleWrapper( \ + reinterpret_cast(&new_value))); \ + field = FindFieldFromCode( \ + field_idx, referrer, self, sizeof(PrimitiveType)); \ + } else { \ + field = FindFieldFromCode( \ + field_idx, referrer, self, sizeof(PrimitiveType)); \ + } \ + if (LIKELY(field != nullptr)) { \ + field->Set ## Kind (field->GetDeclaringClass(), new_value); \ + return 0; \ + } \ + return -1; \ + } \ + \ + extern "C" int artSet ## Kind ## InstanceFromCode(uint32_t field_idx, \ + mirror::Object* obj, \ + SetType new_value, \ + ArtMethod* referrer, \ + Thread* self) \ + REQUIRES_SHARED(Locks::mutator_lock_) { \ + ScopedQuickEntrypointChecks sqec(self); \ + ArtField* field = FindFieldFast( \ + field_idx, referrer, Instance ## PrimitiveOrObject ## Write, \ + sizeof(PrimitiveType)); \ + if (LIKELY(field != nullptr && obj != nullptr)) { \ + field->Set ## Kind (obj, new_value); \ + return 0; \ + } \ + if (IsObject) { \ + StackHandleScope<1> hs(self); \ + HandleWrapper h_obj(hs.NewHandleWrapper( \ + reinterpret_cast(&new_value))); \ + field = FindInstanceField( \ + field_idx, \ + referrer, \ + self, \ + sizeof(PrimitiveType), \ + &obj); \ + } else { \ + field = FindInstanceField( \ + field_idx, \ + referrer, \ + self, \ + sizeof(PrimitiveType), \ + &obj); \ + } \ + if (LIKELY(field != nullptr)) { \ + field->Set ## Kind(obj, new_value); \ + return 0; \ + } \ + return -1; \ + } \ + \ + extern "C" RetType artGet ## Kind ## StaticFromCompiledCode( \ + uint32_t field_idx, \ + Thread* self) \ + REQUIRES_SHARED(Locks::mutator_lock_) { \ + return artGet ## Kind ## StaticFromCode( \ + field_idx, GetReferrer(self), self); \ + } \ + \ + extern "C" RetType artGet ## Kind ## InstanceFromCompiledCode( \ + uint32_t field_idx, \ + mirror::Object* obj, \ + Thread* self) \ + REQUIRES_SHARED(Locks::mutator_lock_) { \ + return artGet ## Kind ## InstanceFromCode( \ + field_idx, obj, GetReferrer(self), self); \ + } \ + \ + extern "C" int artSet ## Kind ## StaticFromCompiledCode( \ + uint32_t field_idx, \ + SetType new_value, \ + Thread* self) \ + REQUIRES_SHARED(Locks::mutator_lock_) { \ + return artSet ## Kind ## StaticFromCode( \ + field_idx, new_value, GetReferrer(self), self); \ + } \ + \ + extern "C" int artSet ## Kind ## InstanceFromCompiledCode( \ + uint32_t field_idx, \ + mirror::Object* obj, \ + SetType new_value, \ + Thread* self) \ + REQUIRES_SHARED(Locks::mutator_lock_) { \ + return artSet ## Kind ## InstanceFromCode( \ + field_idx, obj, new_value, GetReferrer(self), self); \ + } + +ART_GET_FIELD_FROM_CODE(Byte, int8_t, ssize_t, uint32_t, Primitive, false, ) +ART_GET_FIELD_FROM_CODE(Boolean, int8_t, size_t, uint32_t, Primitive, false, ) +ART_GET_FIELD_FROM_CODE(Short, int16_t, ssize_t, uint16_t, Primitive, false, ) +ART_GET_FIELD_FROM_CODE(Char, int16_t, size_t, uint16_t, Primitive, false, ) +ART_GET_FIELD_FROM_CODE(32, int32_t, size_t, uint32_t, Primitive, false, ) +ART_GET_FIELD_FROM_CODE(64, int64_t, uint64_t, uint64_t, Primitive, false, ) +ART_GET_FIELD_FROM_CODE(Obj, mirror::HeapReference, mirror::Object*, + mirror::Object*, Object, true, .Ptr()) + + +// To cut on the number of entrypoints, we have shared entries for +// byte/boolean and char/short for setting an instance or static field. We just +// forward those to the unsigned variant. +extern "C" int artSet8StaticFromCompiledCode(uint32_t field_idx, + uint32_t new_value, + Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, - referrer, - StaticObjectRead, - sizeof(mirror::HeapReference)); - if (LIKELY(field != nullptr)) { - return field->GetObj(field->GetDeclaringClass()).Ptr(); - } - field = FindFieldFromCode(field_idx, - referrer, - self, - sizeof(mirror::HeapReference)); - if (LIKELY(field != nullptr)) { - return field->GetObj(field->GetDeclaringClass()).Ptr(); - } - return nullptr; // Will throw exception by checking with Thread::Current. + return artSetBooleanStaticFromCode(field_idx, new_value, GetReferrer(self), self); } -extern "C" ssize_t artGetByteInstanceFromCode(uint32_t field_idx, - mirror::Object* obj, - ArtMethod* referrer, +extern "C" int artSet16StaticFromCompiledCode(uint32_t field_idx, + uint16_t new_value, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int8_t)); - if (LIKELY(field != nullptr && obj != nullptr)) { - return field->GetByte(obj); - } - field = FindInstanceField(field_idx, - referrer, - self, - sizeof(int8_t), - &obj); - if (LIKELY(field != nullptr)) { - return field->GetByte(obj); - } - return 0; // Will throw exception by checking with Thread::Current. + return artSetCharStaticFromCode(field_idx, new_value, GetReferrer(self), self); } -extern "C" size_t artGetBooleanInstanceFromCode(uint32_t field_idx, - mirror::Object* obj, - ArtMethod* referrer, - Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int8_t)); - if (LIKELY(field != nullptr && obj != nullptr)) { - return field->GetBoolean(obj); - } - field = FindInstanceField(field_idx, - referrer, - self, - sizeof(int8_t), - &obj); - if (LIKELY(field != nullptr)) { - return field->GetBoolean(obj); - } - return 0; // Will throw exception by checking with Thread::Current. -} -extern "C" ssize_t artGetShortInstanceFromCode(uint32_t field_idx, +extern "C" int artSet8InstanceFromCompiledCode(uint32_t field_idx, mirror::Object* obj, - ArtMethod* referrer, + uint8_t new_value, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int16_t)); - if (LIKELY(field != nullptr && obj != nullptr)) { - return field->GetShort(obj); - } - field = FindInstanceField(field_idx, - referrer, - self, - sizeof(int16_t), - &obj); - if (LIKELY(field != nullptr)) { - return field->GetShort(obj); - } - return 0; // Will throw exception by checking with Thread::Current. -} - -extern "C" size_t artGetCharInstanceFromCode(uint32_t field_idx, - mirror::Object* obj, - ArtMethod* referrer, - Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int16_t)); - if (LIKELY(field != nullptr && obj != nullptr)) { - return field->GetChar(obj); - } - field = FindInstanceField(field_idx, - referrer, - self, - sizeof(int16_t), - &obj); - if (LIKELY(field != nullptr)) { - return field->GetChar(obj); - } - return 0; // Will throw exception by checking with Thread::Current. + return artSetBooleanInstanceFromCode(field_idx, obj, new_value, GetReferrer(self), self); } -extern "C" size_t artGet32InstanceFromCode(uint32_t field_idx, - mirror::Object* obj, - ArtMethod* referrer, - Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int32_t)); - if (LIKELY(field != nullptr && obj != nullptr)) { - return field->Get32(obj); - } - field = FindInstanceField(field_idx, - referrer, - self, - sizeof(int32_t), - &obj); - if (LIKELY(field != nullptr)) { - return field->Get32(obj); - } - return 0; // Will throw exception by checking with Thread::Current. -} - -extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, - mirror::Object* obj, - ArtMethod* referrer, - Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int64_t)); - if (LIKELY(field != nullptr && obj != nullptr)) { - return field->Get64(obj); - } - field = FindInstanceField(field_idx, - referrer, - self, - sizeof(int64_t), - &obj); - if (LIKELY(field != nullptr)) { - return field->Get64(obj); - } - return 0; // Will throw exception by checking with Thread::Current. -} - -extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, - mirror::Object* obj, - ArtMethod* referrer, - Thread* self) +extern "C" int artSet16InstanceFromCompiledCode(uint32_t field_idx, + mirror::Object* obj, + uint16_t new_value, + Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, - referrer, - InstanceObjectRead, - sizeof(mirror::HeapReference)); - if (LIKELY(field != nullptr && obj != nullptr)) { - return field->GetObj(obj).Ptr(); - } - field = FindInstanceField(field_idx, - referrer, - self, - sizeof(mirror::HeapReference), - &obj); - if (LIKELY(field != nullptr)) { - return field->GetObj(obj).Ptr(); - } - return nullptr; // Will throw exception by checking with Thread::Current. + return artSetCharInstanceFromCode(field_idx, obj, new_value, GetReferrer(self), self); } extern "C" int artSet8StaticFromCode(uint32_t field_idx, @@ -317,32 +263,7 @@ extern "C" int artSet8StaticFromCode(uint32_t field_idx, ArtMethod* referrer, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int8_t)); - if (LIKELY(field != nullptr)) { - Primitive::Type type = field->GetTypeAsPrimitiveType(); - // Compiled code can't use transactional mode. - if (type == Primitive::kPrimBoolean) { - field->SetBoolean(field->GetDeclaringClass(), new_value); - } else { - DCHECK_EQ(Primitive::kPrimByte, type); - field->SetByte(field->GetDeclaringClass(), new_value); - } - return 0; // success - } - field = FindFieldFromCode(field_idx, referrer, self, sizeof(int8_t)); - if (LIKELY(field != nullptr)) { - Primitive::Type type = field->GetTypeAsPrimitiveType(); - // Compiled code can't use transactional mode. - if (type == Primitive::kPrimBoolean) { - field->SetBoolean(field->GetDeclaringClass(), new_value); - } else { - DCHECK_EQ(Primitive::kPrimByte, type); - field->SetByte(field->GetDeclaringClass(), new_value); - } - return 0; // success - } - return -1; // failure + return artSetBooleanStaticFromCode(field_idx, new_value, referrer, self); } extern "C" int artSet16StaticFromCode(uint32_t field_idx, @@ -350,108 +271,7 @@ extern "C" int artSet16StaticFromCode(uint32_t field_idx, ArtMethod* referrer, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int16_t)); - if (LIKELY(field != nullptr)) { - Primitive::Type type = field->GetTypeAsPrimitiveType(); - // Compiled code can't use transactional mode. - if (type == Primitive::kPrimChar) { - field->SetChar(field->GetDeclaringClass(), new_value); - } else { - DCHECK_EQ(Primitive::kPrimShort, type); - field->SetShort(field->GetDeclaringClass(), new_value); - } - return 0; // success - } - field = FindFieldFromCode(field_idx, referrer, self, sizeof(int16_t)); - if (LIKELY(field != nullptr)) { - Primitive::Type type = field->GetTypeAsPrimitiveType(); - // Compiled code can't use transactional mode. - if (type == Primitive::kPrimChar) { - field->SetChar(field->GetDeclaringClass(), new_value); - } else { - DCHECK_EQ(Primitive::kPrimShort, type); - field->SetShort(field->GetDeclaringClass(), new_value); - } - return 0; // success - } - return -1; // failure -} - -extern "C" int artSet32StaticFromCode(uint32_t field_idx, - uint32_t new_value, - ArtMethod* referrer, - Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int32_t)); - if (LIKELY(field != nullptr)) { - // Compiled code can't use transactional mode. - field->Set32(field->GetDeclaringClass(), new_value); - return 0; // success - } - field = FindFieldFromCode(field_idx, referrer, self, sizeof(int32_t)); - if (LIKELY(field != nullptr)) { - // Compiled code can't use transactional mode. - field->Set32(field->GetDeclaringClass(), new_value); - return 0; // success - } - return -1; // failure -} - -extern "C" int artSet64StaticFromCode(uint32_t field_idx, - ArtMethod* referrer, - uint64_t new_value, - Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t)); - if (LIKELY(field != nullptr)) { - // Compiled code can't use transactional mode. - field->Set64(field->GetDeclaringClass(), new_value); - return 0; // success - } - field = FindFieldFromCode(field_idx, referrer, self, sizeof(int64_t)); - if (LIKELY(field != nullptr)) { - // Compiled code can't use transactional mode. - field->Set64(field->GetDeclaringClass(), new_value); - return 0; // success - } - return -1; // failure -} - -extern "C" int artSetObjStaticFromCode(uint32_t field_idx, - mirror::Object* new_value, - ArtMethod* referrer, - Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, - referrer, - StaticObjectWrite, - sizeof(mirror::HeapReference)); - if (LIKELY(field != nullptr)) { - if (LIKELY(!field->IsPrimitiveType())) { - // Compiled code can't use transactional mode. - field->SetObj(field->GetDeclaringClass(), new_value); - return 0; // success - } - } - { - StackHandleScope<1> hs(self); - HandleWrapper h_obj(hs.NewHandleWrapper(&new_value)); - field = FindFieldFromCode( - field_idx, - referrer, - self, - sizeof(mirror::HeapReference)); - } - if (LIKELY(field != nullptr)) { - // Compiled code can't use transactional mode. - field->SetObj(field->GetDeclaringClass(), new_value); - return 0; // success - } - return -1; // failure + return artSetCharStaticFromCode(field_idx, new_value, referrer, self); } extern "C" int artSet8InstanceFromCode(uint32_t field_idx, @@ -460,35 +280,7 @@ extern "C" int artSet8InstanceFromCode(uint32_t field_idx, ArtMethod* referrer, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int8_t)); - if (LIKELY(field != nullptr && obj != nullptr)) { - Primitive::Type type = field->GetTypeAsPrimitiveType(); - // Compiled code can't use transactional mode. - if (type == Primitive::kPrimBoolean) { - field->SetBoolean(obj, new_value); - } else { - DCHECK_EQ(Primitive::kPrimByte, type); - field->SetByte(obj, new_value); - } - return 0; // success - } - field = FindInstanceField(field_idx, - referrer, - self, - sizeof(int8_t), - &obj); - if (LIKELY(field != nullptr)) { - Primitive::Type type = field->GetTypeAsPrimitiveType(); - // Compiled code can't use transactional mode. - if (type == Primitive::kPrimBoolean) { - field->SetBoolean(obj, new_value); - } else { - field->SetByte(obj, new_value); - } - return 0; // success - } - return -1; // failure + return artSetBooleanInstanceFromCode(field_idx, obj, new_value, referrer, self); } extern "C" int artSet16InstanceFromCode(uint32_t field_idx, @@ -497,126 +289,7 @@ extern "C" int artSet16InstanceFromCode(uint32_t field_idx, ArtMethod* referrer, Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int16_t)); - if (LIKELY(field != nullptr && obj != nullptr)) { - Primitive::Type type = field->GetTypeAsPrimitiveType(); - // Compiled code can't use transactional mode. - if (type == Primitive::kPrimChar) { - field->SetChar(obj, new_value); - } else { - DCHECK_EQ(Primitive::kPrimShort, type); - field->SetShort(obj, new_value); - } - return 0; // success - } - field = FindInstanceField(field_idx, - referrer, - self, - sizeof(int16_t), - &obj); - if (LIKELY(field != nullptr)) { - Primitive::Type type = field->GetTypeAsPrimitiveType(); - // Compiled code can't use transactional mode. - if (type == Primitive::kPrimChar) { - field->SetChar(obj, new_value); - } else { - DCHECK_EQ(Primitive::kPrimShort, type); - field->SetShort(obj, new_value); - } - return 0; // success - } - return -1; // failure -} - -extern "C" int artSet32InstanceFromCode(uint32_t field_idx, - mirror::Object* obj, - uint32_t new_value, - ArtMethod* referrer, - Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int32_t)); - if (LIKELY(field != nullptr && obj != nullptr)) { - // Compiled code can't use transactional mode. - field->Set32(obj, new_value); - return 0; // success - } - field = FindInstanceField(field_idx, - referrer, - self, - sizeof(int32_t), - &obj); - if (LIKELY(field != nullptr)) { - // Compiled code can't use transactional mode. - field->Set32(obj, new_value); - return 0; // success - } - return -1; // failure -} - -extern "C" int artSet64InstanceFromCode(uint32_t field_idx, - mirror::Object* obj, - uint64_t new_value, - ArtMethod* referrer, - Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int64_t)); - if (LIKELY(field != nullptr && obj != nullptr)) { - // Compiled code can't use transactional mode. - field->Set64(obj, new_value); - return 0; // success - } - field = FindInstanceField(field_idx, - referrer, - self, - sizeof(int64_t), - &obj); - if (LIKELY(field != nullptr)) { - // Compiled code can't use transactional mode. - field->Set64(obj, new_value); - return 0; - } - return -1; // failure -} - -extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, - mirror::Object* obj, - mirror::Object* new_value, - ArtMethod* referrer, - Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); - ArtField* field = FindFieldFast(field_idx, - referrer, - InstanceObjectWrite, - sizeof(mirror::HeapReference)); - if (LIKELY(field != nullptr && obj != nullptr)) { - // Compiled code can't use transactional mode. - field->SetObj(obj, new_value); - return 0; // success - } - { - StackHandleScope<2> hs(self); - HandleWrapper h_obj(hs.NewHandleWrapper(&obj)); - HandleWrapper h_new_value(hs.NewHandleWrapper(&new_value)); - field = FindFieldFromCode( - field_idx, - referrer, - self, - sizeof(mirror::HeapReference)); - } - if (LIKELY(field != nullptr)) { - if (UNLIKELY(obj == nullptr)) { - ThrowNullPointerExceptionForFieldAccess(field, false); - } else { - // Compiled code can't use transactional mode. - field->SetObj(obj, new_value); - return 0; // success - } - } - return -1; // failure + return artSetCharInstanceFromCode(field_idx, obj, new_value, referrer, self); } extern "C" mirror::Object* artReadBarrierMark(mirror::Object* obj) {