xref: /aosp_15_r20/art/runtime/arch/arm/jni_entrypoints_arm.S (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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