summaryrefslogtreecommitdiffstats
path: root/compiler/jni/quick/arm64/calling_convention_arm64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/jni/quick/arm64/calling_convention_arm64.cc')
-rw-r--r--compiler/jni/quick/arm64/calling_convention_arm64.cc38
1 files changed, 19 insertions, 19 deletions
diff --git a/compiler/jni/quick/arm64/calling_convention_arm64.cc b/compiler/jni/quick/arm64/calling_convention_arm64.cc
index 05eb80a51a..a6caff1c70 100644
--- a/compiler/jni/quick/arm64/calling_convention_arm64.cc
+++ b/compiler/jni/quick/arm64/calling_convention_arm64.cc
@@ -157,27 +157,25 @@ const ManagedRegisterEntrySpills& Arm64ManagedRuntimeCallingConvention::EntrySpi
Arm64JniCallingConvention::Arm64JniCallingConvention(bool is_static, bool is_synchronized,
const char* shorty)
: JniCallingConvention(is_static, is_synchronized, shorty, kFramePointerSize) {
- // TODO: Ugly hard code...
- // Should generate these according to the spill mask automatically.
- callee_save_regs_.push_back(Arm64ManagedRegister::FromXRegister(X20));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromXRegister(X21));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromXRegister(X22));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromXRegister(X23));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromXRegister(X24));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromXRegister(X25));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromXRegister(X26));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromXRegister(X27));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromXRegister(X28));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromXRegister(X29));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromXRegister(X30));
+ uint32_t core_spill_mask = CoreSpillMask();
+ for (int x_reg = 0; x_reg < kNumberOfXRegisters; ++x_reg) {
+ if (((1 << x_reg) & core_spill_mask) != 0) {
+ callee_save_regs_.push_back(
+ Arm64ManagedRegister::FromXRegister(static_cast<XRegister>(x_reg)));
+ }
+ }
- for (size_t i = 0; i < arraysize(kDCalleeSaveRegisters); ++i) {
- callee_save_regs_.push_back(Arm64ManagedRegister::FromDRegister(kDCalleeSaveRegisters[i]));
+ uint32_t fp_spill_mask = FpSpillMask();
+ for (int d_reg = 0; d_reg < kNumberOfDRegisters; ++d_reg) {
+ if (((1 << d_reg) & fp_spill_mask) != 0) {
+ callee_save_regs_.push_back(
+ Arm64ManagedRegister::FromDRegister(static_cast<DRegister>(d_reg)));
+ }
}
}
uint32_t Arm64JniCallingConvention::CoreSpillMask() const {
- // Compute spill mask to agree with callee saves initialized in the constructor
+ // Compute spill mask to agree with callee saves initialized in the constructor.
// Note: The native jni function may call to some VM runtime functions which may suspend
// or trigger GC. And the jni method frame will become top quick frame in those cases.
// So we need to satisfy GC to save LR and callee-save registers which is similar to
@@ -186,12 +184,14 @@ uint32_t Arm64JniCallingConvention::CoreSpillMask() const {
// Jni method is the method that compiled by jni compiler.
// Call chain: managed code(java) --> jni method --> jni function.
// Thread register(X18, scratched by aapcs64) is not saved on stack, it is saved in ETR(X21).
- // Suspend register(x19) is preserved by aapcs64 and it is not used in Jni method.
- return 1 << X20 | 1 << X21 | 1 << X22 | 1 << X23 | 1 << X24 | 1 << X25 |
- 1 << X26 | 1 << X27 | 1 << X28 | 1 << X29 | 1 << LR;
+ return 1 << X19 | 1 << X20 | 1 << X21 | 1 << X22 | 1 << X23 | 1 << X24 |
+ 1 << X25 | 1 << X26 | 1 << X27 | 1 << X28 | 1 << X29 | 1 << LR;
}
uint32_t Arm64JniCallingConvention::FpSpillMask() const {
+ // Considering the case, java_method_1 --> jni method --> jni function --> java_method_2, we may
+ // break on java_method_2 and we still need to find out the values of DEX registers in
+ // java_method_1. So all callee-saves(in managed code) need to be saved.
uint32_t result = 0;
for (size_t i = 0; i < arraysize(kDCalleeSaveRegisters); ++i) {
result |= (1 << kDCalleeSaveRegisters[i]);