1*795d594fSAndroid Build Coastguard Worker/* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2023 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_riscv64.S" 18*795d594fSAndroid Build Coastguard Worker 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker.macro JNI_SAVE_MANAGED_ARGS_TRAMPOLINE name, cxx_name, arg1 = "none" 21*795d594fSAndroid Build Coastguard Worker .extern \cxx_name 22*795d594fSAndroid Build Coastguard WorkerENTRY \name 23*795d594fSAndroid Build Coastguard Worker // Save args and RA. 24*795d594fSAndroid Build Coastguard Worker SAVE_ALL_ARGS_INCREASE_FRAME /*padding*/ 8 + /*RA*/ 8 25*795d594fSAndroid Build Coastguard Worker SAVE_GPR ra, (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 mv a0, \arg1 29*795d594fSAndroid Build Coastguard Worker .endif 30*795d594fSAndroid Build Coastguard Worker call \cxx_name 31*795d594fSAndroid Build Coastguard Worker // Restore RA and args and return. 32*795d594fSAndroid Build Coastguard Worker RESTORE_GPR ra, (ALL_ARGS_SIZE + /*padding*/ 8) 33*795d594fSAndroid Build Coastguard Worker RESTORE_ALL_ARGS_DECREASE_FRAME /*padding*/ 8 + /*RA*/ 8 34*795d594fSAndroid Build Coastguard Worker ret 35*795d594fSAndroid Build Coastguard WorkerEND \name 36*795d594fSAndroid Build Coastguard Worker.endm 37*795d594fSAndroid Build Coastguard Worker 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 INCREASE_FRAME 32 44*795d594fSAndroid Build Coastguard Worker sd a0, 0(sp) 45*795d594fSAndroid Build Coastguard Worker fsd fa0, 8(sp) 46*795d594fSAndroid Build Coastguard Worker SAVE_GPR ra, 24 47*795d594fSAndroid Build Coastguard Worker // Call `cxx_name()`. 48*795d594fSAndroid Build Coastguard Worker mv a0, \arg1 49*795d594fSAndroid Build Coastguard Worker .ifnc \arg2, none 50*795d594fSAndroid Build Coastguard Worker mv a1, \arg2 51*795d594fSAndroid Build Coastguard Worker .endif 52*795d594fSAndroid Build Coastguard Worker call \cxx_name 53*795d594fSAndroid Build Coastguard Worker // Restore result registers and return. 54*795d594fSAndroid Build Coastguard Worker ld a0, 0(sp) 55*795d594fSAndroid Build Coastguard Worker fld fa0, 8(sp) 56*795d594fSAndroid Build Coastguard Worker RESTORE_GPR ra, 24 57*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME 32 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 WorkerENTRY art_jni_dlsym_lookup_critical_stub 65*795d594fSAndroid Build Coastguard Worker // The hidden arg holding the tagged method is t0 (loaded by compiled JNI stub, compiled 66*795d594fSAndroid Build Coastguard Worker // managed code, or `art_quick_generic_jni_trampoline`). Bit 0 set means generic JNI. 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: 'bnez' doesn't always have enough range (+/-4KB) to reach art_jni_dlsym_lookup_stub so 69*795d594fSAndroid Build Coastguard Worker // 'tail' is used instead. 70*795d594fSAndroid Build Coastguard Worker andi t6, t0, 1 71*795d594fSAndroid Build Coastguard Worker beqz t6, .Lcritical_not_generic_jni 72*795d594fSAndroid Build Coastguard Worker tail art_jni_dlsym_lookup_stub 73*795d594fSAndroid Build Coastguard Worker 74*795d594fSAndroid Build Coastguard Worker.Lcritical_not_generic_jni: 75*795d594fSAndroid Build Coastguard Worker // Save args, the hidden arg and caller PC. No CFI needed for args and the hidden arg. 76*795d594fSAndroid Build Coastguard Worker SAVE_ALL_ARGS_INCREASE_FRAME 2*8 77*795d594fSAndroid Build Coastguard Worker SAVE_GPR t0, (ALL_ARGS_SIZE + 0) 78*795d594fSAndroid Build Coastguard Worker SAVE_GPR ra, (ALL_ARGS_SIZE + 8) 79*795d594fSAndroid Build Coastguard Worker 80*795d594fSAndroid Build Coastguard Worker // Call artCriticalNativeFrameSize(method, caller_pc) 81*795d594fSAndroid Build Coastguard Worker mv a0, t0 // a0 := method (from hidden arg) 82*795d594fSAndroid Build Coastguard Worker mv a1, ra // a1 := caller_pc 83*795d594fSAndroid Build Coastguard Worker call artCriticalNativeFrameSize 84*795d594fSAndroid Build Coastguard Worker 85*795d594fSAndroid Build Coastguard Worker // Move frame size to T2. 86*795d594fSAndroid Build Coastguard Worker mv t2, a0 87*795d594fSAndroid Build Coastguard Worker 88*795d594fSAndroid Build Coastguard Worker // Restore args, the hidden arg and caller PC. 89*795d594fSAndroid Build Coastguard Worker RESTORE_GPR t0, (ALL_ARGS_SIZE + 0) 90*795d594fSAndroid Build Coastguard Worker RESTORE_GPR ra, (ALL_ARGS_SIZE + 8) 91*795d594fSAndroid Build Coastguard Worker RESTORE_ALL_ARGS_DECREASE_FRAME 2*8 92*795d594fSAndroid Build Coastguard Worker 93*795d594fSAndroid Build Coastguard Worker // Reserve space for a SaveRefsAndArgs managed frame, either for the actual runtime 94*795d594fSAndroid Build Coastguard Worker // method or for a GenericJNI frame which is similar but has a native method and a tag. 95*795d594fSAndroid Build Coastguard Worker // Add space for RA and padding to keep the stack 16-byte aligned. 96*795d594fSAndroid Build Coastguard Worker INCREASE_FRAME (FRAME_SIZE_SAVE_REFS_AND_ARGS + 16) 97*795d594fSAndroid Build Coastguard Worker 98*795d594fSAndroid Build Coastguard Worker // Prepare the return address for managed stack walk of the SaveRefsAndArgs frame. 99*795d594fSAndroid Build Coastguard Worker // If we're coming from JNI stub with tail call, it is RA. If we're coming from 100*795d594fSAndroid Build Coastguard Worker // JNI stub that saved the return address, it will be the last value we copy below. 101*795d594fSAndroid Build Coastguard Worker // If we're coming directly from compiled code, it is RA, set further down. 102*795d594fSAndroid Build Coastguard Worker mv t4, ra 103*795d594fSAndroid Build Coastguard Worker 104*795d594fSAndroid Build Coastguard Worker // Move the stack args if any. Calculate the base address of the managed frame in the process. 105*795d594fSAndroid Build Coastguard Worker addi t1, sp, 16 106*795d594fSAndroid Build Coastguard Worker beqz t2, .Lcritical_skip_copy_args 107*795d594fSAndroid Build Coastguard Worker.Lcritical_copy_args_loop: 108*795d594fSAndroid Build Coastguard Worker ld t3, FRAME_SIZE_SAVE_REFS_AND_ARGS+0(t1) 109*795d594fSAndroid Build Coastguard Worker ld t4, FRAME_SIZE_SAVE_REFS_AND_ARGS+8(t1) 110*795d594fSAndroid Build Coastguard Worker addi t2, t2, -16 111*795d594fSAndroid Build Coastguard Worker sd t3, 0-16(t1) 112*795d594fSAndroid Build Coastguard Worker sd t4, 8-16(t1) 113*795d594fSAndroid Build Coastguard Worker addi t1, t1, 16 114*795d594fSAndroid Build Coastguard Worker bnez t2, .Lcritical_copy_args_loop 115*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_copy_args: 116*795d594fSAndroid Build Coastguard Worker 117*795d594fSAndroid Build Coastguard Worker // Spill registers for the SaveRefsAndArgs frame above the stack args. 118*795d594fSAndroid Build Coastguard Worker // Note that the runtime shall not examine the args here, otherwise we would have to 119*795d594fSAndroid Build Coastguard Worker // move them in registers and stack to account for the difference between managed and 120*795d594fSAndroid Build Coastguard Worker // native ABIs. Do not update CFI while we hold the frame address in T1 and the values 121*795d594fSAndroid Build Coastguard Worker // in registers are unchanged. 122*795d594fSAndroid Build Coastguard Worker // stack slot (0*8)(t1) is for ArtMethod* 123*795d594fSAndroid Build Coastguard Worker fsd fa0, (1*8)(t1) 124*795d594fSAndroid Build Coastguard Worker fsd fa1, (2*8)(t1) 125*795d594fSAndroid Build Coastguard Worker fsd fa2, (3*8)(t1) 126*795d594fSAndroid Build Coastguard Worker fsd fa3, (4*8)(t1) 127*795d594fSAndroid Build Coastguard Worker fsd fa4, (5*8)(t1) 128*795d594fSAndroid Build Coastguard Worker fsd fa5, (6*8)(t1) 129*795d594fSAndroid Build Coastguard Worker fsd fa6, (7*8)(t1) 130*795d594fSAndroid Build Coastguard Worker fsd fa7, (8*8)(t1) 131*795d594fSAndroid Build Coastguard Worker sd fp, (9*8)(t1) // x8, frame pointer 132*795d594fSAndroid Build Coastguard Worker // s1 (x9) is the ART thread register 133*795d594fSAndroid Build Coastguard Worker // a0 (x10) is the method pointer 134*795d594fSAndroid Build Coastguard Worker sd a1, (10*8)(t1) // x11 135*795d594fSAndroid Build Coastguard Worker sd a2, (11*8)(t1) // x12 136*795d594fSAndroid Build Coastguard Worker sd a3, (12*8)(t1) // x13 137*795d594fSAndroid Build Coastguard Worker sd a4, (13*8)(t1) // x14 138*795d594fSAndroid Build Coastguard Worker sd a5, (14*8)(t1) // x15 139*795d594fSAndroid Build Coastguard Worker sd a6, (15*8)(t1) // x16 140*795d594fSAndroid Build Coastguard Worker sd a7, (16*8)(t1) // x17 141*795d594fSAndroid Build Coastguard Worker sd s2, (17*8)(t1) // x18 142*795d594fSAndroid Build Coastguard Worker sd s3, (18*8)(t1) // x19 143*795d594fSAndroid Build Coastguard Worker sd s4, (19*8)(t1) // x20 144*795d594fSAndroid Build Coastguard Worker sd s5, (20*8)(t1) // x21 145*795d594fSAndroid Build Coastguard Worker sd s6, (21*8)(t1) // x22 146*795d594fSAndroid Build Coastguard Worker sd s7, (22*8)(t1) // x23 147*795d594fSAndroid Build Coastguard Worker sd s8, (23*8)(t1) // x24 148*795d594fSAndroid Build Coastguard Worker sd s9, (24*8)(t1) // x25 149*795d594fSAndroid Build Coastguard Worker sd s10, (25*8)(t1) // x26 150*795d594fSAndroid Build Coastguard Worker sd s11, (26*8)(t1) // x27 151*795d594fSAndroid Build Coastguard Worker sd t4, (27*8)(t1) // t4: Save return address for tail call from JNI stub. 152*795d594fSAndroid Build Coastguard Worker // (If there were any stack args, we're storing the value that's already there. 153*795d594fSAndroid Build Coastguard Worker // For direct calls from compiled managed code, we shall overwrite this below.) 154*795d594fSAndroid Build Coastguard Worker 155*795d594fSAndroid Build Coastguard Worker // Move the managed frame address to native callee-save register fp (x8) and update CFI. 156*795d594fSAndroid Build Coastguard Worker mv fp, t1 157*795d594fSAndroid Build Coastguard Worker // Skip args FA0-FA7, A1-A7 158*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 8, 8, (9*8) 159*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 18, 8, (17*8) 160*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 19, 8, (18*8) 161*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 20, 8, (19*8) 162*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 21, 8, (20*8) 163*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 22, 8, (21*8) 164*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 23, 8, (22*8) 165*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 24, 8, (23*8) 166*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 25, 8, (24*8) 167*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 26, 8, (25*8) 168*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 27, 8, (26*8) 169*795d594fSAndroid Build Coastguard Worker // The saved return PC for managed stack walk is not necessarily our RA. 170*795d594fSAndroid Build Coastguard Worker 171*795d594fSAndroid Build Coastguard Worker // Save our return PC below the managed frame. 172*795d594fSAndroid Build Coastguard Worker sd ra, -__SIZEOF_POINTER__(fp) 173*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 1, 8, -__SIZEOF_POINTER__ 174*795d594fSAndroid Build Coastguard Worker 175*795d594fSAndroid Build Coastguard Worker lw t2, ART_METHOD_ACCESS_FLAGS_OFFSET(t0) // Load access flags. 176*795d594fSAndroid Build Coastguard Worker addi t1, fp, 1 // Prepare managed SP tagged for a GenericJNI frame. 177*795d594fSAndroid Build Coastguard Worker slliw t2, t2, 31 - ACCESS_FLAGS_METHOD_IS_NATIVE_BIT 178*795d594fSAndroid Build Coastguard Worker bltz t2, .Lcritical_skip_prepare_runtime_method 179*795d594fSAndroid Build Coastguard Worker 180*795d594fSAndroid Build Coastguard Worker // When coming from a compiled method, the return PC for managed stack walk is RA. 181*795d594fSAndroid Build Coastguard Worker // (When coming from a compiled stub, the correct return PC is already stored above.) 182*795d594fSAndroid Build Coastguard Worker sd ra, (FRAME_SIZE_SAVE_REFS_AND_ARGS - __SIZEOF_POINTER__)(fp) 183*795d594fSAndroid Build Coastguard Worker 184*795d594fSAndroid Build Coastguard Worker // Replace the target method with the SaveRefsAndArgs runtime method. 185*795d594fSAndroid Build Coastguard Worker LOAD_RUNTIME_INSTANCE t0 186*795d594fSAndroid Build Coastguard Worker ld t0, RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET(t0) 187*795d594fSAndroid Build Coastguard Worker 188*795d594fSAndroid Build Coastguard Worker mv t1, fp // Prepare untagged managed SP for the runtime method. 189*795d594fSAndroid Build Coastguard Worker 190*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_prepare_runtime_method: 191*795d594fSAndroid Build Coastguard Worker // Store the method on the bottom of the managed frame. 192*795d594fSAndroid Build Coastguard Worker sd t0, (fp) 193*795d594fSAndroid Build Coastguard Worker 194*795d594fSAndroid Build Coastguard Worker // Place (maybe tagged) managed SP in Thread::Current()->top_quick_frame. 195*795d594fSAndroid Build Coastguard Worker sd t1, THREAD_TOP_QUICK_FRAME_OFFSET(xSELF) 196*795d594fSAndroid Build Coastguard Worker 197*795d594fSAndroid Build Coastguard Worker // Preserve the native arg register A0 in callee-save register S2 (x18) which was saved above. 198*795d594fSAndroid Build Coastguard Worker mv s2, a0 199*795d594fSAndroid Build Coastguard Worker 200*795d594fSAndroid Build Coastguard Worker // Call artFindNativeMethodRunnable() 201*795d594fSAndroid Build Coastguard Worker mv a0, xSELF // pass Thread::Current() 202*795d594fSAndroid Build Coastguard Worker call artFindNativeMethodRunnable 203*795d594fSAndroid Build Coastguard Worker 204*795d594fSAndroid Build Coastguard Worker // Store result in scratch reg. 205*795d594fSAndroid Build Coastguard Worker mv t0, a0 206*795d594fSAndroid Build Coastguard Worker 207*795d594fSAndroid Build Coastguard Worker // Restore the native arg register A0. 208*795d594fSAndroid Build Coastguard Worker mv a0, s2 209*795d594fSAndroid Build Coastguard Worker 210*795d594fSAndroid Build Coastguard Worker // Restore our return PC. 211*795d594fSAndroid Build Coastguard Worker RESTORE_GPR_BASE fp, ra, -__SIZEOF_POINTER__ 212*795d594fSAndroid Build Coastguard Worker 213*795d594fSAndroid Build Coastguard Worker // Remember the end of out args before restoring FP. 214*795d594fSAndroid Build Coastguard Worker addi t1, fp, -16 215*795d594fSAndroid Build Coastguard Worker 216*795d594fSAndroid Build Coastguard Worker // Restore arg registers. 217*795d594fSAndroid Build Coastguard Worker fld fa0, (1*8)(fp) 218*795d594fSAndroid Build Coastguard Worker fld fa1, (2*8)(fp) 219*795d594fSAndroid Build Coastguard Worker fld fa2, (3*8)(fp) 220*795d594fSAndroid Build Coastguard Worker fld fa3, (4*8)(fp) 221*795d594fSAndroid Build Coastguard Worker fld fa4, (5*8)(fp) 222*795d594fSAndroid Build Coastguard Worker fld fa5, (6*8)(fp) 223*795d594fSAndroid Build Coastguard Worker fld fa6, (7*8)(fp) 224*795d594fSAndroid Build Coastguard Worker fld fa7, (8*8)(fp) 225*795d594fSAndroid Build Coastguard Worker // fp (x8) is restored last to keep CFI data valid until then. 226*795d594fSAndroid Build Coastguard Worker // s1 (x9) is the ART thread register 227*795d594fSAndroid Build Coastguard Worker // a0 (x10) is the method pointer 228*795d594fSAndroid Build Coastguard Worker ld a1, (10*8)(fp) // x11 229*795d594fSAndroid Build Coastguard Worker ld a2, (11*8)(fp) // x12 230*795d594fSAndroid Build Coastguard Worker ld a3, (12*8)(fp) // x13 231*795d594fSAndroid Build Coastguard Worker ld a4, (13*8)(fp) // x14 232*795d594fSAndroid Build Coastguard Worker ld a5, (14*8)(fp) // x15 233*795d594fSAndroid Build Coastguard Worker ld a6, (15*8)(fp) // x16 234*795d594fSAndroid Build Coastguard Worker ld a7, (16*8)(fp) // x17 235*795d594fSAndroid Build Coastguard Worker RESTORE_GPR_BASE fp, s2, (17*8) // x18 236*795d594fSAndroid Build Coastguard Worker RESTORE_GPR_BASE fp, s3, (18*8) // x19 237*795d594fSAndroid Build Coastguard Worker RESTORE_GPR_BASE fp, s4, (19*8) // x20 238*795d594fSAndroid Build Coastguard Worker RESTORE_GPR_BASE fp, s5, (20*8) // x21 239*795d594fSAndroid Build Coastguard Worker RESTORE_GPR_BASE fp, s6, (21*8) // x22 240*795d594fSAndroid Build Coastguard Worker RESTORE_GPR_BASE fp, s7, (22*8) // x23 241*795d594fSAndroid Build Coastguard Worker RESTORE_GPR_BASE fp, s8, (23*8) // x24 242*795d594fSAndroid Build Coastguard Worker RESTORE_GPR_BASE fp, s9, (24*8) // x25 243*795d594fSAndroid Build Coastguard Worker RESTORE_GPR_BASE fp, s10, (25*8) // x26 244*795d594fSAndroid Build Coastguard Worker RESTORE_GPR_BASE fp, s11, (26*8) // x27 245*795d594fSAndroid Build Coastguard Worker RESTORE_GPR_BASE fp, fp, (9*8) // fp (x8) is restored last 246*795d594fSAndroid Build Coastguard Worker 247*795d594fSAndroid Build Coastguard Worker // Check for exception before moving args back to keep the return PC for managed stack walk. 248*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 249*795d594fSAndroid Build Coastguard Worker beqz t0, .Lcritical_deliver_exception 250*795d594fSAndroid Build Coastguard Worker 251*795d594fSAndroid Build Coastguard Worker // Move stack args to their original place. 252*795d594fSAndroid Build Coastguard Worker beq t1, sp, .Lcritical_skip_copy_args_back 253*795d594fSAndroid Build Coastguard Worker sub t2, t1, sp 254*795d594fSAndroid Build Coastguard Worker.Lcritical_copy_args_back_loop: 255*795d594fSAndroid Build Coastguard Worker ld t3, 0-16(t1) 256*795d594fSAndroid Build Coastguard Worker ld t4, 8-16(t1) 257*795d594fSAndroid Build Coastguard Worker addi t2, t2, -16 258*795d594fSAndroid Build Coastguard Worker sd t3, FRAME_SIZE_SAVE_REFS_AND_ARGS+0(t1) 259*795d594fSAndroid Build Coastguard Worker sd t4, FRAME_SIZE_SAVE_REFS_AND_ARGS+8(t1) 260*795d594fSAndroid Build Coastguard Worker addi t1, t1, -16 261*795d594fSAndroid Build Coastguard Worker bnez t2, .Lcritical_copy_args_back_loop 262*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_copy_args_back: 263*795d594fSAndroid Build Coastguard Worker 264*795d594fSAndroid Build Coastguard Worker // Remove the frame reservation. 265*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME (FRAME_SIZE_SAVE_REFS_AND_ARGS + 16) 266*795d594fSAndroid Build Coastguard Worker 267*795d594fSAndroid Build Coastguard Worker // Do the tail call. 268*795d594fSAndroid Build Coastguard Worker jr t0 269*795d594fSAndroid Build Coastguard Worker 270*795d594fSAndroid Build Coastguard Worker.Lcritical_deliver_exception: 271*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_AND_ARGS + 16 272*795d594fSAndroid Build Coastguard Worker // If this is called from a method that catches the exception, all callee-save registers need 273*795d594fSAndroid Build Coastguard Worker // to be saved, so that the exception handling code can read them in case they contain live 274*795d594fSAndroid Build Coastguard Worker // values later used by that method. This includes callee-save FP registers which are not 275*795d594fSAndroid Build Coastguard Worker // saved in a SaveRefsAndArgs frame, so we cannot reuse the managed frame we have built above. 276*795d594fSAndroid Build Coastguard Worker // That's why we checked for exception after restoring registers from that frame. 277*795d594fSAndroid Build Coastguard Worker // We need to build a SaveAllCalleeSaves frame instead. Args are irrelevant at this 278*795d594fSAndroid Build Coastguard Worker // point but keep the area allocated for stack args to keep CFA definition simple. 279*795d594fSAndroid Build Coastguard Worker#if FRAME_SIZE_SAVE_ALL_CALLEE_SAVES > FRAME_SIZE_SAVE_REFS_AND_ARGS 280*795d594fSAndroid Build Coastguard Worker#error "Expanding stack frame from kSaveRefsAndArgs to kSaveAllCalleeSaves is not implemented." 281*795d594fSAndroid Build Coastguard Worker#endif 282*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS - FRAME_SIZE_SAVE_ALL_CALLEE_SAVES 283*795d594fSAndroid Build Coastguard Worker 284*795d594fSAndroid Build Coastguard Worker // Calculate the base address of the managed frame. 285*795d594fSAndroid Build Coastguard Worker addi t1, t1, 16 + FRAME_SIZE_SAVE_REFS_AND_ARGS - FRAME_SIZE_SAVE_ALL_CALLEE_SAVES 286*795d594fSAndroid Build Coastguard Worker 287*795d594fSAndroid Build Coastguard Worker // Spill registers for the SaveAllCalleeSaves frame above the stack args area. Do not update 288*795d594fSAndroid Build Coastguard Worker // CFI while we hold the frame address in T1 and the values in registers are unchanged. 289*795d594fSAndroid Build Coastguard Worker // stack slot (0*8)(t1) is for ArtMethod* 290*795d594fSAndroid Build Coastguard Worker // stack slot (1*8)(t1) is for padding 291*795d594fSAndroid Build Coastguard Worker // FP callee-saves. 292*795d594fSAndroid Build Coastguard Worker fsd fs0, (8*2)(t1) // f8 293*795d594fSAndroid Build Coastguard Worker fsd fs1, (8*3)(t1) // f9 294*795d594fSAndroid Build Coastguard Worker fsd fs2, (8*4)(t1) // f18 295*795d594fSAndroid Build Coastguard Worker fsd fs3, (8*5)(t1) // f19 296*795d594fSAndroid Build Coastguard Worker fsd fs4, (8*6)(t1) // f20 297*795d594fSAndroid Build Coastguard Worker fsd fs5, (8*7)(t1) // f21 298*795d594fSAndroid Build Coastguard Worker fsd fs6, (8*8)(t1) // f22 299*795d594fSAndroid Build Coastguard Worker fsd fs7, (8*9)(t1) // f23 300*795d594fSAndroid Build Coastguard Worker fsd fs8, (8*10)(t1) // f24 301*795d594fSAndroid Build Coastguard Worker fsd fs9, (8*11)(t1) // f25 302*795d594fSAndroid Build Coastguard Worker fsd fs10, (8*12)(t1) // f26 303*795d594fSAndroid Build Coastguard Worker fsd fs11, (8*13)(t1) // f27 304*795d594fSAndroid Build Coastguard Worker // GP callee-saves 305*795d594fSAndroid Build Coastguard Worker sd s0, (8*14)(t1) // x8/fp, frame pointer 306*795d594fSAndroid Build Coastguard Worker // s1 (x9) is the ART thread register 307*795d594fSAndroid Build Coastguard Worker sd s2, (8*15)(t1) // x18 308*795d594fSAndroid Build Coastguard Worker sd s3, (8*16)(t1) // x19 309*795d594fSAndroid Build Coastguard Worker sd s4, (8*17)(t1) // x20 310*795d594fSAndroid Build Coastguard Worker sd s5, (8*18)(t1) // x21 311*795d594fSAndroid Build Coastguard Worker sd s6, (8*19)(t1) // x22 312*795d594fSAndroid Build Coastguard Worker sd s7, (8*20)(t1) // x23 313*795d594fSAndroid Build Coastguard Worker sd s8, (8*21)(t1) // x24 314*795d594fSAndroid Build Coastguard Worker sd s9, (8*22)(t1) // x25 315*795d594fSAndroid Build Coastguard Worker sd s10, (8*23)(t1) // x26 316*795d594fSAndroid Build Coastguard Worker sd s11, (8*24)(t1) // x27 317*795d594fSAndroid Build Coastguard Worker // Keep the caller PC for managed stack walk. 318*795d594fSAndroid Build Coastguard Worker 319*795d594fSAndroid Build Coastguard Worker // Move the managed frame address to native callee-save register fp (x8) and update CFI. 320*795d594fSAndroid Build Coastguard Worker mv fp, t1 321*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 8, 8, (14*8) // fp/x8: The base register for these CFI expressions. 322*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG /*FP reg*/ 32 + 8, 8, (8*2) // fs0/f8 323*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG /*FP reg*/ 32 + 9, 8, (8*3) // fs1/f9 324*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG /*FP reg*/ 32 + 18, 8, (8*4) // fs2/f18 325*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG /*FP reg*/ 32 + 19, 8, (8*5) // fs3/f19 326*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG /*FP reg*/ 32 + 20, 8, (8*6) // fs4/f20 327*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG /*FP reg*/ 32 + 21, 8, (8*7) // fs5/f21 328*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG /*FP reg*/ 32 + 22, 8, (8*8) // fs6/f22 329*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG /*FP reg*/ 32 + 23, 8, (8*9) // fs7/f23 330*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG /*FP reg*/ 32 + 24, 8, (8*10) // fs8/f24 331*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG /*FP reg*/ 32 + 25, 8, (8*11) // fs9/f25 332*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG /*FP reg*/ 32 + 26, 8, (8*12) // fs10/f26 333*795d594fSAndroid Build Coastguard Worker // CFI expression for fp (x8) already emitted above. 334*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 18, 8, (15*8) // s2/x18 335*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 19, 8, (16*8) // s3/x19 336*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 20, 8, (17*8) // s4/x20 337*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 21, 8, (18*8) // s5/x21 338*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 22, 8, (19*8) // s6/x22 339*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 23, 8, (20*8) // s7/x23 340*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 24, 8, (21*8) // s8/x24 341*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 25, 8, (22*8) // s9/x25 342*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 26, 8, (23*8) // s10/x26 343*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 27, 8, (24*8) // s11/x27 344*795d594fSAndroid Build Coastguard Worker // The saved return PC for managed stack walk is not necessarily our RA. 345*795d594fSAndroid Build Coastguard Worker 346*795d594fSAndroid Build Coastguard Worker // Save our return PC below the managed frame. 347*795d594fSAndroid Build Coastguard Worker sd ra, -__SIZEOF_POINTER__(fp) 348*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG 1, 8, -__SIZEOF_POINTER__ 349*795d594fSAndroid Build Coastguard Worker 350*795d594fSAndroid Build Coastguard Worker // Store ArtMethod* Runtime::callee_save_methods_[kSaveAllCalleeSaves] to the managed frame. 351*795d594fSAndroid Build Coastguard Worker LOAD_RUNTIME_INSTANCE t0 352*795d594fSAndroid Build Coastguard Worker ld t0, RUNTIME_SAVE_ALL_CALLEE_SAVES_METHOD_OFFSET(t0) 353*795d594fSAndroid Build Coastguard Worker sd t0, (fp) 354*795d594fSAndroid Build Coastguard Worker 355*795d594fSAndroid Build Coastguard Worker // Place the managed frame SP in Thread::Current()->top_quick_frame. 356*795d594fSAndroid Build Coastguard Worker sd fp, THREAD_TOP_QUICK_FRAME_OFFSET(xSELF) 357*795d594fSAndroid Build Coastguard Worker 358*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION_FRAME_READY 359*795d594fSAndroid Build Coastguard WorkerEND art_jni_dlsym_lookup_critical_stub 360*795d594fSAndroid Build Coastguard Worker 361*795d594fSAndroid Build Coastguard Worker /* 362*795d594fSAndroid Build Coastguard Worker * Read barrier for the method's declaring class needed by JNI stub for static methods. 363*795d594fSAndroid Build Coastguard Worker * (We're using a pointer to the declaring class in `ArtMethod` as `jclass`.) 364*795d594fSAndroid Build Coastguard Worker */ 365*795d594fSAndroid Build Coastguard Worker// The method argument is already in a0 for call to `artJniReadBarrier(ArtMethod*)`. 366*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_read_barrier, artJniReadBarrier 367*795d594fSAndroid Build Coastguard Worker 368*795d594fSAndroid Build Coastguard Worker /* 369*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMethodStart()` that preserves all managed arguments. 370*795d594fSAndroid Build Coastguard Worker */ 371*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_method_start, artJniMethodStart, xSELF 372*795d594fSAndroid Build Coastguard Worker 373*795d594fSAndroid Build Coastguard Worker /* 374*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMethodEntryHook` that preserves all managed arguments. 375*795d594fSAndroid Build Coastguard Worker */ 376*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_method_entry_hook, artJniMethodEntryHook, xSELF 377*795d594fSAndroid Build Coastguard Worker 378*795d594fSAndroid Build Coastguard Worker /* 379*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMonitoredMethodStart()` that preserves all managed arguments. 380*795d594fSAndroid Build Coastguard Worker */ 381*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_monitored_method_start, artJniMonitoredMethodStart, xSELF 382*795d594fSAndroid Build Coastguard Worker 383*795d594fSAndroid Build Coastguard Worker /* 384*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMethodEnd()` that preserves all return registers. 385*795d594fSAndroid Build Coastguard Worker */ 386*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_method_end, artJniMethodEnd, xSELF 387*795d594fSAndroid Build Coastguard Worker 388*795d594fSAndroid Build Coastguard Worker /* 389*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMonitoredMethodEnd()` that preserves all return registers. 390*795d594fSAndroid Build Coastguard Worker */ 391*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_monitored_method_end, artJniMonitoredMethodEnd, xSELF 392*795d594fSAndroid Build Coastguard Worker 393*795d594fSAndroid Build Coastguard Worker /* 394*795d594fSAndroid Build Coastguard Worker * Entry from JNI stub that tries to lock the object in a fast path and 395*795d594fSAndroid Build Coastguard Worker * calls `artLockObjectFromCode()` (the same as for managed code) for the 396*795d594fSAndroid Build Coastguard Worker * difficult cases, may block for GC. 397*795d594fSAndroid Build Coastguard Worker * Custom calling convention: 398*795d594fSAndroid Build Coastguard Worker * T0 holds the non-null object to lock. 399*795d594fSAndroid Build Coastguard Worker * Callee-save registers have been saved and can be used as temporaries. 400*795d594fSAndroid Build Coastguard Worker * All argument registers need to be preserved. 401*795d594fSAndroid Build Coastguard Worker */ 402*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_lock_object 403*795d594fSAndroid Build Coastguard Worker LOCK_OBJECT_FAST_PATH t0, art_jni_lock_object_no_inline, /*can_be_null*/ 0 404*795d594fSAndroid Build Coastguard WorkerEND art_jni_lock_object 405*795d594fSAndroid Build Coastguard Worker 406*795d594fSAndroid Build Coastguard Worker /* 407*795d594fSAndroid Build Coastguard Worker * Entry from JNI stub that calls `artLockObjectFromCode()` 408*795d594fSAndroid Build Coastguard Worker * (the same as for managed code), may block for GC. 409*795d594fSAndroid Build Coastguard Worker * Custom calling convention: 410*795d594fSAndroid Build Coastguard Worker * T0 holds the non-null object to lock. 411*795d594fSAndroid Build Coastguard Worker * Callee-save registers have been saved and can be used as temporaries. 412*795d594fSAndroid Build Coastguard Worker * All argument registers need to be preserved. 413*795d594fSAndroid Build Coastguard Worker */ 414*795d594fSAndroid Build Coastguard Worker .extern artLockObjectFromCode 415*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_lock_object_no_inline 416*795d594fSAndroid Build Coastguard Worker // This is also the slow path for art_jni_lock_object. 417*795d594fSAndroid Build Coastguard Worker // Save args and RA. 418*795d594fSAndroid Build Coastguard Worker SAVE_ALL_ARGS_INCREASE_FRAME /*padding*/ 8 + /*RA*/ 8 419*795d594fSAndroid Build Coastguard Worker SAVE_GPR ra, (ALL_ARGS_SIZE + /*padding*/ 8) 420*795d594fSAndroid Build Coastguard Worker // Call `artLockObjectFromCode()`. 421*795d594fSAndroid Build Coastguard Worker mv a0, t0 // Pass the object to lock. 422*795d594fSAndroid Build Coastguard Worker mv a1, xSELF // Pass Thread::Current(). 423*795d594fSAndroid Build Coastguard Worker call artLockObjectFromCode // (Object* obj, Thread*) 424*795d594fSAndroid Build Coastguard Worker // Restore return address. 425*795d594fSAndroid Build Coastguard Worker RESTORE_GPR ra, (ALL_ARGS_SIZE + /*padding*/ 8) 426*795d594fSAndroid Build Coastguard Worker // Check result. 427*795d594fSAndroid Build Coastguard Worker bnez a0, 1f 428*795d594fSAndroid Build Coastguard Worker // Restore register args a0-a7, fa0-fa7 and return. 429*795d594fSAndroid Build Coastguard Worker RESTORE_ALL_ARGS_DECREASE_FRAME /*padding*/ 8 + /*RA*/ 8 430*795d594fSAndroid Build Coastguard Worker ret 431*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset (ALL_ARGS_SIZE + /*padding*/ 8 + /*RA*/ 8) 432*795d594fSAndroid Build Coastguard Worker1: 433*795d594fSAndroid Build Coastguard Worker // All args are irrelevant when throwing an exception. Remove the spill area. 434*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME (ALL_ARGS_SIZE + /*padding*/ 8 + /*RA*/ 8) 435*795d594fSAndroid Build Coastguard Worker // Make a call to `artDeliverPendingExceptionFromCode()`. 436*795d594fSAndroid Build Coastguard Worker // Rely on the JNI transition frame constructed in the JNI stub. 437*795d594fSAndroid Build Coastguard Worker mv a0, xSELF // Pass Thread::Current(). 438*795d594fSAndroid Build Coastguard Worker call artDeliverPendingExceptionFromCode // (Thread*) 439*795d594fSAndroid Build Coastguard Worker call art_quick_do_long_jump // (Context*) 440*795d594fSAndroid Build Coastguard Worker unimp // Unreached 441*795d594fSAndroid Build Coastguard WorkerEND art_jni_lock_object_no_inline 442*795d594fSAndroid Build Coastguard Worker 443*795d594fSAndroid Build Coastguard Worker /* 444*795d594fSAndroid Build Coastguard Worker * Entry from JNI stub that tries to unlock the object in a fast path and calls 445*795d594fSAndroid Build Coastguard Worker * `artJniUnlockObject()` for the difficult cases. Note that failure to unlock 446*795d594fSAndroid Build Coastguard Worker * is fatal, so we do not need to check for exceptions in the slow path. 447*795d594fSAndroid Build Coastguard Worker * Custom calling convention: 448*795d594fSAndroid Build Coastguard Worker * T0 holds the non-null object to unlock. 449*795d594fSAndroid Build Coastguard Worker * Callee-save registers have been saved and can be used as temporaries. 450*795d594fSAndroid Build Coastguard Worker * Return registers a0 and fa0 need to be preserved. 451*795d594fSAndroid Build Coastguard Worker */ 452*795d594fSAndroid Build Coastguard WorkerENTRY art_jni_unlock_object 453*795d594fSAndroid Build Coastguard Worker UNLOCK_OBJECT_FAST_PATH t0, art_jni_unlock_object_no_inline, /*can_be_null*/ 0 454*795d594fSAndroid Build Coastguard WorkerEND art_jni_unlock_object 455*795d594fSAndroid Build Coastguard Worker 456*795d594fSAndroid Build Coastguard Worker /* 457*795d594fSAndroid Build Coastguard Worker * Entry from JNI stub that calls `artJniUnlockObject()`. Note that failure to 458*795d594fSAndroid Build Coastguard Worker * unlock is fatal, so we do not need to check for exceptions. 459*795d594fSAndroid Build Coastguard Worker * Custom calling convention: 460*795d594fSAndroid Build Coastguard Worker * T0 holds the non-null object to unlock. 461*795d594fSAndroid Build Coastguard Worker * Callee-save registers have been saved and can be used as temporaries. 462*795d594fSAndroid Build Coastguard Worker * Return registers a0 and fa0 need to be preserved. 463*795d594fSAndroid Build Coastguard Worker */ 464*795d594fSAndroid Build Coastguard Worker // This is also the slow path for art_jni_unlock_object. 465*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_unlock_object_no_inline, artJniUnlockObject, t0, xSELF 466