1*795d594fSAndroid Build Coastguard Worker/* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker#include "asm_support_arm.S" 18*795d594fSAndroid Build Coastguard Worker 19*795d594fSAndroid Build Coastguard Worker#define MANAGED_ARGS_R4_LR_SAVE_SIZE /*s0-s15*/ 16 * 4 + /*r0-r3*/ 4 * 4 + /*r4*/ 4 + /*lr*/ 4 20*795d594fSAndroid Build Coastguard Worker 21*795d594fSAndroid Build Coastguard Worker// Note: R4 is saved for stack alignment. 22*795d594fSAndroid Build Coastguard Worker.macro SAVE_MANAGED_ARGS_R4_LR_INCREASE_FRAME 23*795d594fSAndroid Build Coastguard Worker // Save GPR args r0-r3 and return address. Also save r4 for stack alignment. 24*795d594fSAndroid Build Coastguard Worker push {r0-r4, lr} 25*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 24 26*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 20 27*795d594fSAndroid Build Coastguard Worker // Save FPR args. 28*795d594fSAndroid Build Coastguard Worker vpush {s0-s15} 29*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 64 30*795d594fSAndroid Build Coastguard Worker.endm 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Worker.macro RESTORE_MANAGED_ARGS_R4_AND_RETURN restore_cfa 33*795d594fSAndroid Build Coastguard Worker // Restore FPR args. 34*795d594fSAndroid Build Coastguard Worker vpop {s0-s15} 35*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -64 36*795d594fSAndroid Build Coastguard Worker // Restore GPR args and r4 and return. 37*795d594fSAndroid Build Coastguard Worker pop {r0-r4, pc} 38*795d594fSAndroid Build Coastguard Worker .if \restore_cfa 39*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 64 40*795d594fSAndroid Build Coastguard Worker .endif 41*795d594fSAndroid Build Coastguard Worker.endm 42*795d594fSAndroid Build Coastguard Worker 43*795d594fSAndroid Build Coastguard Worker.macro JNI_SAVE_MANAGED_ARGS_TRAMPOLINE name, cxx_name, arg1 = "none" 44*795d594fSAndroid Build Coastguard Worker .extern \cxx_name 45*795d594fSAndroid Build Coastguard WorkerENTRY \name 46*795d594fSAndroid Build Coastguard Worker // Note: Managed callee-save registers have been saved by the JNI stub. 47*795d594fSAndroid Build Coastguard Worker // Save managed args, r4 (for stack alignment) and LR. 48*795d594fSAndroid Build Coastguard Worker SAVE_MANAGED_ARGS_R4_LR_INCREASE_FRAME 49*795d594fSAndroid Build Coastguard Worker // Call `cxx_name()`. 50*795d594fSAndroid Build Coastguard Worker .ifnc \arg1, none 51*795d594fSAndroid Build Coastguard Worker mov r0, \arg1 @ Pass arg1. 52*795d594fSAndroid Build Coastguard Worker .endif 53*795d594fSAndroid Build Coastguard Worker bl \cxx_name @ Call cxx_name(...). 54*795d594fSAndroid Build Coastguard Worker // Restore args and R4 and return. 55*795d594fSAndroid Build Coastguard Worker RESTORE_MANAGED_ARGS_R4_AND_RETURN /*restore_cfa*/ 0 56*795d594fSAndroid Build Coastguard WorkerEND \name 57*795d594fSAndroid Build Coastguard Worker.endm 58*795d594fSAndroid Build Coastguard Worker 59*795d594fSAndroid Build Coastguard Worker.macro JNI_SAVE_RETURN_VALUE_TRAMPOLINE name, cxx_name, arg1, arg2 = "none", label = "none" 60*795d594fSAndroid Build Coastguard Worker .extern \cxx_name 61*795d594fSAndroid Build Coastguard WorkerENTRY \name 62*795d594fSAndroid Build Coastguard Worker .ifnc \label, none 63*795d594fSAndroid Build Coastguard Worker \label: 64*795d594fSAndroid Build Coastguard Worker .endif 65*795d594fSAndroid Build Coastguard Worker // Save GPR return registers and return address. Also save r4 for stack alignment. 66*795d594fSAndroid Build Coastguard Worker push {r0-r1, r4, lr} 67*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 16 68*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 12 69*795d594fSAndroid Build Coastguard Worker // Save FPR return registers. 70*795d594fSAndroid Build Coastguard Worker vpush {s0-s1} 71*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 8 72*795d594fSAndroid Build Coastguard Worker // Call `cxx_name()`. 73*795d594fSAndroid Build Coastguard Worker mov r0, \arg1 @ Pass arg1. 74*795d594fSAndroid Build Coastguard Worker .ifnc \arg2, none 75*795d594fSAndroid Build Coastguard Worker mov r1, \arg2 @ Pass arg2. 76*795d594fSAndroid Build Coastguard Worker .endif 77*795d594fSAndroid Build Coastguard Worker bl \cxx_name @ Call cxx_name(...). 78*795d594fSAndroid Build Coastguard Worker // Restore FPR return registers. 79*795d594fSAndroid Build Coastguard Worker vpop {s0-s1} 80*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -8 81*795d594fSAndroid Build Coastguard Worker // Restore GPR return registers and r4 and return. 82*795d594fSAndroid Build Coastguard Worker pop {r0-r1, r4, pc} 83*795d594fSAndroid Build Coastguard WorkerEND \name 84*795d594fSAndroid Build Coastguard Worker.endm 85*795d594fSAndroid Build Coastguard Worker 86*795d594fSAndroid Build Coastguard Worker /* 87*795d594fSAndroid Build Coastguard Worker * Jni dlsym lookup stub for @CriticalNative. 88*795d594fSAndroid Build Coastguard Worker */ 89*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_dlsym_lookup_critical_stub 90*795d594fSAndroid Build Coastguard Worker // The hidden arg holding the tagged method (bit 0 set means GenericJNI) is r4. 91*795d594fSAndroid Build Coastguard Worker // For Generic JNI we already have a managed frame, so we reuse the art_jni_dlsym_lookup_stub. 92*795d594fSAndroid Build Coastguard Worker tst r4, #1 93*795d594fSAndroid Build Coastguard Worker bne art_jni_dlsym_lookup_stub 94*795d594fSAndroid Build Coastguard Worker 95*795d594fSAndroid Build Coastguard Worker // Reserve space for a SaveRefsAndArgs managed frame, either for the actual runtime 96*795d594fSAndroid Build Coastguard Worker // method or for a GenericJNI frame which is similar but has a native method and a tag. 97*795d594fSAndroid Build Coastguard Worker // Do this eagerly, so that we can use these registers as temps without the need to 98*795d594fSAndroid Build Coastguard Worker // save and restore them multiple times. 99*795d594fSAndroid Build Coastguard Worker INCREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS 100*795d594fSAndroid Build Coastguard Worker 101*795d594fSAndroid Build Coastguard Worker // Save args, the hidden arg and caller PC. No CFI needed for args and the hidden arg. 102*795d594fSAndroid Build Coastguard Worker push {r0, r1, r2, r3, r4, lr} 103*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 24 104*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 20 105*795d594fSAndroid Build Coastguard Worker 106*795d594fSAndroid Build Coastguard Worker // Call artCriticalNativeFrameSize(method, caller_pc) 107*795d594fSAndroid Build Coastguard Worker mov r0, r4 // r0 := method (from hidden arg) 108*795d594fSAndroid Build Coastguard Worker mov r1, lr // r1 := caller_pc 109*795d594fSAndroid Build Coastguard Worker bl artCriticalNativeFrameSize 110*795d594fSAndroid Build Coastguard Worker 111*795d594fSAndroid Build Coastguard Worker // Prepare the return address for managed stack walk of the SaveRefsAndArgs frame. 112*795d594fSAndroid Build Coastguard Worker // If we're coming from JNI stub with tail call, it is LR. If we're coming from 113*795d594fSAndroid Build Coastguard Worker // JNI stub that saved the return address, it will be the last value we copy below. 114*795d594fSAndroid Build Coastguard Worker // If we're coming directly from compiled code, it is LR, set further down. 115*795d594fSAndroid Build Coastguard Worker ldr lr, [sp, #20] 116*795d594fSAndroid Build Coastguard Worker 117*795d594fSAndroid Build Coastguard Worker // Move the stack args if any. 118*795d594fSAndroid Build Coastguard Worker add r4, sp, #24 119*795d594fSAndroid Build Coastguard Worker cbz r0, .Lcritical_skip_copy_args 120*795d594fSAndroid Build Coastguard Worker.Lcritical_copy_args_loop: 121*795d594fSAndroid Build Coastguard Worker ldrd ip, lr, [r4, #FRAME_SIZE_SAVE_REFS_AND_ARGS] 122*795d594fSAndroid Build Coastguard Worker subs r0, r0, #8 123*795d594fSAndroid Build Coastguard Worker strd ip, lr, [r4], #8 124*795d594fSAndroid Build Coastguard Worker bne .Lcritical_copy_args_loop 125*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_copy_args: 126*795d594fSAndroid Build Coastguard Worker // The managed frame address is now in R4. This is conveniently a callee-save in native ABI. 127*795d594fSAndroid Build Coastguard Worker 128*795d594fSAndroid Build Coastguard Worker // Restore args. 129*795d594fSAndroid Build Coastguard Worker pop {r0, r1, r2, r3} 130*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -16 131*795d594fSAndroid Build Coastguard Worker 132*795d594fSAndroid Build Coastguard Worker // Spill registers for the SaveRefsAndArgs frame above the stack args. 133*795d594fSAndroid Build Coastguard Worker // Note that the runtime shall not examine the args here, otherwise we would have to 134*795d594fSAndroid Build Coastguard Worker // move them in registers and stack to account for the difference between managed and 135*795d594fSAndroid Build Coastguard Worker // native ABIs. 136*795d594fSAndroid Build Coastguard Worker add ip, r4, #FRAME_SIZE_SAVE_REFS_AND_ARGS - 40 137*795d594fSAndroid Build Coastguard Worker stmia ip, {r1-r3, r5-r8, r10-r11, lr} // LR: Save return address for tail call from JNI stub. 138*795d594fSAndroid Build Coastguard Worker // (If there were any stack args, we're storing the value that's already there. 139*795d594fSAndroid Build Coastguard Worker // For direct calls from compiled managed code, we shall overwrite this below.) 140*795d594fSAndroid Build Coastguard Worker // Skip args r1-r3. 141*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 5, 4, FRAME_SIZE_SAVE_REFS_AND_ARGS - 28 142*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 6, 4, FRAME_SIZE_SAVE_REFS_AND_ARGS - 24 143*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 7, 4, FRAME_SIZE_SAVE_REFS_AND_ARGS - 20 144*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 8, 4, FRAME_SIZE_SAVE_REFS_AND_ARGS - 16 145*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 10, 4, FRAME_SIZE_SAVE_REFS_AND_ARGS - 12 146*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 11, 4, FRAME_SIZE_SAVE_REFS_AND_ARGS - 8 147*795d594fSAndroid Build Coastguard Worker // The saved return PC for managed stack walk is not necessarily our LR. 148*795d594fSAndroid Build Coastguard Worker // Skip managed FP args as these are native ABI caller-saves and not args. 149*795d594fSAndroid Build Coastguard Worker 150*795d594fSAndroid Build Coastguard Worker // Restore the hidden arg to r1 and caller PC. 151*795d594fSAndroid Build Coastguard Worker pop {r1, lr} 152*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -8 153*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 154*795d594fSAndroid Build Coastguard Worker 155*795d594fSAndroid Build Coastguard Worker // Save our return PC in the padding. 156*795d594fSAndroid Build Coastguard Worker str lr, [r4, #__SIZEOF_POINTER__] 157*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 14, 4, __SIZEOF_POINTER__ 158*795d594fSAndroid Build Coastguard Worker 159*795d594fSAndroid Build Coastguard Worker ldr ip, [r1, #ART_METHOD_ACCESS_FLAGS_OFFSET] // Load access flags. 160*795d594fSAndroid Build Coastguard Worker add r2, r4, #1 // Prepare managed SP tagged for a GenericJNI frame. 161*795d594fSAndroid Build Coastguard Worker tst ip, #ACCESS_FLAGS_METHOD_IS_NATIVE 162*795d594fSAndroid Build Coastguard Worker bne .Lcritical_skip_prepare_runtime_method 163*795d594fSAndroid Build Coastguard Worker 164*795d594fSAndroid Build Coastguard Worker // When coming from a compiled method, the return PC for managed stack walk is LR. 165*795d594fSAndroid Build Coastguard Worker // (When coming from a compiled stub, the correct return PC is already stored above.) 166*795d594fSAndroid Build Coastguard Worker str lr, [r4, #(FRAME_SIZE_SAVE_REFS_AND_ARGS - __SIZEOF_POINTER__)] 167*795d594fSAndroid Build Coastguard Worker 168*795d594fSAndroid Build Coastguard Worker // Replace the target method with the SaveRefsAndArgs runtime method. 169*795d594fSAndroid Build Coastguard Worker LOAD_RUNTIME_INSTANCE r1 170*795d594fSAndroid Build Coastguard Worker ldr r1, [r1, #RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET] 171*795d594fSAndroid Build Coastguard Worker 172*795d594fSAndroid Build Coastguard Worker mov r2, r4 // Prepare untagged managed SP for the runtime method. 173*795d594fSAndroid Build Coastguard Worker 174*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_prepare_runtime_method: 175*795d594fSAndroid Build Coastguard Worker // Store the method on the bottom of the managed frame. 176*795d594fSAndroid Build Coastguard Worker str r1, [r4] 177*795d594fSAndroid Build Coastguard Worker 178*795d594fSAndroid Build Coastguard Worker // Place (maybe tagged) managed SP in Thread::Current()->top_quick_frame. 179*795d594fSAndroid Build Coastguard Worker str r2, [rSELF, #THREAD_TOP_QUICK_FRAME_OFFSET] 180*795d594fSAndroid Build Coastguard Worker 181*795d594fSAndroid Build Coastguard Worker // Preserve the native arg register r0 in callee-save register r10 which was saved above. 182*795d594fSAndroid Build Coastguard Worker mov r10, r0 183*795d594fSAndroid Build Coastguard Worker 184*795d594fSAndroid Build Coastguard Worker // Call artFindNativeMethodRunnable() 185*795d594fSAndroid Build Coastguard Worker mov r0, rSELF // pass Thread::Current() 186*795d594fSAndroid Build Coastguard Worker bl artFindNativeMethodRunnable 187*795d594fSAndroid Build Coastguard Worker 188*795d594fSAndroid Build Coastguard Worker // Store result in scratch reg. 189*795d594fSAndroid Build Coastguard Worker mov ip, r0 190*795d594fSAndroid Build Coastguard Worker 191*795d594fSAndroid Build Coastguard Worker // Restore the native arg register r0. 192*795d594fSAndroid Build Coastguard Worker mov r0, r10 193*795d594fSAndroid Build Coastguard Worker 194*795d594fSAndroid Build Coastguard Worker // Restore the frame. We shall not need the method anymore. 195*795d594fSAndroid Build Coastguard Worker add r1, r4, #FRAME_SIZE_SAVE_REFS_AND_ARGS - 40 196*795d594fSAndroid Build Coastguard Worker ldmia r1, {r1-r3, r5-r8, r10-r11} 197*795d594fSAndroid Build Coastguard Worker .cfi_restore r5 198*795d594fSAndroid Build Coastguard Worker .cfi_restore r6 199*795d594fSAndroid Build Coastguard Worker .cfi_restore r7 200*795d594fSAndroid Build Coastguard Worker .cfi_restore r8 201*795d594fSAndroid Build Coastguard Worker .cfi_restore r10 202*795d594fSAndroid Build Coastguard Worker .cfi_restore r11 203*795d594fSAndroid Build Coastguard Worker 204*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 205*795d594fSAndroid Build Coastguard Worker 206*795d594fSAndroid Build Coastguard Worker // Check for exception before moving args back to keep the return PC for managed stack walk. 207*795d594fSAndroid Build Coastguard Worker cmp ip, #0 208*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 209*795d594fSAndroid Build Coastguard Worker beq .Lcritical_deliver_exception 210*795d594fSAndroid Build Coastguard Worker 211*795d594fSAndroid Build Coastguard Worker // Restore our return PC. 212*795d594fSAndroid Build Coastguard Worker ldr lr, [r4, #__SIZEOF_POINTER__] 213*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 214*795d594fSAndroid Build Coastguard Worker 215*795d594fSAndroid Build Coastguard Worker // Move stack args to their original place. 216*795d594fSAndroid Build Coastguard Worker cmp sp, r4 217*795d594fSAndroid Build Coastguard Worker beq .Lcritical_skip_copy_args_back 218*795d594fSAndroid Build Coastguard Worker push {r0, r1, r2, r3} 219*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 16 220*795d594fSAndroid Build Coastguard Worker add r0, sp, #16 221*795d594fSAndroid Build Coastguard Worker sub r0, r4, r0 222*795d594fSAndroid Build Coastguard Worker.Lcritical_copy_args_loop_back: 223*795d594fSAndroid Build Coastguard Worker ldrd r2, r3, [r4, #-8]! 224*795d594fSAndroid Build Coastguard Worker subs r0, r0, #8 225*795d594fSAndroid Build Coastguard Worker strd r2, r3, [r4, #FRAME_SIZE_SAVE_REFS_AND_ARGS] 226*795d594fSAndroid Build Coastguard Worker bne .Lcritical_copy_args_loop_back 227*795d594fSAndroid Build Coastguard Worker pop {r0, r1, r2, r3} 228*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -16 229*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_copy_args_back: 230*795d594fSAndroid Build Coastguard Worker 231*795d594fSAndroid Build Coastguard Worker // Remove the frame reservation. 232*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS 233*795d594fSAndroid Build Coastguard Worker 234*795d594fSAndroid Build Coastguard Worker // Do the tail call. 235*795d594fSAndroid Build Coastguard Worker bx ip 236*795d594fSAndroid Build Coastguard Worker 237*795d594fSAndroid Build Coastguard Worker.Lcritical_deliver_exception: 238*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_AND_ARGS 239*795d594fSAndroid Build Coastguard Worker // The exception delivery checks that rSELF was saved but the SaveRefsAndArgs 240*795d594fSAndroid Build Coastguard Worker // frame does not save it, so we cannot use the existing SaveRefsAndArgs frame. 241*795d594fSAndroid Build Coastguard Worker // That's why we checked for exception after restoring registers from it. 242*795d594fSAndroid Build Coastguard Worker // We need to build a SaveAllCalleeSaves frame instead. Args are irrelevant at this 243*795d594fSAndroid Build Coastguard Worker // point but keep the area allocated for stack args to keep CFA definition simple. 244*795d594fSAndroid Build Coastguard Worker#if FRAME_SIZE_SAVE_REFS_AND_ARGS != FRAME_SIZE_SAVE_ALL_CALLEE_SAVES 245*795d594fSAndroid Build Coastguard Worker# error "Expected FRAME_SIZE_SAVE_REFS_AND_ARGS == FRAME_SIZE_SAVE_ALL_CALLEE_SAVES" 246*795d594fSAndroid Build Coastguard Worker // Otherwise we would need to adjust SP and R4 and move our return PC which is at [R4, #4]. 247*795d594fSAndroid Build Coastguard Worker // (Luckily, both SaveRefsAndArgs and SaveAllCalleeSaves frames have padding there.) 248*795d594fSAndroid Build Coastguard Worker#endif 249*795d594fSAndroid Build Coastguard Worker 250*795d594fSAndroid Build Coastguard Worker // Spill registers for the SaveAllCalleeSaves frame above the stack args area. 251*795d594fSAndroid Build Coastguard Worker add ip, r4, #FRAME_SIZE_SAVE_ALL_CALLEE_SAVES - 32 252*795d594fSAndroid Build Coastguard Worker stmia ip, {r5-r11} // Keep the caller PC for managed stack walk. 253*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 5, 4, FRAME_SIZE_SAVE_ALL_CALLEE_SAVES - 32 254*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 6, 4, FRAME_SIZE_SAVE_ALL_CALLEE_SAVES - 28 255*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 7, 4, FRAME_SIZE_SAVE_ALL_CALLEE_SAVES - 24 256*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 8, 4, FRAME_SIZE_SAVE_ALL_CALLEE_SAVES - 20 257*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 9, 4, FRAME_SIZE_SAVE_ALL_CALLEE_SAVES - 16 258*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 10, 4, FRAME_SIZE_SAVE_ALL_CALLEE_SAVES - 12 259*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 11, 4, FRAME_SIZE_SAVE_ALL_CALLEE_SAVES - 8 260*795d594fSAndroid Build Coastguard Worker // Skip R4, it is callee-save in managed ABI. 261*795d594fSAndroid Build Coastguard Worker add ip, r4, #12 262*795d594fSAndroid Build Coastguard Worker vstmia ip, {s16-s31} 263*795d594fSAndroid Build Coastguard Worker 264*795d594fSAndroid Build Coastguard Worker // Store ArtMethod* Runtime::callee_save_methods_[kSaveAllCalleeSaves] to the managed frame. 265*795d594fSAndroid Build Coastguard Worker LOAD_RUNTIME_INSTANCE ip 266*795d594fSAndroid Build Coastguard Worker ldr ip, [ip, #RUNTIME_SAVE_ALL_CALLEE_SAVES_METHOD_OFFSET] 267*795d594fSAndroid Build Coastguard Worker str ip, [r4] 268*795d594fSAndroid Build Coastguard Worker 269*795d594fSAndroid Build Coastguard Worker // Place the managed frame SP in Thread::Current()->top_quick_frame. 270*795d594fSAndroid Build Coastguard Worker str r4, [rSELF, #THREAD_TOP_QUICK_FRAME_OFFSET] 271*795d594fSAndroid Build Coastguard Worker 272*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION_FRAME_READY 273*795d594fSAndroid Build Coastguard WorkerEND art_jni_dlsym_lookup_critical_stub 274*795d594fSAndroid Build Coastguard Worker 275*795d594fSAndroid Build Coastguard Worker /* 276*795d594fSAndroid Build Coastguard Worker * Read barrier for the method's declaring class needed by JNI stub for static methods. 277*795d594fSAndroid Build Coastguard Worker * (We're using a pointer to the declaring class in `ArtMethod` as `jclass`.) 278*795d594fSAndroid Build Coastguard Worker */ 279*795d594fSAndroid Build Coastguard Worker// The method argument is already in r0 for call to `artJniReadBarrier(ArtMethod*)`. 280*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_read_barrier, artJniReadBarrier 281*795d594fSAndroid Build Coastguard Worker 282*795d594fSAndroid Build Coastguard Worker /* 283*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMethodStart()` that preserves all managed arguments. 284*795d594fSAndroid Build Coastguard Worker */ 285*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_method_start, artJniMethodStart, rSELF 286*795d594fSAndroid Build Coastguard Worker 287*795d594fSAndroid Build Coastguard Worker /* 288*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMethodEntryHook()` that preserves all managed arguments. 289*795d594fSAndroid Build Coastguard Worker */ 290*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_method_entry_hook, artJniMethodEntryHook, rSELF 291*795d594fSAndroid Build Coastguard Worker 292*795d594fSAndroid Build Coastguard Worker /* 293*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMonitoredMethodStart()` that preserves all managed arguments. 294*795d594fSAndroid Build Coastguard Worker */ 295*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_monitored_method_start, artJniMonitoredMethodStart, rSELF 296*795d594fSAndroid Build Coastguard Worker 297*795d594fSAndroid Build Coastguard Worker /* 298*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMethodEnd()` that preserves all return registers. 299*795d594fSAndroid Build Coastguard Worker */ 300*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_method_end, artJniMethodEnd, rSELF 301*795d594fSAndroid Build Coastguard Worker 302*795d594fSAndroid Build Coastguard Worker /* 303*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMonitoredMethodEnd()` that preserves all return registers. 304*795d594fSAndroid Build Coastguard Worker */ 305*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_monitored_method_end, artJniMonitoredMethodEnd, rSELF 306*795d594fSAndroid Build Coastguard Worker 307*795d594fSAndroid Build Coastguard Worker /* 308*795d594fSAndroid Build Coastguard Worker * Entry from JNI stub that tries to lock the object in a fast path and 309*795d594fSAndroid Build Coastguard Worker * calls `artLockObjectFromCode()` (the same as for managed code) for the 310*795d594fSAndroid Build Coastguard Worker * difficult cases, may block for GC. 311*795d594fSAndroid Build Coastguard Worker * Custom calling convention: 312*795d594fSAndroid Build Coastguard Worker * r4 holds the non-null object to lock. 313*795d594fSAndroid Build Coastguard Worker * Callee-save registers have been saved and can be used as temporaries. 314*795d594fSAndroid Build Coastguard Worker * All argument registers need to be preserved. 315*795d594fSAndroid Build Coastguard Worker */ 316*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_lock_object 317*795d594fSAndroid Build Coastguard Worker // Note: the slow path is actually the art_jni_lock_object_no_inline (tail call). 318*795d594fSAndroid Build Coastguard Worker LOCK_OBJECT_FAST_PATH r4, r5, r6, r7, .Llock_object_jni_slow, /*can_be_null*/ 0 319*795d594fSAndroid Build Coastguard WorkerEND art_jni_lock_object 320*795d594fSAndroid Build Coastguard Worker 321*795d594fSAndroid Build Coastguard Worker /* 322*795d594fSAndroid Build Coastguard Worker * Entry from JNI stub that calls `artLockObjectFromCode()` 323*795d594fSAndroid Build Coastguard Worker * (the same as for managed code), may block for GC. 324*795d594fSAndroid Build Coastguard Worker * Custom calling convention: 325*795d594fSAndroid Build Coastguard Worker * r4 holds the non-null object to lock. 326*795d594fSAndroid Build Coastguard Worker * Callee-save registers have been saved and can be used as temporaries. 327*795d594fSAndroid Build Coastguard Worker * All argument registers need to be preserved. 328*795d594fSAndroid Build Coastguard Worker */ 329*795d594fSAndroid Build Coastguard Worker .extern artLockObjectFromCode 330*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_lock_object_no_inline 331*795d594fSAndroid Build Coastguard Worker // This is also the slow path for art_jni_lock_object. 332*795d594fSAndroid Build Coastguard Worker // Note that we need a local label as the assembler emits bad instructions 333*795d594fSAndroid Build Coastguard Worker // for CBZ/CBNZ if we try to jump to `art_jni_lock_object_no_inline`. 334*795d594fSAndroid Build Coastguard Worker.Llock_object_jni_slow: 335*795d594fSAndroid Build Coastguard Worker // Save managed args, r4 (for stack alignment) and LR. 336*795d594fSAndroid Build Coastguard Worker SAVE_MANAGED_ARGS_R4_LR_INCREASE_FRAME 337*795d594fSAndroid Build Coastguard Worker // Call `artLockObjectFromCode()` 338*795d594fSAndroid Build Coastguard Worker mov r0, r4 @ Pass the object to lock. 339*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ Pass Thread::Current(). 340*795d594fSAndroid Build Coastguard Worker bl artLockObjectFromCode @ (Object* obj, Thread*) 341*795d594fSAndroid Build Coastguard Worker // Check result. 342*795d594fSAndroid Build Coastguard Worker cbnz r0, 1f 343*795d594fSAndroid Build Coastguard Worker // Restore args and r4 and return. 344*795d594fSAndroid Build Coastguard Worker RESTORE_MANAGED_ARGS_R4_AND_RETURN /*restore_cfa*/ 1 345*795d594fSAndroid Build Coastguard Worker1: 346*795d594fSAndroid Build Coastguard Worker // All args are irrelevant when throwing an exception and R4 is preserved 347*795d594fSAndroid Build Coastguard Worker // by the `artLockObjectFromCode()` call. Load LR and drop saved args and R4. 348*795d594fSAndroid Build Coastguard Worker ldr lr, [sp, #(MANAGED_ARGS_R4_LR_SAVE_SIZE - 4)] 349*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 350*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME MANAGED_ARGS_R4_LR_SAVE_SIZE 351*795d594fSAndroid Build Coastguard Worker // Make a call to `artDeliverPendingExceptionFromCode()`. 352*795d594fSAndroid Build Coastguard Worker // Rely on the JNI transition frame constructed in the JNI stub. 353*795d594fSAndroid Build Coastguard Worker mov r0, rSELF @ Pass Thread::Current(). 354*795d594fSAndroid Build Coastguard Worker bl artDeliverPendingExceptionFromCode @ (Thread*) 355*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 356*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 357*795d594fSAndroid Build Coastguard WorkerEND art_jni_lock_object_no_inline 358*795d594fSAndroid Build Coastguard Worker 359*795d594fSAndroid Build Coastguard Worker /* 360*795d594fSAndroid Build Coastguard Worker * Entry from JNI stub that tries to unlock the object in a fast path and calls 361*795d594fSAndroid Build Coastguard Worker * `artJniUnlockObject()` for the difficult cases. Note that failure to unlock 362*795d594fSAndroid Build Coastguard Worker * is fatal, so we do not need to check for exceptions in the slow path. 363*795d594fSAndroid Build Coastguard Worker * Custom calling convention: 364*795d594fSAndroid Build Coastguard Worker * r4 holds the non-null object to unlock. 365*795d594fSAndroid Build Coastguard Worker * Callee-save registers have been saved and can be used as temporaries. 366*795d594fSAndroid Build Coastguard Worker * Return registers r0-r1 and s0-s1 need to be preserved. 367*795d594fSAndroid Build Coastguard Worker */ 368*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_unlock_object 369*795d594fSAndroid Build Coastguard Worker // Note: the slow path is actually the art_jni_unlock_object_no_inline (tail call). 370*795d594fSAndroid Build Coastguard Worker UNLOCK_OBJECT_FAST_PATH r4, r5, r6, r7, .Lunlock_object_jni_slow, /*can_be_null*/ 0 371*795d594fSAndroid Build Coastguard WorkerEND art_jni_unlock_object 372*795d594fSAndroid Build Coastguard Worker 373*795d594fSAndroid Build Coastguard Worker /* 374*795d594fSAndroid Build Coastguard Worker * Entry from JNI stub that calls `artJniUnlockObject()`. Note that failure to 375*795d594fSAndroid Build Coastguard Worker * unlock is fatal, so we do not need to check for exceptions. 376*795d594fSAndroid Build Coastguard Worker * Custom calling convention: 377*795d594fSAndroid Build Coastguard Worker * r4 holds the non-null object to unlock. 378*795d594fSAndroid Build Coastguard Worker * Callee-save registers have been saved and can be used as temporaries. 379*795d594fSAndroid Build Coastguard Worker * Return registers r0-r1 and s0-s1 need to be preserved. 380*795d594fSAndroid Build Coastguard Worker */ 381*795d594fSAndroid Build Coastguard Worker // This is also the slow path for art_jni_unlock_object. 382*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_unlock_object_no_inline, artJniUnlockObject, r4, rSELF, \ 383*795d594fSAndroid Build Coastguard Worker /* Note that we need a local label as the assembler emits bad instructions */ \ 384*795d594fSAndroid Build Coastguard Worker /* for CBZ/CBNZ if we try to jump to `art_jni_unlock_object_no_inline`. */ \ 385*795d594fSAndroid Build Coastguard Worker .Lunlock_object_jni_slow 386