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_x86.S" 18*795d594fSAndroid Build Coastguard Worker 19*795d594fSAndroid Build Coastguard Worker#define MANAGED_ARGS_SAVE_SIZE /*xmm0-xmm3*/ 4 * 8 + /*padding*/ 4 + /* GPR args */ 4 * 4 20*795d594fSAndroid Build Coastguard Worker 21*795d594fSAndroid Build Coastguard Worker// Save register args and adds space for outgoing arguments. 22*795d594fSAndroid Build Coastguard Worker// With `call_args_space = 0`, the ESP shall be 8-byte aligned but not 16-byte aligned, 23*795d594fSAndroid Build Coastguard Worker// so either the `call_args_space` should be 8 (or 24, 40, ...) or the user of the macro 24*795d594fSAndroid Build Coastguard Worker// needs to adjust the ESP explicitly afterwards. 25*795d594fSAndroid Build Coastguard WorkerMACRO1(SAVE_MANAGED_ARGS_INCREASE_FRAME, call_args_space) 26*795d594fSAndroid Build Coastguard Worker // Return address is on the stack. 27*795d594fSAndroid Build Coastguard Worker PUSH_ARG ebx 28*795d594fSAndroid Build Coastguard Worker PUSH_ARG edx 29*795d594fSAndroid Build Coastguard Worker PUSH_ARG ecx 30*795d594fSAndroid Build Coastguard Worker PUSH_ARG eax 31*795d594fSAndroid Build Coastguard Worker // Make xmm<n> spill slots 8-byte aligned. 32*795d594fSAndroid Build Coastguard Worker INCREASE_FRAME (\call_args_space + /*FPRs*/ 4 * 8 + /*padding*/ 4) 33*795d594fSAndroid Build Coastguard Worker movsd %xmm0, \call_args_space + 0(%esp) 34*795d594fSAndroid Build Coastguard Worker movsd %xmm1, \call_args_space + 8(%esp) 35*795d594fSAndroid Build Coastguard Worker movsd %xmm2, \call_args_space + 16(%esp) 36*795d594fSAndroid Build Coastguard Worker movsd %xmm3, \call_args_space + 24(%esp) 37*795d594fSAndroid Build Coastguard WorkerEND_MACRO 38*795d594fSAndroid Build Coastguard Worker 39*795d594fSAndroid Build Coastguard WorkerMACRO1(RESTORE_MANAGED_ARGS_DECREASE_FRAME, call_args_space) 40*795d594fSAndroid Build Coastguard Worker movsd \call_args_space + 0(%esp), %xmm0 41*795d594fSAndroid Build Coastguard Worker movsd \call_args_space + 8(%esp), %xmm1 42*795d594fSAndroid Build Coastguard Worker movsd \call_args_space + 16(%esp), %xmm2 43*795d594fSAndroid Build Coastguard Worker movsd \call_args_space + 24(%esp), %xmm3 44*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME \call_args_space + /*FPR args*/ 4 * 8 + /*padding*/ 4 45*795d594fSAndroid Build Coastguard Worker POP_ARG eax 46*795d594fSAndroid Build Coastguard Worker POP_ARG ecx 47*795d594fSAndroid Build Coastguard Worker POP_ARG edx 48*795d594fSAndroid Build Coastguard Worker POP_ARG ebx 49*795d594fSAndroid Build Coastguard WorkerEND_MACRO 50*795d594fSAndroid Build Coastguard Worker 51*795d594fSAndroid Build Coastguard WorkerMACRO3(JNI_SAVE_MANAGED_ARGS_TRAMPOLINE, name, cxx_name, arg1) 52*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION \name 53*795d594fSAndroid Build Coastguard Worker // Note: Managed callee-save registers have been saved by the JNI stub. 54*795d594fSAndroid Build Coastguard Worker // Save register args EAX, ECX, EDX, EBX, mmx0-mmx3, add and padding above `arg1`. 55*795d594fSAndroid Build Coastguard Worker SAVE_MANAGED_ARGS_INCREASE_FRAME /*padding*/ 4 56*795d594fSAndroid Build Coastguard Worker // Call `cxx_name()`. 57*795d594fSAndroid Build Coastguard Worker PUSH_ARG RAW_VAR(arg1) // Pass arg1. 58*795d594fSAndroid Build Coastguard Worker call CALLVAR(cxx_name) // Call cxx_name(...). 59*795d594fSAndroid Build Coastguard Worker // Restore register args EAX, ECX, EDX, EBX, mmx0-mmx3 and return. 60*795d594fSAndroid Build Coastguard Worker RESTORE_MANAGED_ARGS_DECREASE_FRAME /*arg1*/ 4 + /*padding*/ 4 61*795d594fSAndroid Build Coastguard Worker ret 62*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION \name 63*795d594fSAndroid Build Coastguard WorkerEND_MACRO 64*795d594fSAndroid Build Coastguard Worker 65*795d594fSAndroid Build Coastguard WorkerMACRO4(JNI_SAVE_RETURN_VALUE_TRAMPOLINE, name, cxx_name, arg1, arg2) 66*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION \name 67*795d594fSAndroid Build Coastguard Worker // Save return registers. 68*795d594fSAndroid Build Coastguard Worker PUSH_ARG edx 69*795d594fSAndroid Build Coastguard Worker PUSH_ARG eax 70*795d594fSAndroid Build Coastguard Worker .ifnc \arg2, none 71*795d594fSAndroid Build Coastguard Worker INCREASE_FRAME /*mmx0*/ 8 + /*padding*/ 4 72*795d594fSAndroid Build Coastguard Worker movsd %xmm0, 0(%esp) 73*795d594fSAndroid Build Coastguard Worker PUSH_ARG RAW_VAR(arg2) // Pass arg2. 74*795d594fSAndroid Build Coastguard Worker .else 75*795d594fSAndroid Build Coastguard Worker INCREASE_FRAME /*padding*/ 4 + /*mmx0*/ 8 + /*padding*/ 4 76*795d594fSAndroid Build Coastguard Worker movsd %xmm0, 4(%esp) 77*795d594fSAndroid Build Coastguard Worker .endif 78*795d594fSAndroid Build Coastguard Worker // Call `cxx_name()`. 79*795d594fSAndroid Build Coastguard Worker PUSH_ARG RAW_VAR(arg1) // Pass arg1. 80*795d594fSAndroid Build Coastguard Worker call CALLVAR(cxx_name) // Call cxx_name(...). 81*795d594fSAndroid Build Coastguard Worker // Restore return registers and return. 82*795d594fSAndroid Build Coastguard Worker movsd 8(%esp), %xmm0 83*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME /*call args*/ 8 + /*xmm0*/ 8 + /*padding*/ 4 84*795d594fSAndroid Build Coastguard Worker POP_ARG eax 85*795d594fSAndroid Build Coastguard Worker POP_ARG edx 86*795d594fSAndroid Build Coastguard Worker ret 87*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION \name 88*795d594fSAndroid Build Coastguard WorkerEND_MACRO 89*795d594fSAndroid Build Coastguard Worker 90*795d594fSAndroid Build Coastguard Worker /* 91*795d594fSAndroid Build Coastguard Worker * Jni dlsym lookup stub for @CriticalNative. 92*795d594fSAndroid Build Coastguard Worker */ 93*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_jni_dlsym_lookup_critical_stub 94*795d594fSAndroid Build Coastguard Worker // The hidden arg holding the tagged method (bit 0 set means GenericJNI) is eax. 95*795d594fSAndroid Build Coastguard Worker // For Generic JNI we already have a managed frame, so we reuse the art_jni_dlsym_lookup_stub. 96*795d594fSAndroid Build Coastguard Worker testl LITERAL(1), %eax 97*795d594fSAndroid Build Coastguard Worker jnz art_jni_dlsym_lookup_stub 98*795d594fSAndroid Build Coastguard Worker 99*795d594fSAndroid Build Coastguard Worker // Since the native call args are all on the stack, we can use the managed args 100*795d594fSAndroid Build Coastguard Worker // registers as scratch registers. So, EBX, EDX and ECX are available. 101*795d594fSAndroid Build Coastguard Worker 102*795d594fSAndroid Build Coastguard Worker // Load caller PC. 103*795d594fSAndroid Build Coastguard Worker movl (%esp), %ecx 104*795d594fSAndroid Build Coastguard Worker 105*795d594fSAndroid Build Coastguard Worker // Save the caller method from the hidden arg. 106*795d594fSAndroid Build Coastguard Worker PUSH_ARG eax 107*795d594fSAndroid Build Coastguard Worker 108*795d594fSAndroid Build Coastguard Worker // Call artCriticalNativeFrameSize(method, caller_pc). 109*795d594fSAndroid Build Coastguard Worker PUSH_ARG ecx // Pass caller PC. 110*795d594fSAndroid Build Coastguard Worker PUSH_ARG eax // Pass method. 111*795d594fSAndroid Build Coastguard Worker call SYMBOL(artCriticalNativeFrameSize) // (method, caller_pc) 112*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME 8 // Remove args. 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Worker // Restore method register to EBX. 115*795d594fSAndroid Build Coastguard Worker POP_ARG ebx 116*795d594fSAndroid Build Coastguard Worker 117*795d594fSAndroid Build Coastguard Worker // Load caller PC to EDX and redefine return PC for CFI. 118*795d594fSAndroid Build Coastguard Worker movl (%esp), %edx 119*795d594fSAndroid Build Coastguard Worker CFI_REGISTER(%eip, %edx) 120*795d594fSAndroid Build Coastguard Worker 121*795d594fSAndroid Build Coastguard Worker // Reserve space for a SaveRefsAndArgs managed frame, either for the actual runtime 122*795d594fSAndroid Build Coastguard Worker // method or for a GenericJNI frame which is similar but has a native method and a tag. 123*795d594fSAndroid Build Coastguard Worker INCREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS - __SIZEOF_POINTER__ 124*795d594fSAndroid Build Coastguard Worker 125*795d594fSAndroid Build Coastguard Worker // Calculate the number of DWORDs to move. 126*795d594fSAndroid Build Coastguard Worker movl %eax, %ecx 127*795d594fSAndroid Build Coastguard Worker shrl LITERAL(2), %ecx 128*795d594fSAndroid Build Coastguard Worker jecxz .Lcritical_skip_copy_args 129*795d594fSAndroid Build Coastguard Worker 130*795d594fSAndroid Build Coastguard Worker // Save EDI, ESI so that we can use them for moving stack args. 131*795d594fSAndroid Build Coastguard Worker PUSH edi 132*795d594fSAndroid Build Coastguard Worker PUSH esi 133*795d594fSAndroid Build Coastguard Worker 134*795d594fSAndroid Build Coastguard Worker // Move the stack args. 135*795d594fSAndroid Build Coastguard Worker leal 2 * __SIZEOF_POINTER__(%esp), %edi 136*795d594fSAndroid Build Coastguard Worker leal FRAME_SIZE_SAVE_REFS_AND_ARGS(%edi), %esi 137*795d594fSAndroid Build Coastguard Worker rep movsd 138*795d594fSAndroid Build Coastguard Worker 139*795d594fSAndroid Build Coastguard Worker // Restore EDI, ESI. 140*795d594fSAndroid Build Coastguard Worker POP esi 141*795d594fSAndroid Build Coastguard Worker POP edi 142*795d594fSAndroid Build Coastguard Worker 143*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_copy_args: 144*795d594fSAndroid Build Coastguard Worker // Calculate the base address of the managed frame. 145*795d594fSAndroid Build Coastguard Worker leal (%esp, %eax, 1), %eax 146*795d594fSAndroid Build Coastguard Worker 147*795d594fSAndroid Build Coastguard Worker leal 1(%eax), %ecx // Prepare managed SP tagged for a GenericJNI frame. 148*795d594fSAndroid Build Coastguard Worker testl LITERAL(ACCESS_FLAGS_METHOD_IS_NATIVE), ART_METHOD_ACCESS_FLAGS_OFFSET(%ebx) 149*795d594fSAndroid Build Coastguard Worker jnz .Lcritical_skip_prepare_runtime_method 150*795d594fSAndroid Build Coastguard Worker 151*795d594fSAndroid Build Coastguard Worker // Save the return PC for managed stack walk. 152*795d594fSAndroid Build Coastguard Worker // (When coming from a compiled stub, the correct return PC is already there.) 153*795d594fSAndroid Build Coastguard Worker movl %edx, FRAME_SIZE_SAVE_REFS_AND_ARGS - __SIZEOF_POINTER__(%eax) 154*795d594fSAndroid Build Coastguard Worker 155*795d594fSAndroid Build Coastguard Worker // Replace the target method with the SaveRefsAndArgs runtime method. 156*795d594fSAndroid Build Coastguard Worker LOAD_RUNTIME_INSTANCE ebx 157*795d594fSAndroid Build Coastguard Worker movl RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET(%ebx), %ebx 158*795d594fSAndroid Build Coastguard Worker 159*795d594fSAndroid Build Coastguard Worker movl %eax, %ecx // Prepare untagged managed SP for the runtime method. 160*795d594fSAndroid Build Coastguard Worker 161*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_prepare_runtime_method: 162*795d594fSAndroid Build Coastguard Worker // Store the method on the bottom of the managed frame. 163*795d594fSAndroid Build Coastguard Worker movl %ebx, (%eax) 164*795d594fSAndroid Build Coastguard Worker 165*795d594fSAndroid Build Coastguard Worker // Move the managed frame address to native callee-save register EBX. 166*795d594fSAndroid Build Coastguard Worker movl %eax, %ebx 167*795d594fSAndroid Build Coastguard Worker 168*795d594fSAndroid Build Coastguard Worker // Spill registers for the SaveRefsAndArgs frame above the stack args. 169*795d594fSAndroid Build Coastguard Worker movl %edi, 56(%ebx) 170*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG CFI_REG(edi), CFI_REG(ebx), 56 171*795d594fSAndroid Build Coastguard Worker movl %esi, 52(%ebx) 172*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG CFI_REG(esi), CFI_REG(ebx), 52 173*795d594fSAndroid Build Coastguard Worker movl %ebp, 48(%ebx) 174*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG CFI_REG(ebp), CFI_REG(ebx), 48 175*795d594fSAndroid Build Coastguard Worker // Skip managed ABI args EBX, EDX, ECX and FPRs. The runtime shall not examine the 176*795d594fSAndroid Build Coastguard Worker // args in the managed frame. (We have already clobbered EBX, EDX, ECX anyway.) 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 movl %ecx, %fs:THREAD_TOP_QUICK_FRAME_OFFSET 180*795d594fSAndroid Build Coastguard Worker 181*795d594fSAndroid Build Coastguard Worker // Save our return PC in a slot reserved for first FP arg in managed ABI. 182*795d594fSAndroid Build Coastguard Worker movl %edx, __SIZEOF_POINTER__(%ebx) 183*795d594fSAndroid Build Coastguard Worker CFI_EXPRESSION_BREG CFI_REG(eip), CFI_REG(ebx), __SIZEOF_POINTER__ 184*795d594fSAndroid Build Coastguard Worker 185*795d594fSAndroid Build Coastguard Worker // Call artFindNativeMethodRunnable() 186*795d594fSAndroid Build Coastguard Worker INCREASE_FRAME 12 // Align stack. 187*795d594fSAndroid Build Coastguard Worker pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 188*795d594fSAndroid Build Coastguard Worker CFI_ADJUST_CFA_OFFSET(4) 189*795d594fSAndroid Build Coastguard Worker call SYMBOL(artFindNativeMethodRunnable) // (Thread*) 190*795d594fSAndroid Build Coastguard Worker addl LITERAL(16), %esp 191*795d594fSAndroid Build Coastguard Worker CFI_ADJUST_CFA_OFFSET(-16) 192*795d594fSAndroid Build Coastguard Worker 193*795d594fSAndroid Build Coastguard Worker // Check for exception. 194*795d594fSAndroid Build Coastguard Worker test %eax, %eax 195*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 196*795d594fSAndroid Build Coastguard Worker jz .Lcritical_deliver_exception 197*795d594fSAndroid Build Coastguard Worker 198*795d594fSAndroid Build Coastguard Worker // Remember our return PC in EDX. 199*795d594fSAndroid Build Coastguard Worker movl __SIZEOF_POINTER__(%ebx), %edx 200*795d594fSAndroid Build Coastguard Worker CFI_REGISTER(%eip, %edx) 201*795d594fSAndroid Build Coastguard Worker 202*795d594fSAndroid Build Coastguard Worker // Restore callee-save registers from the frame. We shall not need the method anymore. 203*795d594fSAndroid Build Coastguard Worker movl 48(%ebx), %ebp 204*795d594fSAndroid Build Coastguard Worker CFI_RESTORE(%ebp) 205*795d594fSAndroid Build Coastguard Worker movl 52(%ebx), %esi 206*795d594fSAndroid Build Coastguard Worker CFI_RESTORE(%esi) 207*795d594fSAndroid Build Coastguard Worker movl 56(%ebx), %edi 208*795d594fSAndroid Build Coastguard Worker CFI_RESTORE(%edi) 209*795d594fSAndroid Build Coastguard Worker 210*795d594fSAndroid Build Coastguard Worker // Calculate the number of DWORDs to move. 211*795d594fSAndroid Build Coastguard Worker movl %ebx, %ecx 212*795d594fSAndroid Build Coastguard Worker subl %esp, %ecx 213*795d594fSAndroid Build Coastguard Worker shrl LITERAL(2), %ecx 214*795d594fSAndroid Build Coastguard Worker jecxz .Lcritical_skip_copy_args_back 215*795d594fSAndroid Build Coastguard Worker 216*795d594fSAndroid Build Coastguard Worker // Save EDI, ESI so that we can use them for moving stack args. 217*795d594fSAndroid Build Coastguard Worker PUSH edi 218*795d594fSAndroid Build Coastguard Worker PUSH esi 219*795d594fSAndroid Build Coastguard Worker 220*795d594fSAndroid Build Coastguard Worker // Move stack args to their original place. 221*795d594fSAndroid Build Coastguard Worker leal -__SIZEOF_POINTER__(%ebx), %esi 222*795d594fSAndroid Build Coastguard Worker leal FRAME_SIZE_SAVE_REFS_AND_ARGS - __SIZEOF_POINTER__(%ebx), %edi 223*795d594fSAndroid Build Coastguard Worker std 224*795d594fSAndroid Build Coastguard Worker rep movsd 225*795d594fSAndroid Build Coastguard Worker cld 226*795d594fSAndroid Build Coastguard Worker 227*795d594fSAndroid Build Coastguard Worker // Restore EDI, ESI. 228*795d594fSAndroid Build Coastguard Worker POP esi 229*795d594fSAndroid Build Coastguard Worker POP edi 230*795d594fSAndroid Build Coastguard Worker 231*795d594fSAndroid Build Coastguard Worker.Lcritical_skip_copy_args_back: 232*795d594fSAndroid Build Coastguard Worker // Remove the frame reservation. 233*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS - __SIZEOF_POINTER__ 234*795d594fSAndroid Build Coastguard Worker 235*795d594fSAndroid Build Coastguard Worker // Store our return PC. 236*795d594fSAndroid Build Coastguard Worker movl %edx, (%esp) 237*795d594fSAndroid Build Coastguard Worker CFI_REL_OFFSET(%eip, 0) 238*795d594fSAndroid Build Coastguard Worker 239*795d594fSAndroid Build Coastguard Worker // Do the tail call. 240*795d594fSAndroid Build Coastguard Worker jmp *%eax 241*795d594fSAndroid Build Coastguard Worker 242*795d594fSAndroid Build Coastguard Worker.Lcritical_deliver_exception: 243*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA %esp, FRAME_SIZE_SAVE_REFS_AND_ARGS 244*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION_FRAME_READY 245*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_jni_dlsym_lookup_critical_stub 246*795d594fSAndroid Build Coastguard Worker 247*795d594fSAndroid Build Coastguard Worker /* 248*795d594fSAndroid Build Coastguard Worker * Read barrier for the method's declaring class needed by JNI stub for static methods. 249*795d594fSAndroid Build Coastguard Worker * (We're using a pointer to the declaring class in `ArtMethod` as `jclass`.) 250*795d594fSAndroid Build Coastguard Worker */ 251*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_read_barrier, artJniReadBarrier, eax 252*795d594fSAndroid Build Coastguard Worker 253*795d594fSAndroid Build Coastguard Worker /* 254*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMethodStart()` that preserves all managed arguments. 255*795d594fSAndroid Build Coastguard Worker */ 256*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_method_start, artJniMethodStart, fs:THREAD_SELF_OFFSET 257*795d594fSAndroid Build Coastguard Worker 258*795d594fSAndroid Build Coastguard Worker /* 259*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMethodEntryHook` that preserves all managed arguments. 260*795d594fSAndroid Build Coastguard Worker */ 261*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE \ 262*795d594fSAndroid Build Coastguard Worker art_jni_method_entry_hook, artJniMethodEntryHook, fs:THREAD_SELF_OFFSET 263*795d594fSAndroid Build Coastguard Worker 264*795d594fSAndroid Build Coastguard Worker /* 265*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMonitoredMethodStart()` that preserves all managed arguments. 266*795d594fSAndroid Build Coastguard Worker */ 267*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_MANAGED_ARGS_TRAMPOLINE \ 268*795d594fSAndroid Build Coastguard Worker art_jni_monitored_method_start, artJniMonitoredMethodStart, fs:THREAD_SELF_OFFSET 269*795d594fSAndroid Build Coastguard Worker 270*795d594fSAndroid Build Coastguard Worker /* 271*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMethodEnd()` that preserves all return registers. 272*795d594fSAndroid Build Coastguard Worker */ 273*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_method_end, artJniMethodEnd, fs:THREAD_SELF_OFFSET, none 274*795d594fSAndroid Build Coastguard Worker 275*795d594fSAndroid Build Coastguard Worker /* 276*795d594fSAndroid Build Coastguard Worker * Trampoline to `artJniMonitoredMethodEnd()` that preserves all return registers. 277*795d594fSAndroid Build Coastguard Worker */ 278*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE \ 279*795d594fSAndroid Build Coastguard Worker art_jni_monitored_method_end, artJniMonitoredMethodEnd, fs:THREAD_SELF_OFFSET, none 280*795d594fSAndroid Build Coastguard Worker 281*795d594fSAndroid Build Coastguard Worker /* 282*795d594fSAndroid Build Coastguard Worker * Entry from JNI stub that tries to lock the object in a fast path and 283*795d594fSAndroid Build Coastguard Worker * calls `artLockObjectFromCode()` (the same as for managed code) for the 284*795d594fSAndroid Build Coastguard Worker * difficult cases, may block for GC. 285*795d594fSAndroid Build Coastguard Worker * Custom calling convention: 286*795d594fSAndroid Build Coastguard Worker * EBP holds the non-null object to lock. 287*795d594fSAndroid Build Coastguard Worker * Callee-save registers have been saved and can be used as temporaries (except EBP). 288*795d594fSAndroid Build Coastguard Worker * All argument registers need to be preserved. 289*795d594fSAndroid Build Coastguard Worker */ 290*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_jni_lock_object 291*795d594fSAndroid Build Coastguard Worker movl %eax, %edi // Preserve EAX in a callee-save register. 292*795d594fSAndroid Build Coastguard Worker LOCK_OBJECT_FAST_PATH ebp, esi, /*saved_eax*/ edi .Llock_object_jni_slow 293*795d594fSAndroid Build Coastguard Worker 294*795d594fSAndroid Build Coastguard Worker.Llock_object_jni_slow: 295*795d594fSAndroid Build Coastguard Worker movl %edi, %eax // Restore EAX. 296*795d594fSAndroid Build Coastguard Worker jmp SYMBOL(art_jni_lock_object_no_inline) 297*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_jni_lock_object 298*795d594fSAndroid Build Coastguard Worker 299*795d594fSAndroid Build Coastguard Worker /* 300*795d594fSAndroid Build Coastguard Worker * Entry from JNI stub that calls `artLockObjectFromCode()` 301*795d594fSAndroid Build Coastguard Worker * (the same as for managed code), may block for GC. 302*795d594fSAndroid Build Coastguard Worker * Custom calling convention: 303*795d594fSAndroid Build Coastguard Worker * EBP holds the non-null object to lock. 304*795d594fSAndroid Build Coastguard Worker * Callee-save registers have been saved and can be used as temporaries (except EBP). 305*795d594fSAndroid Build Coastguard Worker * All argument registers need to be preserved. 306*795d594fSAndroid Build Coastguard Worker */ 307*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_jni_lock_object_no_inline 308*795d594fSAndroid Build Coastguard Worker // This is also the slow path for art_jni_lock_object. 309*795d594fSAndroid Build Coastguard Worker // Save register args EAX, ECX, EDX, EBX, mmx0-mmx3; original value of EAX is in EDI. 310*795d594fSAndroid Build Coastguard Worker SAVE_MANAGED_ARGS_INCREASE_FRAME /*call_args_space*/ 0 311*795d594fSAndroid Build Coastguard Worker // Note: The stack is not 16-byte aligned here but it shall be after pushing args for the call. 312*795d594fSAndroid Build Coastguard Worker // Call `artLockObjectFromCode()` 313*795d594fSAndroid Build Coastguard Worker pushl %fs:THREAD_SELF_OFFSET // Pass Thread::Current(). 314*795d594fSAndroid Build Coastguard Worker CFI_ADJUST_CFA_OFFSET(4) 315*795d594fSAndroid Build Coastguard Worker PUSH_ARG ebp // Pass the object to lock. 316*795d594fSAndroid Build Coastguard Worker call SYMBOL(artLockObjectFromCode) // (object, Thread*) 317*795d594fSAndroid Build Coastguard Worker // Check result. 318*795d594fSAndroid Build Coastguard Worker testl %eax, %eax 319*795d594fSAndroid Build Coastguard Worker jnz 1f 320*795d594fSAndroid Build Coastguard Worker // Restore register args EAX, ECX, EDX, EBX, mmx0-mmx3 and return. 321*795d594fSAndroid Build Coastguard Worker RESTORE_MANAGED_ARGS_DECREASE_FRAME /*call_args_space*/ 8 322*795d594fSAndroid Build Coastguard Worker ret 323*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset (/*call args*/ 8 + MANAGED_ARGS_SAVE_SIZE) 324*795d594fSAndroid Build Coastguard Worker1: 325*795d594fSAndroid Build Coastguard Worker // All args are irrelevant when throwing an exception. 326*795d594fSAndroid Build Coastguard Worker // Remove the spill area except for new padding to align stack. 327*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME (/*call args*/ 8 + MANAGED_ARGS_SAVE_SIZE - /*new padding*/ 8) 328*795d594fSAndroid Build Coastguard Worker // Rely on the JNI transition frame constructed in the JNI stub. 329*795d594fSAndroid Build Coastguard Worker pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current() 330*795d594fSAndroid Build Coastguard Worker CFI_ADJUST_CFA_OFFSET(4) 331*795d594fSAndroid Build Coastguard Worker call SYMBOL(artDeliverPendingExceptionFromCode) // (Thread*) 332*795d594fSAndroid Build Coastguard Worker call SYMBOL(art_quick_do_long_jump) 333*795d594fSAndroid Build Coastguard Worker UNREACHABLE 334*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_jni_lock_object_no_inline 335*795d594fSAndroid Build Coastguard Worker 336*795d594fSAndroid Build Coastguard Worker /* 337*795d594fSAndroid Build Coastguard Worker * Entry from JNI stub that tries to unlock the object in a fast path and calls 338*795d594fSAndroid Build Coastguard Worker * `artJniUnlockObject()` for the difficult cases. Note that failure to unlock 339*795d594fSAndroid Build Coastguard Worker * is fatal, so we do not need to check for exceptions in the slow path. 340*795d594fSAndroid Build Coastguard Worker * Custom calling convention: 341*795d594fSAndroid Build Coastguard Worker * EBP holds the non-null object to unlock. 342*795d594fSAndroid Build Coastguard Worker * Callee-save registers have been saved and can be used as temporaries (except EBP). 343*795d594fSAndroid Build Coastguard Worker * Return registers EAX, EDX and mmx0 need to be preserved. 344*795d594fSAndroid Build Coastguard Worker */ 345*795d594fSAndroid Build Coastguard WorkerDEFINE_FUNCTION art_jni_unlock_object 346*795d594fSAndroid Build Coastguard Worker movl %eax, %edi // Preserve EAX in a different register. 347*795d594fSAndroid Build Coastguard Worker UNLOCK_OBJECT_FAST_PATH ebp, esi, /*saved_eax*/ edi, .Lunlock_object_jni_slow 348*795d594fSAndroid Build Coastguard Worker 349*795d594fSAndroid Build Coastguard Worker .Lunlock_object_jni_slow: 350*795d594fSAndroid Build Coastguard Worker movl %edi, %eax // Restore EAX. 351*795d594fSAndroid Build Coastguard Worker jmp SYMBOL(art_jni_unlock_object_no_inline) 352*795d594fSAndroid Build Coastguard WorkerEND_FUNCTION art_jni_unlock_object 353*795d594fSAndroid Build Coastguard Worker 354*795d594fSAndroid Build Coastguard Worker /* 355*795d594fSAndroid Build Coastguard Worker * Entry from JNI stub that calls `artJniUnlockObject()`. Note that failure to 356*795d594fSAndroid Build Coastguard Worker * unlock is fatal, so we do not need to check for exceptions. 357*795d594fSAndroid Build Coastguard Worker * Custom calling convention: 358*795d594fSAndroid Build Coastguard Worker * EBP holds the non-null object to unlock. 359*795d594fSAndroid Build Coastguard Worker * Callee-save registers have been saved and can be used as temporaries (except EBP). 360*795d594fSAndroid Build Coastguard Worker * Return registers EAX, EDX and mmx0 need to be preserved. 361*795d594fSAndroid Build Coastguard Worker */ 362*795d594fSAndroid Build Coastguard Worker // This is also the slow path for art_jni_unlock_object. 363*795d594fSAndroid Build Coastguard WorkerJNI_SAVE_RETURN_VALUE_TRAMPOLINE \ 364*795d594fSAndroid Build Coastguard Worker art_jni_unlock_object_no_inline, artJniUnlockObject, ebp, fs:THREAD_SELF_OFFSET 365