xref: /aosp_15_r20/art/runtime/arch/arm64/jni_entrypoints_arm64.S (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker/*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2014 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_arm64.S"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker.macro JNI_SAVE_MANAGED_ARGS_TRAMPOLINE name, cxx_name, arg1 = "none"
20*795d594fSAndroid Build Coastguard Worker    .extern \cxx_name
21*795d594fSAndroid Build Coastguard WorkerENTRY \name
22*795d594fSAndroid Build Coastguard Worker    // Save args and LR.
23*795d594fSAndroid Build Coastguard Worker    SAVE_ALL_ARGS_INCREASE_FRAME /*padding*/ 8 + /*LR*/ 8
24*795d594fSAndroid Build Coastguard Worker    str    lr, [sp, #(ALL_ARGS_SIZE + /*padding*/ 8)]
25*795d594fSAndroid Build Coastguard Worker    .cfi_rel_offset lr, ALL_ARGS_SIZE + /*padding*/ 8
26*795d594fSAndroid Build Coastguard Worker    // Call `cxx_name()`.
27*795d594fSAndroid Build Coastguard Worker    .ifnc \arg1, none
28*795d594fSAndroid Build Coastguard Worker        mov x0, \arg1                          // Pass arg1.
29*795d594fSAndroid Build Coastguard Worker    .endif
30*795d594fSAndroid Build Coastguard Worker    bl     \cxx_name                           // Call cxx_name(...).
31*795d594fSAndroid Build Coastguard Worker    // Restore LR and args and return.
32*795d594fSAndroid Build Coastguard Worker    ldr    lr, [sp, #(ALL_ARGS_SIZE + /*padding*/ 8)]
33*795d594fSAndroid Build Coastguard Worker    .cfi_restore lr
34*795d594fSAndroid Build Coastguard Worker    RESTORE_ALL_ARGS_DECREASE_FRAME /*padding*/ 8 + /*LR*/ 8
35*795d594fSAndroid Build Coastguard Worker    ret
36*795d594fSAndroid Build Coastguard WorkerEND \name
37*795d594fSAndroid Build Coastguard Worker.endm
38*795d594fSAndroid Build Coastguard Worker
39*795d594fSAndroid Build Coastguard Worker.macro JNI_SAVE_RETURN_VALUE_TRAMPOLINE name, cxx_name, arg1, arg2 = "none"
40*795d594fSAndroid Build Coastguard Worker    .extern \cxx_name
41*795d594fSAndroid Build Coastguard WorkerENTRY \name
42*795d594fSAndroid Build Coastguard Worker    // Save return registers and return address.
43*795d594fSAndroid Build Coastguard Worker    stp    x0, lr, [sp, #-32]!
44*795d594fSAndroid Build Coastguard Worker    .cfi_adjust_cfa_offset 32
45*795d594fSAndroid Build Coastguard Worker    .cfi_rel_offset lr, 8
46*795d594fSAndroid Build Coastguard Worker    str    d0, [sp, #16]
47*795d594fSAndroid Build Coastguard Worker    // Call `cxx_name()`.
48*795d594fSAndroid Build Coastguard Worker    mov    x0, \arg1                           // Pass arg1.
49*795d594fSAndroid Build Coastguard Worker    .ifnc \arg2, none
50*795d594fSAndroid Build Coastguard Worker        mov x1, \arg2                          // Pass arg2.
51*795d594fSAndroid Build Coastguard Worker    .endif
52*795d594fSAndroid Build Coastguard Worker    bl     \cxx_name                           // Call cxx_name(...).
53*795d594fSAndroid Build Coastguard Worker    // Restore return registers and return.
54*795d594fSAndroid Build Coastguard Worker    ldr    d0, [sp, #16]
55*795d594fSAndroid Build Coastguard Worker    ldp    x0, lr, [sp], #32
56*795d594fSAndroid Build Coastguard Worker    .cfi_adjust_cfa_offset -32
57*795d594fSAndroid Build Coastguard Worker    .cfi_restore lr
58*795d594fSAndroid Build Coastguard Worker    ret
59*795d594fSAndroid Build Coastguard WorkerEND \name
60*795d594fSAndroid Build Coastguard Worker.endm
61*795d594fSAndroid Build Coastguard Worker
62*795d594fSAndroid Build Coastguard Worker    /*
63*795d594fSAndroid Build Coastguard Worker     * Jni dlsym lookup stub for @CriticalNative.
64*795d594fSAndroid Build Coastguard Worker     */
65*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_dlsym_lookup_critical_stub
66*795d594fSAndroid Build Coastguard Worker    // The hidden arg holding the tagged method (bit 0 set means GenericJNI) is x15.
67*795d594fSAndroid Build Coastguard Worker    // For Generic JNI we already have a managed frame, so we reuse the art_jni_dlsym_lookup_stub.
68*795d594fSAndroid Build Coastguard Worker    // Note: 'tbnz' doesn't always have enough range (+/-32KB) to reach art_jni_dlsym_lookup_stub
69*795d594fSAndroid Build Coastguard Worker    // so 'b' (+/-128MB) is used instead.
70*795d594fSAndroid Build Coastguard Worker    tbz  x15, #0, .Lcritical_not_generic_jni
71*795d594fSAndroid Build Coastguard Worker    b art_jni_dlsym_lookup_stub
72*795d594fSAndroid Build Coastguard Worker
73*795d594fSAndroid Build Coastguard Worker.Lcritical_not_generic_jni:
74*795d594fSAndroid Build Coastguard Worker    // Save args, the hidden arg and caller PC. No CFI needed for args and the hidden arg.
75*795d594fSAndroid Build Coastguard Worker    SAVE_ALL_ARGS_INCREASE_FRAME 2 * 8
76*795d594fSAndroid Build Coastguard Worker    stp   x15, lr, [sp, #ALL_ARGS_SIZE]
77*795d594fSAndroid Build Coastguard Worker    .cfi_rel_offset lr, ALL_ARGS_SIZE + 8
78*795d594fSAndroid Build Coastguard Worker
79*795d594fSAndroid Build Coastguard Worker    // Call artCriticalNativeFrameSize(method, caller_pc)
80*795d594fSAndroid Build Coastguard Worker    mov   x0, x15  // x0 := method (from hidden arg)
81*795d594fSAndroid Build Coastguard Worker    mov   x1, lr   // x1 := caller_pc
82*795d594fSAndroid Build Coastguard Worker    bl    artCriticalNativeFrameSize
83*795d594fSAndroid Build Coastguard Worker
84*795d594fSAndroid Build Coastguard Worker    // Move frame size to x14.
85*795d594fSAndroid Build Coastguard Worker    mov   x14, x0
86*795d594fSAndroid Build Coastguard Worker
87*795d594fSAndroid Build Coastguard Worker    // Restore args, the hidden arg and caller PC.
88*795d594fSAndroid Build Coastguard Worker    ldp   x15, lr, [sp, #128]
89*795d594fSAndroid Build Coastguard Worker    .cfi_restore lr
90*795d594fSAndroid Build Coastguard Worker    RESTORE_ALL_ARGS_DECREASE_FRAME 2 * 8
91*795d594fSAndroid Build Coastguard Worker
92*795d594fSAndroid Build Coastguard Worker    // Reserve space for a SaveRefsAndArgs managed frame, either for the actual runtime
93*795d594fSAndroid Build Coastguard Worker    // method or for a GenericJNI frame which is similar but has a native method and a tag.
94*795d594fSAndroid Build Coastguard Worker    INCREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS
95*795d594fSAndroid Build Coastguard Worker
96*795d594fSAndroid Build Coastguard Worker    // Calculate the base address of the managed frame.
97*795d594fSAndroid Build Coastguard Worker    add   x13, sp, x14
98*795d594fSAndroid Build Coastguard Worker
99*795d594fSAndroid Build Coastguard Worker    // Prepare the return address for managed stack walk of the SaveRefsAndArgs frame.
100*795d594fSAndroid Build Coastguard Worker    // If we're coming from JNI stub with tail call, it is LR. If we're coming from
101*795d594fSAndroid Build Coastguard Worker    // JNI stub that saved the return address, it will be the last value we copy below.
102*795d594fSAndroid Build Coastguard Worker    // If we're coming directly from compiled code, it is LR, set further down.
103*795d594fSAndroid Build Coastguard Worker    mov   xIP1, lr
104*795d594fSAndroid Build Coastguard Worker
105*795d594fSAndroid Build Coastguard Worker    // Move the stack args if any.
106*795d594fSAndroid Build Coastguard Worker    cbz   x14, .Lcritical_skip_copy_args
107*795d594fSAndroid Build Coastguard Worker    mov   x12, sp
108*795d594fSAndroid Build Coastguard Worker.Lcritical_copy_args_loop:
109*795d594fSAndroid Build Coastguard Worker    ldp   xIP0, xIP1, [x12, #FRAME_SIZE_SAVE_REFS_AND_ARGS]
110*795d594fSAndroid Build Coastguard Worker    subs  x14, x14, #16
111*795d594fSAndroid Build Coastguard Worker    stp   xIP0, xIP1, [x12], #16
112*795d594fSAndroid Build Coastguard Worker    bne   .Lcritical_copy_args_loop
113*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_copy_args:
114*795d594fSAndroid Build Coastguard Worker
115*795d594fSAndroid Build Coastguard Worker    // Spill registers for the SaveRefsAndArgs frame above the stack args.
116*795d594fSAndroid Build Coastguard Worker    // Note that the runtime shall not examine the args here, otherwise we would have to
117*795d594fSAndroid Build Coastguard Worker    // move them in registers and stack to account for the difference between managed and
118*795d594fSAndroid Build Coastguard Worker    // native ABIs. Do not update CFI while we hold the frame address in x13 and the values
119*795d594fSAndroid Build Coastguard Worker    // in registers are unchanged.
120*795d594fSAndroid Build Coastguard Worker    stp   d0, d1, [x13, #16]
121*795d594fSAndroid Build Coastguard Worker    stp   d2, d3, [x13, #32]
122*795d594fSAndroid Build Coastguard Worker    stp   d4, d5, [x13, #48]
123*795d594fSAndroid Build Coastguard Worker    stp   d6, d7, [x13, #64]
124*795d594fSAndroid Build Coastguard Worker    stp   x1, x2, [x13, #80]
125*795d594fSAndroid Build Coastguard Worker    stp   x3, x4, [x13, #96]
126*795d594fSAndroid Build Coastguard Worker    stp   x5, x6, [x13, #112]
127*795d594fSAndroid Build Coastguard Worker    stp   x7, x20, [x13, #128]
128*795d594fSAndroid Build Coastguard Worker    stp   x21, x22, [x13, #144]
129*795d594fSAndroid Build Coastguard Worker    stp   x23, x24, [x13, #160]
130*795d594fSAndroid Build Coastguard Worker    stp   x25, x26, [x13, #176]
131*795d594fSAndroid Build Coastguard Worker    stp   x27, x28, [x13, #192]
132*795d594fSAndroid Build Coastguard Worker    stp   x29, xIP1, [x13, #208]  // xIP1: Save return address for tail call from JNI stub.
133*795d594fSAndroid Build Coastguard Worker    // (If there were any stack args, we're storing the value that's already there.
134*795d594fSAndroid Build Coastguard Worker    // For direct calls from compiled managed code, we shall overwrite this below.)
135*795d594fSAndroid Build Coastguard Worker
136*795d594fSAndroid Build Coastguard Worker    // Move the managed frame address to native callee-save register x29 and update CFI.
137*795d594fSAndroid Build Coastguard Worker    mov   x29, x13
138*795d594fSAndroid Build Coastguard Worker    // Skip args d0-d7, x1-x7
139*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 20, 29, 136
140*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 21, 29, 144
141*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 22, 29, 152
142*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 23, 29, 160
143*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 24, 29, 168
144*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 25, 29, 176
145*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 26, 29, 184
146*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 27, 29, 192
147*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 28, 29, 200
148*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 29, 29, 208
149*795d594fSAndroid Build Coastguard Worker    // The saved return PC for managed stack walk is not necessarily our LR.
150*795d594fSAndroid Build Coastguard Worker
151*795d594fSAndroid Build Coastguard Worker    // Save our return PC in the padding.
152*795d594fSAndroid Build Coastguard Worker    str   lr, [x29, #__SIZEOF_POINTER__]
153*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 30, 29, __SIZEOF_POINTER__
154*795d594fSAndroid Build Coastguard Worker
155*795d594fSAndroid Build Coastguard Worker    ldr   wIP0, [x15, #ART_METHOD_ACCESS_FLAGS_OFFSET]  // Load access flags.
156*795d594fSAndroid Build Coastguard Worker    add   x14, x29, #1            // Prepare managed SP tagged for a GenericJNI frame.
157*795d594fSAndroid Build Coastguard Worker    tbnz  wIP0, #ACCESS_FLAGS_METHOD_IS_NATIVE_BIT, .Lcritical_skip_prepare_runtime_method
158*795d594fSAndroid Build Coastguard Worker
159*795d594fSAndroid Build Coastguard Worker    // When coming from a compiled method, the return PC for managed stack walk is LR.
160*795d594fSAndroid Build Coastguard Worker    // (When coming from a compiled stub, the correct return PC is already stored above.)
161*795d594fSAndroid Build Coastguard Worker    str   lr, [x29, #(FRAME_SIZE_SAVE_REFS_AND_ARGS - __SIZEOF_POINTER__)]
162*795d594fSAndroid Build Coastguard Worker
163*795d594fSAndroid Build Coastguard Worker    // Replace the target method with the SaveRefsAndArgs runtime method.
164*795d594fSAndroid Build Coastguard Worker    LOAD_RUNTIME_INSTANCE x15
165*795d594fSAndroid Build Coastguard Worker    ldr   x15, [x15, #RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET]
166*795d594fSAndroid Build Coastguard Worker
167*795d594fSAndroid Build Coastguard Worker    mov   x14, x29                // Prepare untagged managed SP for the runtime method.
168*795d594fSAndroid Build Coastguard Worker
169*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_prepare_runtime_method:
170*795d594fSAndroid Build Coastguard Worker    // Store the method on the bottom of the managed frame.
171*795d594fSAndroid Build Coastguard Worker    str   x15, [x29]
172*795d594fSAndroid Build Coastguard Worker
173*795d594fSAndroid Build Coastguard Worker    // Place (maybe tagged) managed SP in Thread::Current()->top_quick_frame.
174*795d594fSAndroid Build Coastguard Worker    str   x14, [xSELF, #THREAD_TOP_QUICK_FRAME_OFFSET]
175*795d594fSAndroid Build Coastguard Worker
176*795d594fSAndroid Build Coastguard Worker    // Preserve the native arg register x0 in callee-save register x28 which was saved above.
177*795d594fSAndroid Build Coastguard Worker    mov   x28, x0
178*795d594fSAndroid Build Coastguard Worker
179*795d594fSAndroid Build Coastguard Worker    // Call artFindNativeMethodRunnable()
180*795d594fSAndroid Build Coastguard Worker    mov   x0, xSELF   // pass Thread::Current()
181*795d594fSAndroid Build Coastguard Worker    bl    artFindNativeMethodRunnable
182*795d594fSAndroid Build Coastguard Worker
183*795d594fSAndroid Build Coastguard Worker    // Store result in scratch reg.
184*795d594fSAndroid Build Coastguard Worker    mov   x13, x0
185*795d594fSAndroid Build Coastguard Worker
186*795d594fSAndroid Build Coastguard Worker    // Restore the native arg register x0.
187*795d594fSAndroid Build Coastguard Worker    mov   x0, x28
188*795d594fSAndroid Build Coastguard Worker
189*795d594fSAndroid Build Coastguard Worker    // Restore our return PC.
190*795d594fSAndroid Build Coastguard Worker    RESTORE_REG_BASE x29, lr, __SIZEOF_POINTER__
191*795d594fSAndroid Build Coastguard Worker
192*795d594fSAndroid Build Coastguard Worker    // Remember the stack args size, negated because SP cannot be on the right-hand side in SUB.
193*795d594fSAndroid Build Coastguard Worker    sub   x14, sp, x29
194*795d594fSAndroid Build Coastguard Worker
195*795d594fSAndroid Build Coastguard Worker    // Restore the frame. We shall not need the method anymore.
196*795d594fSAndroid Build Coastguard Worker    ldp   d0, d1, [x29, #16]
197*795d594fSAndroid Build Coastguard Worker    ldp   d2, d3, [x29, #32]
198*795d594fSAndroid Build Coastguard Worker    ldp   d4, d5, [x29, #48]
199*795d594fSAndroid Build Coastguard Worker    ldp   d6, d7, [x29, #64]
200*795d594fSAndroid Build Coastguard Worker    ldp   x1, x2, [x29, #80]
201*795d594fSAndroid Build Coastguard Worker    ldp   x3, x4, [x29, #96]
202*795d594fSAndroid Build Coastguard Worker    ldp   x5, x6, [x29, #112]
203*795d594fSAndroid Build Coastguard Worker    ldp   x7, x20, [x29, #128]
204*795d594fSAndroid Build Coastguard Worker    .cfi_restore x20
205*795d594fSAndroid Build Coastguard Worker    RESTORE_TWO_REGS_BASE x29, x21, x22, 144
206*795d594fSAndroid Build Coastguard Worker    RESTORE_TWO_REGS_BASE x29, x23, x24, 160
207*795d594fSAndroid Build Coastguard Worker    RESTORE_TWO_REGS_BASE x29, x25, x26, 176
208*795d594fSAndroid Build Coastguard Worker    RESTORE_TWO_REGS_BASE x29, x27, x28, 192
209*795d594fSAndroid Build Coastguard Worker    RESTORE_REG_BASE x29, x29, 208
210*795d594fSAndroid Build Coastguard Worker
211*795d594fSAndroid Build Coastguard Worker    REFRESH_MARKING_REGISTER
212*795d594fSAndroid Build Coastguard Worker
213*795d594fSAndroid Build Coastguard Worker    // Check for exception before moving args back to keep the return PC for managed stack walk.
214*795d594fSAndroid Build Coastguard Worker    CFI_REMEMBER_STATE
215*795d594fSAndroid Build Coastguard Worker    cbz   x13, .Lcritical_deliver_exception
216*795d594fSAndroid Build Coastguard Worker
217*795d594fSAndroid Build Coastguard Worker    // Move stack args to their original place.
218*795d594fSAndroid Build Coastguard Worker    cbz   x14, .Lcritical_skip_copy_args_back
219*795d594fSAndroid Build Coastguard Worker    sub   x12, sp, x14
220*795d594fSAndroid Build Coastguard Worker.Lcritical_copy_args_back_loop:
221*795d594fSAndroid Build Coastguard Worker    ldp   xIP0, xIP1, [x12, #-16]!
222*795d594fSAndroid Build Coastguard Worker    adds  x14, x14, #16
223*795d594fSAndroid Build Coastguard Worker    stp   xIP0, xIP1, [x12, #FRAME_SIZE_SAVE_REFS_AND_ARGS]
224*795d594fSAndroid Build Coastguard Worker    bne   .Lcritical_copy_args_back_loop
225*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_copy_args_back:
226*795d594fSAndroid Build Coastguard Worker
227*795d594fSAndroid Build Coastguard Worker    // Remove the frame reservation.
228*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS
229*795d594fSAndroid Build Coastguard Worker
230*795d594fSAndroid Build Coastguard Worker    // Do the tail call.
231*795d594fSAndroid Build Coastguard Worker    br    x13
232*795d594fSAndroid Build Coastguard Worker
233*795d594fSAndroid Build Coastguard Worker.Lcritical_deliver_exception:
234*795d594fSAndroid Build Coastguard Worker    CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_AND_ARGS
235*795d594fSAndroid Build Coastguard Worker    // The exception delivery checks that xSELF was saved but the SaveRefsAndArgs
236*795d594fSAndroid Build Coastguard Worker    // frame does not save it, so we cannot use the existing SaveRefsAndArgs frame.
237*795d594fSAndroid Build Coastguard Worker    // That's why we checked for exception after restoring registers from it.
238*795d594fSAndroid Build Coastguard Worker    // We need to build a SaveAllCalleeSaves frame instead. Args are irrelevant at this
239*795d594fSAndroid Build Coastguard Worker    // point but keep the area allocated for stack args to keep CFA definition simple.
240*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS - FRAME_SIZE_SAVE_ALL_CALLEE_SAVES
241*795d594fSAndroid Build Coastguard Worker
242*795d594fSAndroid Build Coastguard Worker    // Calculate the base address of the managed frame.
243*795d594fSAndroid Build Coastguard Worker    sub   x13, sp, x14
244*795d594fSAndroid Build Coastguard Worker
245*795d594fSAndroid Build Coastguard Worker    // Spill registers for the SaveAllCalleeSaves frame above the stack args area. Do not update
246*795d594fSAndroid Build Coastguard Worker    // CFI while we hold the frame address in x13 and the values in registers are unchanged.
247*795d594fSAndroid Build Coastguard Worker    stp   d8, d9, [x13, #16]
248*795d594fSAndroid Build Coastguard Worker    stp   d10, d11, [x13, #32]
249*795d594fSAndroid Build Coastguard Worker    stp   d12, d13, [x13, #48]
250*795d594fSAndroid Build Coastguard Worker    stp   d14, d15, [x13, #64]
251*795d594fSAndroid Build Coastguard Worker    stp   x19, x20, [x13, #80]
252*795d594fSAndroid Build Coastguard Worker    stp   x21, x22, [x13, #96]
253*795d594fSAndroid Build Coastguard Worker    stp   x23, x24, [x13, #112]
254*795d594fSAndroid Build Coastguard Worker    stp   x25, x26, [x13, #128]
255*795d594fSAndroid Build Coastguard Worker    stp   x27, x28, [x13, #144]
256*795d594fSAndroid Build Coastguard Worker    str   x29, [x13, #160]
257*795d594fSAndroid Build Coastguard Worker    // Keep the caller PC for managed stack walk.
258*795d594fSAndroid Build Coastguard Worker
259*795d594fSAndroid Build Coastguard Worker    // Move the managed frame address to native callee-save register x29 and update CFI.
260*795d594fSAndroid Build Coastguard Worker    mov   x29, x13
261*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 19, 29, 80
262*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 20, 29, 88
263*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 21, 29, 96
264*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 22, 29, 104
265*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 23, 29, 112
266*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 24, 29, 120
267*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 25, 29, 128
268*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 26, 29, 136
269*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 27, 29, 144
270*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 28, 29, 152
271*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 29, 29, 160
272*795d594fSAndroid Build Coastguard Worker    // The saved return PC for managed stack walk is not necessarily our LR.
273*795d594fSAndroid Build Coastguard Worker
274*795d594fSAndroid Build Coastguard Worker    // Save our return PC in the padding.
275*795d594fSAndroid Build Coastguard Worker    str   lr, [x29, #__SIZEOF_POINTER__]
276*795d594fSAndroid Build Coastguard Worker    CFI_EXPRESSION_BREG 30, 29, __SIZEOF_POINTER__
277*795d594fSAndroid Build Coastguard Worker
278*795d594fSAndroid Build Coastguard Worker    // Store ArtMethod* Runtime::callee_save_methods_[kSaveAllCalleeSaves] to the managed frame.
279*795d594fSAndroid Build Coastguard Worker    LOAD_RUNTIME_INSTANCE xIP0
280*795d594fSAndroid Build Coastguard Worker    ldr   xIP0, [xIP0, #RUNTIME_SAVE_ALL_CALLEE_SAVES_METHOD_OFFSET]
281*795d594fSAndroid Build Coastguard Worker    str   xIP0, [x29]
282*795d594fSAndroid Build Coastguard Worker
283*795d594fSAndroid Build Coastguard Worker    // Place the managed frame SP in Thread::Current()->top_quick_frame.
284*795d594fSAndroid Build Coastguard Worker    str   x29, [xSELF, #THREAD_TOP_QUICK_FRAME_OFFSET]
285*795d594fSAndroid Build Coastguard Worker
286*795d594fSAndroid Build Coastguard Worker    DELIVER_PENDING_EXCEPTION_FRAME_READY
287*795d594fSAndroid Build Coastguard WorkerEND art_jni_dlsym_lookup_critical_stub
288*795d594fSAndroid Build Coastguard Worker
289*795d594fSAndroid Build Coastguard Worker    /*
290*795d594fSAndroid Build Coastguard Worker     * Read barrier for the method's declaring class needed by JNI stub for static methods.
291*795d594fSAndroid Build Coastguard Worker     * (We're using a pointer to the declaring class in `ArtMethod` as `jclass`.)
292*795d594fSAndroid Build Coastguard Worker     */
293*795d594fSAndroid Build Coastguard Worker// The method argument is already in x0 for call to `artJniReadBarrier(ArtMethod*)`.
294*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_read_barrier, artJniReadBarrier
295*795d594fSAndroid Build Coastguard Worker
296*795d594fSAndroid Build Coastguard Worker    /*
297*795d594fSAndroid Build Coastguard Worker     * Trampoline to `artJniMethodStart()` that preserves all managed arguments.
298*795d594fSAndroid Build Coastguard Worker     */
299*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_method_start, artJniMethodStart, xSELF
300*795d594fSAndroid Build Coastguard Worker
301*795d594fSAndroid Build Coastguard Worker    /*
302*795d594fSAndroid Build Coastguard Worker     * Trampoline to `artJniMethodEntryHook` that preserves all managed arguments.
303*795d594fSAndroid Build Coastguard Worker     */
304*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_method_entry_hook, artJniMethodEntryHook, xSELF
305*795d594fSAndroid Build Coastguard Worker
306*795d594fSAndroid Build Coastguard Worker    /*
307*795d594fSAndroid Build Coastguard Worker     * Trampoline to `artJniMonitoredMethodStart()` that preserves all managed arguments.
308*795d594fSAndroid Build Coastguard Worker     */
309*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_monitored_method_start, artJniMonitoredMethodStart, xSELF
310*795d594fSAndroid Build Coastguard Worker
311*795d594fSAndroid Build Coastguard Worker    /*
312*795d594fSAndroid Build Coastguard Worker     * Trampoline to `artJniMethodEnd()` that preserves all return registers.
313*795d594fSAndroid Build Coastguard Worker     */
314*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_method_end, artJniMethodEnd, xSELF
315*795d594fSAndroid Build Coastguard Worker
316*795d594fSAndroid Build Coastguard Worker    /*
317*795d594fSAndroid Build Coastguard Worker     * Trampoline to `artJniMonitoredMethodEnd()` that preserves all return registers.
318*795d594fSAndroid Build Coastguard Worker     */
319*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_monitored_method_end, artJniMonitoredMethodEnd, xSELF
320*795d594fSAndroid Build Coastguard Worker
321*795d594fSAndroid Build Coastguard Worker    /*
322*795d594fSAndroid Build Coastguard Worker     * Entry from JNI stub that tries to lock the object in a fast path and
323*795d594fSAndroid Build Coastguard Worker     * calls `artLockObjectFromCode()` (the same as for managed code) for the
324*795d594fSAndroid Build Coastguard Worker     * difficult cases, may block for GC.
325*795d594fSAndroid Build Coastguard Worker     * Custom calling convention:
326*795d594fSAndroid Build Coastguard Worker     *     x15 holds the non-null object to lock.
327*795d594fSAndroid Build Coastguard Worker     *     Callee-save registers have been saved and can be used as temporaries.
328*795d594fSAndroid Build Coastguard Worker     *     All argument registers need to be preserved.
329*795d594fSAndroid Build Coastguard Worker     */
330*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_lock_object
331*795d594fSAndroid Build Coastguard Worker    LOCK_OBJECT_FAST_PATH x15, art_jni_lock_object_no_inline, /*can_be_null*/ 0
332*795d594fSAndroid Build Coastguard WorkerEND art_jni_lock_object
333*795d594fSAndroid Build Coastguard Worker
334*795d594fSAndroid Build Coastguard Worker    /*
335*795d594fSAndroid Build Coastguard Worker     * Entry from JNI stub that calls `artLockObjectFromCode()`
336*795d594fSAndroid Build Coastguard Worker     * (the same as for managed code), may block for GC.
337*795d594fSAndroid Build Coastguard Worker     * Custom calling convention:
338*795d594fSAndroid Build Coastguard Worker     *     x15 holds the non-null object to lock.
339*795d594fSAndroid Build Coastguard Worker     *     Callee-save registers have been saved and can be used as temporaries.
340*795d594fSAndroid Build Coastguard Worker     *     All argument registers need to be preserved.
341*795d594fSAndroid Build Coastguard Worker     */
342*795d594fSAndroid Build Coastguard Worker    .extern artLockObjectFromCode
343*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_lock_object_no_inline
344*795d594fSAndroid Build Coastguard Worker    // This is also the slow path for art_jni_lock_object.
345*795d594fSAndroid Build Coastguard Worker    // Save args and LR.
346*795d594fSAndroid Build Coastguard Worker    SAVE_ALL_ARGS_INCREASE_FRAME /*padding*/ 8 + /*LR*/ 8
347*795d594fSAndroid Build Coastguard Worker    str    lr, [sp, #(ALL_ARGS_SIZE + /*padding*/ 8)]
348*795d594fSAndroid Build Coastguard Worker    .cfi_rel_offset lr, ALL_ARGS_SIZE + /*padding*/ 8
349*795d594fSAndroid Build Coastguard Worker    // Call `artLockObjectFromCode()`.
350*795d594fSAndroid Build Coastguard Worker    mov    x0, x15                    // Pass the object to lock.
351*795d594fSAndroid Build Coastguard Worker    mov    x1, xSELF                  // Pass Thread::Current().
352*795d594fSAndroid Build Coastguard Worker    bl     artLockObjectFromCode      // (Object* obj, Thread*)
353*795d594fSAndroid Build Coastguard Worker    // Restore return address.
354*795d594fSAndroid Build Coastguard Worker    ldr    lr, [sp, #(ALL_ARGS_SIZE + /*padding*/ 8)]
355*795d594fSAndroid Build Coastguard Worker    .cfi_restore lr
356*795d594fSAndroid Build Coastguard Worker    // Check result.
357*795d594fSAndroid Build Coastguard Worker    cbnz   x0, 1f
358*795d594fSAndroid Build Coastguard Worker    // Restore register args x0-x7, d0-d7 and return.
359*795d594fSAndroid Build Coastguard Worker    RESTORE_ALL_ARGS_DECREASE_FRAME /*padding*/ 8 + /*LR*/ 8
360*795d594fSAndroid Build Coastguard Worker    ret
361*795d594fSAndroid Build Coastguard Worker    .cfi_adjust_cfa_offset (ALL_ARGS_SIZE + /*padding*/ 8 + /*LR*/ 8)
362*795d594fSAndroid Build Coastguard Worker1:
363*795d594fSAndroid Build Coastguard Worker    // All args are irrelevant when throwing an exception. Remove the spill area.
364*795d594fSAndroid Build Coastguard Worker    DECREASE_FRAME (ALL_ARGS_SIZE + /*padding*/ 8 + /*LR*/ 8)
365*795d594fSAndroid Build Coastguard Worker    // Make a call to `artDeliverPendingExceptionFromCode()`.
366*795d594fSAndroid Build Coastguard Worker    // Rely on the JNI transition frame constructed in the JNI stub.
367*795d594fSAndroid Build Coastguard Worker    mov    x0, xSELF                            // Pass Thread::Current().
368*795d594fSAndroid Build Coastguard Worker    bl     artDeliverPendingExceptionFromCode   // (Thread*)
369*795d594fSAndroid Build Coastguard Worker    bl     art_quick_do_long_jump               // (Context*)
370*795d594fSAndroid Build Coastguard Worker    brk 0  // Unreached
371*795d594fSAndroid Build Coastguard WorkerEND art_jni_lock_object_no_inline
372*795d594fSAndroid Build Coastguard Worker
373*795d594fSAndroid Build Coastguard Worker    /*
374*795d594fSAndroid Build Coastguard Worker     * Entry from JNI stub that tries to unlock the object in a fast path and calls
375*795d594fSAndroid Build Coastguard Worker     * `artJniUnlockObject()` for the difficult cases. Note that failure to unlock
376*795d594fSAndroid Build Coastguard Worker     * is fatal, so we do not need to check for exceptions in the slow path.
377*795d594fSAndroid Build Coastguard Worker     * Custom calling convention:
378*795d594fSAndroid Build Coastguard Worker     *     x15 holds the non-null object to unlock.
379*795d594fSAndroid Build Coastguard Worker     *     Callee-save registers have been saved and can be used as temporaries.
380*795d594fSAndroid Build Coastguard Worker     *     Return registers r0 and d0 need to be preserved.
381*795d594fSAndroid Build Coastguard Worker     */
382*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_unlock_object
383*795d594fSAndroid Build Coastguard Worker    UNLOCK_OBJECT_FAST_PATH x15, art_jni_unlock_object_no_inline, /*can_be_null*/ 0
384*795d594fSAndroid Build Coastguard WorkerEND art_jni_unlock_object
385*795d594fSAndroid Build Coastguard Worker
386*795d594fSAndroid Build Coastguard Worker    /*
387*795d594fSAndroid Build Coastguard Worker     * Entry from JNI stub that calls `artJniUnlockObject()`. Note that failure to
388*795d594fSAndroid Build Coastguard Worker     * unlock is fatal, so we do not need to check for exceptions.
389*795d594fSAndroid Build Coastguard Worker     * Custom calling convention:
390*795d594fSAndroid Build Coastguard Worker     *     x15 holds the non-null object to unlock.
391*795d594fSAndroid Build Coastguard Worker     *     Callee-save registers have been saved and can be used as temporaries.
392*795d594fSAndroid Build Coastguard Worker     *     Return registers r0 and d0 need to be preserved.
393*795d594fSAndroid Build Coastguard Worker     */
394*795d594fSAndroid Build Coastguard Worker    // This is also the slow path for art_jni_unlock_object.
395*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_unlock_object_no_inline, artJniUnlockObject, x15, xSELF
396