summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jaeheon Yi <jaeheon@google.com> 2023-09-12 20:32:05 -0700
committer Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2023-09-19 21:38:53 +0000
commit9b4fba296b04ca02300b6c76c8367fbec0308ac2 (patch)
tree7f2b147b733bc4639ab4a68bce565364a6456912
parent3937b95e1ecfb890fe51caf19ca565c98b602c07 (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.S72
-rw-r--r--runtime/arch/riscv64/asm_support_riscv64.h4
-rw-r--r--runtime/interpreter/mterp/riscv64/control_flow.S8
-rw-r--r--runtime/interpreter/mterp/riscv64/main.S33
-rw-r--r--runtime/nterp_helpers.cc3
-rw-r--r--tools/cpp-define-generator/mirror_class.def58
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())