summaryrefslogtreecommitdiffstats
path: root/compiler/jni
diff options
context:
space:
mode:
authorZheng Xu <zheng.xu@arm.com>2014-07-25 11:49:42 +0800
committerAndreas Gampe <agampe@google.com>2014-07-29 00:38:14 -0700
commitb551fdcda9eb128c80de37c4fb978968bec6d4b3 (patch)
tree62942f412f2275e2e9188f71c370cd95ec91e17f /compiler/jni
parent2815f1242c6c3ea1fc2df7bb5e4bd1924f4e75f7 (diff)
downloadandroid_art-b551fdcda9eb128c80de37c4fb978968bec6d4b3.tar.gz
android_art-b551fdcda9eb128c80de37c4fb978968bec6d4b3.tar.bz2
android_art-b551fdcda9eb128c80de37c4fb978968bec6d4b3.zip
AArch64: Clean up CalleeSaveMethod frame and the use of temp registers.
CalleeSaveMethod frame size changes : SaveAll : 368 -> 176 RefOnly : 176 -> 96 RefsAndArgs : 304 -> 224 JNI register spill size changes : 160 -> 88 In the transition assembly, use registers following the rules: 1. x0-x7 as temp/argument registers. 2. IP0, IP1 as scratch registers. 3. After correct type of callee-save-frame has been setup, all registers are scratch-able(probably except xSELF and xSUSPEND). 4. When restore callee-save-frame, IP0 and IP1 should be untouched. 5. From C to managed code, we assume all callee save register in AAPCS will be restored by managed code except x19(SUSPEND). In quick compiler: 1. Use IP0, IP1 as scratch register. 2. Use IP1 as hidden argument register(IP0 will be scratched by trampoline.) Change-Id: I05ed9d418b01b9e87218a7608536f57e7a286e4c
Diffstat (limited to 'compiler/jni')
-rw-r--r--compiler/jni/quick/arm64/calling_convention_arm64.cc33
1 files changed, 16 insertions, 17 deletions
diff --git a/compiler/jni/quick/arm64/calling_convention_arm64.cc b/compiler/jni/quick/arm64/calling_convention_arm64.cc
index 0a00d7d8ac..b95dad261e 100644
--- a/compiler/jni/quick/arm64/calling_convention_arm64.cc
+++ b/compiler/jni/quick/arm64/calling_convention_arm64.cc
@@ -152,7 +152,8 @@ const ManagedRegisterEntrySpills& Arm64ManagedRuntimeCallingConvention::EntrySpi
Arm64JniCallingConvention::Arm64JniCallingConvention(bool is_static, bool is_synchronized,
const char* shorty)
: JniCallingConvention(is_static, is_synchronized, shorty, kFramePointerSize) {
- callee_save_regs_.push_back(Arm64ManagedRegister::FromCoreRegister(X19));
+ // TODO: Ugly hard code...
+ // Should generate these according to the spill mask automatically.
callee_save_regs_.push_back(Arm64ManagedRegister::FromCoreRegister(X20));
callee_save_regs_.push_back(Arm64ManagedRegister::FromCoreRegister(X21));
callee_save_regs_.push_back(Arm64ManagedRegister::FromCoreRegister(X22));
@@ -164,30 +165,28 @@ Arm64JniCallingConvention::Arm64JniCallingConvention(bool is_static, bool is_syn
callee_save_regs_.push_back(Arm64ManagedRegister::FromCoreRegister(X28));
callee_save_regs_.push_back(Arm64ManagedRegister::FromCoreRegister(X29));
callee_save_regs_.push_back(Arm64ManagedRegister::FromCoreRegister(X30));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromDRegister(D8));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromDRegister(D9));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromDRegister(D10));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromDRegister(D11));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromDRegister(D12));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromDRegister(D13));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromDRegister(D14));
- callee_save_regs_.push_back(Arm64ManagedRegister::FromDRegister(D15));
}
uint32_t Arm64JniCallingConvention::CoreSpillMask() const {
// Compute spill mask to agree with callee saves initialized in the constructor
- uint32_t result = 0;
- result = 1 << X19 | 1 << X20 | 1 << X21 | 1 << X22 | 1 << X23 | 1 << X24 |
- 1 << X25 | 1 << X26 | 1 << X27 | 1 << X28 | 1 << X29 | 1 << LR;
- return result;
+ // 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
+ // CalleeSaveMethod(RefOnly) frame.
+ // Jni function is the native function which the java code wants to call.
+ // 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;
}
uint32_t Arm64JniCallingConvention::FpSpillMask() const {
// Compute spill mask to agree with callee saves initialized in the constructor
- uint32_t result = 0;
- result = 1 << D8 | 1 << D9 | 1 << D10 | 1 << D11 | 1 << D12 | 1 << D13 |
- 1 << D14 | 1 << D15;
- return result;
+ // Note: All callee-save fp registers will be preserved by aapcs64. And they are not used
+ // in the jni method.
+ return 0;
}
ManagedRegister Arm64JniCallingConvention::ReturnScratchRegister() const {