File: jni_entrypoints_arm64.S

package info (click to toggle)
android-platform-art 11.0.0%2Br48-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 78,932 kB
  • sloc: cpp: 459,858; java: 163,268; asm: 22,644; python: 9,815; sh: 6,330; ansic: 4,117; xml: 2,855; perl: 77; makefile: 73
file content (232 lines) | stat: -rw-r--r-- 7,977 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "asm_support_arm64.S"

    /*
     * Jni dlsym lookup stub.
     */
    .extern artFindNativeMethod
    .extern artFindNativeMethodRunnable

ENTRY art_jni_dlsym_lookup_stub
    // spill regs.
    stp   x29, x30, [sp, #-16]!
    .cfi_adjust_cfa_offset 16
    .cfi_rel_offset x29, 0
    .cfi_rel_offset x30, 8
    mov   x29, sp
    stp   d6, d7,   [sp, #-16]!
    .cfi_adjust_cfa_offset 16
    stp   d4, d5,   [sp, #-16]!
    .cfi_adjust_cfa_offset 16
    stp   d2, d3,   [sp, #-16]!
    .cfi_adjust_cfa_offset 16
    stp   d0, d1,   [sp, #-16]!
    .cfi_adjust_cfa_offset 16
    stp   x6, x7,   [sp, #-16]!
    .cfi_adjust_cfa_offset 16
    stp   x4, x5,   [sp, #-16]!
    .cfi_adjust_cfa_offset 16
    stp   x2, x3,   [sp, #-16]!
    .cfi_adjust_cfa_offset 16
    stp   x0, x1,   [sp, #-16]!
    .cfi_adjust_cfa_offset 16

    mov x0, xSELF   // pass Thread::Current()
    // Call artFindNativeMethod() for normal native and artFindNativeMethodRunnable()
    // for @FastNative or @CriticalNative.
    ldr   xIP0, [x0, #THREAD_TOP_QUICK_FRAME_OFFSET]      // uintptr_t tagged_quick_frame
    bic   xIP0, xIP0, #1                                  // ArtMethod** sp
    ldr   xIP0, [xIP0]                                    // ArtMethod* method
    ldr   xIP0, [xIP0, #ART_METHOD_ACCESS_FLAGS_OFFSET]   // uint32_t access_flags
    mov   xIP1, #(ACCESS_FLAGS_METHOD_IS_FAST_NATIVE | ACCESS_FLAGS_METHOD_IS_CRITICAL_NATIVE)
    tst   xIP0, xIP1
    b.ne  .Llookup_stub_fast_native
    bl    artFindNativeMethod
    b     .Llookup_stub_continue
    .Llookup_stub_fast_native:
    bl    artFindNativeMethodRunnable
.Llookup_stub_continue:
    mov   x17, x0    // store result in scratch reg.

    // load spill regs.
    ldp   x0, x1,   [sp], #16
    .cfi_adjust_cfa_offset -16
    ldp   x2, x3,   [sp], #16
    .cfi_adjust_cfa_offset -16
    ldp   x4, x5,   [sp], #16
    .cfi_adjust_cfa_offset -16
    ldp   x6, x7,   [sp], #16
    .cfi_adjust_cfa_offset -16
    ldp   d0, d1,   [sp], #16
    .cfi_adjust_cfa_offset -16
    ldp   d2, d3,   [sp], #16
    .cfi_adjust_cfa_offset -16
    ldp   d4, d5,   [sp], #16
    .cfi_adjust_cfa_offset -16
    ldp   d6, d7,   [sp], #16
    .cfi_adjust_cfa_offset -16
    ldp   x29, x30, [sp], #16
    .cfi_adjust_cfa_offset -16
    .cfi_restore x29
    .cfi_restore x30

    cbz   x17, 1f   // is method code null ?
    br    x17       // if non-null, tail call to method's code.

1:
    ret             // restore regs and return to caller to handle exception.
END art_jni_dlsym_lookup_stub

ENTRY art_jni_dlsym_lookup_critical_stub
    // The hidden arg holding the tagged method (bit 0 set means GenericJNI) is x15.
    // For Generic JNI we already have a managed frame, so we reuse the art_jni_dlsym_lookup_stub.
    tbnz  x15, #0, art_jni_dlsym_lookup_stub

    // We need to create a GenericJNI managed frame above the stack args.

    // GenericJNI frame is similar to SaveRegsAndArgs frame with the native method
    // instead of runtime method saved at the bottom. Note that the runtime shall
    // not examine the args here, otherwise we would have to move them in registers
    // and stack to account for the difference between managed and native ABIs.
    INCREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS
    SETUP_SAVE_REFS_AND_ARGS_FRAME_INTERNAL sp
    // Save the hidden arg as method pointer, x0 in the padding.
    // (x0 is an arg in native ABI but not considered an arg in managed ABI.)
    SAVE_TWO_REGS x15, x0, 0

    // Call artCriticalNativeOutArgsSize(method)
    mov   x0, x15  // x0 := method (from hidden arg)
    bl    artCriticalNativeOutArgsSize

    // Check if we have any stack args.
    cbnz  x0, .Lcritical_has_stack_args

    // Without stack args, the frame is fully constructed.
    // Place tagged managed sp in Thread::Current()->top_quick_frame.
    mov   xIP0, sp
    orr   xIP0, xIP0, #1  // Tag as GenericJNI frame.
    str   xIP0, [xSELF, #THREAD_TOP_QUICK_FRAME_OFFSET]

    // Call artFindNativeMethodRunnable()
    mov   x0, xSELF   // pass Thread::Current()
    bl    artFindNativeMethodRunnable

    // Store result in scratch reg.
    mov   xIP0, x0

    // Restore frame.
    .cfi_remember_state
    RESTORE_TWO_REGS x15, x0, 0
    RESTORE_SAVE_REFS_AND_ARGS_FRAME
    REFRESH_MARKING_REGISTER

    // Check for exception.
    cbz   xIP0, .Lcritical_deliver_exception

    // Do the tail call
    br    xIP0
    .cfi_restore_state
    .cfi_def_cfa_offset FRAME_SIZE_SAVE_REFS_AND_ARGS

.Lcritical_has_stack_args:
    // Move the out args size to a scratch register.
    mov   xIP0, x0

    // Restore register args as we're about to move stack args.
    RESTORE_TWO_REGS x15, x0, 0
    RESTORE_SAVE_REFS_AND_ARGS_FRAME_INTERNAL sp

    // Move out args. For simplicity include the return address at the end.
    mov   x8, sp        // Destination.
    add   x9, sp, xIP0  // Destination end.
1:
    ldp   x10, x11, [x8, #FRAME_SIZE_SAVE_REFS_AND_ARGS]
    stp   x10, x11, [x8], #16
    cmp   x8, x9
    bne   1b

    // Save our LR, load caller's LR and redefine CFI to take ownership of the JNI stub frame.
    str   xLR, [x9, #-__SIZEOF_POINTER__]
    mov   xLR, x11  // The last moved value from the loop above.
    .cfi_def_cfa x9, FRAME_SIZE_SAVE_REFS_AND_ARGS

    // Re-create the SaveRefsAndArgs frame above the args.
    SETUP_SAVE_REFS_AND_ARGS_FRAME_INTERNAL x9
    SAVE_TWO_REGS_BASE x9, x15, x0, 0

    // Move the frame register to a callee-save register.
    mov   x29, x9
    .cfi_def_cfa_register x29

    // Place tagged managed sp in Thread::Current()->top_quick_frame.
    orr   xIP0, x29, #1  // Tag as GenericJNI frame.
    str   xIP0, [xSELF, #THREAD_TOP_QUICK_FRAME_OFFSET]

    // Call artFindNativeMethodRunnable()
    mov   x0, xSELF   // pass Thread::Current()
    bl    artFindNativeMethodRunnable

    // Store result in scratch reg.
    mov   xIP0, x0

    // Restore the frame.
    mov   x9, x29
    .cfi_def_cfa_register x9
    RESTORE_TWO_REGS_BASE x9, x15, x0, 0
    RESTORE_SAVE_REFS_AND_ARGS_FRAME_INTERNAL x9
    REFRESH_MARKING_REGISTER

    // Check for exception.
    cbz   xIP0, 3f

    // Move stack args to their original place.
    mov   x8, x9
2:
    ldp   x10, x11, [x8, #-16]!
    stp   x10, x11, [x8, #FRAME_SIZE_SAVE_REFS_AND_ARGS]
    cmp   sp, x8
    bne   2b

    // Replace original return address with caller's return address.
    ldr   xIP1, [x9, #(FRAME_SIZE_SAVE_REFS_AND_ARGS - __SIZEOF_POINTER__)]
    str   xLR, [x9, #(FRAME_SIZE_SAVE_REFS_AND_ARGS - __SIZEOF_POINTER__)]

    // Restore LR and redefine CFI to release ownership of the JNI stub frame.
    .cfi_remember_state
    mov   xLR, xIP1
    .cfi_def_cfa sp, FRAME_SIZE_SAVE_REFS_AND_ARGS

    // Remove the frame reservation.
    DECREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS

    // Do the tail call.
    br    xIP0
    .cfi_restore_state
    .cfi_def_cfa x9, FRAME_SIZE_SAVE_REFS_AND_ARGS

3:
    // Drop stack args and the SaveRefsAndArgs reservation.
    mov   sp, x9
    add   sp, sp, #FRAME_SIZE_SAVE_REFS_AND_ARGS
    .cfi_def_cfa sp, 0

.Lcritical_deliver_exception:
    // When delivering exception, we check that xSELF was saved but the SaveRefsAndArgs frame does
    // not save it, so we cannot use DELIVER_PENDING_EXCEPTION_FRAME_READY with the above frames.
    DELIVER_PENDING_EXCEPTION
END art_jni_dlsym_lookup_critical_stub