diff options
| author | 2023-09-12 20:32:05 -0700 | |
|---|---|---|
| committer | 2023-09-19 21:38:53 +0000 | |
| commit | 9b4fba296b04ca02300b6c76c8367fbec0308ac2 (patch) | |
| tree | 7f2b147b733bc4639ab4a68bce565364a6456912 | |
| parent | 3937b95e1ecfb890fe51caf19ca565c98b602c07 (diff) | |
riscv64: ExecuteNterpImpl with class init
Test: Run these opcodes against all interpreter
tests on a Linux RISC-V VM.
(1) setup
lunch aosp_riscv64-userdebug
export ART_TEST_SSH_USER=ubuntu
export ART_TEST_SSH_HOST=localhost
export ART_TEST_SSH_PORT=10001
export ART_TEST_ON_VM=true
. art/tools/buildbot-utils.sh
art/tools/buildbot-build.sh --target
# Create, boot and configure the VM.
art/tools/buildbot-vm.sh create
art/tools/buildbot-vm.sh boot
art/tools/buildbot-vm.sh setup-ssh # password: 'ubuntu'
art/tools/buildbot-cleanup-device.sh
art/tools/buildbot-setup-device.sh
art/tools/buildbot-sync.sh
(2) test
art/test.py --target -r --no-prebuild --ndebug --64 -j 12 --cdex-none --interpreter
Clean with `m check_cfi` too.
Bug: 283082047
Change-Id: I7d1369961d9ec52a098bf36af5825c6abdad23d9
| -rw-r--r-- | runtime/arch/riscv64/asm_support_riscv64.S | 72 | ||||
| -rw-r--r-- | runtime/arch/riscv64/asm_support_riscv64.h | 4 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/riscv64/control_flow.S | 8 | ||||
| -rw-r--r-- | runtime/interpreter/mterp/riscv64/main.S | 33 | ||||
| -rw-r--r-- | runtime/nterp_helpers.cc | 3 | ||||
| -rw-r--r-- | tools/cpp-define-generator/mirror_class.def | 58 |
6 files changed, 134 insertions, 44 deletions
diff --git a/runtime/arch/riscv64/asm_support_riscv64.S b/runtime/arch/riscv64/asm_support_riscv64.S index b8d05505bf..113daed9f8 100644 --- a/runtime/arch/riscv64/asm_support_riscv64.S +++ b/runtime/arch/riscv64/asm_support_riscv64.S @@ -561,6 +561,78 @@ .endm +.macro SETUP_NTERP_SAVE_CALLEE_SAVES +#if (NTERP_SIZE_SAVE_CALLEE_SAVES != 8*(12 + 1 + 10 + 1)) +#error "NTERP_SIZE_SAVE_CALLEE_SAVES(RISCV64) size not as expected." +#endif + // FP callee-saves. + SAVE_FPR fs0, (8*0) // f8 + SAVE_FPR fs1, (8*1) // f9 + SAVE_FPR fs2, (8*2) // f18 + SAVE_FPR fs3, (8*3) // f19 + SAVE_FPR fs4, (8*4) // f20 + SAVE_FPR fs5, (8*5) // f21 + SAVE_FPR fs6, (8*6) // f22 + SAVE_FPR fs7, (8*7) // f23 + SAVE_FPR fs8, (8*8) // f24 + SAVE_FPR fs9, (8*9) // f25 + SAVE_FPR fs10, (8*10) // f26 + SAVE_FPR fs11, (8*11) // f27 + + // GP callee-saves + SAVE_GPR s0, (8*12) // x8/fp, frame pointer + // s1 (x9) is the ART thread register + SAVE_GPR s2, (8*13) // x18 + SAVE_GPR s3, (8*14) // x19 + SAVE_GPR s4, (8*15) // x20 + SAVE_GPR s5, (8*16) // x21 + SAVE_GPR s6, (8*17) // x22 + SAVE_GPR s7, (8*18) // x23 + SAVE_GPR s8, (8*19) // x24 + SAVE_GPR s9, (8*20) // x25 + SAVE_GPR s10, (8*21) // x26 + SAVE_GPR s11, (8*22) // x27 + + SAVE_GPR ra, (8*23) // x1, return address +.endm + + +.macro RESTORE_NTERP_SAVE_CALLEE_SAVES +#if (NTERP_SIZE_SAVE_CALLEE_SAVES != 8*(12 + 1 + 10 + 1)) +#error "NTERP_SIZE_SAVE_CALLEE_SAVES(RISCV64) size not as expected." +#endif + // FP callee-saves. + RESTORE_FPR fs0, (8*0) // f8 + RESTORE_FPR fs1, (8*1) // f9 + RESTORE_FPR fs2, (8*2) // f18 + RESTORE_FPR fs3, (8*3) // f19 + RESTORE_FPR fs4, (8*4) // f20 + RESTORE_FPR fs5, (8*5) // f21 + RESTORE_FPR fs6, (8*6) // f22 + RESTORE_FPR fs7, (8*7) // f23 + RESTORE_FPR fs8, (8*8) // f24 + RESTORE_FPR fs9, (8*9) // f25 + RESTORE_FPR fs10, (8*10) // f26 + RESTORE_FPR fs11, (8*11) // f27 + + // GP callee-saves + RESTORE_GPR s0, (8*12) // x8/fp, frame pointer + // s1 is the ART thread register + RESTORE_GPR s2, (8*13) // x18 + RESTORE_GPR s3, (8*14) // x19 + RESTORE_GPR s4, (8*15) // x20 + RESTORE_GPR s5, (8*16) // x21 + RESTORE_GPR s6, (8*17) // x22 + RESTORE_GPR s7, (8*18) // x23 + RESTORE_GPR s8, (8*19) // x24 + RESTORE_GPR s9, (8*20) // x25 + RESTORE_GPR s10, (8*21) // x26 + RESTORE_GPR s11, (8*22) // x27 + + RESTORE_GPR ra, (8*23) // x1, return address +.endm + + // Macro that calls through to artDeliverPendingExceptionFromCode, where the pending exception is // Thread::Current()->exception_ when the runtime method frame is ready. .macro DELIVER_PENDING_EXCEPTION_FRAME_READY diff --git a/runtime/arch/riscv64/asm_support_riscv64.h b/runtime/arch/riscv64/asm_support_riscv64.h index 7e84039fc8..504c575414 100644 --- a/runtime/arch/riscv64/asm_support_riscv64.h +++ b/runtime/arch/riscv64/asm_support_riscv64.h @@ -38,6 +38,10 @@ // total 8*(32 + 27 + 1) = 480 // Excluded GPRs are: SP, Zero, TP, GP, S1/TR (ART thread register). #define FRAME_SIZE_SAVE_EVERYTHING 480 + +// FS0 - FS11, S0, S2 - S11, RA, +// total 8*(12 + 1 + 10 + 1) = 192 +#define NTERP_SIZE_SAVE_CALLEE_SAVES 192 // clang-format on #endif // ART_RUNTIME_ARCH_RISCV64_ASM_SUPPORT_RISCV64_H_ diff --git a/runtime/interpreter/mterp/riscv64/control_flow.S b/runtime/interpreter/mterp/riscv64/control_flow.S index 05ad426773..3c6fc54a28 100644 --- a/runtime/interpreter/mterp/riscv64/control_flow.S +++ b/runtime/interpreter/mterp/riscv64/control_flow.S @@ -27,12 +27,12 @@ CFI_REMEMBER_STATE ld sp, -8(xREFS) // caller's interpreted frame pointer - .cfi_def_cfa sp, FRAME_SIZE_SAVE_ALL_CALLEE_SAVES - RESTORE_ALL_CALLEE_SAVES - DECREASE_FRAME FRAME_SIZE_SAVE_ALL_CALLEE_SAVES + .cfi_def_cfa sp, NTERP_SIZE_SAVE_CALLEE_SAVES + RESTORE_NTERP_SAVE_CALLEE_SAVES + DECREASE_FRAME NTERP_SIZE_SAVE_CALLEE_SAVES ret .cfi_restore_state - CFI_DEF_CFA_BREG_PLUS_UCONST CFI_REFS, -8, FRAME_SIZE_SAVE_ALL_CALLEE_SAVES + CFI_DEF_CFA_BREG_PLUS_UCONST CFI_REFS, -8, NTERP_SIZE_SAVE_CALLEE_SAVES // return-wide vAA // Format 11x: AA|10 diff --git a/runtime/interpreter/mterp/riscv64/main.S b/runtime/interpreter/mterp/riscv64/main.S index a0a02afad3..8fbb4bada2 100644 --- a/runtime/interpreter/mterp/riscv64/main.S +++ b/runtime/interpreter/mterp/riscv64/main.S @@ -188,7 +188,7 @@ END \name .cfi_def_cfa_register \old_sp mv sp, t0 sd \old_sp, -8(\refs) - CFI_DEF_CFA_BREG_PLUS_UCONST \cfi_refs, -8, FRAME_SIZE_SAVE_ALL_CALLEE_SAVES + CFI_DEF_CFA_BREG_PLUS_UCONST \cfi_refs, -8, NTERP_SIZE_SAVE_CALLEE_SAVES // Put nulls in reference array. beqz \regs, 2f @@ -434,10 +434,33 @@ END \name * a0 ArtMethod* callee * a1-a7 method parameters */ - OAT_ENTRY ExecuteNterpWithClinitImpl +#if MIRROR_CLASS_STATUS_SHIFT < 12 +#error mirror class status bits cannot use LUI load technique +#endif .cfi_startproc - unimp + // For simplicity, we don't do a read barrier here, but instead rely + // on art_quick_resolution_trampoline to always have a suspend point before + // calling back here. + ld t0, ART_METHOD_DECLARING_CLASS_OFFSET(a0) + lw t1, MIRROR_CLASS_STATUS_OFFSET(t0) // t1 := status word, sext + lui t2, MIRROR_CLASS_STATUS_VISIBLY_INITIALIZED << (MIRROR_CLASS_STATUS_SHIFT - 12) + // The unsigned comparison works in tandem with the 64-bit sign-extension of + // the status bits at the top of the 32-bit word. The order of the status + // constants (sign extended from LUI) is unchanged with unsigned comparison. + bgeu t1, t2, ExecuteNterpImpl + lui t2, MIRROR_CLASS_STATUS_INITIALIZED << (MIRROR_CLASS_STATUS_SHIFT - 12) + bltu t1, t2, .Linitializing_check + fence w, w + j ExecuteNterpImpl +.Linitializing_check: + lui t2, MIRROR_CLASS_STATUS_INITIALIZING << (MIRROR_CLASS_STATUS_SHIFT - 12) + bltu t1, t2, .Lresolution_trampoline + ld t1, MIRROR_CLASS_CLINIT_THREAD_ID_OFFSET(t0) + ld t0, THREAD_TID_OFFSET(xSELF) + beq t0, t1, ExecuteNterpImpl +.Lresolution_trampoline: + tail art_quick_resolution_trampoline .cfi_endproc .type EndExecuteNterpWithClinitImpl, @function .hidden EndExecuteNterpWithClinitImpl @@ -452,8 +475,8 @@ OAT_ENTRY ExecuteNterpImpl add t0, t0, sp ld zero, (t0) - INCREASE_FRAME FRAME_SIZE_SAVE_ALL_CALLEE_SAVES - SAVE_ALL_CALLEE_SAVES + INCREASE_FRAME NTERP_SIZE_SAVE_CALLEE_SAVES + SETUP_NTERP_SAVE_CALLEE_SAVES ld xPC, ART_METHOD_DATA_OFFSET_64(a0) SETUP_STACK_FRAME xPC, CFI_REFS, xREFS, xFP, /*reg count*/ s7, /*in count*/s8, /*old sp*/s9 diff --git a/runtime/nterp_helpers.cc b/runtime/nterp_helpers.cc index 67d8497539..5e4786248f 100644 --- a/runtime/nterp_helpers.cc +++ b/runtime/nterp_helpers.cc @@ -235,9 +235,6 @@ bool CanMethodUseNterp(ArtMethod* method, InstructionSet isa) { return false; } if (isa == InstructionSet::kRiscv64) { - if (method->NeedsClinitCheckBeforeCall()) { - return false; // Riscv64 nterp does not implement ExecuteNterpWithClinitImpl. - } if (method->GetDexFile()->IsCompactDexFile()) { return false; // Riscv64 nterp does not support compact dex yet. } diff --git a/tools/cpp-define-generator/mirror_class.def b/tools/cpp-define-generator/mirror_class.def index 23d5dcb759..2f229e4846 100644 --- a/tools/cpp-define-generator/mirror_class.def +++ b/tools/cpp-define-generator/mirror_class.def @@ -19,52 +19,46 @@ #include "subtype_check.h" #endif -ASM_DEFINE(MIRROR_CLASS_ACCESS_FLAGS_OFFSET, - art::mirror::Class::AccessFlagsOffset().Int32Value()) +ASM_DEFINE(MIRROR_CLASS_ACCESS_FLAGS_OFFSET, art::mirror::Class::AccessFlagsOffset().Int32Value()) +ASM_DEFINE(MIRROR_CLASS_CLINIT_THREAD_ID_OFFSET, + art::mirror::Class::ClinitThreadIdOffset().Int32Value()) ASM_DEFINE(MIRROR_CLASS_COMPONENT_TYPE_OFFSET, art::mirror::Class::ComponentTypeOffset().Int32Value()) -ASM_DEFINE(MIRROR_CLASS_DEX_CACHE_OFFSET, - art::mirror::Class::DexCacheOffset().Int32Value()) -ASM_DEFINE(MIRROR_CLASS_IF_TABLE_OFFSET, - art::mirror::Class::IfTableOffset().Int32Value()) +ASM_DEFINE(MIRROR_CLASS_DEX_CACHE_OFFSET, art::mirror::Class::DexCacheOffset().Int32Value()) +ASM_DEFINE(MIRROR_CLASS_IF_TABLE_OFFSET, art::mirror::Class::IfTableOffset().Int32Value()) +ASM_DEFINE(MIRROR_CLASS_IMT_PTR_OFFSET_32, + art::mirror::Class::ImtPtrOffset(art::PointerSize::k32).Int32Value()) +ASM_DEFINE(MIRROR_CLASS_IMT_PTR_OFFSET_64, + art::mirror::Class::ImtPtrOffset(art::PointerSize::k64).Int32Value()) ASM_DEFINE(MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET, art::mirror::Class::PrimitiveTypeOffset().Int32Value()) ASM_DEFINE(MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET, art::mirror::Class::ObjectSizeAllocFastPathOffset().Int32Value()) -ASM_DEFINE(MIRROR_CLASS_OBJECT_SIZE_OFFSET, - art::mirror::Class::ObjectSizeOffset().Int32Value()) -ASM_DEFINE(MIRROR_CLASS_STATUS_OFFSET, - art::mirror::Class::StatusOffset().Int32Value()) -ASM_DEFINE(PRIMITIVE_TYPE_SIZE_SHIFT_SHIFT, - art::mirror::Class::kPrimitiveTypeSizeShiftShift) +ASM_DEFINE(MIRROR_CLASS_OBJECT_SIZE_OFFSET, art::mirror::Class::ObjectSizeOffset().Int32Value()) +ASM_DEFINE(MIRROR_CLASS_STATUS_OFFSET, art::mirror::Class::StatusOffset().Int32Value()) +ASM_DEFINE(MIRROR_CLASS_SUPER_CLASS_OFFSET, art::mirror::Class::SuperClassOffset().Int32Value()) ASM_DEFINE(MIRROR_CLASS_VTABLE_OFFSET_32, art::mirror::Class::EmbeddedVTableOffset(art::PointerSize::k32).Int32Value()) ASM_DEFINE(MIRROR_CLASS_VTABLE_OFFSET_64, art::mirror::Class::EmbeddedVTableOffset(art::PointerSize::k64).Int32Value()) -ASM_DEFINE(MIRROR_CLASS_IMT_PTR_OFFSET_32, - art::mirror::Class::ImtPtrOffset(art::PointerSize::k32).Int32Value()) -ASM_DEFINE(MIRROR_CLASS_IMT_PTR_OFFSET_64, - art::mirror::Class::ImtPtrOffset(art::PointerSize::k64).Int32Value()) -ASM_DEFINE(MIRROR_CLASS_SUPER_CLASS_OFFSET, - art::mirror::Class::SuperClassOffset().Int32Value()) -ASM_DEFINE(MIRROR_CLASS_IS_INTERFACE_FLAG, art::kAccInterface) -ASM_DEFINE(MIRROR_CLASS_IS_INTERFACE_FLAG_BIT, - art::WhichPowerOf2(art::kAccInterface)) + ASM_DEFINE(MIRROR_CLASS_STATUS_SHIFT, art::SubtypeCheckBits::BitStructSizeOf()) -ASM_DEFINE(MIRROR_CLASS_STATUS_VISIBLY_INITIALIZED, - art::enum_cast<uint32_t>(art::ClassStatus::kVisiblyInitialized)) -ASM_DEFINE(MIRROR_CLASS_STATUS_VISIBLY_INITIALIZED_SHIFTED, - art::enum_cast<uint32_t>(art::ClassStatus::kVisiblyInitialized) << - art::SubtypeCheckBits::BitStructSizeOf()) +ASM_DEFINE(PRIMITIVE_TYPE_SIZE_SHIFT_SHIFT, art::mirror::Class::kPrimitiveTypeSizeShiftShift) + +ASM_DEFINE(MIRROR_CLASS_IS_INTERFACE_FLAG, art::kAccInterface) +ASM_DEFINE(MIRROR_CLASS_IS_INTERFACE_FLAG_BIT, art::WhichPowerOf2(art::kAccInterface)) ASM_DEFINE(MIRROR_CLASS_STATUS_INITIALIZED, art::enum_cast<uint32_t>(art::ClassStatus::kInitialized)) ASM_DEFINE(MIRROR_CLASS_STATUS_INITIALIZED_SHIFTED, - art::enum_cast<uint32_t>(art::ClassStatus::kInitialized) << - art::SubtypeCheckBits::BitStructSizeOf()) + art::enum_cast<uint32_t>(art::ClassStatus::kInitialized) + << art::SubtypeCheckBits::BitStructSizeOf()) ASM_DEFINE(MIRROR_CLASS_STATUS_INITIALIZING, art::enum_cast<uint32_t>(art::ClassStatus::kInitializing)) ASM_DEFINE(MIRROR_CLASS_STATUS_INITIALIZING_SHIFTED, - art::enum_cast<uint32_t>(art::ClassStatus::kInitializing) << - art::SubtypeCheckBits::BitStructSizeOf()) -ASM_DEFINE(MIRROR_CLASS_CLINIT_THREAD_ID_OFFSET, - art::mirror::Class::ClinitThreadIdOffset().Int32Value()) + art::enum_cast<uint32_t>(art::ClassStatus::kInitializing) + << art::SubtypeCheckBits::BitStructSizeOf()) +ASM_DEFINE(MIRROR_CLASS_STATUS_VISIBLY_INITIALIZED, + art::enum_cast<uint32_t>(art::ClassStatus::kVisiblyInitialized)) +ASM_DEFINE(MIRROR_CLASS_STATUS_VISIBLY_INITIALIZED_SHIFTED, + art::enum_cast<uint32_t>(art::ClassStatus::kVisiblyInitialized) + << art::SubtypeCheckBits::BitStructSizeOf()) |