1*795d594fSAndroid Build Coastguard Worker/* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker#include "asm_support_arm.S" 18*795d594fSAndroid Build Coastguard Worker#include "interpreter/cfi_asm_support.h" 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker#include "arch/quick_alloc_entrypoints.S" 21*795d594fSAndroid Build Coastguard Worker#include "arch/quick_field_entrypoints.S" 22*795d594fSAndroid Build Coastguard Worker 23*795d594fSAndroid Build Coastguard Worker /* Deliver the given exception */ 24*795d594fSAndroid Build Coastguard Worker .extern artDeliverExceptionFromCode 25*795d594fSAndroid Build Coastguard Worker /* Deliver an exception pending on a thread */ 26*795d594fSAndroid Build Coastguard Worker .extern artDeliverPendingException 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker.macro SETUP_SAVE_REFS_AND_ARGS_FRAME rTemp 29*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY 30*795d594fSAndroid Build Coastguard Worker LOAD_RUNTIME_INSTANCE \rTemp @ Load Runtime::Current into rTemp. 31*795d594fSAndroid Build Coastguard Worker @ Load kSaveRefsAndArgs Method* into rTemp. 32*795d594fSAndroid Build Coastguard Worker ldr \rTemp, [\rTemp, #RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET] 33*795d594fSAndroid Build Coastguard Worker str \rTemp, [sp, #0] @ Place Method* at bottom of stack. 34*795d594fSAndroid Build Coastguard Worker str sp, [rSELF, #THREAD_TOP_QUICK_FRAME_OFFSET] @ Place sp in Thread::Current()->top_quick_frame. 35*795d594fSAndroid Build Coastguard Worker.endm 36*795d594fSAndroid Build Coastguard Worker 37*795d594fSAndroid Build Coastguard Worker.macro SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_R0 38*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_AND_ARGS_FRAME_REGISTERS_ONLY 39*795d594fSAndroid Build Coastguard Worker str r0, [sp, #0] @ Store ArtMethod* to bottom of stack. 40*795d594fSAndroid Build Coastguard Worker str sp, [rSELF, #THREAD_TOP_QUICK_FRAME_OFFSET] @ Place sp in Thread::Current()->top_quick_frame. 41*795d594fSAndroid Build Coastguard Worker.endm 42*795d594fSAndroid Build Coastguard Worker 43*795d594fSAndroid Build Coastguard Worker /* 44*795d594fSAndroid Build Coastguard Worker * Macro that sets up the callee save frame to conform with 45*795d594fSAndroid Build Coastguard Worker * Runtime::CreateCalleeSaveMethod(kSaveEverything) 46*795d594fSAndroid Build Coastguard Worker * when core registers are already saved. 47*795d594fSAndroid Build Coastguard Worker */ 48*795d594fSAndroid Build Coastguard Worker.macro SETUP_SAVE_EVERYTHING_FRAME_CORE_REGS_SAVED rTemp, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET 49*795d594fSAndroid Build Coastguard Worker @ 14 words of callee saves and args already saved. 50*795d594fSAndroid Build Coastguard Worker vpush {d0-d15} @ 32 words, 2 for each of the 16 saved doubles. 51*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 128 52*795d594fSAndroid Build Coastguard Worker sub sp, #8 @ 2 words of space, alignment padding and Method* 53*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 8 54*795d594fSAndroid Build Coastguard Worker LOAD_RUNTIME_INSTANCE \rTemp @ Load Runtime::Current into rTemp. 55*795d594fSAndroid Build Coastguard Worker @ Load kSaveEverything Method* into rTemp. 56*795d594fSAndroid Build Coastguard Worker ldr \rTemp, [\rTemp, #\runtime_method_offset] 57*795d594fSAndroid Build Coastguard Worker str \rTemp, [sp, #0] @ Place Method* at bottom of stack. 58*795d594fSAndroid Build Coastguard Worker str sp, [rSELF, #THREAD_TOP_QUICK_FRAME_OFFSET] @ Place sp in Thread::Current()->top_quick_frame. 59*795d594fSAndroid Build Coastguard Worker 60*795d594fSAndroid Build Coastguard Worker // Ugly compile-time check, but we only have the preprocessor. 61*795d594fSAndroid Build Coastguard Worker#if (FRAME_SIZE_SAVE_EVERYTHING != 56 + 128 + 8) 62*795d594fSAndroid Build Coastguard Worker#error "FRAME_SIZE_SAVE_EVERYTHING(ARM) size not as expected." 63*795d594fSAndroid Build Coastguard Worker#endif 64*795d594fSAndroid Build Coastguard Worker.endm 65*795d594fSAndroid Build Coastguard Worker 66*795d594fSAndroid Build Coastguard Worker /* 67*795d594fSAndroid Build Coastguard Worker * Macro that sets up the callee save frame to conform with 68*795d594fSAndroid Build Coastguard Worker * Runtime::CreateCalleeSaveMethod(kSaveEverything) 69*795d594fSAndroid Build Coastguard Worker */ 70*795d594fSAndroid Build Coastguard Worker.macro SETUP_SAVE_EVERYTHING_FRAME rTemp, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET 71*795d594fSAndroid Build Coastguard Worker push {r0-r12, lr} @ 14 words of callee saves and args. 72*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 56 73*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r0, 0 74*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r1, 4 75*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r2, 8 76*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r3, 12 77*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r4, 16 78*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r5, 20 79*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r6, 24 80*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r7, 28 81*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r8, 32 82*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r9, 36 83*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r10, 40 84*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r11, 44 85*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset ip, 48 86*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 52 87*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_EVERYTHING_FRAME_CORE_REGS_SAVED \rTemp, \runtime_method_offset 88*795d594fSAndroid Build Coastguard Worker.endm 89*795d594fSAndroid Build Coastguard Worker 90*795d594fSAndroid Build Coastguard Worker.macro RESTORE_SAVE_EVERYTHING_FRAME 91*795d594fSAndroid Build Coastguard Worker add sp, #8 @ rewind sp 92*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -8 93*795d594fSAndroid Build Coastguard Worker vpop {d0-d15} 94*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -128 95*795d594fSAndroid Build Coastguard Worker pop {r0-r12, lr} @ 14 words of callee saves 96*795d594fSAndroid Build Coastguard Worker .cfi_restore r0 97*795d594fSAndroid Build Coastguard Worker .cfi_restore r1 98*795d594fSAndroid Build Coastguard Worker .cfi_restore r2 99*795d594fSAndroid Build Coastguard Worker .cfi_restore r3 100*795d594fSAndroid Build Coastguard Worker .cfi_restore r4 101*795d594fSAndroid Build Coastguard Worker .cfi_restore r5 102*795d594fSAndroid Build Coastguard Worker .cfi_restore r6 103*795d594fSAndroid Build Coastguard Worker .cfi_restore r7 104*795d594fSAndroid Build Coastguard Worker .cfi_restore r8 105*795d594fSAndroid Build Coastguard Worker .cfi_restore r9 106*795d594fSAndroid Build Coastguard Worker .cfi_restore r10 107*795d594fSAndroid Build Coastguard Worker .cfi_restore r11 108*795d594fSAndroid Build Coastguard Worker .cfi_restore r12 109*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 110*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -56 111*795d594fSAndroid Build Coastguard Worker.endm 112*795d594fSAndroid Build Coastguard Worker 113*795d594fSAndroid Build Coastguard Worker.macro RESTORE_SAVE_EVERYTHING_FRAME_KEEP_R0 114*795d594fSAndroid Build Coastguard Worker add sp, #8 @ rewind sp 115*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -8 116*795d594fSAndroid Build Coastguard Worker vpop {d0-d15} 117*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -128 118*795d594fSAndroid Build Coastguard Worker add sp, #4 @ skip r0 119*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -4 120*795d594fSAndroid Build Coastguard Worker .cfi_restore r0 @ debugger can no longer restore caller's r0 121*795d594fSAndroid Build Coastguard Worker pop {r1-r12, lr} @ 13 words of callee saves 122*795d594fSAndroid Build Coastguard Worker .cfi_restore r1 123*795d594fSAndroid Build Coastguard Worker .cfi_restore r2 124*795d594fSAndroid Build Coastguard Worker .cfi_restore r3 125*795d594fSAndroid Build Coastguard Worker .cfi_restore r4 126*795d594fSAndroid Build Coastguard Worker .cfi_restore r5 127*795d594fSAndroid Build Coastguard Worker .cfi_restore r6 128*795d594fSAndroid Build Coastguard Worker .cfi_restore r7 129*795d594fSAndroid Build Coastguard Worker .cfi_restore r8 130*795d594fSAndroid Build Coastguard Worker .cfi_restore r9 131*795d594fSAndroid Build Coastguard Worker .cfi_restore r10 132*795d594fSAndroid Build Coastguard Worker .cfi_restore r11 133*795d594fSAndroid Build Coastguard Worker .cfi_restore r12 134*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 135*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -52 136*795d594fSAndroid Build Coastguard Worker.endm 137*795d594fSAndroid Build Coastguard Worker 138*795d594fSAndroid Build Coastguard Worker.macro RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION is_ref = 0 139*795d594fSAndroid Build Coastguard Worker // Use R2 to allow returning 64-bit values in R0-R1. 140*795d594fSAndroid Build Coastguard Worker ldr r2, [rSELF, # THREAD_EXCEPTION_OFFSET] // Get exception field. 141*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 142*795d594fSAndroid Build Coastguard Worker cbnz r2, 1f 143*795d594fSAndroid Build Coastguard Worker DEOPT_OR_RETURN r2, \is_ref // Check if deopt is required 144*795d594fSAndroid Build Coastguard Worker1: 145*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, 0 146*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION 147*795d594fSAndroid Build Coastguard Worker.endm 148*795d594fSAndroid Build Coastguard Worker 149*795d594fSAndroid Build Coastguard Worker.macro RETURN_REF_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION 150*795d594fSAndroid Build Coastguard Worker RETURN_OR_DEOPT_OR_DELIVER_PENDING_EXCEPTION /* is_ref= */ 1 151*795d594fSAndroid Build Coastguard Worker.endm 152*795d594fSAndroid Build Coastguard Worker 153*795d594fSAndroid Build Coastguard Worker.macro DEOPT_OR_RETURN temp, is_ref = 0 154*795d594fSAndroid Build Coastguard Worker ldr \temp, [rSELF, #THREAD_DEOPT_CHECK_REQUIRED_OFFSET] 155*795d594fSAndroid Build Coastguard Worker cbnz \temp, 2f 156*795d594fSAndroid Build Coastguard Worker bx lr 157*795d594fSAndroid Build Coastguard Worker2: 158*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_EVERYTHING_FRAME \temp 159*795d594fSAndroid Build Coastguard Worker mov r2, \is_ref // pass if result is a reference 160*795d594fSAndroid Build Coastguard Worker mov r1, r0 // pass the result 161*795d594fSAndroid Build Coastguard Worker mov r0, rSELF // Thread::Current 162*795d594fSAndroid Build Coastguard Worker bl artDeoptimizeIfNeeded 163*795d594fSAndroid Build Coastguard Worker 164*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 165*795d594fSAndroid Build Coastguard Worker cbnz r0, 3f 166*795d594fSAndroid Build Coastguard Worker 167*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_EVERYTHING_FRAME 168*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 169*795d594fSAndroid Build Coastguard Worker bx lr 170*795d594fSAndroid Build Coastguard Worker 171*795d594fSAndroid Build Coastguard Worker3: 172*795d594fSAndroid Build Coastguard Worker // Deoptimize 173*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_EVERYTHING 174*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump // (Context*) 175*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 176*795d594fSAndroid Build Coastguard Worker.endm 177*795d594fSAndroid Build Coastguard Worker 178*795d594fSAndroid Build Coastguard Worker.macro DEOPT_OR_RESTORE_SAVE_EVERYTHING_FRAME_AND_RETURN_R0 temp, is_ref 179*795d594fSAndroid Build Coastguard Worker ldr \temp, [rSELF, #THREAD_DEOPT_CHECK_REQUIRED_OFFSET] 180*795d594fSAndroid Build Coastguard Worker cbnz \temp, 2f 181*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 182*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_EVERYTHING_FRAME_KEEP_R0 183*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 184*795d594fSAndroid Build Coastguard Worker bx lr 185*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_EVERYTHING 186*795d594fSAndroid Build Coastguard Worker2: 187*795d594fSAndroid Build Coastguard Worker str r0, [sp, SAVE_EVERYTHING_FRAME_R0_OFFSET] // update result in the frame 188*795d594fSAndroid Build Coastguard Worker mov r2, \is_ref // pass if result is a reference 189*795d594fSAndroid Build Coastguard Worker mov r1, r0 // pass the result 190*795d594fSAndroid Build Coastguard Worker mov r0, rSELF // Thread::Current 191*795d594fSAndroid Build Coastguard Worker bl artDeoptimizeIfNeeded 192*795d594fSAndroid Build Coastguard Worker 193*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 194*795d594fSAndroid Build Coastguard Worker cbnz r0, 3f 195*795d594fSAndroid Build Coastguard Worker 196*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_EVERYTHING_FRAME 197*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 198*795d594fSAndroid Build Coastguard Worker bx lr 199*795d594fSAndroid Build Coastguard Worker 200*795d594fSAndroid Build Coastguard Worker3: 201*795d594fSAndroid Build Coastguard Worker // Deoptimize 202*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_EVERYTHING 203*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump // (Context*) 204*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 205*795d594fSAndroid Build Coastguard Worker.endm 206*795d594fSAndroid Build Coastguard Worker 207*795d594fSAndroid Build Coastguard Worker.macro NO_ARG_RUNTIME_EXCEPTION c_name, cxx_name 208*795d594fSAndroid Build Coastguard Worker .extern \cxx_name 209*795d594fSAndroid Build Coastguard WorkerENTRY \c_name 210*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_ALL_CALLEE_SAVES_FRAME r0 @ save all registers as basis for long jump context 211*795d594fSAndroid Build Coastguard Worker mov r0, rSELF @ pass Thread::Current 212*795d594fSAndroid Build Coastguard Worker bl \cxx_name @ \cxx_name(Thread*) 213*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 214*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 215*795d594fSAndroid Build Coastguard WorkerEND \c_name 216*795d594fSAndroid Build Coastguard Worker.endm 217*795d594fSAndroid Build Coastguard Worker 218*795d594fSAndroid Build Coastguard Worker.macro NO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING c_name, cxx_name 219*795d594fSAndroid Build Coastguard Worker .extern \cxx_name 220*795d594fSAndroid Build Coastguard WorkerENTRY \c_name 221*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_EVERYTHING_FRAME r0 @ save all registers as basis for long jump context 222*795d594fSAndroid Build Coastguard Worker mov r0, rSELF @ pass Thread::Current 223*795d594fSAndroid Build Coastguard Worker bl \cxx_name @ \cxx_name(Thread*) 224*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 225*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 226*795d594fSAndroid Build Coastguard WorkerEND \c_name 227*795d594fSAndroid Build Coastguard Worker.endm 228*795d594fSAndroid Build Coastguard Worker 229*795d594fSAndroid Build Coastguard Worker.macro ONE_ARG_RUNTIME_EXCEPTION c_name, cxx_name 230*795d594fSAndroid Build Coastguard Worker .extern \cxx_name 231*795d594fSAndroid Build Coastguard WorkerENTRY \c_name 232*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_ALL_CALLEE_SAVES_FRAME r1 @ save all registers as basis for long jump context 233*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ pass Thread::Current 234*795d594fSAndroid Build Coastguard Worker bl \cxx_name @ \cxx_name(Thread*) 235*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 236*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 237*795d594fSAndroid Build Coastguard WorkerEND \c_name 238*795d594fSAndroid Build Coastguard Worker.endm 239*795d594fSAndroid Build Coastguard Worker 240*795d594fSAndroid Build Coastguard Worker.macro TWO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING c_name, cxx_name 241*795d594fSAndroid Build Coastguard Worker .extern \cxx_name 242*795d594fSAndroid Build Coastguard WorkerENTRY \c_name 243*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_EVERYTHING_FRAME r2 @ save all registers as basis for long jump context 244*795d594fSAndroid Build Coastguard Worker mov r2, rSELF @ pass Thread::Current 245*795d594fSAndroid Build Coastguard Worker bl \cxx_name @ \cxx_name(Thread*) 246*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 247*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 248*795d594fSAndroid Build Coastguard WorkerEND \c_name 249*795d594fSAndroid Build Coastguard Worker.endm 250*795d594fSAndroid Build Coastguard Worker 251*795d594fSAndroid Build Coastguard Worker.macro RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER 252*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 253*795d594fSAndroid Build Coastguard Worker cbnz r0, 1f @ result non-zero branch over 254*795d594fSAndroid Build Coastguard Worker DEOPT_OR_RETURN r1 255*795d594fSAndroid Build Coastguard Worker1: 256*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, 0 257*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION 258*795d594fSAndroid Build Coastguard Worker.endm 259*795d594fSAndroid Build Coastguard Worker 260*795d594fSAndroid Build Coastguard Worker.macro RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER 261*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 262*795d594fSAndroid Build Coastguard Worker cbz r0, 1f @ result zero branch over 263*795d594fSAndroid Build Coastguard Worker DEOPT_OR_RETURN r1, /* is_ref= */ 1 264*795d594fSAndroid Build Coastguard Worker1: 265*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, 0 266*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION 267*795d594fSAndroid Build Coastguard Worker.endm 268*795d594fSAndroid Build Coastguard Worker 269*795d594fSAndroid Build Coastguard Worker// Macros taking opportunity of code similarities for downcalls. 270*795d594fSAndroid Build Coastguard Worker// Used for field and allocation entrypoints. 271*795d594fSAndroid Build Coastguard Worker.macro N_ARG_DOWNCALL n, name, entrypoint, return 272*795d594fSAndroid Build Coastguard Worker .extern \entrypoint 273*795d594fSAndroid Build Coastguard WorkerENTRY \name 274*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_ONLY_FRAME r\n @ save callee saves in case of GC 275*795d594fSAndroid Build Coastguard Worker mov r\n, rSELF @ pass Thread::Current 276*795d594fSAndroid Build Coastguard Worker bl \entrypoint @ (<args>, Thread*) 277*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME 278*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 279*795d594fSAndroid Build Coastguard Worker \return 280*795d594fSAndroid Build Coastguard WorkerEND \name 281*795d594fSAndroid Build Coastguard Worker.endm 282*795d594fSAndroid Build Coastguard Worker 283*795d594fSAndroid Build Coastguard Worker.macro ONE_ARG_DOWNCALL name, entrypoint, return 284*795d594fSAndroid Build Coastguard Worker N_ARG_DOWNCALL 1, \name, \entrypoint, \return 285*795d594fSAndroid Build Coastguard Worker.endm 286*795d594fSAndroid Build Coastguard Worker 287*795d594fSAndroid Build Coastguard Worker.macro TWO_ARG_DOWNCALL name, entrypoint, return 288*795d594fSAndroid Build Coastguard Worker N_ARG_DOWNCALL 2, \name, \entrypoint, \return 289*795d594fSAndroid Build Coastguard Worker.endm 290*795d594fSAndroid Build Coastguard Worker 291*795d594fSAndroid Build Coastguard Worker.macro THREE_ARG_DOWNCALL name, entrypoint, return 292*795d594fSAndroid Build Coastguard Worker N_ARG_DOWNCALL 3, \name, \entrypoint, \return 293*795d594fSAndroid Build Coastguard Worker.endm 294*795d594fSAndroid Build Coastguard Worker 295*795d594fSAndroid Build Coastguard Worker// Macro to facilitate adding new allocation entrypoints. 296*795d594fSAndroid Build Coastguard Worker.macro FOUR_ARG_DOWNCALL name, entrypoint, return 297*795d594fSAndroid Build Coastguard Worker .extern \entrypoint 298*795d594fSAndroid Build Coastguard WorkerENTRY \name 299*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_ONLY_FRAME r12 @ save callee saves in case of GC 300*795d594fSAndroid Build Coastguard Worker str rSELF, [sp, #-16]! @ expand the frame and pass Thread::Current 301*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 16 302*795d594fSAndroid Build Coastguard Worker bl \entrypoint @ (<args>, Thread*) 303*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME 16 @ strip the extra frame 304*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME 305*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 306*795d594fSAndroid Build Coastguard Worker \return 307*795d594fSAndroid Build Coastguard WorkerEND \name 308*795d594fSAndroid Build Coastguard Worker.endm 309*795d594fSAndroid Build Coastguard Worker 310*795d594fSAndroid Build Coastguard Worker /* 311*795d594fSAndroid Build Coastguard Worker * Called by managed code, saves callee saves and then calls artThrowException 312*795d594fSAndroid Build Coastguard Worker * that will place a mock Method* at the bottom of the stack. Arg1 holds the exception. 313*795d594fSAndroid Build Coastguard Worker */ 314*795d594fSAndroid Build Coastguard WorkerONE_ARG_RUNTIME_EXCEPTION art_quick_deliver_exception, artDeliverExceptionFromCode 315*795d594fSAndroid Build Coastguard Worker 316*795d594fSAndroid Build Coastguard Worker /* 317*795d594fSAndroid Build Coastguard Worker * Called by managed code to create and deliver a NullPointerException. 318*795d594fSAndroid Build Coastguard Worker */ 319*795d594fSAndroid Build Coastguard WorkerNO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING art_quick_throw_null_pointer_exception, artThrowNullPointerExceptionFromCode 320*795d594fSAndroid Build Coastguard Worker 321*795d594fSAndroid Build Coastguard Worker /* 322*795d594fSAndroid Build Coastguard Worker * Call installed by a signal handler to create and deliver a NullPointerException. 323*795d594fSAndroid Build Coastguard Worker */ 324*795d594fSAndroid Build Coastguard Worker .extern art_quick_throw_null_pointer_exception_from_signal 325*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_throw_null_pointer_exception_from_signal 326*795d594fSAndroid Build Coastguard Worker // The fault handler pushes the gc map address, i.e. "return address", to stack 327*795d594fSAndroid Build Coastguard Worker // and passes the fault address in LR. So we need to set up the CFI info accordingly. 328*795d594fSAndroid Build Coastguard Worker .cfi_def_cfa_offset __SIZEOF_POINTER__ 329*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 0 330*795d594fSAndroid Build Coastguard Worker push {r0-r12} @ 13 words of callee saves and args; LR already saved. 331*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 52 332*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r0, 0 333*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r1, 4 334*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r2, 8 335*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r3, 12 336*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r4, 16 337*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r5, 20 338*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r6, 24 339*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r7, 28 340*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r8, 32 341*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r9, 36 342*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r10, 40 343*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r11, 44 344*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset ip, 48 345*795d594fSAndroid Build Coastguard Worker 346*795d594fSAndroid Build Coastguard Worker @ save all registers as basis for long jump context 347*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_EVERYTHING_FRAME_CORE_REGS_SAVED r1 348*795d594fSAndroid Build Coastguard Worker mov r0, lr @ pass the fault address stored in LR by the fault handler. 349*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ pass Thread::Current 350*795d594fSAndroid Build Coastguard Worker bl artThrowNullPointerExceptionFromSignal @ (Thread*) 351*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 352*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 353*795d594fSAndroid Build Coastguard WorkerEND art_quick_throw_null_pointer_exception_from_signal 354*795d594fSAndroid Build Coastguard Worker 355*795d594fSAndroid Build Coastguard Worker /* 356*795d594fSAndroid Build Coastguard Worker * Called by managed code to create and deliver an ArithmeticException. 357*795d594fSAndroid Build Coastguard Worker */ 358*795d594fSAndroid Build Coastguard WorkerNO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING art_quick_throw_div_zero, artThrowDivZeroFromCode 359*795d594fSAndroid Build Coastguard Worker 360*795d594fSAndroid Build Coastguard Worker /* 361*795d594fSAndroid Build Coastguard Worker * Called by managed code to create and deliver an ArrayIndexOutOfBoundsException. Arg1 holds 362*795d594fSAndroid Build Coastguard Worker * index, arg2 holds limit. 363*795d594fSAndroid Build Coastguard Worker */ 364*795d594fSAndroid Build Coastguard WorkerTWO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING art_quick_throw_array_bounds, artThrowArrayBoundsFromCode 365*795d594fSAndroid Build Coastguard Worker 366*795d594fSAndroid Build Coastguard Worker /* 367*795d594fSAndroid Build Coastguard Worker * Called by managed code to create and deliver a StringIndexOutOfBoundsException 368*795d594fSAndroid Build Coastguard Worker * as if thrown from a call to String.charAt(). Arg1 holds index, arg2 holds limit. 369*795d594fSAndroid Build Coastguard Worker */ 370*795d594fSAndroid Build Coastguard WorkerTWO_ARG_RUNTIME_EXCEPTION_SAVE_EVERYTHING art_quick_throw_string_bounds, artThrowStringBoundsFromCode 371*795d594fSAndroid Build Coastguard Worker 372*795d594fSAndroid Build Coastguard Worker /* 373*795d594fSAndroid Build Coastguard Worker * Called by managed code to create and deliver a StackOverflowError. 374*795d594fSAndroid Build Coastguard Worker */ 375*795d594fSAndroid Build Coastguard WorkerNO_ARG_RUNTIME_EXCEPTION art_quick_throw_stack_overflow, artThrowStackOverflowFromCode 376*795d594fSAndroid Build Coastguard Worker 377*795d594fSAndroid Build Coastguard Worker /* 378*795d594fSAndroid Build Coastguard Worker * All generated callsites for interface invokes and invocation slow paths will load arguments 379*795d594fSAndroid Build Coastguard Worker * as usual - except instead of loading arg0/r0 with the target Method*, arg0/r0 will contain 380*795d594fSAndroid Build Coastguard Worker * the method_idx. This wrapper will save arg1-arg3, and call the appropriate C helper. 381*795d594fSAndroid Build Coastguard Worker * NOTE: "this" is first visible argument of the target, and so can be found in arg1/r1. 382*795d594fSAndroid Build Coastguard Worker * 383*795d594fSAndroid Build Coastguard Worker * The helper will attempt to locate the target and return a 64-bit result in r0/r1 consisting 384*795d594fSAndroid Build Coastguard Worker * of the target Method* in r0 and method->code_ in r1. 385*795d594fSAndroid Build Coastguard Worker * 386*795d594fSAndroid Build Coastguard Worker * If unsuccessful, the helper will return null/null. There will bea pending exception in the 387*795d594fSAndroid Build Coastguard Worker * thread and we branch to another stub to deliver it. 388*795d594fSAndroid Build Coastguard Worker * 389*795d594fSAndroid Build Coastguard Worker * On success this wrapper will restore arguments and *jump* to the target, leaving the lr 390*795d594fSAndroid Build Coastguard Worker * pointing back to the original caller. 391*795d594fSAndroid Build Coastguard Worker * 392*795d594fSAndroid Build Coastguard Worker * Clobbers IP (R12). 393*795d594fSAndroid Build Coastguard Worker */ 394*795d594fSAndroid Build Coastguard Worker.macro INVOKE_TRAMPOLINE_BODY cxx_name 395*795d594fSAndroid Build Coastguard Worker .extern \cxx_name 396*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_AND_ARGS_FRAME r2 @ save callee saves in case allocation triggers GC 397*795d594fSAndroid Build Coastguard Worker mov r2, rSELF @ pass Thread::Current 398*795d594fSAndroid Build Coastguard Worker mov r3, sp 399*795d594fSAndroid Build Coastguard Worker bl \cxx_name @ (method_idx, this, Thread*, SP) 400*795d594fSAndroid Build Coastguard Worker mov r12, r1 @ save Method*->code_ 401*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_AND_ARGS_FRAME 402*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 403*795d594fSAndroid Build Coastguard Worker cbz r0, 1f @ did we find the target? if not go to exception delivery 404*795d594fSAndroid Build Coastguard Worker bx r12 @ tail call to target 405*795d594fSAndroid Build Coastguard Worker1: 406*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION 407*795d594fSAndroid Build Coastguard Worker.endm 408*795d594fSAndroid Build Coastguard Worker.macro INVOKE_TRAMPOLINE c_name, cxx_name 409*795d594fSAndroid Build Coastguard WorkerENTRY \c_name 410*795d594fSAndroid Build Coastguard Worker INVOKE_TRAMPOLINE_BODY \cxx_name 411*795d594fSAndroid Build Coastguard WorkerEND \c_name 412*795d594fSAndroid Build Coastguard Worker.endm 413*795d594fSAndroid Build Coastguard Worker 414*795d594fSAndroid Build Coastguard WorkerINVOKE_TRAMPOLINE art_quick_invoke_interface_trampoline_with_access_check, artInvokeInterfaceTrampolineWithAccessCheck 415*795d594fSAndroid Build Coastguard Worker 416*795d594fSAndroid Build Coastguard WorkerINVOKE_TRAMPOLINE art_quick_invoke_static_trampoline_with_access_check, artInvokeStaticTrampolineWithAccessCheck 417*795d594fSAndroid Build Coastguard WorkerINVOKE_TRAMPOLINE art_quick_invoke_direct_trampoline_with_access_check, artInvokeDirectTrampolineWithAccessCheck 418*795d594fSAndroid Build Coastguard WorkerINVOKE_TRAMPOLINE art_quick_invoke_super_trampoline_with_access_check, artInvokeSuperTrampolineWithAccessCheck 419*795d594fSAndroid Build Coastguard WorkerINVOKE_TRAMPOLINE art_quick_invoke_virtual_trampoline_with_access_check, artInvokeVirtualTrampolineWithAccessCheck 420*795d594fSAndroid Build Coastguard Worker 421*795d594fSAndroid Build Coastguard Worker /* 422*795d594fSAndroid Build Coastguard Worker * Quick invocation stub internal. 423*795d594fSAndroid Build Coastguard Worker * On entry: 424*795d594fSAndroid Build Coastguard Worker * r0 = method pointer 425*795d594fSAndroid Build Coastguard Worker * r1 = argument array or null for no argument methods 426*795d594fSAndroid Build Coastguard Worker * r2 = size of argument array in bytes 427*795d594fSAndroid Build Coastguard Worker * r3 = (managed) thread pointer 428*795d594fSAndroid Build Coastguard Worker * [sp] = JValue* result 429*795d594fSAndroid Build Coastguard Worker * [sp + 4] = result_in_float 430*795d594fSAndroid Build Coastguard Worker * [sp + 8] = core register argument array 431*795d594fSAndroid Build Coastguard Worker * [sp + 12] = fp register argument array 432*795d594fSAndroid Build Coastguard Worker * +-------------------------+ 433*795d594fSAndroid Build Coastguard Worker * | uint32_t* fp_reg_args | 434*795d594fSAndroid Build Coastguard Worker * | uint32_t* core_reg_args | 435*795d594fSAndroid Build Coastguard Worker * | result_in_float | <- Caller frame 436*795d594fSAndroid Build Coastguard Worker * | Jvalue* result | 437*795d594fSAndroid Build Coastguard Worker * +-------------------------+ 438*795d594fSAndroid Build Coastguard Worker * | lr | 439*795d594fSAndroid Build Coastguard Worker * | r11 | 440*795d594fSAndroid Build Coastguard Worker * | r9 | 441*795d594fSAndroid Build Coastguard Worker * | r4 | <- r11 442*795d594fSAndroid Build Coastguard Worker * +-------------------------+ 443*795d594fSAndroid Build Coastguard Worker * | uint32_t out[n-1] | 444*795d594fSAndroid Build Coastguard Worker * | : : | Outs 445*795d594fSAndroid Build Coastguard Worker * | uint32_t out[0] | 446*795d594fSAndroid Build Coastguard Worker * | StackRef<ArtMethod> | <- SP value=null 447*795d594fSAndroid Build Coastguard Worker * +-------------------------+ 448*795d594fSAndroid Build Coastguard Worker */ 449*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_invoke_stub_internal 450*795d594fSAndroid Build Coastguard Worker SPILL_ALL_CALLEE_SAVE_GPRS @ spill regs (9) 451*795d594fSAndroid Build Coastguard Worker mov r11, sp @ save the stack pointer 452*795d594fSAndroid Build Coastguard Worker .cfi_def_cfa_register r11 453*795d594fSAndroid Build Coastguard Worker 454*795d594fSAndroid Build Coastguard Worker mov r9, r3 @ move managed thread pointer into r9 455*795d594fSAndroid Build Coastguard Worker 456*795d594fSAndroid Build Coastguard Worker add r4, r2, #4 @ create space for method pointer in frame 457*795d594fSAndroid Build Coastguard Worker sub r4, sp, r4 @ reserve & align *stack* to 16 bytes: native calling 458*795d594fSAndroid Build Coastguard Worker and r4, #0xFFFFFFF0 @ convention only aligns to 8B, so we have to ensure ART 459*795d594fSAndroid Build Coastguard Worker mov sp, r4 @ 16B alignment ourselves. 460*795d594fSAndroid Build Coastguard Worker 461*795d594fSAndroid Build Coastguard Worker mov r4, r0 @ save method* 462*795d594fSAndroid Build Coastguard Worker add r0, sp, #4 @ pass stack pointer + method ptr as dest for memcpy 463*795d594fSAndroid Build Coastguard Worker bl memcpy @ memcpy (dest, src, bytes) 464*795d594fSAndroid Build Coastguard Worker mov ip, #0 @ set ip to 0 465*795d594fSAndroid Build Coastguard Worker str ip, [sp] @ store null for method* at bottom of frame 466*795d594fSAndroid Build Coastguard Worker 467*795d594fSAndroid Build Coastguard Worker ldr ip, [r11, #48] @ load fp register argument array pointer 468*795d594fSAndroid Build Coastguard Worker vldm ip, {s0-s15} @ copy s0 - s15 469*795d594fSAndroid Build Coastguard Worker 470*795d594fSAndroid Build Coastguard Worker ldr ip, [r11, #44] @ load core register argument array pointer 471*795d594fSAndroid Build Coastguard Worker mov r0, r4 @ restore method* 472*795d594fSAndroid Build Coastguard Worker add ip, ip, #4 @ skip r0 473*795d594fSAndroid Build Coastguard Worker ldm ip, {r1-r3} @ copy r1 - r3 474*795d594fSAndroid Build Coastguard Worker 475*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 476*795d594fSAndroid Build Coastguard Worker 477*795d594fSAndroid Build Coastguard Worker ldr ip, [r0, #ART_METHOD_QUICK_CODE_OFFSET_32] @ get pointer to the code 478*795d594fSAndroid Build Coastguard Worker blx ip @ call the method 479*795d594fSAndroid Build Coastguard Worker 480*795d594fSAndroid Build Coastguard Worker mov sp, r11 @ restore the stack pointer 481*795d594fSAndroid Build Coastguard Worker .cfi_def_cfa_register sp 482*795d594fSAndroid Build Coastguard Worker 483*795d594fSAndroid Build Coastguard Worker ldr r4, [sp, #40] @ load result_is_float 484*795d594fSAndroid Build Coastguard Worker ldr r9, [sp, #36] @ load the result pointer 485*795d594fSAndroid Build Coastguard Worker cmp r4, #0 486*795d594fSAndroid Build Coastguard Worker ite eq 487*795d594fSAndroid Build Coastguard Worker strdeq r0, [r9] @ store r0/r1 into result pointer 488*795d594fSAndroid Build Coastguard Worker vstrne d0, [r9] @ store s0-s1/d0 into result pointer 489*795d594fSAndroid Build Coastguard Worker 490*795d594fSAndroid Build Coastguard Worker pop {r4, r5, r6, r7, r8, r9, r10, r11, pc} @ restore spill regs 491*795d594fSAndroid Build Coastguard WorkerEND art_quick_invoke_stub_internal 492*795d594fSAndroid Build Coastguard Worker 493*795d594fSAndroid Build Coastguard Worker /* 494*795d594fSAndroid Build Coastguard Worker * On stack replacement stub. 495*795d594fSAndroid Build Coastguard Worker * On entry: 496*795d594fSAndroid Build Coastguard Worker * r0 = stack to copy 497*795d594fSAndroid Build Coastguard Worker * r1 = size of stack 498*795d594fSAndroid Build Coastguard Worker * r2 = pc to call 499*795d594fSAndroid Build Coastguard Worker * r3 = JValue* result 500*795d594fSAndroid Build Coastguard Worker * [sp] = shorty 501*795d594fSAndroid Build Coastguard Worker * [sp + 4] = thread 502*795d594fSAndroid Build Coastguard Worker */ 503*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_osr_stub 504*795d594fSAndroid Build Coastguard Worker SPILL_ALL_CALLEE_SAVE_GPRS @ Spill regs (9) 505*795d594fSAndroid Build Coastguard Worker vpush {s16-s31} @ Spill fp-regs (16) 506*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 64 507*795d594fSAndroid Build Coastguard Worker SAVE_SIZE=(9*4+16*4) 508*795d594fSAndroid Build Coastguard Worker mov r11, sp @ Save the stack pointer 509*795d594fSAndroid Build Coastguard Worker .cfi_def_cfa r11, SAVE_SIZE @ CFA = r11 + SAVE_SIZE 510*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 511*795d594fSAndroid Build Coastguard Worker mov r10, r1 @ Save size of stack 512*795d594fSAndroid Build Coastguard Worker ldr r9, [r11, #(SAVE_SIZE+4)] @ Move managed thread pointer into r9 513*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 514*795d594fSAndroid Build Coastguard Worker mov r6, r2 @ Save the pc to call 515*795d594fSAndroid Build Coastguard Worker sub r7, sp, #12 @ Reserve space for stack pointer, 516*795d594fSAndroid Build Coastguard Worker @ JValue* result, and ArtMethod* slot. 517*795d594fSAndroid Build Coastguard Worker and r7, #0xFFFFFFF0 @ Align stack pointer 518*795d594fSAndroid Build Coastguard Worker mov sp, r7 @ Update stack pointer 519*795d594fSAndroid Build Coastguard Worker str r11, [sp, #4] @ Save old stack pointer 520*795d594fSAndroid Build Coastguard Worker str r3, [sp, #8] @ Save JValue* result 521*795d594fSAndroid Build Coastguard Worker mov ip, #0 522*795d594fSAndroid Build Coastguard Worker str ip, [sp] @ Store null for ArtMethod* at bottom of frame 523*795d594fSAndroid Build Coastguard Worker // r11 isn't properly spilled in the osr method, so we need use DWARF expression. 524*795d594fSAndroid Build Coastguard Worker // NB: the CFI must be before the call since this is the address gdb will lookup. 525*795d594fSAndroid Build Coastguard Worker // NB: gdb expects that cfa_expression returns the CFA value (not address to it). 526*795d594fSAndroid Build Coastguard Worker .cfi_escape /* CFA = [sp + 4] + SAVE_SIZE */ \ 527*795d594fSAndroid Build Coastguard Worker 0x0f, 6, /* DW_CFA_def_cfa_expression(len) */ \ 528*795d594fSAndroid Build Coastguard Worker 0x92, 13, 4, /* DW_OP_bregx(reg,offset) */ \ 529*795d594fSAndroid Build Coastguard Worker 0x06, /* DW_OP_deref */ \ 530*795d594fSAndroid Build Coastguard Worker 0x23, SAVE_SIZE /* DW_OP_plus_uconst(val) */ 531*795d594fSAndroid Build Coastguard Worker bl .Losr_entry @ Call the method 532*795d594fSAndroid Build Coastguard Worker ldr r10, [sp, #8] @ Restore JValue* result 533*795d594fSAndroid Build Coastguard Worker ldr sp, [sp, #4] @ Restore saved stack pointer 534*795d594fSAndroid Build Coastguard Worker .cfi_def_cfa sp, SAVE_SIZE @ CFA = sp + SAVE_SIZE 535*795d594fSAndroid Build Coastguard Worker strd r0, [r10] @ Store r0/r1 into result pointer 536*795d594fSAndroid Build Coastguard Worker vpop {s16-s31} 537*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -64 538*795d594fSAndroid Build Coastguard Worker pop {r4, r5, r6, r7, r8, r9, r10, r11, pc} 539*795d594fSAndroid Build Coastguard Worker.Losr_entry: 540*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA r11, SAVE_SIZE @ CFA = r11 + SAVE_SIZE 541*795d594fSAndroid Build Coastguard Worker sub sp, sp, r10 @ Reserve space for callee stack 542*795d594fSAndroid Build Coastguard Worker sub r10, r10, #4 543*795d594fSAndroid Build Coastguard Worker str lr, [sp, r10] @ Store link register per the compiler ABI 544*795d594fSAndroid Build Coastguard Worker mov r2, r10 545*795d594fSAndroid Build Coastguard Worker mov r1, r0 546*795d594fSAndroid Build Coastguard Worker mov r0, sp 547*795d594fSAndroid Build Coastguard Worker bl memcpy @ memcpy (dest r0, src r1, bytes r2) 548*795d594fSAndroid Build Coastguard Worker bx r6 549*795d594fSAndroid Build Coastguard WorkerEND art_quick_osr_stub 550*795d594fSAndroid Build Coastguard Worker 551*795d594fSAndroid Build Coastguard Worker /* 552*795d594fSAndroid Build Coastguard Worker * On entry r0 is the long jump context. This is expected to be returned from a previous 553*795d594fSAndroid Build Coastguard Worker * entrypoint call which threw an exception or deoptimized. 554*795d594fSAndroid Build Coastguard Worker * The r12 (IP) shall be clobbered rather than retrieved from gprs_. 555*795d594fSAndroid Build Coastguard Worker */ 556*795d594fSAndroid Build Coastguard WorkerARM_ENTRY art_quick_do_long_jump 557*795d594fSAndroid Build Coastguard Worker // Reserve space for the gprs + fprs; 558*795d594fSAndroid Build Coastguard Worker INCREASE_FRAME ARM_LONG_JUMP_CONTEXT_SIZE 559*795d594fSAndroid Build Coastguard Worker 560*795d594fSAndroid Build Coastguard Worker mov r1, sp 561*795d594fSAndroid Build Coastguard Worker add r2, sp, #ARM_LONG_JUMP_GPRS_SIZE 562*795d594fSAndroid Build Coastguard Worker 563*795d594fSAndroid Build Coastguard Worker bl artContextCopyForLongJump // Context* context, uintptr_t* gprs, uintptr_t* fprs 564*795d594fSAndroid Build Coastguard Worker 565*795d594fSAndroid Build Coastguard Worker add r0, sp, #ARM_LONG_JUMP_GPRS_SIZE 566*795d594fSAndroid Build Coastguard Worker 567*795d594fSAndroid Build Coastguard Worker vldm r0, {s0-s31} @ Load all fprs from argument fprs_. 568*795d594fSAndroid Build Coastguard Worker @ Do not access fprs_ from now, they may be below SP. 569*795d594fSAndroid Build Coastguard Worker ldm sp, {r0-r11} @ load r0-r11 from gprs_. 570*795d594fSAndroid Build Coastguard Worker ldr r12, [sp, #60] @ Load the value of PC (r15) from gprs_ (60 = 4 * 15) into IP (r12). 571*795d594fSAndroid Build Coastguard Worker ldr lr, [sp, #56] @ Load LR from gprs_, 56 = 4 * 14. 572*795d594fSAndroid Build Coastguard Worker ldr sp, [sp, #52] @ Load SP from gprs_ 52 = 4 * 13. 573*795d594fSAndroid Build Coastguard Worker @ Do not access gprs_ from now, they are below SP. 574*795d594fSAndroid Build Coastguard Worker .cfi_def_cfa_offset 0 575*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 576*795d594fSAndroid Build Coastguard Worker bx r12 @ Do long jump. 577*795d594fSAndroid Build Coastguard WorkerEND art_quick_do_long_jump 578*795d594fSAndroid Build Coastguard Worker 579*795d594fSAndroid Build Coastguard Worker /* 580*795d594fSAndroid Build Coastguard Worker * Entry from managed code that calls artHandleFillArrayDataFromCode and delivers exception on 581*795d594fSAndroid Build Coastguard Worker * failure. 582*795d594fSAndroid Build Coastguard Worker */ 583*795d594fSAndroid Build Coastguard WorkerTWO_ARG_DOWNCALL art_quick_handle_fill_data, \ 584*795d594fSAndroid Build Coastguard Worker artHandleFillArrayDataFromCode, \ 585*795d594fSAndroid Build Coastguard Worker RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER 586*795d594fSAndroid Build Coastguard Worker 587*795d594fSAndroid Build Coastguard Worker /* 588*795d594fSAndroid Build Coastguard Worker * Entry from managed code that tries to lock the object in a fast path and 589*795d594fSAndroid Build Coastguard Worker * calls `artLockObjectFromCode()` for the difficult cases, may block for GC. 590*795d594fSAndroid Build Coastguard Worker * r0 holds the possibly null object to lock. 591*795d594fSAndroid Build Coastguard Worker */ 592*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_lock_object 593*795d594fSAndroid Build Coastguard Worker // Note: the slow path is actually the art_quick_lock_object_no_inline (tail call). 594*795d594fSAndroid Build Coastguard Worker LOCK_OBJECT_FAST_PATH r0, r1, r2, r3, .Llock_object_slow, /*can_be_null*/ 1 595*795d594fSAndroid Build Coastguard WorkerEND art_quick_lock_object 596*795d594fSAndroid Build Coastguard Worker 597*795d594fSAndroid Build Coastguard Worker /* 598*795d594fSAndroid Build Coastguard Worker * Entry from managed code that calls `artLockObjectFromCode()`, may block for GC. 599*795d594fSAndroid Build Coastguard Worker * r0 holds the possibly null object to lock. 600*795d594fSAndroid Build Coastguard Worker */ 601*795d594fSAndroid Build Coastguard Worker .extern artLockObjectFromCode 602*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_lock_object_no_inline 603*795d594fSAndroid Build Coastguard Worker // This is also the slow path for art_quick_lock_object. 604*795d594fSAndroid Build Coastguard Worker // Note that we need a local label as the assembler emits bad instructions 605*795d594fSAndroid Build Coastguard Worker // for CBZ/CBNZ if we try to jump to `art_quick_lock_object_no_inline`. 606*795d594fSAndroid Build Coastguard Worker.Llock_object_slow: 607*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_ONLY_FRAME r1 @ save callee saves in case we block 608*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ pass Thread::Current 609*795d594fSAndroid Build Coastguard Worker bl artLockObjectFromCode @ (Object* obj, Thread*) 610*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME 611*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 612*795d594fSAndroid Build Coastguard Worker RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER 613*795d594fSAndroid Build Coastguard WorkerEND art_quick_lock_object_no_inline 614*795d594fSAndroid Build Coastguard Worker 615*795d594fSAndroid Build Coastguard Worker /* 616*795d594fSAndroid Build Coastguard Worker * Entry from managed code that tries to unlock the object in a fast path and calls 617*795d594fSAndroid Build Coastguard Worker * `artUnlockObjectFromCode()` for the difficult cases and delivers exception on failure. 618*795d594fSAndroid Build Coastguard Worker * r0 holds the possibly null object to unlock. 619*795d594fSAndroid Build Coastguard Worker */ 620*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_unlock_object 621*795d594fSAndroid Build Coastguard Worker // Note: the slow path is actually the art_quick_unlock_object_no_inline (tail call). 622*795d594fSAndroid Build Coastguard Worker UNLOCK_OBJECT_FAST_PATH r0, r1, r2, r3, .Lunlock_object_slow, /*can_be_null*/ 1 623*795d594fSAndroid Build Coastguard WorkerEND art_quick_unlock_object 624*795d594fSAndroid Build Coastguard Worker 625*795d594fSAndroid Build Coastguard Worker /* 626*795d594fSAndroid Build Coastguard Worker * Entry from managed code that calls `artUnlockObjectFromCode()` 627*795d594fSAndroid Build Coastguard Worker * and delivers exception on failure. 628*795d594fSAndroid Build Coastguard Worker * r0 holds the possibly null object to unlock. 629*795d594fSAndroid Build Coastguard Worker */ 630*795d594fSAndroid Build Coastguard Worker .extern artUnlockObjectFromCode 631*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_unlock_object_no_inline 632*795d594fSAndroid Build Coastguard Worker // This is also the slow path for art_quick_unlock_object. 633*795d594fSAndroid Build Coastguard Worker // Note that we need a local label as the assembler emits bad instructions 634*795d594fSAndroid Build Coastguard Worker // for CBZ/CBNZ if we try to jump to `art_quick_unlock_object_no_inline`. 635*795d594fSAndroid Build Coastguard Worker.Lunlock_object_slow: 636*795d594fSAndroid Build Coastguard Worker @ save callee saves in case exception allocation triggers GC 637*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_ONLY_FRAME r1 638*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ pass Thread::Current 639*795d594fSAndroid Build Coastguard Worker bl artUnlockObjectFromCode @ (Object* obj, Thread*) 640*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME 641*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 642*795d594fSAndroid Build Coastguard Worker RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER 643*795d594fSAndroid Build Coastguard WorkerEND art_quick_unlock_object_no_inline 644*795d594fSAndroid Build Coastguard Worker 645*795d594fSAndroid Build Coastguard Worker /* 646*795d594fSAndroid Build Coastguard Worker * Entry from managed code that calls artInstanceOfFromCode and on failure calls 647*795d594fSAndroid Build Coastguard Worker * artThrowClassCastExceptionForObject. 648*795d594fSAndroid Build Coastguard Worker */ 649*795d594fSAndroid Build Coastguard Worker .extern artInstanceOfFromCode 650*795d594fSAndroid Build Coastguard Worker .extern artThrowClassCastExceptionForObject 651*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_check_instance_of 652*795d594fSAndroid Build Coastguard Worker // Type check using the bit string passes null as the target class. In that case just throw. 653*795d594fSAndroid Build Coastguard Worker cbz r1, .Lthrow_class_cast_exception_for_bitstring_check 654*795d594fSAndroid Build Coastguard Worker 655*795d594fSAndroid Build Coastguard Worker push {r0-r2, lr} @ save arguments, padding (r2) and link register 656*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 16 657*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r0, 0 658*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r1, 4 659*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r2, 8 660*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 12 661*795d594fSAndroid Build Coastguard Worker bl artInstanceOfFromCode 662*795d594fSAndroid Build Coastguard Worker cbz r0, .Lthrow_class_cast_exception 663*795d594fSAndroid Build Coastguard Worker pop {r0-r2, pc} 664*795d594fSAndroid Build Coastguard Worker 665*795d594fSAndroid Build Coastguard Worker.Lthrow_class_cast_exception: 666*795d594fSAndroid Build Coastguard Worker pop {r0-r2, lr} 667*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -16 668*795d594fSAndroid Build Coastguard Worker .cfi_restore r0 669*795d594fSAndroid Build Coastguard Worker .cfi_restore r1 670*795d594fSAndroid Build Coastguard Worker .cfi_restore r2 671*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 672*795d594fSAndroid Build Coastguard Worker 673*795d594fSAndroid Build Coastguard Worker.Lthrow_class_cast_exception_for_bitstring_check: 674*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_ALL_CALLEE_SAVES_FRAME r2 @ save all registers as basis for long jump context 675*795d594fSAndroid Build Coastguard Worker mov r2, rSELF @ pass Thread::Current 676*795d594fSAndroid Build Coastguard Worker bl artThrowClassCastExceptionForObject @ (Object*, Class*, Thread*) 677*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 678*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 679*795d594fSAndroid Build Coastguard WorkerEND art_quick_check_instance_of 680*795d594fSAndroid Build Coastguard Worker 681*795d594fSAndroid Build Coastguard Worker// Restore rReg's value from [sp, #offset] if rReg is not the same as rExclude. 682*795d594fSAndroid Build Coastguard Worker.macro POP_REG_NE rReg, offset, rExclude 683*795d594fSAndroid Build Coastguard Worker .ifnc \rReg, \rExclude 684*795d594fSAndroid Build Coastguard Worker ldr \rReg, [sp, #\offset] @ restore rReg 685*795d594fSAndroid Build Coastguard Worker .cfi_restore \rReg 686*795d594fSAndroid Build Coastguard Worker .endif 687*795d594fSAndroid Build Coastguard Worker.endm 688*795d594fSAndroid Build Coastguard Worker 689*795d594fSAndroid Build Coastguard Worker// Save rReg's value to [sp, #offset]. 690*795d594fSAndroid Build Coastguard Worker.macro PUSH_REG rReg, offset 691*795d594fSAndroid Build Coastguard Worker str \rReg, [sp, #\offset] @ save rReg 692*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset \rReg, \offset 693*795d594fSAndroid Build Coastguard Worker.endm 694*795d594fSAndroid Build Coastguard Worker 695*795d594fSAndroid Build Coastguard Worker // Helper macros for `art_quick_aput_obj`. 696*795d594fSAndroid Build Coastguard Worker#ifdef USE_READ_BARRIER 697*795d594fSAndroid Build Coastguard Worker#ifdef USE_BAKER_READ_BARRIER 698*795d594fSAndroid Build Coastguard Worker.macro BAKER_RB_CHECK_GRAY_BIT_AND_LOAD rDest, rObj, offset, gray_slow_path_label 699*795d594fSAndroid Build Coastguard Worker ldr ip, [\rObj, #MIRROR_OBJECT_LOCK_WORD_OFFSET] 700*795d594fSAndroid Build Coastguard Worker tst ip, #LOCK_WORD_READ_BARRIER_STATE_MASK_SHIFTED 701*795d594fSAndroid Build Coastguard Worker bne \gray_slow_path_label 702*795d594fSAndroid Build Coastguard Worker // False dependency to avoid needing load/load fence. 703*795d594fSAndroid Build Coastguard Worker add \rObj, \rObj, ip, lsr #32 704*795d594fSAndroid Build Coastguard Worker ldr \rDest, [\rObj, #\offset] 705*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF \rDest 706*795d594fSAndroid Build Coastguard Worker.endm 707*795d594fSAndroid Build Coastguard Worker 708*795d594fSAndroid Build Coastguard Worker.macro BAKER_RB_LOAD_AND_MARK rDest, rObj, offset, mark_function 709*795d594fSAndroid Build Coastguard Worker ldr \rDest, [\rObj, #\offset] 710*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF \rDest 711*795d594fSAndroid Build Coastguard Worker str lr, [sp, #-8]! @ Save LR with correct stack alignment. 712*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 0 713*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 8 714*795d594fSAndroid Build Coastguard Worker bl \mark_function 715*795d594fSAndroid Build Coastguard Worker ldr lr, [sp], #8 @ Restore LR. 716*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 717*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -8 718*795d594fSAndroid Build Coastguard Worker.endm 719*795d594fSAndroid Build Coastguard Worker#else // USE_BAKER_READ_BARRIER 720*795d594fSAndroid Build Coastguard Worker .extern artReadBarrierSlow 721*795d594fSAndroid Build Coastguard Worker.macro READ_BARRIER_SLOW rDest, rObj, offset 722*795d594fSAndroid Build Coastguard Worker push {r0-r3, ip, lr} @ 6 words for saved registers (used in art_quick_aput_obj) 723*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 24 724*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r0, 0 725*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r1, 4 726*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r2, 8 727*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r3, 12 728*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset ip, 16 729*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 20 730*795d594fSAndroid Build Coastguard Worker sub sp, #8 @ push padding 731*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 8 732*795d594fSAndroid Build Coastguard Worker @ mov r0, \rRef @ pass ref in r0 (no-op for now since parameter ref is unused) 733*795d594fSAndroid Build Coastguard Worker .ifnc \rObj, r1 734*795d594fSAndroid Build Coastguard Worker mov r1, \rObj @ pass rObj 735*795d594fSAndroid Build Coastguard Worker .endif 736*795d594fSAndroid Build Coastguard Worker mov r2, #\offset @ pass offset 737*795d594fSAndroid Build Coastguard Worker bl artReadBarrierSlow @ artReadBarrierSlow(ref, rObj, offset) 738*795d594fSAndroid Build Coastguard Worker @ No need to unpoison return value in r0, artReadBarrierSlow() would do the unpoisoning. 739*795d594fSAndroid Build Coastguard Worker .ifnc \rDest, r0 740*795d594fSAndroid Build Coastguard Worker mov \rDest, r0 @ save return value in rDest 741*795d594fSAndroid Build Coastguard Worker .endif 742*795d594fSAndroid Build Coastguard Worker add sp, #8 @ pop padding 743*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -8 744*795d594fSAndroid Build Coastguard Worker POP_REG_NE r0, 0, \rDest @ conditionally restore saved registers 745*795d594fSAndroid Build Coastguard Worker POP_REG_NE r1, 4, \rDest 746*795d594fSAndroid Build Coastguard Worker POP_REG_NE r2, 8, \rDest 747*795d594fSAndroid Build Coastguard Worker POP_REG_NE r3, 12, \rDest 748*795d594fSAndroid Build Coastguard Worker POP_REG_NE ip, 16, \rDest 749*795d594fSAndroid Build Coastguard Worker add sp, #20 750*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -20 751*795d594fSAndroid Build Coastguard Worker pop {lr} @ restore lr 752*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -4 753*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 754*795d594fSAndroid Build Coastguard Worker.endm 755*795d594fSAndroid Build Coastguard Worker#endif // USE_BAKER_READ_BARRIER 756*795d594fSAndroid Build Coastguard Worker#endif // USE_READ_BARRIER 757*795d594fSAndroid Build Coastguard Worker 758*795d594fSAndroid Build Coastguard Worker .hidden art_quick_aput_obj 759*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_aput_obj 760*795d594fSAndroid Build Coastguard Worker#if defined(USE_READ_BARRIER) && !defined(USE_BAKER_READ_BARRIER) 761*795d594fSAndroid Build Coastguard Worker @ The offset to .Ldo_aput_null is too large to use cbz due to expansion from `READ_BARRIER_SLOW`. 762*795d594fSAndroid Build Coastguard Worker tst r2, r2 763*795d594fSAndroid Build Coastguard Worker beq .Laput_obj_null 764*795d594fSAndroid Build Coastguard Worker READ_BARRIER_SLOW r3, r0, MIRROR_OBJECT_CLASS_OFFSET 765*795d594fSAndroid Build Coastguard Worker READ_BARRIER_SLOW r3, r3, MIRROR_CLASS_COMPONENT_TYPE_OFFSET 766*795d594fSAndroid Build Coastguard Worker READ_BARRIER_SLOW r4, r2, MIRROR_OBJECT_CLASS_OFFSET 767*795d594fSAndroid Build Coastguard Worker#else // !defined(USE_READ_BARRIER) || defined(USE_BAKER_READ_BARRIER) 768*795d594fSAndroid Build Coastguard Worker cbz r2, .Laput_obj_null 769*795d594fSAndroid Build Coastguard Worker#ifdef USE_READ_BARRIER 770*795d594fSAndroid Build Coastguard Worker cmp rMR, #0 771*795d594fSAndroid Build Coastguard Worker bne .Laput_obj_gc_marking 772*795d594fSAndroid Build Coastguard Worker#endif // USE_READ_BARRIER 773*795d594fSAndroid Build Coastguard Worker ldr r3, [r0, #MIRROR_OBJECT_CLASS_OFFSET] 774*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r3 775*795d594fSAndroid Build Coastguard Worker // R4 is a scratch register in managed ARM ABI. 776*795d594fSAndroid Build Coastguard Worker ldr r4, [r2, #MIRROR_OBJECT_CLASS_OFFSET] 777*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r4 778*795d594fSAndroid Build Coastguard Worker ldr r3, [r3, #MIRROR_CLASS_COMPONENT_TYPE_OFFSET] 779*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r3 780*795d594fSAndroid Build Coastguard Worker#endif // !defined(USE_READ_BARRIER) || defined(USE_BAKER_READ_BARRIER) 781*795d594fSAndroid Build Coastguard Worker cmp r3, r4 @ value's type == array's component type - trivial assignability 782*795d594fSAndroid Build Coastguard Worker bne .Laput_obj_check_assignability 783*795d594fSAndroid Build Coastguard Worker.Laput_obj_store: 784*795d594fSAndroid Build Coastguard Worker add r3, r0, #MIRROR_OBJECT_ARRAY_DATA_OFFSET 785*795d594fSAndroid Build Coastguard Worker POISON_HEAP_REF r2 786*795d594fSAndroid Build Coastguard Worker str r2, [r3, r1, lsl #2] 787*795d594fSAndroid Build Coastguard Worker ldr r3, [rSELF, #THREAD_CARD_TABLE_OFFSET] 788*795d594fSAndroid Build Coastguard Worker lsr r0, r0, #CARD_TABLE_CARD_SHIFT 789*795d594fSAndroid Build Coastguard Worker strb r3, [r3, r0] 790*795d594fSAndroid Build Coastguard Worker blx lr 791*795d594fSAndroid Build Coastguard Worker 792*795d594fSAndroid Build Coastguard Worker.Laput_obj_null: 793*795d594fSAndroid Build Coastguard Worker add r3, r0, #MIRROR_OBJECT_ARRAY_DATA_OFFSET 794*795d594fSAndroid Build Coastguard Worker str r2, [r3, r1, lsl #2] 795*795d594fSAndroid Build Coastguard Worker blx lr 796*795d594fSAndroid Build Coastguard Worker 797*795d594fSAndroid Build Coastguard Worker.Laput_obj_check_assignability: 798*795d594fSAndroid Build Coastguard Worker push {r0-r2, lr} @ save arguments 799*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 16 800*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 12 801*795d594fSAndroid Build Coastguard Worker mov r1, r4 802*795d594fSAndroid Build Coastguard Worker mov r0, r3 803*795d594fSAndroid Build Coastguard Worker bl artIsAssignableFromCode 804*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 805*795d594fSAndroid Build Coastguard Worker cbz r0, .Lthrow_array_store_exception 806*795d594fSAndroid Build Coastguard Worker pop {r0-r2, lr} 807*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 808*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -16 809*795d594fSAndroid Build Coastguard Worker add r3, r0, #MIRROR_OBJECT_ARRAY_DATA_OFFSET 810*795d594fSAndroid Build Coastguard Worker POISON_HEAP_REF r2 811*795d594fSAndroid Build Coastguard Worker str r2, [r3, r1, lsl #2] 812*795d594fSAndroid Build Coastguard Worker ldr r3, [rSELF, #THREAD_CARD_TABLE_OFFSET] 813*795d594fSAndroid Build Coastguard Worker lsr r0, r0, #CARD_TABLE_CARD_SHIFT 814*795d594fSAndroid Build Coastguard Worker strb r3, [r3, r0] 815*795d594fSAndroid Build Coastguard Worker blx lr 816*795d594fSAndroid Build Coastguard Worker 817*795d594fSAndroid Build Coastguard Worker.Lthrow_array_store_exception: 818*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, 16 819*795d594fSAndroid Build Coastguard Worker pop {r0-r2, lr} 820*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 821*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -16 822*795d594fSAndroid Build Coastguard Worker#if defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) 823*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 824*795d594fSAndroid Build Coastguard Worker#endif // defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) 825*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_ALL_CALLEE_SAVES_FRAME r3 826*795d594fSAndroid Build Coastguard Worker mov r1, r2 827*795d594fSAndroid Build Coastguard Worker mov r2, rSELF @ Pass Thread::Current. 828*795d594fSAndroid Build Coastguard Worker bl artThrowArrayStoreException @ (Class*, Class*, Thread*) 829*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 830*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 831*795d594fSAndroid Build Coastguard Worker 832*795d594fSAndroid Build Coastguard Worker#if defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) 833*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, 0 834*795d594fSAndroid Build Coastguard Worker.Laput_obj_gc_marking: 835*795d594fSAndroid Build Coastguard Worker BAKER_RB_CHECK_GRAY_BIT_AND_LOAD \ 836*795d594fSAndroid Build Coastguard Worker r3, r0, MIRROR_OBJECT_CLASS_OFFSET, .Laput_obj_mark_array_class 837*795d594fSAndroid Build Coastguard Worker.Laput_obj_mark_array_class_continue: 838*795d594fSAndroid Build Coastguard Worker BAKER_RB_CHECK_GRAY_BIT_AND_LOAD \ 839*795d594fSAndroid Build Coastguard Worker r3, r3, MIRROR_CLASS_COMPONENT_TYPE_OFFSET, .Laput_obj_mark_array_element 840*795d594fSAndroid Build Coastguard Worker.Laput_obj_mark_array_element_continue: 841*795d594fSAndroid Build Coastguard Worker BAKER_RB_CHECK_GRAY_BIT_AND_LOAD \ 842*795d594fSAndroid Build Coastguard Worker r4, r2, MIRROR_OBJECT_CLASS_OFFSET, .Laput_obj_mark_object_class 843*795d594fSAndroid Build Coastguard Worker.Laput_obj_mark_object_class_continue: 844*795d594fSAndroid Build Coastguard Worker 845*795d594fSAndroid Build Coastguard Worker cmp r3, r4 @ value's type == array's component type - trivial assignability 846*795d594fSAndroid Build Coastguard Worker // All registers are set up for correctly `.Laput_obj_check_assignability`. 847*795d594fSAndroid Build Coastguard Worker bne .Laput_obj_check_assignability 848*795d594fSAndroid Build Coastguard Worker b .Laput_obj_store 849*795d594fSAndroid Build Coastguard Worker 850*795d594fSAndroid Build Coastguard Worker.Laput_obj_mark_array_class: 851*795d594fSAndroid Build Coastguard Worker BAKER_RB_LOAD_AND_MARK r3, r0, MIRROR_OBJECT_CLASS_OFFSET, art_quick_read_barrier_mark_reg03 852*795d594fSAndroid Build Coastguard Worker b .Laput_obj_mark_array_class_continue 853*795d594fSAndroid Build Coastguard Worker 854*795d594fSAndroid Build Coastguard Worker.Laput_obj_mark_array_element: 855*795d594fSAndroid Build Coastguard Worker BAKER_RB_LOAD_AND_MARK \ 856*795d594fSAndroid Build Coastguard Worker r3, r3, MIRROR_CLASS_COMPONENT_TYPE_OFFSET, art_quick_read_barrier_mark_reg03 857*795d594fSAndroid Build Coastguard Worker b .Laput_obj_mark_array_element_continue 858*795d594fSAndroid Build Coastguard Worker 859*795d594fSAndroid Build Coastguard Worker.Laput_obj_mark_object_class: 860*795d594fSAndroid Build Coastguard Worker BAKER_RB_LOAD_AND_MARK r4, r2, MIRROR_OBJECT_CLASS_OFFSET, art_quick_read_barrier_mark_reg04 861*795d594fSAndroid Build Coastguard Worker b .Laput_obj_mark_object_class_continue 862*795d594fSAndroid Build Coastguard Worker#endif // defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) 863*795d594fSAndroid Build Coastguard WorkerEND art_quick_aput_obj 864*795d594fSAndroid Build Coastguard Worker 865*795d594fSAndroid Build Coastguard Worker /* 866*795d594fSAndroid Build Coastguard Worker * Macro for resolution and initialization of indexed DEX file 867*795d594fSAndroid Build Coastguard Worker * constants such as classes and strings. 868*795d594fSAndroid Build Coastguard Worker */ 869*795d594fSAndroid Build Coastguard Worker.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL name, entrypoint, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET 870*795d594fSAndroid Build Coastguard Worker .extern \entrypoint 871*795d594fSAndroid Build Coastguard WorkerENTRY \name 872*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_EVERYTHING_FRAME r1, \runtime_method_offset @ save everything in case of GC 873*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ pass Thread::Current 874*795d594fSAndroid Build Coastguard Worker bl \entrypoint @ (uint32_t index, Thread*) 875*795d594fSAndroid Build Coastguard Worker cbz r0, 1f @ If result is null, deliver the OOME. 876*795d594fSAndroid Build Coastguard Worker str r0, [sp, #136] @ store result in the frame 877*795d594fSAndroid Build Coastguard Worker DEOPT_OR_RESTORE_SAVE_EVERYTHING_FRAME_AND_RETURN_R0 r1, /* is_ref= */ 1 878*795d594fSAndroid Build Coastguard Worker1: 879*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION_FRAME_READY 880*795d594fSAndroid Build Coastguard WorkerEND \name 881*795d594fSAndroid Build Coastguard Worker.endm 882*795d594fSAndroid Build Coastguard Worker 883*795d594fSAndroid Build Coastguard Worker.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT name, entrypoint 884*795d594fSAndroid Build Coastguard Worker ONE_ARG_SAVE_EVERYTHING_DOWNCALL \name, \entrypoint, RUNTIME_SAVE_EVERYTHING_FOR_CLINIT_METHOD_OFFSET 885*795d594fSAndroid Build Coastguard Worker.endm 886*795d594fSAndroid Build Coastguard Worker 887*795d594fSAndroid Build Coastguard WorkerONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_static_storage, artInitializeStaticStorageFromCode 888*795d594fSAndroid Build Coastguard WorkerONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_resolve_type, artResolveTypeFromCode 889*795d594fSAndroid Build Coastguard WorkerONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_type_and_verify_access, artResolveTypeAndVerifyAccessFromCode 890*795d594fSAndroid Build Coastguard WorkerONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_handle, artResolveMethodHandleFromCode 891*795d594fSAndroid Build Coastguard WorkerONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode 892*795d594fSAndroid Build Coastguard WorkerONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode 893*795d594fSAndroid Build Coastguard Worker 894*795d594fSAndroid Build Coastguard Worker// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are 895*795d594fSAndroid Build Coastguard Worker// defined with a macro in runtime/entrypoints/quick/quick_field_entrypoints.cc. 896*795d594fSAndroid Build Coastguard Worker 897*795d594fSAndroid Build Coastguard WorkerGENERATE_STATIC_FIELD_GETTERS 898*795d594fSAndroid Build Coastguard Worker 899*795d594fSAndroid Build Coastguard WorkerGENERATE_INSTANCE_FIELD_GETTERS 900*795d594fSAndroid Build Coastguard Worker 901*795d594fSAndroid Build Coastguard WorkerGENERATE_STATIC_FIELD_SETTERS /* emit64= */ 0 902*795d594fSAndroid Build Coastguard Worker 903*795d594fSAndroid Build Coastguard WorkerGENERATE_INSTANCE_FIELD_SETTERS /* emit64= */ 0 904*795d594fSAndroid Build Coastguard Worker 905*795d594fSAndroid Build Coastguard Worker /* 906*795d594fSAndroid Build Coastguard Worker * Called by managed code to resolve an instance field and store a wide value. 907*795d594fSAndroid Build Coastguard Worker */ 908*795d594fSAndroid Build Coastguard Worker .extern artSet64InstanceFromCompiledCode 909*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_set64_instance 910*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_ONLY_FRAME r12 @ save callee saves in case of GC 911*795d594fSAndroid Build Coastguard Worker @ r2:r3 contain the wide argument 912*795d594fSAndroid Build Coastguard Worker str rSELF, [sp, #-16]! @ expand the frame and pass Thread::Current 913*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 16 914*795d594fSAndroid Build Coastguard Worker bl artSet64InstanceFromCompiledCode @ (field_idx, Object*, new_val, Thread*) 915*795d594fSAndroid Build Coastguard Worker add sp, #16 @ release out args 916*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -16 917*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME @ TODO: we can clearly save an add here 918*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 919*795d594fSAndroid Build Coastguard Worker RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER 920*795d594fSAndroid Build Coastguard WorkerEND art_quick_set64_instance 921*795d594fSAndroid Build Coastguard Worker 922*795d594fSAndroid Build Coastguard Worker .extern artSet64StaticFromCompiledCode 923*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_set64_static 924*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_ONLY_FRAME r12 @ save callee saves in case of GC 925*795d594fSAndroid Build Coastguard Worker @ r2:r3 contain the wide argument 926*795d594fSAndroid Build Coastguard Worker str rSELF, [sp, #-16]! @ expand the frame and pass Thread::Current 927*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 16 928*795d594fSAndroid Build Coastguard Worker bl artSet64StaticFromCompiledCode @ (field_idx, new_val, Thread*) 929*795d594fSAndroid Build Coastguard Worker add sp, #16 @ release out args 930*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -16 931*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME @ TODO: we can clearly save an add here 932*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 933*795d594fSAndroid Build Coastguard Worker RETURN_OR_DEOPT_IF_INT_RESULT_IS_ZERO_OR_DELIVER 934*795d594fSAndroid Build Coastguard WorkerEND art_quick_set64_static 935*795d594fSAndroid Build Coastguard Worker 936*795d594fSAndroid Build Coastguard Worker// Generate the allocation entrypoints for each allocator. 937*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_FOR_NON_TLAB_ALLOCATORS 938*795d594fSAndroid Build Coastguard Worker// Comment out allocators that have arm specific asm. 939*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_region_tlab, RegionTLAB) 940*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_region_tlab, RegionTLAB) 941*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_region_tlab, RegionTLAB) 942*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_region_tlab, RegionTLAB) 943*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_region_tlab, RegionTLAB) 944*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_region_tlab, RegionTLAB) 945*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_region_tlab, RegionTLAB) 946*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED32(_region_tlab, RegionTLAB) 947*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED64(_region_tlab, RegionTLAB) 948*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(_region_tlab, RegionTLAB) 949*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_CHARS(_region_tlab, RegionTLAB) 950*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_STRING(_region_tlab, RegionTLAB) 951*795d594fSAndroid Build Coastguard Worker 952*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_RESOLVED(_tlab, TLAB) 953*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_INITIALIZED(_tlab, TLAB) 954*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_OBJECT_WITH_ACCESS_CHECK(_tlab, TLAB) 955*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_OBJECT(_tlab, TLAB) 956*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED(_tlab, TLAB) 957*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED8(_tlab, TLAB) 958*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED16(_tlab, TLAB) 959*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED32(_tlab, TLAB) 960*795d594fSAndroid Build Coastguard Worker// GENERATE_ALLOC_ENTRYPOINTS_ALLOC_ARRAY_RESOLVED64(_tlab, TLAB) 961*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_BYTES(_tlab, TLAB) 962*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_CHARS(_tlab, TLAB) 963*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ENTRYPOINTS_ALLOC_STRING_FROM_STRING(_tlab, TLAB) 964*795d594fSAndroid Build Coastguard Worker 965*795d594fSAndroid Build Coastguard Worker// A hand-written override for GENERATE_ALLOC_ENTRYPOINTS_ALLOC_RESOLVED_OBJECT(_rosalloc, RosAlloc). 966*795d594fSAndroid Build Coastguard Worker// 967*795d594fSAndroid Build Coastguard Worker// If isInitialized=1 then the compiler assumes the object's class has already been initialized. 968*795d594fSAndroid Build Coastguard Worker// If isInitialized=0 the compiler can only assume it's been at least resolved. 969*795d594fSAndroid Build Coastguard Worker.macro ART_QUICK_ALLOC_OBJECT_ROSALLOC c_name, cxx_name, isInitialized 970*795d594fSAndroid Build Coastguard WorkerENTRY \c_name 971*795d594fSAndroid Build Coastguard Worker // Fast path rosalloc allocation. 972*795d594fSAndroid Build Coastguard Worker // r0: type/return value, rSELF (r9): Thread::Current 973*795d594fSAndroid Build Coastguard Worker // r1, r2, r3, r12: free. 974*795d594fSAndroid Build Coastguard Worker ldr r3, [rSELF, #THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET] // Check if the thread local 975*795d594fSAndroid Build Coastguard Worker // allocation stack has room. 976*795d594fSAndroid Build Coastguard Worker // TODO: consider using ldrd. 977*795d594fSAndroid Build Coastguard Worker ldr r12, [rSELF, #THREAD_LOCAL_ALLOC_STACK_END_OFFSET] 978*795d594fSAndroid Build Coastguard Worker cmp r3, r12 979*795d594fSAndroid Build Coastguard Worker bhs .Lslow_path\c_name 980*795d594fSAndroid Build Coastguard Worker 981*795d594fSAndroid Build Coastguard Worker ldr r3, [r0, #MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET] // Load the object size (r3) 982*795d594fSAndroid Build Coastguard Worker cmp r3, #ROSALLOC_MAX_THREAD_LOCAL_BRACKET_SIZE // Check if the size is for a thread 983*795d594fSAndroid Build Coastguard Worker // local allocation. 984*795d594fSAndroid Build Coastguard Worker // If the class is not yet visibly initialized, or it is finalizable, 985*795d594fSAndroid Build Coastguard Worker // the object size will be very large to force the branch below to be taken. 986*795d594fSAndroid Build Coastguard Worker // 987*795d594fSAndroid Build Coastguard Worker // See Class::SetStatus() in class.cc for more details. 988*795d594fSAndroid Build Coastguard Worker bhs .Lslow_path\c_name 989*795d594fSAndroid Build Coastguard Worker // Compute the rosalloc bracket index 990*795d594fSAndroid Build Coastguard Worker // from the size. Since the size is 991*795d594fSAndroid Build Coastguard Worker // already aligned we can combine the 992*795d594fSAndroid Build Coastguard Worker // two shifts together. 993*795d594fSAndroid Build Coastguard Worker add r12, rSELF, r3, lsr #(ROSALLOC_BRACKET_QUANTUM_SIZE_SHIFT - POINTER_SIZE_SHIFT) 994*795d594fSAndroid Build Coastguard Worker // Subtract pointer size since there 995*795d594fSAndroid Build Coastguard Worker // are no runs for 0 byte allocations 996*795d594fSAndroid Build Coastguard Worker // and the size is already aligned. 997*795d594fSAndroid Build Coastguard Worker // Load the rosalloc run (r12) 998*795d594fSAndroid Build Coastguard Worker ldr r12, [r12, #(THREAD_ROSALLOC_RUNS_OFFSET - __SIZEOF_POINTER__)] 999*795d594fSAndroid Build Coastguard Worker // Load the free list head (r3). This 1000*795d594fSAndroid Build Coastguard Worker // will be the return val. 1001*795d594fSAndroid Build Coastguard Worker ldr r3, [r12, #(ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_HEAD_OFFSET)] 1002*795d594fSAndroid Build Coastguard Worker cbz r3, .Lslow_path\c_name 1003*795d594fSAndroid Build Coastguard Worker // "Point of no slow path". Won't go to the slow path from here on. OK to clobber r0 and r1. 1004*795d594fSAndroid Build Coastguard Worker ldr r1, [r3, #ROSALLOC_SLOT_NEXT_OFFSET] // Load the next pointer of the head 1005*795d594fSAndroid Build Coastguard Worker // and update the list head with the 1006*795d594fSAndroid Build Coastguard Worker // next pointer. 1007*795d594fSAndroid Build Coastguard Worker str r1, [r12, #(ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_HEAD_OFFSET)] 1008*795d594fSAndroid Build Coastguard Worker // Store the class pointer in the 1009*795d594fSAndroid Build Coastguard Worker // header. This also overwrites the 1010*795d594fSAndroid Build Coastguard Worker // next pointer. The offsets are 1011*795d594fSAndroid Build Coastguard Worker // asserted to match. 1012*795d594fSAndroid Build Coastguard Worker#if ROSALLOC_SLOT_NEXT_OFFSET != MIRROR_OBJECT_CLASS_OFFSET 1013*795d594fSAndroid Build Coastguard Worker#error "Class pointer needs to overwrite next pointer." 1014*795d594fSAndroid Build Coastguard Worker#endif 1015*795d594fSAndroid Build Coastguard Worker POISON_HEAP_REF r0 1016*795d594fSAndroid Build Coastguard Worker str r0, [r3, #MIRROR_OBJECT_CLASS_OFFSET] 1017*795d594fSAndroid Build Coastguard Worker // Push the new object onto the thread 1018*795d594fSAndroid Build Coastguard Worker // local allocation stack and 1019*795d594fSAndroid Build Coastguard Worker // increment the thread local 1020*795d594fSAndroid Build Coastguard Worker // allocation stack top. 1021*795d594fSAndroid Build Coastguard Worker ldr r1, [rSELF, #THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET] 1022*795d594fSAndroid Build Coastguard Worker str r3, [r1], #COMPRESSED_REFERENCE_SIZE // (Increment r1 as a side effect.) 1023*795d594fSAndroid Build Coastguard Worker str r1, [rSELF, #THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET] 1024*795d594fSAndroid Build Coastguard Worker // Decrement the size of the free list 1025*795d594fSAndroid Build Coastguard Worker 1026*795d594fSAndroid Build Coastguard Worker // After this "STR" the object is published to the thread local allocation stack, 1027*795d594fSAndroid Build Coastguard Worker // and it will be observable from a runtime internal (eg. Heap::VisitObjects) point of view. 1028*795d594fSAndroid Build Coastguard Worker // It is not yet visible to the running (user) compiled code until after the return. 1029*795d594fSAndroid Build Coastguard Worker // 1030*795d594fSAndroid Build Coastguard Worker // To avoid the memory barrier prior to the "STR", a trick is employed, by differentiating 1031*795d594fSAndroid Build Coastguard Worker // the state of the allocation stack slot. It can be a pointer to one of: 1032*795d594fSAndroid Build Coastguard Worker // 0) Null entry, because the stack was bumped but the new pointer wasn't written yet. 1033*795d594fSAndroid Build Coastguard Worker // (The stack initial state is "null" pointers). 1034*795d594fSAndroid Build Coastguard Worker // 1) A partially valid object, with an invalid class pointer to the next free rosalloc slot. 1035*795d594fSAndroid Build Coastguard Worker // 2) A fully valid object, with a valid class pointer pointing to a real class. 1036*795d594fSAndroid Build Coastguard Worker // Other states are not allowed. 1037*795d594fSAndroid Build Coastguard Worker // 1038*795d594fSAndroid Build Coastguard Worker // An object that is invalid only temporarily, and will eventually become valid. 1039*795d594fSAndroid Build Coastguard Worker // The internal runtime code simply checks if the object is not null or is partial and then 1040*795d594fSAndroid Build Coastguard Worker // ignores it. 1041*795d594fSAndroid Build Coastguard Worker // 1042*795d594fSAndroid Build Coastguard Worker // (Note: The actual check is done by seeing if a non-null object has a class pointer pointing 1043*795d594fSAndroid Build Coastguard Worker // to ClassClass, and that the ClassClass's class pointer is self-cyclic. A rosalloc free slot 1044*795d594fSAndroid Build Coastguard Worker // "next" pointer is not-cyclic.) 1045*795d594fSAndroid Build Coastguard Worker // 1046*795d594fSAndroid Build Coastguard Worker // See also b/28790624 for a listing of CLs dealing with this race. 1047*795d594fSAndroid Build Coastguard Worker ldr r1, [r12, #(ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_SIZE_OFFSET)] 1048*795d594fSAndroid Build Coastguard Worker sub r1, #1 1049*795d594fSAndroid Build Coastguard Worker // TODO: consider combining this store 1050*795d594fSAndroid Build Coastguard Worker // and the list head store above using 1051*795d594fSAndroid Build Coastguard Worker // strd. 1052*795d594fSAndroid Build Coastguard Worker str r1, [r12, #(ROSALLOC_RUN_FREE_LIST_OFFSET + ROSALLOC_RUN_FREE_LIST_SIZE_OFFSET)] 1053*795d594fSAndroid Build Coastguard Worker 1054*795d594fSAndroid Build Coastguard Worker mov r0, r3 // Set the return value and return. 1055*795d594fSAndroid Build Coastguard Worker // No barrier. The class is already observably initialized (otherwise the fast 1056*795d594fSAndroid Build Coastguard Worker // path size check above would fail) and new-instance allocations are protected 1057*795d594fSAndroid Build Coastguard Worker // from publishing by the compiler which inserts its own StoreStore barrier. 1058*795d594fSAndroid Build Coastguard Worker bx lr 1059*795d594fSAndroid Build Coastguard Worker 1060*795d594fSAndroid Build Coastguard Worker.Lslow_path\c_name: 1061*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_ONLY_FRAME r2 @ save callee saves in case of GC 1062*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ pass Thread::Current 1063*795d594fSAndroid Build Coastguard Worker bl \cxx_name @ (mirror::Class* cls, Thread*) 1064*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME 1065*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 1066*795d594fSAndroid Build Coastguard Worker RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER 1067*795d594fSAndroid Build Coastguard WorkerEND \c_name 1068*795d594fSAndroid Build Coastguard Worker.endm 1069*795d594fSAndroid Build Coastguard Worker 1070*795d594fSAndroid Build Coastguard WorkerART_QUICK_ALLOC_OBJECT_ROSALLOC art_quick_alloc_object_resolved_rosalloc, artAllocObjectFromCodeResolvedRosAlloc, /* isInitialized */ 0 1071*795d594fSAndroid Build Coastguard WorkerART_QUICK_ALLOC_OBJECT_ROSALLOC art_quick_alloc_object_initialized_rosalloc, artAllocObjectFromCodeInitializedRosAlloc, /* isInitialized */ 1 1072*795d594fSAndroid Build Coastguard Worker 1073*795d594fSAndroid Build Coastguard Worker// The common fast path code for art_quick_alloc_object_resolved/initialized_tlab 1074*795d594fSAndroid Build Coastguard Worker// and art_quick_alloc_object_resolved/initialized_region_tlab. 1075*795d594fSAndroid Build Coastguard Worker// 1076*795d594fSAndroid Build Coastguard Worker// r0: type, rSELF (r9): Thread::Current, r1, r2, r3, r12: free. 1077*795d594fSAndroid Build Coastguard Worker// Need to preserve r0 to the slow path. 1078*795d594fSAndroid Build Coastguard Worker// 1079*795d594fSAndroid Build Coastguard Worker// If isInitialized=1 then the compiler assumes the object's class has already been initialized. 1080*795d594fSAndroid Build Coastguard Worker// If isInitialized=0 the compiler can only assume it's been at least resolved. 1081*795d594fSAndroid Build Coastguard Worker.macro ALLOC_OBJECT_RESOLVED_TLAB_FAST_PATH slowPathLabel isInitialized 1082*795d594fSAndroid Build Coastguard Worker // Load thread_local_pos (r12) and 1083*795d594fSAndroid Build Coastguard Worker // thread_local_end (r3) with ldrd. 1084*795d594fSAndroid Build Coastguard Worker // Check constraints for ldrd. 1085*795d594fSAndroid Build Coastguard Worker#if !((THREAD_LOCAL_POS_OFFSET + 4 == THREAD_LOCAL_END_OFFSET) && (THREAD_LOCAL_POS_OFFSET % 8 == 0)) 1086*795d594fSAndroid Build Coastguard Worker#error "Thread::thread_local_pos/end must be consecutive and are 8 byte aligned for performance" 1087*795d594fSAndroid Build Coastguard Worker#endif 1088*795d594fSAndroid Build Coastguard Worker ldrd r12, r3, [rSELF, #THREAD_LOCAL_POS_OFFSET] 1089*795d594fSAndroid Build Coastguard Worker sub r12, r3, r12 // Compute the remaining buf size. 1090*795d594fSAndroid Build Coastguard Worker ldr r3, [r0, #MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET] // Load the object size (r3). 1091*795d594fSAndroid Build Coastguard Worker cmp r3, r12 // Check if it fits. 1092*795d594fSAndroid Build Coastguard Worker // If the class is not yet visibly initialized, or it is finalizable, 1093*795d594fSAndroid Build Coastguard Worker // the object size will be very large to force the branch below to be taken. 1094*795d594fSAndroid Build Coastguard Worker // 1095*795d594fSAndroid Build Coastguard Worker // See Class::SetStatus() in class.cc for more details. 1096*795d594fSAndroid Build Coastguard Worker bhi \slowPathLabel 1097*795d594fSAndroid Build Coastguard Worker // "Point of no slow path". Won't go to the slow path from here on. OK to clobber r0 and r1. 1098*795d594fSAndroid Build Coastguard Worker // Reload old thread_local_pos (r0) 1099*795d594fSAndroid Build Coastguard Worker // for the return value. 1100*795d594fSAndroid Build Coastguard Worker ldr r2, [rSELF, #THREAD_LOCAL_POS_OFFSET] 1101*795d594fSAndroid Build Coastguard Worker add r1, r2, r3 1102*795d594fSAndroid Build Coastguard Worker str r1, [rSELF, #THREAD_LOCAL_POS_OFFSET] // Store new thread_local_pos. 1103*795d594fSAndroid Build Coastguard Worker // After this "STR" the object is published to the thread local allocation stack, 1104*795d594fSAndroid Build Coastguard Worker // and it will be observable from a runtime internal (eg. Heap::VisitObjects) point of view. 1105*795d594fSAndroid Build Coastguard Worker // It is not yet visible to the running (user) compiled code until after the return. 1106*795d594fSAndroid Build Coastguard Worker // 1107*795d594fSAndroid Build Coastguard Worker // To avoid the memory barrier prior to the "STR", a trick is employed, by differentiating 1108*795d594fSAndroid Build Coastguard Worker // the state of the object. It can be either: 1109*795d594fSAndroid Build Coastguard Worker // 1) A partially valid object, with a null class pointer 1110*795d594fSAndroid Build Coastguard Worker // (because the initial state of TLAB buffers is all 0s/nulls). 1111*795d594fSAndroid Build Coastguard Worker // 2) A fully valid object, with a valid class pointer pointing to a real class. 1112*795d594fSAndroid Build Coastguard Worker // Other states are not allowed. 1113*795d594fSAndroid Build Coastguard Worker // 1114*795d594fSAndroid Build Coastguard Worker // An object that is invalid only temporarily, and will eventually become valid. 1115*795d594fSAndroid Build Coastguard Worker // The internal runtime code simply checks if the object is not null or is partial and then 1116*795d594fSAndroid Build Coastguard Worker // ignores it. 1117*795d594fSAndroid Build Coastguard Worker // 1118*795d594fSAndroid Build Coastguard Worker // (Note: The actual check is done by checking that the object's class pointer is non-null. 1119*795d594fSAndroid Build Coastguard Worker // Also, unlike rosalloc, the object can never be observed as null). 1120*795d594fSAndroid Build Coastguard Worker POISON_HEAP_REF r0 1121*795d594fSAndroid Build Coastguard Worker str r0, [r2, #MIRROR_OBJECT_CLASS_OFFSET] // Store the class pointer. 1122*795d594fSAndroid Build Coastguard Worker mov r0, r2 1123*795d594fSAndroid Build Coastguard Worker // No barrier. The class is already observably initialized (otherwise the fast 1124*795d594fSAndroid Build Coastguard Worker // path size check above would fail) and new-instance allocations are protected 1125*795d594fSAndroid Build Coastguard Worker // from publishing by the compiler which inserts its own StoreStore barrier. 1126*795d594fSAndroid Build Coastguard Worker bx lr 1127*795d594fSAndroid Build Coastguard Worker.endm 1128*795d594fSAndroid Build Coastguard Worker 1129*795d594fSAndroid Build Coastguard Worker// The common code for art_quick_alloc_object_*region_tlab 1130*795d594fSAndroid Build Coastguard Worker// Currently the implementation ignores isInitialized. TODO(b/172087402): clean this up. 1131*795d594fSAndroid Build Coastguard Worker// Caller must execute a constructor fence after this. 1132*795d594fSAndroid Build Coastguard Worker.macro GENERATE_ALLOC_OBJECT_RESOLVED_TLAB name, entrypoint, isInitialized 1133*795d594fSAndroid Build Coastguard WorkerENTRY \name 1134*795d594fSAndroid Build Coastguard Worker // Fast path tlab allocation. 1135*795d594fSAndroid Build Coastguard Worker // r0: type, rSELF (r9): Thread::Current 1136*795d594fSAndroid Build Coastguard Worker // r1, r2, r3, r12: free. 1137*795d594fSAndroid Build Coastguard Worker ALLOC_OBJECT_RESOLVED_TLAB_FAST_PATH .Lslow_path\name, \isInitialized 1138*795d594fSAndroid Build Coastguard Worker.Lslow_path\name: 1139*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_ONLY_FRAME r2 // Save callee saves in case of GC. 1140*795d594fSAndroid Build Coastguard Worker mov r1, rSELF // Pass Thread::Current. 1141*795d594fSAndroid Build Coastguard Worker bl \entrypoint // (mirror::Class* klass, Thread*) 1142*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME 1143*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 1144*795d594fSAndroid Build Coastguard Worker RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER 1145*795d594fSAndroid Build Coastguard WorkerEND \name 1146*795d594fSAndroid Build Coastguard Worker.endm 1147*795d594fSAndroid Build Coastguard Worker 1148*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_OBJECT_RESOLVED_TLAB art_quick_alloc_object_resolved_region_tlab, artAllocObjectFromCodeResolvedRegionTLAB, /* isInitialized */ 0 1149*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_OBJECT_RESOLVED_TLAB art_quick_alloc_object_initialized_region_tlab, artAllocObjectFromCodeInitializedRegionTLAB, /* isInitialized */ 1 1150*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_OBJECT_RESOLVED_TLAB art_quick_alloc_object_resolved_tlab, artAllocObjectFromCodeResolvedTLAB, /* isInitialized */ 0 1151*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_OBJECT_RESOLVED_TLAB art_quick_alloc_object_initialized_tlab, artAllocObjectFromCodeInitializedTLAB, /* isInitialized */ 1 1152*795d594fSAndroid Build Coastguard Worker 1153*795d594fSAndroid Build Coastguard Worker 1154*795d594fSAndroid Build Coastguard Worker// The common fast path code for art_quick_alloc_array_resolved/initialized_tlab 1155*795d594fSAndroid Build Coastguard Worker// and art_quick_alloc_array_resolved/initialized_region_tlab. 1156*795d594fSAndroid Build Coastguard Worker// 1157*795d594fSAndroid Build Coastguard Worker// r0: type, r1: component_count, r2: total_size, rSELF (r9): Thread::Current, r3, r12: free. 1158*795d594fSAndroid Build Coastguard Worker// Need to preserve r0 and r1 to the slow path. 1159*795d594fSAndroid Build Coastguard Worker.macro ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED_WITH_SIZE slowPathLabel 1160*795d594fSAndroid Build Coastguard Worker and r2, r2, #OBJECT_ALIGNMENT_MASK_TOGGLED // Apply alignment mask 1161*795d594fSAndroid Build Coastguard Worker // (addr + 7) & ~7. 1162*795d594fSAndroid Build Coastguard Worker 1163*795d594fSAndroid Build Coastguard Worker // Load thread_local_pos (r3) and 1164*795d594fSAndroid Build Coastguard Worker // thread_local_end (r12) with ldrd. 1165*795d594fSAndroid Build Coastguard Worker // Check constraints for ldrd. 1166*795d594fSAndroid Build Coastguard Worker#if !((THREAD_LOCAL_POS_OFFSET + 4 == THREAD_LOCAL_END_OFFSET) && (THREAD_LOCAL_POS_OFFSET % 8 == 0)) 1167*795d594fSAndroid Build Coastguard Worker#error "Thread::thread_local_pos/end must be consecutive and are 8 byte aligned for performance" 1168*795d594fSAndroid Build Coastguard Worker#endif 1169*795d594fSAndroid Build Coastguard Worker ldrd r3, r12, [rSELF, #THREAD_LOCAL_POS_OFFSET] 1170*795d594fSAndroid Build Coastguard Worker sub r12, r12, r3 // Compute the remaining buf size. 1171*795d594fSAndroid Build Coastguard Worker cmp r2, r12 // Check if the total_size fits. 1172*795d594fSAndroid Build Coastguard Worker // The array class is always initialized here. Unlike new-instance, 1173*795d594fSAndroid Build Coastguard Worker // this does not act as a double test. 1174*795d594fSAndroid Build Coastguard Worker bhi \slowPathLabel 1175*795d594fSAndroid Build Coastguard Worker // "Point of no slow path". Won't go to the slow path from here on. OK to clobber r0 and r1. 1176*795d594fSAndroid Build Coastguard Worker add r2, r2, r3 1177*795d594fSAndroid Build Coastguard Worker str r2, [rSELF, #THREAD_LOCAL_POS_OFFSET] // Store new thread_local_pos. 1178*795d594fSAndroid Build Coastguard Worker POISON_HEAP_REF r0 1179*795d594fSAndroid Build Coastguard Worker str r0, [r3, #MIRROR_OBJECT_CLASS_OFFSET] // Store the class pointer. 1180*795d594fSAndroid Build Coastguard Worker str r1, [r3, #MIRROR_ARRAY_LENGTH_OFFSET] // Store the array length. 1181*795d594fSAndroid Build Coastguard Worker mov r0, r3 1182*795d594fSAndroid Build Coastguard Worker// new-array is special. The class is loaded and immediately goes to the Initialized state 1183*795d594fSAndroid Build Coastguard Worker// before it is published. Therefore the only fence needed is for the publication of the object. 1184*795d594fSAndroid Build Coastguard Worker// See ClassLinker::CreateArrayClass() for more details. 1185*795d594fSAndroid Build Coastguard Worker 1186*795d594fSAndroid Build Coastguard Worker// For publication of the new array, we don't need a 'dmb ishst' here. 1187*795d594fSAndroid Build Coastguard Worker// The compiler generates 'dmb ishst' for all new-array insts. 1188*795d594fSAndroid Build Coastguard Worker bx lr 1189*795d594fSAndroid Build Coastguard Worker.endm 1190*795d594fSAndroid Build Coastguard Worker 1191*795d594fSAndroid Build Coastguard Worker// Caller must execute a constructor fence after this. 1192*795d594fSAndroid Build Coastguard Worker.macro GENERATE_ALLOC_ARRAY_TLAB name, entrypoint, size_setup 1193*795d594fSAndroid Build Coastguard WorkerENTRY \name 1194*795d594fSAndroid Build Coastguard Worker // Fast path array allocation for region tlab allocation. 1195*795d594fSAndroid Build Coastguard Worker // r0: mirror::Class* type 1196*795d594fSAndroid Build Coastguard Worker // r1: int32_t component_count 1197*795d594fSAndroid Build Coastguard Worker // rSELF (r9): thread 1198*795d594fSAndroid Build Coastguard Worker // r2, r3, r12: free. 1199*795d594fSAndroid Build Coastguard Worker \size_setup .Lslow_path\name 1200*795d594fSAndroid Build Coastguard Worker ALLOC_ARRAY_TLAB_FAST_PATH_RESOLVED_WITH_SIZE .Lslow_path\name 1201*795d594fSAndroid Build Coastguard Worker.Lslow_path\name: 1202*795d594fSAndroid Build Coastguard Worker // r0: mirror::Class* klass 1203*795d594fSAndroid Build Coastguard Worker // r1: int32_t component_count 1204*795d594fSAndroid Build Coastguard Worker // r2: Thread* self 1205*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_ONLY_FRAME r2 // save callee saves in case of GC 1206*795d594fSAndroid Build Coastguard Worker mov r2, rSELF // pass Thread::Current 1207*795d594fSAndroid Build Coastguard Worker bl \entrypoint 1208*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME 1209*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 1210*795d594fSAndroid Build Coastguard Worker RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER 1211*795d594fSAndroid Build Coastguard WorkerEND \name 1212*795d594fSAndroid Build Coastguard Worker.endm 1213*795d594fSAndroid Build Coastguard Worker 1214*795d594fSAndroid Build Coastguard Worker.macro COMPUTE_ARRAY_SIZE_UNKNOWN slow_path 1215*795d594fSAndroid Build Coastguard Worker movw r2, #((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_WIDE_ARRAY_DATA_OFFSET) / 8) 1216*795d594fSAndroid Build Coastguard Worker cmp r1, r2 1217*795d594fSAndroid Build Coastguard Worker bhi \slow_path 1218*795d594fSAndroid Build Coastguard Worker // Array classes are never finalizable 1219*795d594fSAndroid Build Coastguard Worker // or uninitialized, no need to check. 1220*795d594fSAndroid Build Coastguard Worker ldr r3, [r0, #MIRROR_CLASS_COMPONENT_TYPE_OFFSET] // Load component type 1221*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF r3 1222*795d594fSAndroid Build Coastguard Worker ldr r3, [r3, #MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET] 1223*795d594fSAndroid Build Coastguard Worker lsr r3, r3, #PRIMITIVE_TYPE_SIZE_SHIFT_SHIFT // Component size shift is in high 16 1224*795d594fSAndroid Build Coastguard Worker // bits. 1225*795d594fSAndroid Build Coastguard Worker lsl r2, r1, r3 // Calculate data size 1226*795d594fSAndroid Build Coastguard Worker // Add array data offset and alignment. 1227*795d594fSAndroid Build Coastguard Worker add r2, r2, #(MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) 1228*795d594fSAndroid Build Coastguard Worker#if MIRROR_WIDE_ARRAY_DATA_OFFSET != MIRROR_INT_ARRAY_DATA_OFFSET + 4 1229*795d594fSAndroid Build Coastguard Worker#error Long array data offset must be 4 greater than int array data offset. 1230*795d594fSAndroid Build Coastguard Worker#endif 1231*795d594fSAndroid Build Coastguard Worker 1232*795d594fSAndroid Build Coastguard Worker add r3, r3, #1 // Add 4 to the length only if the 1233*795d594fSAndroid Build Coastguard Worker // component size shift is 3 1234*795d594fSAndroid Build Coastguard Worker // (for 64 bit alignment). 1235*795d594fSAndroid Build Coastguard Worker and r3, r3, #4 1236*795d594fSAndroid Build Coastguard Worker add r2, r2, r3 1237*795d594fSAndroid Build Coastguard Worker.endm 1238*795d594fSAndroid Build Coastguard Worker 1239*795d594fSAndroid Build Coastguard Worker.macro COMPUTE_ARRAY_SIZE_8 slow_path 1240*795d594fSAndroid Build Coastguard Worker // Possibly a large object, go slow. 1241*795d594fSAndroid Build Coastguard Worker // Also does negative array size check. 1242*795d594fSAndroid Build Coastguard Worker movw r2, #(MIN_LARGE_OBJECT_THRESHOLD - MIRROR_INT_ARRAY_DATA_OFFSET) 1243*795d594fSAndroid Build Coastguard Worker cmp r1, r2 1244*795d594fSAndroid Build Coastguard Worker bhi \slow_path 1245*795d594fSAndroid Build Coastguard Worker // Add array data offset and alignment. 1246*795d594fSAndroid Build Coastguard Worker add r2, r1, #(MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) 1247*795d594fSAndroid Build Coastguard Worker.endm 1248*795d594fSAndroid Build Coastguard Worker 1249*795d594fSAndroid Build Coastguard Worker.macro COMPUTE_ARRAY_SIZE_16 slow_path 1250*795d594fSAndroid Build Coastguard Worker // Possibly a large object, go slow. 1251*795d594fSAndroid Build Coastguard Worker // Also does negative array size check. 1252*795d594fSAndroid Build Coastguard Worker movw r2, #((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_INT_ARRAY_DATA_OFFSET) / 2) 1253*795d594fSAndroid Build Coastguard Worker cmp r1, r2 1254*795d594fSAndroid Build Coastguard Worker bhi \slow_path 1255*795d594fSAndroid Build Coastguard Worker lsl r2, r1, #1 1256*795d594fSAndroid Build Coastguard Worker // Add array data offset and alignment. 1257*795d594fSAndroid Build Coastguard Worker add r2, r2, #(MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) 1258*795d594fSAndroid Build Coastguard Worker.endm 1259*795d594fSAndroid Build Coastguard Worker 1260*795d594fSAndroid Build Coastguard Worker.macro COMPUTE_ARRAY_SIZE_32 slow_path 1261*795d594fSAndroid Build Coastguard Worker // Possibly a large object, go slow. 1262*795d594fSAndroid Build Coastguard Worker // Also does negative array size check. 1263*795d594fSAndroid Build Coastguard Worker movw r2, #((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_INT_ARRAY_DATA_OFFSET) / 4) 1264*795d594fSAndroid Build Coastguard Worker cmp r1, r2 1265*795d594fSAndroid Build Coastguard Worker bhi \slow_path 1266*795d594fSAndroid Build Coastguard Worker lsl r2, r1, #2 1267*795d594fSAndroid Build Coastguard Worker // Add array data offset and alignment. 1268*795d594fSAndroid Build Coastguard Worker add r2, r2, #(MIRROR_INT_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) 1269*795d594fSAndroid Build Coastguard Worker.endm 1270*795d594fSAndroid Build Coastguard Worker 1271*795d594fSAndroid Build Coastguard Worker.macro COMPUTE_ARRAY_SIZE_64 slow_path 1272*795d594fSAndroid Build Coastguard Worker // Possibly a large object, go slow. 1273*795d594fSAndroid Build Coastguard Worker // Also does negative array size check. 1274*795d594fSAndroid Build Coastguard Worker movw r2, #((MIN_LARGE_OBJECT_THRESHOLD - MIRROR_LONG_ARRAY_DATA_OFFSET) / 8) 1275*795d594fSAndroid Build Coastguard Worker cmp r1, r2 1276*795d594fSAndroid Build Coastguard Worker bhi \slow_path 1277*795d594fSAndroid Build Coastguard Worker lsl r2, r1, #3 1278*795d594fSAndroid Build Coastguard Worker // Add array data offset and alignment. 1279*795d594fSAndroid Build Coastguard Worker add r2, r2, #(MIRROR_WIDE_ARRAY_DATA_OFFSET + OBJECT_ALIGNMENT_MASK) 1280*795d594fSAndroid Build Coastguard Worker.endm 1281*795d594fSAndroid Build Coastguard Worker 1282*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_UNKNOWN 1283*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved8_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_8 1284*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved16_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_16 1285*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved32_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_32 1286*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_region_tlab, artAllocArrayFromCodeResolvedRegionTLAB, COMPUTE_ARRAY_SIZE_64 1287*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_UNKNOWN 1288*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved8_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_8 1289*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved16_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_16 1290*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved32_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_32 1291*795d594fSAndroid Build Coastguard WorkerGENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_64 1292*795d594fSAndroid Build Coastguard Worker 1293*795d594fSAndroid Build Coastguard Worker /* 1294*795d594fSAndroid Build Coastguard Worker * Called by managed code when the value in rSUSPEND has been decremented to 0. 1295*795d594fSAndroid Build Coastguard Worker */ 1296*795d594fSAndroid Build Coastguard Worker .extern artTestSuspendFromCode 1297*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_test_suspend 1298*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_EVERYTHING_FRAME r0, RUNTIME_SAVE_EVERYTHING_FOR_SUSPEND_CHECK_METHOD_OFFSET @ save everything for GC stack crawl 1299*795d594fSAndroid Build Coastguard Worker mov r0, rSELF 1300*795d594fSAndroid Build Coastguard Worker bl artTestSuspendFromCode @ (Thread*) 1301*795d594fSAndroid Build Coastguard Worker 1302*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 1303*795d594fSAndroid Build Coastguard Worker cbnz r0, .Ltest_suspend_deoptimize 1304*795d594fSAndroid Build Coastguard Worker 1305*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_EVERYTHING_FRAME 1306*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 1307*795d594fSAndroid Build Coastguard Worker bx lr 1308*795d594fSAndroid Build Coastguard Worker 1309*795d594fSAndroid Build Coastguard Worker.Ltest_suspend_deoptimize: 1310*795d594fSAndroid Build Coastguard Worker // Deoptimize 1311*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_EVERYTHING 1312*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 1313*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 1314*795d594fSAndroid Build Coastguard WorkerEND art_quick_test_suspend 1315*795d594fSAndroid Build Coastguard Worker 1316*795d594fSAndroid Build Coastguard Worker .extern artImplicitSuspendFromCode 1317*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_implicit_suspend 1318*795d594fSAndroid Build Coastguard Worker mov r0, rSELF 1319*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_ONLY_FRAME r1 @ save callee saves for stack crawl 1320*795d594fSAndroid Build Coastguard Worker bl artImplicitSuspendFromCode @ (Thread*) 1321*795d594fSAndroid Build Coastguard Worker 1322*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 1323*795d594fSAndroid Build Coastguard Worker cbnz r0, .Limplicit_suspend_deopt 1324*795d594fSAndroid Build Coastguard Worker 1325*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME 1326*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 1327*795d594fSAndroid Build Coastguard Worker bx lr 1328*795d594fSAndroid Build Coastguard Worker 1329*795d594fSAndroid Build Coastguard Worker.Limplicit_suspend_deopt: 1330*795d594fSAndroid Build Coastguard Worker // Deoptimize 1331*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_ONLY 1332*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 1333*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 1334*795d594fSAndroid Build Coastguard WorkerEND art_quick_implicit_suspend 1335*795d594fSAndroid Build Coastguard Worker 1336*795d594fSAndroid Build Coastguard Worker /* 1337*795d594fSAndroid Build Coastguard Worker * Called by managed code that is attempting to call a method on a proxy class. On entry 1338*795d594fSAndroid Build Coastguard Worker * r0 holds the proxy method and r1 holds the receiver; r2 and r3 may contain arguments. The 1339*795d594fSAndroid Build Coastguard Worker * frame size of the invoked proxy method agrees with a ref and args callee save frame. 1340*795d594fSAndroid Build Coastguard Worker */ 1341*795d594fSAndroid Build Coastguard Worker .extern artQuickProxyInvokeHandler 1342*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_proxy_invoke_handler 1343*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_R0 1344*795d594fSAndroid Build Coastguard Worker mov r2, rSELF @ pass Thread::Current 1345*795d594fSAndroid Build Coastguard Worker mov r3, sp @ pass SP 1346*795d594fSAndroid Build Coastguard Worker blx artQuickProxyInvokeHandler @ (Method* proxy method, receiver, Thread*, SP) 1347*795d594fSAndroid Build Coastguard Worker ldr r2, [rSELF, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ 1348*795d594fSAndroid Build Coastguard Worker // Tear down the callee-save frame. Skip arg registers. 1349*795d594fSAndroid Build Coastguard Worker add sp, #(FRAME_SIZE_SAVE_REFS_AND_ARGS - FRAME_SIZE_SAVE_REFS_ONLY) 1350*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -(FRAME_SIZE_SAVE_REFS_AND_ARGS - FRAME_SIZE_SAVE_REFS_ONLY) 1351*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME 1352*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 1353*795d594fSAndroid Build Coastguard Worker cbnz r2, 1f @ success if no exception is pending 1354*795d594fSAndroid Build Coastguard Worker vmov d0, r0, r1 @ store into fpr, for when it's a fpr return... 1355*795d594fSAndroid Build Coastguard Worker bx lr @ return on success 1356*795d594fSAndroid Build Coastguard Worker1: 1357*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION 1358*795d594fSAndroid Build Coastguard WorkerEND art_quick_proxy_invoke_handler 1359*795d594fSAndroid Build Coastguard Worker 1360*795d594fSAndroid Build Coastguard Worker /* 1361*795d594fSAndroid Build Coastguard Worker * Called to resolve an imt conflict. 1362*795d594fSAndroid Build Coastguard Worker * r0 is the conflict ArtMethod. 1363*795d594fSAndroid Build Coastguard Worker * r12 is a hidden argument that holds the target interface method. 1364*795d594fSAndroid Build Coastguard Worker * 1365*795d594fSAndroid Build Coastguard Worker * Note that this stub writes to r0, r4, and r12. 1366*795d594fSAndroid Build Coastguard Worker */ 1367*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_imt_conflict_trampoline 1368*795d594fSAndroid Build Coastguard Worker ldr r0, [r0, #ART_METHOD_JNI_OFFSET_32] // Load ImtConflictTable 1369*795d594fSAndroid Build Coastguard Worker ldr r4, [r0] // Load first entry in ImtConflictTable. 1370*795d594fSAndroid Build Coastguard Worker.Limt_table_iterate: 1371*795d594fSAndroid Build Coastguard Worker cmp r4, r12 1372*795d594fSAndroid Build Coastguard Worker // Branch if found. Benchmarks have shown doing a branch here is better. 1373*795d594fSAndroid Build Coastguard Worker beq .Limt_table_found 1374*795d594fSAndroid Build Coastguard Worker // If the entry is null, the interface method is not in the ImtConflictTable. 1375*795d594fSAndroid Build Coastguard Worker cbz r4, .Lconflict_trampoline 1376*795d594fSAndroid Build Coastguard Worker // Iterate over the entries of the ImtConflictTable. 1377*795d594fSAndroid Build Coastguard Worker ldr r4, [r0, #(2 * __SIZEOF_POINTER__)]! 1378*795d594fSAndroid Build Coastguard Worker b .Limt_table_iterate 1379*795d594fSAndroid Build Coastguard Worker.Limt_table_found: 1380*795d594fSAndroid Build Coastguard Worker // We successfully hit an entry in the table. Load the target method 1381*795d594fSAndroid Build Coastguard Worker // and jump to it. 1382*795d594fSAndroid Build Coastguard Worker ldr r0, [r0, #__SIZEOF_POINTER__] 1383*795d594fSAndroid Build Coastguard Worker ldr pc, [r0, #ART_METHOD_QUICK_CODE_OFFSET_32] 1384*795d594fSAndroid Build Coastguard Worker.Lconflict_trampoline: 1385*795d594fSAndroid Build Coastguard Worker // Pass interface method to the trampoline. 1386*795d594fSAndroid Build Coastguard Worker mov r0, r12 1387*795d594fSAndroid Build Coastguard Worker INVOKE_TRAMPOLINE_BODY artInvokeInterfaceTrampoline 1388*795d594fSAndroid Build Coastguard WorkerEND art_quick_imt_conflict_trampoline 1389*795d594fSAndroid Build Coastguard Worker 1390*795d594fSAndroid Build Coastguard Worker .extern artQuickResolutionTrampoline 1391*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_resolution_trampoline 1392*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_AND_ARGS_FRAME r2 1393*795d594fSAndroid Build Coastguard Worker mov r2, rSELF @ pass Thread::Current 1394*795d594fSAndroid Build Coastguard Worker mov r3, sp @ pass SP 1395*795d594fSAndroid Build Coastguard Worker blx artQuickResolutionTrampoline @ (Method* called, receiver, Thread*, SP) 1396*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 1397*795d594fSAndroid Build Coastguard Worker cbz r0, 1f @ is code pointer null? goto exception 1398*795d594fSAndroid Build Coastguard Worker mov r12, r0 1399*795d594fSAndroid Build Coastguard Worker ldr r0, [sp, #0] @ load resolved method in r0 1400*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_AND_ARGS_FRAME 1401*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 1402*795d594fSAndroid Build Coastguard Worker bx r12 @ tail-call into actual code 1403*795d594fSAndroid Build Coastguard Worker1: 1404*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_AND_ARGS 1405*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_AND_ARGS_FRAME 1406*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION 1407*795d594fSAndroid Build Coastguard WorkerEND art_quick_resolution_trampoline 1408*795d594fSAndroid Build Coastguard Worker 1409*795d594fSAndroid Build Coastguard Worker /* 1410*795d594fSAndroid Build Coastguard Worker * Called to do a generic JNI down-call 1411*795d594fSAndroid Build Coastguard Worker */ 1412*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_generic_jni_trampoline 1413*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_R0 1414*795d594fSAndroid Build Coastguard Worker 1415*795d594fSAndroid Build Coastguard Worker // Save rSELF 1416*795d594fSAndroid Build Coastguard Worker mov r11, rSELF 1417*795d594fSAndroid Build Coastguard Worker // Save SP , so we can have static CFI info. r10 is saved in ref_and_args. 1418*795d594fSAndroid Build Coastguard Worker mov r10, sp 1419*795d594fSAndroid Build Coastguard Worker .cfi_def_cfa_register r10 1420*795d594fSAndroid Build Coastguard Worker 1421*795d594fSAndroid Build Coastguard Worker sub sp, sp, #GENERIC_JNI_TRAMPOLINE_RESERVED_AREA 1422*795d594fSAndroid Build Coastguard Worker 1423*795d594fSAndroid Build Coastguard Worker // prepare for artQuickGenericJniTrampoline call 1424*795d594fSAndroid Build Coastguard Worker // (Thread*, managed_sp, reserved_area) 1425*795d594fSAndroid Build Coastguard Worker // r0 r1 r2 <= C calling convention 1426*795d594fSAndroid Build Coastguard Worker // rSELF r10 sp <= where they are 1427*795d594fSAndroid Build Coastguard Worker 1428*795d594fSAndroid Build Coastguard Worker mov r0, rSELF // Thread* 1429*795d594fSAndroid Build Coastguard Worker mov r1, r10 // SP for the managed frame. 1430*795d594fSAndroid Build Coastguard Worker mov r2, sp // reserved area for arguments and other saved data (up to managed frame) 1431*795d594fSAndroid Build Coastguard Worker blx artQuickGenericJniTrampoline // (Thread*, managed_sp, reserved_area) 1432*795d594fSAndroid Build Coastguard Worker 1433*795d594fSAndroid Build Coastguard Worker // The C call will have registered the complete save-frame on success. 1434*795d594fSAndroid Build Coastguard Worker // The result of the call is: 1435*795d594fSAndroid Build Coastguard Worker // r0: pointer to native code, 0 on error. 1436*795d594fSAndroid Build Coastguard Worker // The bottom of the reserved area contains values for arg registers, 1437*795d594fSAndroid Build Coastguard Worker // hidden arg register and SP for out args for the call. 1438*795d594fSAndroid Build Coastguard Worker 1439*795d594fSAndroid Build Coastguard Worker // Check for error (class init check or locking for synchronized native method can throw). 1440*795d594fSAndroid Build Coastguard Worker cbz r0, .Lexception_in_native 1441*795d594fSAndroid Build Coastguard Worker 1442*795d594fSAndroid Build Coastguard Worker // Save the code pointer 1443*795d594fSAndroid Build Coastguard Worker mov lr, r0 1444*795d594fSAndroid Build Coastguard Worker 1445*795d594fSAndroid Build Coastguard Worker // Load parameters from frame into registers r0-r3 (soft-float), 1446*795d594fSAndroid Build Coastguard Worker // hidden arg (r4) for @CriticalNative and SP for out args. 1447*795d594fSAndroid Build Coastguard Worker pop {r0-r3, r4, ip} 1448*795d594fSAndroid Build Coastguard Worker 1449*795d594fSAndroid Build Coastguard Worker // Apply the new SP for out args, releasing unneeded reserved area. 1450*795d594fSAndroid Build Coastguard Worker mov sp, ip 1451*795d594fSAndroid Build Coastguard Worker 1452*795d594fSAndroid Build Coastguard Worker // Softfloat. 1453*795d594fSAndroid Build Coastguard Worker // TODO: Change to hardfloat when supported. 1454*795d594fSAndroid Build Coastguard Worker 1455*795d594fSAndroid Build Coastguard Worker blx lr // native call. 1456*795d594fSAndroid Build Coastguard Worker 1457*795d594fSAndroid Build Coastguard Worker // result sign extension is handled in C code 1458*795d594fSAndroid Build Coastguard Worker // prepare for artQuickGenericJniEndTrampoline call 1459*795d594fSAndroid Build Coastguard Worker // (Thread*, result, result_f) 1460*795d594fSAndroid Build Coastguard Worker // r0 r2,r3 stack <= C calling convention 1461*795d594fSAndroid Build Coastguard Worker // r11 r0,r1 r0,r1 <= where they are 1462*795d594fSAndroid Build Coastguard Worker sub sp, sp, #8 // Stack alignment. 1463*795d594fSAndroid Build Coastguard Worker 1464*795d594fSAndroid Build Coastguard Worker push {r0-r1} 1465*795d594fSAndroid Build Coastguard Worker mov r3, r1 1466*795d594fSAndroid Build Coastguard Worker mov r2, r0 1467*795d594fSAndroid Build Coastguard Worker mov r0, r11 1468*795d594fSAndroid Build Coastguard Worker 1469*795d594fSAndroid Build Coastguard Worker blx artQuickGenericJniEndTrampoline 1470*795d594fSAndroid Build Coastguard Worker 1471*795d594fSAndroid Build Coastguard Worker // Restore self pointer. 1472*795d594fSAndroid Build Coastguard Worker mov rSELF, r11 1473*795d594fSAndroid Build Coastguard Worker 1474*795d594fSAndroid Build Coastguard Worker // Pending exceptions possible. 1475*795d594fSAndroid Build Coastguard Worker ldr r2, [rSELF, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ 1476*795d594fSAndroid Build Coastguard Worker cbnz r2, .Lexception_in_native 1477*795d594fSAndroid Build Coastguard Worker 1478*795d594fSAndroid Build Coastguard Worker // Tear down the alloca. 1479*795d594fSAndroid Build Coastguard Worker mov sp, r10 1480*795d594fSAndroid Build Coastguard Worker 1481*795d594fSAndroid Build Coastguard Worker // store into fpr, for when it's a fpr return... 1482*795d594fSAndroid Build Coastguard Worker vmov d0, r0, r1 1483*795d594fSAndroid Build Coastguard Worker 1484*795d594fSAndroid Build Coastguard Worker LOAD_RUNTIME_INSTANCE r2 1485*795d594fSAndroid Build Coastguard Worker ldrb r2, [r2, #RUN_EXIT_HOOKS_OFFSET_FROM_RUNTIME_INSTANCE] 1486*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 1487*795d594fSAndroid Build Coastguard Worker cbnz r2, .Lcall_method_exit_hook 1488*795d594fSAndroid Build Coastguard Worker.Lcall_method_exit_hook_done: 1489*795d594fSAndroid Build Coastguard Worker 1490*795d594fSAndroid Build Coastguard Worker // Tear down the callee-save frame. Skip arg registers. 1491*795d594fSAndroid Build Coastguard Worker .cfi_def_cfa_register sp 1492*795d594fSAndroid Build Coastguard Worker add sp, #(FRAME_SIZE_SAVE_REFS_AND_ARGS - 7 * 4) 1493*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -(FRAME_SIZE_SAVE_REFS_AND_ARGS - 7 * 4) 1494*795d594fSAndroid Build Coastguard Worker pop {r5-r8, r10-r11, lr} @ This must match the non-args registers restored by 1495*795d594fSAndroid Build Coastguard Worker .cfi_restore r5 @ `RESTORE_SAVE_REFS_AND_ARGS_FRAME`. 1496*795d594fSAndroid Build Coastguard Worker .cfi_restore r6 1497*795d594fSAndroid Build Coastguard Worker .cfi_restore r7 1498*795d594fSAndroid Build Coastguard Worker .cfi_restore r8 1499*795d594fSAndroid Build Coastguard Worker .cfi_restore r10 1500*795d594fSAndroid Build Coastguard Worker .cfi_restore r11 1501*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 1502*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -(7 * 4) 1503*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 1504*795d594fSAndroid Build Coastguard Worker bx lr // ret 1505*795d594fSAndroid Build Coastguard Worker 1506*795d594fSAndroid Build Coastguard Worker.Lcall_method_exit_hook: 1507*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA r10, FRAME_SIZE_SAVE_REFS_AND_ARGS 1508*795d594fSAndroid Build Coastguard Worker mov r2, #FRAME_SIZE_SAVE_REFS_AND_ARGS 1509*795d594fSAndroid Build Coastguard Worker bl art_quick_method_exit_hook 1510*795d594fSAndroid Build Coastguard Worker b .Lcall_method_exit_hook_done 1511*795d594fSAndroid Build Coastguard Worker 1512*795d594fSAndroid Build Coastguard Worker.Lexception_in_native: 1513*795d594fSAndroid Build Coastguard Worker ldr ip, [rSELF, #THREAD_TOP_QUICK_FRAME_OFFSET] 1514*795d594fSAndroid Build Coastguard Worker add ip, ip, #-1 // Remove the GenericJNI tag. ADD/SUB writing directly to SP is UNPREDICTABLE. 1515*795d594fSAndroid Build Coastguard Worker mov sp, ip 1516*795d594fSAndroid Build Coastguard Worker bl art_deliver_pending_exception 1517*795d594fSAndroid Build Coastguard WorkerEND art_quick_generic_jni_trampoline 1518*795d594fSAndroid Build Coastguard Worker 1519*795d594fSAndroid Build Coastguard WorkerENTRY art_deliver_pending_exception 1520*795d594fSAndroid Build Coastguard Worker # This will create a new save-all frame, required by the runtime. 1521*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION 1522*795d594fSAndroid Build Coastguard WorkerEND art_deliver_pending_exception 1523*795d594fSAndroid Build Coastguard Worker 1524*795d594fSAndroid Build Coastguard Worker .extern artQuickToInterpreterBridge 1525*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_to_interpreter_bridge 1526*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_AND_ARGS_FRAME r1 1527*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ pass Thread::Current 1528*795d594fSAndroid Build Coastguard Worker mov r2, sp @ pass SP 1529*795d594fSAndroid Build Coastguard Worker blx artQuickToInterpreterBridge @ (Method* method, Thread*, SP) 1530*795d594fSAndroid Build Coastguard Worker ldr r2, [rSELF, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_ 1531*795d594fSAndroid Build Coastguard Worker // Tear down the callee-save frame. Skip arg registers. 1532*795d594fSAndroid Build Coastguard Worker add sp, #(FRAME_SIZE_SAVE_REFS_AND_ARGS - FRAME_SIZE_SAVE_REFS_ONLY) 1533*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -(FRAME_SIZE_SAVE_REFS_AND_ARGS - FRAME_SIZE_SAVE_REFS_ONLY) 1534*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME 1535*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 1536*795d594fSAndroid Build Coastguard Worker cbnz r2, 1f @ success if no exception is pending 1537*795d594fSAndroid Build Coastguard Worker vmov d0, r0, r1 @ store into fpr, for when it's a fpr return... 1538*795d594fSAndroid Build Coastguard Worker bx lr @ return on success 1539*795d594fSAndroid Build Coastguard Worker1: 1540*795d594fSAndroid Build Coastguard Worker DELIVER_PENDING_EXCEPTION 1541*795d594fSAndroid Build Coastguard WorkerEND art_quick_to_interpreter_bridge 1542*795d594fSAndroid Build Coastguard Worker 1543*795d594fSAndroid Build Coastguard Worker/* 1544*795d594fSAndroid Build Coastguard Worker * Called to attempt to execute an obsolete method. 1545*795d594fSAndroid Build Coastguard Worker */ 1546*795d594fSAndroid Build Coastguard WorkerONE_ARG_RUNTIME_EXCEPTION art_invoke_obsolete_method_stub, artInvokeObsoleteMethod 1547*795d594fSAndroid Build Coastguard Worker 1548*795d594fSAndroid Build Coastguard Worker /* 1549*795d594fSAndroid Build Coastguard Worker * Compiled code has requested that we deoptimize into the interpreter. The deoptimization 1550*795d594fSAndroid Build Coastguard Worker * will long jump to the interpreter bridge. 1551*795d594fSAndroid Build Coastguard Worker */ 1552*795d594fSAndroid Build Coastguard Worker .extern artDeoptimizeFromCompiledCode 1553*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_deoptimize_from_compiled_code 1554*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_EVERYTHING_FRAME r1 1555*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ pass Thread::Current 1556*795d594fSAndroid Build Coastguard Worker blx artDeoptimizeFromCompiledCode @ (DeoptimizationKind, Thread*) 1557*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 1558*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 1559*795d594fSAndroid Build Coastguard WorkerEND art_quick_deoptimize_from_compiled_code 1560*795d594fSAndroid Build Coastguard Worker 1561*795d594fSAndroid Build Coastguard Worker /* 1562*795d594fSAndroid Build Coastguard Worker * Signed 64-bit integer multiply. 1563*795d594fSAndroid Build Coastguard Worker * 1564*795d594fSAndroid Build Coastguard Worker * Consider WXxYZ (r1r0 x r3r2) with a long multiply: 1565*795d594fSAndroid Build Coastguard Worker * WX 1566*795d594fSAndroid Build Coastguard Worker * x YZ 1567*795d594fSAndroid Build Coastguard Worker * -------- 1568*795d594fSAndroid Build Coastguard Worker * ZW ZX 1569*795d594fSAndroid Build Coastguard Worker * YW YX 1570*795d594fSAndroid Build Coastguard Worker * 1571*795d594fSAndroid Build Coastguard Worker * The low word of the result holds ZX, the high word holds 1572*795d594fSAndroid Build Coastguard Worker * (ZW+YX) + (the high overflow from ZX). YW doesn't matter because 1573*795d594fSAndroid Build Coastguard Worker * it doesn't fit in the low 64 bits. 1574*795d594fSAndroid Build Coastguard Worker * 1575*795d594fSAndroid Build Coastguard Worker * Unlike most ARM math operations, multiply instructions have 1576*795d594fSAndroid Build Coastguard Worker * restrictions on using the same register more than once (Rd and Rm 1577*795d594fSAndroid Build Coastguard Worker * cannot be the same). 1578*795d594fSAndroid Build Coastguard Worker */ 1579*795d594fSAndroid Build Coastguard Worker /* mul-long vAA, vBB, vCC */ 1580*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_mul_long 1581*795d594fSAndroid Build Coastguard Worker push {r9-r10} 1582*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 8 1583*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r9, 0 1584*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r10, 4 1585*795d594fSAndroid Build Coastguard Worker mul ip, r2, r1 @ ip<- ZxW 1586*795d594fSAndroid Build Coastguard Worker umull r9, r10, r2, r0 @ r9/r10 <- ZxX 1587*795d594fSAndroid Build Coastguard Worker mla r2, r0, r3, ip @ r2<- YxX + (ZxW) 1588*795d594fSAndroid Build Coastguard Worker add r10, r2, r10 @ r10<- r10 + low(ZxW + (YxX)) 1589*795d594fSAndroid Build Coastguard Worker mov r0,r9 1590*795d594fSAndroid Build Coastguard Worker mov r1,r10 1591*795d594fSAndroid Build Coastguard Worker pop {r9-r10} 1592*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -8 1593*795d594fSAndroid Build Coastguard Worker .cfi_restore r9 1594*795d594fSAndroid Build Coastguard Worker .cfi_restore r10 1595*795d594fSAndroid Build Coastguard Worker bx lr 1596*795d594fSAndroid Build Coastguard WorkerEND art_quick_mul_long 1597*795d594fSAndroid Build Coastguard Worker 1598*795d594fSAndroid Build Coastguard Worker /* 1599*795d594fSAndroid Build Coastguard Worker * Long integer shift. This is different from the generic 32/64-bit 1600*795d594fSAndroid Build Coastguard Worker * binary operations because vAA/vBB are 64-bit but vCC (the shift 1601*795d594fSAndroid Build Coastguard Worker * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low 1602*795d594fSAndroid Build Coastguard Worker * 6 bits. 1603*795d594fSAndroid Build Coastguard Worker * On entry: 1604*795d594fSAndroid Build Coastguard Worker * r0: low word 1605*795d594fSAndroid Build Coastguard Worker * r1: high word 1606*795d594fSAndroid Build Coastguard Worker * r2: shift count 1607*795d594fSAndroid Build Coastguard Worker */ 1608*795d594fSAndroid Build Coastguard Worker /* shl-long vAA, vBB, vCC */ 1609*795d594fSAndroid Build Coastguard WorkerARM_ENTRY art_quick_shl_long @ ARM code as thumb code requires spills 1610*795d594fSAndroid Build Coastguard Worker and r2, r2, #63 @ r2<- r2 & 0x3f 1611*795d594fSAndroid Build Coastguard Worker mov r1, r1, asl r2 @ r1<- r1 << r2 1612*795d594fSAndroid Build Coastguard Worker rsb r3, r2, #32 @ r3<- 32 - r2 1613*795d594fSAndroid Build Coastguard Worker orr r1, r1, r0, lsr r3 @ r1<- r1 | (r0 << (32-r2)) 1614*795d594fSAndroid Build Coastguard Worker subs ip, r2, #32 @ ip<- r2 - 32 1615*795d594fSAndroid Build Coastguard Worker movpl r1, r0, asl ip @ if r2 >= 32, r1<- r0 << (r2-32) 1616*795d594fSAndroid Build Coastguard Worker mov r0, r0, asl r2 @ r0<- r0 << r2 1617*795d594fSAndroid Build Coastguard Worker bx lr 1618*795d594fSAndroid Build Coastguard WorkerEND art_quick_shl_long 1619*795d594fSAndroid Build Coastguard Worker 1620*795d594fSAndroid Build Coastguard Worker /* 1621*795d594fSAndroid Build Coastguard Worker * Long integer shift. This is different from the generic 32/64-bit 1622*795d594fSAndroid Build Coastguard Worker * binary operations because vAA/vBB are 64-bit but vCC (the shift 1623*795d594fSAndroid Build Coastguard Worker * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low 1624*795d594fSAndroid Build Coastguard Worker * 6 bits. 1625*795d594fSAndroid Build Coastguard Worker * On entry: 1626*795d594fSAndroid Build Coastguard Worker * r0: low word 1627*795d594fSAndroid Build Coastguard Worker * r1: high word 1628*795d594fSAndroid Build Coastguard Worker * r2: shift count 1629*795d594fSAndroid Build Coastguard Worker */ 1630*795d594fSAndroid Build Coastguard Worker /* shr-long vAA, vBB, vCC */ 1631*795d594fSAndroid Build Coastguard WorkerARM_ENTRY art_quick_shr_long @ ARM code as thumb code requires spills 1632*795d594fSAndroid Build Coastguard Worker and r2, r2, #63 @ r0<- r0 & 0x3f 1633*795d594fSAndroid Build Coastguard Worker mov r0, r0, lsr r2 @ r0<- r2 >> r2 1634*795d594fSAndroid Build Coastguard Worker rsb r3, r2, #32 @ r3<- 32 - r2 1635*795d594fSAndroid Build Coastguard Worker orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 1636*795d594fSAndroid Build Coastguard Worker subs ip, r2, #32 @ ip<- r2 - 32 1637*795d594fSAndroid Build Coastguard Worker movpl r0, r1, asr ip @ if r2 >= 32, r0<-r1 >> (r2-32) 1638*795d594fSAndroid Build Coastguard Worker mov r1, r1, asr r2 @ r1<- r1 >> r2 1639*795d594fSAndroid Build Coastguard Worker bx lr 1640*795d594fSAndroid Build Coastguard WorkerEND art_quick_shr_long 1641*795d594fSAndroid Build Coastguard Worker 1642*795d594fSAndroid Build Coastguard Worker /* 1643*795d594fSAndroid Build Coastguard Worker * Long integer shift. This is different from the generic 32/64-bit 1644*795d594fSAndroid Build Coastguard Worker * binary operations because vAA/vBB are 64-bit but vCC (the shift 1645*795d594fSAndroid Build Coastguard Worker * distance) is 32-bit. Also, Dalvik requires us to ignore all but the low 1646*795d594fSAndroid Build Coastguard Worker * 6 bits. 1647*795d594fSAndroid Build Coastguard Worker * On entry: 1648*795d594fSAndroid Build Coastguard Worker * r0: low word 1649*795d594fSAndroid Build Coastguard Worker * r1: high word 1650*795d594fSAndroid Build Coastguard Worker * r2: shift count 1651*795d594fSAndroid Build Coastguard Worker */ 1652*795d594fSAndroid Build Coastguard Worker /* ushr-long vAA, vBB, vCC */ 1653*795d594fSAndroid Build Coastguard WorkerARM_ENTRY art_quick_ushr_long @ ARM code as thumb code requires spills 1654*795d594fSAndroid Build Coastguard Worker and r2, r2, #63 @ r0<- r0 & 0x3f 1655*795d594fSAndroid Build Coastguard Worker mov r0, r0, lsr r2 @ r0<- r2 >> r2 1656*795d594fSAndroid Build Coastguard Worker rsb r3, r2, #32 @ r3<- 32 - r2 1657*795d594fSAndroid Build Coastguard Worker orr r0, r0, r1, asl r3 @ r0<- r0 | (r1 << (32-r2)) 1658*795d594fSAndroid Build Coastguard Worker subs ip, r2, #32 @ ip<- r2 - 32 1659*795d594fSAndroid Build Coastguard Worker movpl r0, r1, lsr ip @ if r2 >= 32, r0<-r1 >>> (r2-32) 1660*795d594fSAndroid Build Coastguard Worker mov r1, r1, lsr r2 @ r1<- r1 >>> r2 1661*795d594fSAndroid Build Coastguard Worker bx lr 1662*795d594fSAndroid Build Coastguard WorkerEND art_quick_ushr_long 1663*795d594fSAndroid Build Coastguard Worker 1664*795d594fSAndroid Build Coastguard Worker /* 1665*795d594fSAndroid Build Coastguard Worker * String's indexOf. 1666*795d594fSAndroid Build Coastguard Worker * 1667*795d594fSAndroid Build Coastguard Worker * On entry: 1668*795d594fSAndroid Build Coastguard Worker * r0: string object (known non-null) 1669*795d594fSAndroid Build Coastguard Worker * r1: char to match (known <= 0xFFFF) 1670*795d594fSAndroid Build Coastguard Worker * r2: Starting offset in string data 1671*795d594fSAndroid Build Coastguard Worker */ 1672*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_indexof 1673*795d594fSAndroid Build Coastguard Worker push {r4, r10-r11, lr} @ 4 words of callee saves 1674*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 16 1675*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r4, 0 1676*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r10, 4 1677*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r11, 8 1678*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 12 1679*795d594fSAndroid Build Coastguard Worker#if (STRING_COMPRESSION_FEATURE) 1680*795d594fSAndroid Build Coastguard Worker ldr r4, [r0, #MIRROR_STRING_COUNT_OFFSET] 1681*795d594fSAndroid Build Coastguard Worker#else 1682*795d594fSAndroid Build Coastguard Worker ldr r3, [r0, #MIRROR_STRING_COUNT_OFFSET] 1683*795d594fSAndroid Build Coastguard Worker#endif 1684*795d594fSAndroid Build Coastguard Worker add r0, #MIRROR_STRING_VALUE_OFFSET 1685*795d594fSAndroid Build Coastguard Worker#if (STRING_COMPRESSION_FEATURE) 1686*795d594fSAndroid Build Coastguard Worker /* r4 count (with flag) and r3 holds actual length */ 1687*795d594fSAndroid Build Coastguard Worker lsr r3, r4, #1 1688*795d594fSAndroid Build Coastguard Worker#endif 1689*795d594fSAndroid Build Coastguard Worker /* Clamp start to [0..count] */ 1690*795d594fSAndroid Build Coastguard Worker cmp r2, #0 1691*795d594fSAndroid Build Coastguard Worker it lt 1692*795d594fSAndroid Build Coastguard Worker movlt r2, #0 1693*795d594fSAndroid Build Coastguard Worker cmp r2, r3 1694*795d594fSAndroid Build Coastguard Worker it gt 1695*795d594fSAndroid Build Coastguard Worker movgt r2, r3 1696*795d594fSAndroid Build Coastguard Worker 1697*795d594fSAndroid Build Coastguard Worker /* Save a copy in r12 to later compute result */ 1698*795d594fSAndroid Build Coastguard Worker mov r12, r0 1699*795d594fSAndroid Build Coastguard Worker 1700*795d594fSAndroid Build Coastguard Worker /* Build pointer to start of data to compare and pre-bias */ 1701*795d594fSAndroid Build Coastguard Worker#if (STRING_COMPRESSION_FEATURE) 1702*795d594fSAndroid Build Coastguard Worker lsrs r4, r4, #1 1703*795d594fSAndroid Build Coastguard Worker bcc .Lstring_indexof_compressed 1704*795d594fSAndroid Build Coastguard Worker#endif 1705*795d594fSAndroid Build Coastguard Worker add r0, r0, r2, lsl #1 1706*795d594fSAndroid Build Coastguard Worker sub r0, #2 1707*795d594fSAndroid Build Coastguard Worker 1708*795d594fSAndroid Build Coastguard Worker /* Compute iteration count */ 1709*795d594fSAndroid Build Coastguard Worker sub r2, r3, r2 1710*795d594fSAndroid Build Coastguard Worker 1711*795d594fSAndroid Build Coastguard Worker /* 1712*795d594fSAndroid Build Coastguard Worker * At this point we have: 1713*795d594fSAndroid Build Coastguard Worker * r0: start of data to test 1714*795d594fSAndroid Build Coastguard Worker * r1: char to compare 1715*795d594fSAndroid Build Coastguard Worker * r2: iteration count 1716*795d594fSAndroid Build Coastguard Worker * r4: compression style (used temporarily) 1717*795d594fSAndroid Build Coastguard Worker * r12: original start of string data 1718*795d594fSAndroid Build Coastguard Worker * r3, r4, r10, r11 available for loading string data 1719*795d594fSAndroid Build Coastguard Worker */ 1720*795d594fSAndroid Build Coastguard Worker 1721*795d594fSAndroid Build Coastguard Worker subs r2, #4 1722*795d594fSAndroid Build Coastguard Worker blt .Lindexof_remainder 1723*795d594fSAndroid Build Coastguard Worker 1724*795d594fSAndroid Build Coastguard Worker.Lindexof_loop4: 1725*795d594fSAndroid Build Coastguard Worker ldrh r3, [r0, #2]! 1726*795d594fSAndroid Build Coastguard Worker ldrh r4, [r0, #2]! 1727*795d594fSAndroid Build Coastguard Worker ldrh r10, [r0, #2]! 1728*795d594fSAndroid Build Coastguard Worker ldrh r11, [r0, #2]! 1729*795d594fSAndroid Build Coastguard Worker cmp r3, r1 1730*795d594fSAndroid Build Coastguard Worker beq .Lmatch_0 1731*795d594fSAndroid Build Coastguard Worker cmp r4, r1 1732*795d594fSAndroid Build Coastguard Worker beq .Lmatch_1 1733*795d594fSAndroid Build Coastguard Worker cmp r10, r1 1734*795d594fSAndroid Build Coastguard Worker beq .Lmatch_2 1735*795d594fSAndroid Build Coastguard Worker cmp r11, r1 1736*795d594fSAndroid Build Coastguard Worker beq .Lmatch_3 1737*795d594fSAndroid Build Coastguard Worker subs r2, #4 1738*795d594fSAndroid Build Coastguard Worker bge .Lindexof_loop4 1739*795d594fSAndroid Build Coastguard Worker 1740*795d594fSAndroid Build Coastguard Worker.Lindexof_remainder: 1741*795d594fSAndroid Build Coastguard Worker adds r2, #4 1742*795d594fSAndroid Build Coastguard Worker beq .Lindexof_nomatch 1743*795d594fSAndroid Build Coastguard Worker 1744*795d594fSAndroid Build Coastguard Worker.Lindexof_loop1: 1745*795d594fSAndroid Build Coastguard Worker ldrh r3, [r0, #2]! 1746*795d594fSAndroid Build Coastguard Worker cmp r3, r1 1747*795d594fSAndroid Build Coastguard Worker beq .Lmatch_3 1748*795d594fSAndroid Build Coastguard Worker subs r2, #1 1749*795d594fSAndroid Build Coastguard Worker bne .Lindexof_loop1 1750*795d594fSAndroid Build Coastguard Worker 1751*795d594fSAndroid Build Coastguard Worker.Lindexof_nomatch: 1752*795d594fSAndroid Build Coastguard Worker mov r0, #-1 1753*795d594fSAndroid Build Coastguard Worker pop {r4, r10-r11, pc} 1754*795d594fSAndroid Build Coastguard Worker 1755*795d594fSAndroid Build Coastguard Worker.Lmatch_0: 1756*795d594fSAndroid Build Coastguard Worker sub r0, #6 1757*795d594fSAndroid Build Coastguard Worker sub r0, r12 1758*795d594fSAndroid Build Coastguard Worker asr r0, r0, #1 1759*795d594fSAndroid Build Coastguard Worker pop {r4, r10-r11, pc} 1760*795d594fSAndroid Build Coastguard Worker.Lmatch_1: 1761*795d594fSAndroid Build Coastguard Worker sub r0, #4 1762*795d594fSAndroid Build Coastguard Worker sub r0, r12 1763*795d594fSAndroid Build Coastguard Worker asr r0, r0, #1 1764*795d594fSAndroid Build Coastguard Worker pop {r4, r10-r11, pc} 1765*795d594fSAndroid Build Coastguard Worker.Lmatch_2: 1766*795d594fSAndroid Build Coastguard Worker sub r0, #2 1767*795d594fSAndroid Build Coastguard Worker sub r0, r12 1768*795d594fSAndroid Build Coastguard Worker asr r0, r0, #1 1769*795d594fSAndroid Build Coastguard Worker pop {r4, r10-r11, pc} 1770*795d594fSAndroid Build Coastguard Worker.Lmatch_3: 1771*795d594fSAndroid Build Coastguard Worker sub r0, r12 1772*795d594fSAndroid Build Coastguard Worker asr r0, r0, #1 1773*795d594fSAndroid Build Coastguard Worker pop {r4, r10-r11, pc} 1774*795d594fSAndroid Build Coastguard Worker#if (STRING_COMPRESSION_FEATURE) 1775*795d594fSAndroid Build Coastguard Worker.Lstring_indexof_compressed: 1776*795d594fSAndroid Build Coastguard Worker add r0, r0, r2 1777*795d594fSAndroid Build Coastguard Worker sub r0, #1 1778*795d594fSAndroid Build Coastguard Worker sub r2, r3, r2 1779*795d594fSAndroid Build Coastguard Worker.Lstring_indexof_compressed_loop: 1780*795d594fSAndroid Build Coastguard Worker subs r2, #1 1781*795d594fSAndroid Build Coastguard Worker blt .Lindexof_nomatch 1782*795d594fSAndroid Build Coastguard Worker ldrb r3, [r0, #1]! 1783*795d594fSAndroid Build Coastguard Worker cmp r3, r1 1784*795d594fSAndroid Build Coastguard Worker beq .Lstring_indexof_compressed_matched 1785*795d594fSAndroid Build Coastguard Worker b .Lstring_indexof_compressed_loop 1786*795d594fSAndroid Build Coastguard Worker.Lstring_indexof_compressed_matched: 1787*795d594fSAndroid Build Coastguard Worker sub r0, r12 1788*795d594fSAndroid Build Coastguard Worker pop {r4, r10-r11, pc} 1789*795d594fSAndroid Build Coastguard Worker#endif 1790*795d594fSAndroid Build Coastguard WorkerEND art_quick_indexof 1791*795d594fSAndroid Build Coastguard Worker 1792*795d594fSAndroid Build Coastguard Worker /* Assembly routines used to handle ABI differences. */ 1793*795d594fSAndroid Build Coastguard Worker 1794*795d594fSAndroid Build Coastguard Worker /* double fmod(double a, double b) */ 1795*795d594fSAndroid Build Coastguard Worker .extern fmod 1796*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_fmod 1797*795d594fSAndroid Build Coastguard Worker push {lr} 1798*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 4 1799*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 0 1800*795d594fSAndroid Build Coastguard Worker sub sp, #4 1801*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 4 1802*795d594fSAndroid Build Coastguard Worker vmov r0, r1, d0 1803*795d594fSAndroid Build Coastguard Worker vmov r2, r3, d1 1804*795d594fSAndroid Build Coastguard Worker bl fmod 1805*795d594fSAndroid Build Coastguard Worker vmov d0, r0, r1 1806*795d594fSAndroid Build Coastguard Worker add sp, #4 1807*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -4 1808*795d594fSAndroid Build Coastguard Worker pop {pc} 1809*795d594fSAndroid Build Coastguard WorkerEND art_quick_fmod 1810*795d594fSAndroid Build Coastguard Worker 1811*795d594fSAndroid Build Coastguard Worker /* float fmodf(float a, float b) */ 1812*795d594fSAndroid Build Coastguard Worker .extern fmodf 1813*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_fmodf 1814*795d594fSAndroid Build Coastguard Worker push {lr} 1815*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 4 1816*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 0 1817*795d594fSAndroid Build Coastguard Worker sub sp, #4 1818*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 4 1819*795d594fSAndroid Build Coastguard Worker vmov r0, r1, d0 1820*795d594fSAndroid Build Coastguard Worker bl fmodf 1821*795d594fSAndroid Build Coastguard Worker vmov s0, r0 1822*795d594fSAndroid Build Coastguard Worker add sp, #4 1823*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -4 1824*795d594fSAndroid Build Coastguard Worker pop {pc} 1825*795d594fSAndroid Build Coastguard WorkerEND art_quick_fmodf 1826*795d594fSAndroid Build Coastguard Worker 1827*795d594fSAndroid Build Coastguard Worker /* int64_t art_d2l(double d) */ 1828*795d594fSAndroid Build Coastguard Worker .extern art_d2l 1829*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_d2l 1830*795d594fSAndroid Build Coastguard Worker vmov r0, r1, d0 1831*795d594fSAndroid Build Coastguard Worker b art_d2l 1832*795d594fSAndroid Build Coastguard WorkerEND art_quick_d2l 1833*795d594fSAndroid Build Coastguard Worker 1834*795d594fSAndroid Build Coastguard Worker /* int64_t art_f2l(float f) */ 1835*795d594fSAndroid Build Coastguard Worker .extern art_f2l 1836*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_f2l 1837*795d594fSAndroid Build Coastguard Worker vmov r0, s0 1838*795d594fSAndroid Build Coastguard Worker b art_f2l 1839*795d594fSAndroid Build Coastguard WorkerEND art_quick_f2l 1840*795d594fSAndroid Build Coastguard Worker 1841*795d594fSAndroid Build Coastguard Worker /* float art_l2f(int64_t l) */ 1842*795d594fSAndroid Build Coastguard Worker .extern art_l2f 1843*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_l2f 1844*795d594fSAndroid Build Coastguard Worker push {lr} 1845*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 4 1846*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 0 1847*795d594fSAndroid Build Coastguard Worker sub sp, #4 1848*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 4 1849*795d594fSAndroid Build Coastguard Worker bl art_l2f 1850*795d594fSAndroid Build Coastguard Worker vmov s0, r0 1851*795d594fSAndroid Build Coastguard Worker add sp, #4 1852*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -4 1853*795d594fSAndroid Build Coastguard Worker pop {pc} 1854*795d594fSAndroid Build Coastguard WorkerEND art_quick_l2f 1855*795d594fSAndroid Build Coastguard Worker 1856*795d594fSAndroid Build Coastguard Worker .extern artStringBuilderAppend 1857*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_string_builder_append 1858*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_ONLY_FRAME r2 @ save callee saves in case of GC 1859*795d594fSAndroid Build Coastguard Worker add r1, sp, #(FRAME_SIZE_SAVE_REFS_ONLY + __SIZEOF_POINTER__) @ pass args 1860*795d594fSAndroid Build Coastguard Worker mov r2, rSELF @ pass Thread::Current 1861*795d594fSAndroid Build Coastguard Worker bl artStringBuilderAppend @ (uint32_t, const unit32_t*, Thread*) 1862*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_ONLY_FRAME 1863*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 1864*795d594fSAndroid Build Coastguard Worker RETURN_OR_DEOPT_IF_RESULT_IS_NON_NULL_OR_DELIVER 1865*795d594fSAndroid Build Coastguard WorkerEND art_quick_string_builder_append 1866*795d594fSAndroid Build Coastguard Worker 1867*795d594fSAndroid Build Coastguard Worker /* 1868*795d594fSAndroid Build Coastguard Worker * Create a function `name` calling the ReadBarrier::Mark routine, 1869*795d594fSAndroid Build Coastguard Worker * getting its argument and returning its result through register 1870*795d594fSAndroid Build Coastguard Worker * `reg`, saving and restoring all caller-save registers. 1871*795d594fSAndroid Build Coastguard Worker * 1872*795d594fSAndroid Build Coastguard Worker * IP is clobbered; `reg` must not be IP. 1873*795d594fSAndroid Build Coastguard Worker * 1874*795d594fSAndroid Build Coastguard Worker * If `reg` is different from `r0`, the generated function follows a 1875*795d594fSAndroid Build Coastguard Worker * non-standard runtime calling convention: 1876*795d594fSAndroid Build Coastguard Worker * - register `reg` (which may be different from R0) is used to pass the (sole) argument, 1877*795d594fSAndroid Build Coastguard Worker * - register `reg` (which may be different from R0) is used to return the result, 1878*795d594fSAndroid Build Coastguard Worker * - all other registers are callee-save (the values they hold are preserved). 1879*795d594fSAndroid Build Coastguard Worker */ 1880*795d594fSAndroid Build Coastguard Worker.macro READ_BARRIER_MARK_REG name, reg 1881*795d594fSAndroid Build Coastguard WorkerENTRY \name 1882*795d594fSAndroid Build Coastguard Worker // Null check so that we can load the lock word. 1883*795d594fSAndroid Build Coastguard Worker SMART_CBZ \reg, .Lret_rb_\name 1884*795d594fSAndroid Build Coastguard Worker // Check lock word for mark bit, if marked return. Use IP for scratch since it is blocked. 1885*795d594fSAndroid Build Coastguard Worker ldr ip, [\reg, MIRROR_OBJECT_LOCK_WORD_OFFSET] 1886*795d594fSAndroid Build Coastguard Worker tst ip, #LOCK_WORD_MARK_BIT_MASK_SHIFTED 1887*795d594fSAndroid Build Coastguard Worker beq .Lnot_marked_rb_\name 1888*795d594fSAndroid Build Coastguard Worker // Already marked, return right away. 1889*795d594fSAndroid Build Coastguard Worker.Lret_rb_\name: 1890*795d594fSAndroid Build Coastguard Worker bx lr 1891*795d594fSAndroid Build Coastguard Worker 1892*795d594fSAndroid Build Coastguard Worker.Lnot_marked_rb_\name: 1893*795d594fSAndroid Build Coastguard Worker // Test that both the forwarding state bits are 1. 1894*795d594fSAndroid Build Coastguard Worker#if (LOCK_WORD_STATE_SHIFT != 30) || (LOCK_WORD_STATE_FORWARDING_ADDRESS != 3) 1895*795d594fSAndroid Build Coastguard Worker // To use "CMP ip, #modified-immediate; BHS", we need the lock word state in 1896*795d594fSAndroid Build Coastguard Worker // the highest bits and the "forwarding address" state to have all bits set. 1897*795d594fSAndroid Build Coastguard Worker#error "Unexpected lock word state shift or forwarding address state value." 1898*795d594fSAndroid Build Coastguard Worker#endif 1899*795d594fSAndroid Build Coastguard Worker cmp ip, #(LOCK_WORD_STATE_FORWARDING_ADDRESS << LOCK_WORD_STATE_SHIFT) 1900*795d594fSAndroid Build Coastguard Worker bhs .Lret_forwarding_address\name 1901*795d594fSAndroid Build Coastguard Worker 1902*795d594fSAndroid Build Coastguard Worker.Lslow_rb_\name: 1903*795d594fSAndroid Build Coastguard Worker // Save IP: The kSaveEverything entrypoint art_quick_resolve_string used to 1904*795d594fSAndroid Build Coastguard Worker // make a tail call here. Currently, it serves only for stack alignment but 1905*795d594fSAndroid Build Coastguard Worker // we may reintroduce kSaveEverything calls here in the future. 1906*795d594fSAndroid Build Coastguard Worker push {r0-r4, r9, ip, lr} @ save return address, core caller-save registers and ip 1907*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 32 1908*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r0, 0 1909*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r1, 4 1910*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r2, 8 1911*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r3, 12 1912*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r4, 16 1913*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r9, 20 1914*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset ip, 24 1915*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 28 1916*795d594fSAndroid Build Coastguard Worker 1917*795d594fSAndroid Build Coastguard Worker .ifnc \reg, r0 1918*795d594fSAndroid Build Coastguard Worker mov r0, \reg @ pass arg1 - obj from `reg` 1919*795d594fSAndroid Build Coastguard Worker .endif 1920*795d594fSAndroid Build Coastguard Worker 1921*795d594fSAndroid Build Coastguard Worker vpush {s0-s15} @ save floating-point caller-save registers 1922*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 64 1923*795d594fSAndroid Build Coastguard Worker bl artReadBarrierMark @ r0 <- artReadBarrierMark(obj) 1924*795d594fSAndroid Build Coastguard Worker vpop {s0-s15} @ restore floating-point registers 1925*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -64 1926*795d594fSAndroid Build Coastguard Worker 1927*795d594fSAndroid Build Coastguard Worker .ifc \reg, r0 @ Save result to the stack slot or destination register. 1928*795d594fSAndroid Build Coastguard Worker str r0, [sp, #0] 1929*795d594fSAndroid Build Coastguard Worker .else 1930*795d594fSAndroid Build Coastguard Worker .ifc \reg, r1 1931*795d594fSAndroid Build Coastguard Worker str r0, [sp, #4] 1932*795d594fSAndroid Build Coastguard Worker .else 1933*795d594fSAndroid Build Coastguard Worker .ifc \reg, r2 1934*795d594fSAndroid Build Coastguard Worker str r0, [sp, #8] 1935*795d594fSAndroid Build Coastguard Worker .else 1936*795d594fSAndroid Build Coastguard Worker .ifc \reg, r3 1937*795d594fSAndroid Build Coastguard Worker str r0, [sp, #12] 1938*795d594fSAndroid Build Coastguard Worker .else 1939*795d594fSAndroid Build Coastguard Worker .ifc \reg, r4 1940*795d594fSAndroid Build Coastguard Worker str r0, [sp, #16] 1941*795d594fSAndroid Build Coastguard Worker .else 1942*795d594fSAndroid Build Coastguard Worker .ifc \reg, r9 1943*795d594fSAndroid Build Coastguard Worker str r0, [sp, #20] 1944*795d594fSAndroid Build Coastguard Worker .else 1945*795d594fSAndroid Build Coastguard Worker mov \reg, r0 1946*795d594fSAndroid Build Coastguard Worker .endif 1947*795d594fSAndroid Build Coastguard Worker .endif 1948*795d594fSAndroid Build Coastguard Worker .endif 1949*795d594fSAndroid Build Coastguard Worker .endif 1950*795d594fSAndroid Build Coastguard Worker .endif 1951*795d594fSAndroid Build Coastguard Worker .endif 1952*795d594fSAndroid Build Coastguard Worker 1953*795d594fSAndroid Build Coastguard Worker pop {r0-r4, r9, ip, lr} @ restore caller-save registers 1954*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -32 1955*795d594fSAndroid Build Coastguard Worker .cfi_restore r0 1956*795d594fSAndroid Build Coastguard Worker .cfi_restore r1 1957*795d594fSAndroid Build Coastguard Worker .cfi_restore r2 1958*795d594fSAndroid Build Coastguard Worker .cfi_restore r3 1959*795d594fSAndroid Build Coastguard Worker .cfi_restore r4 1960*795d594fSAndroid Build Coastguard Worker .cfi_restore r9 1961*795d594fSAndroid Build Coastguard Worker .cfi_restore ip 1962*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 1963*795d594fSAndroid Build Coastguard Worker bx lr 1964*795d594fSAndroid Build Coastguard Worker.Lret_forwarding_address\name: 1965*795d594fSAndroid Build Coastguard Worker // Shift left by the forwarding address shift. This clears out the state bits since they are 1966*795d594fSAndroid Build Coastguard Worker // in the top 2 bits of the lock word. 1967*795d594fSAndroid Build Coastguard Worker lsl \reg, ip, #LOCK_WORD_STATE_FORWARDING_ADDRESS_SHIFT 1968*795d594fSAndroid Build Coastguard Worker bx lr 1969*795d594fSAndroid Build Coastguard WorkerEND \name 1970*795d594fSAndroid Build Coastguard Worker.endm 1971*795d594fSAndroid Build Coastguard Worker 1972*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg00, r0 1973*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg01, r1 1974*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg02, r2 1975*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg03, r3 1976*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg04, r4 1977*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg05, r5 1978*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg06, r6 1979*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg07, r7 1980*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg08, r8 1981*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg09, r9 1982*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg10, r10 1983*795d594fSAndroid Build Coastguard WorkerREAD_BARRIER_MARK_REG art_quick_read_barrier_mark_reg11, r11 1984*795d594fSAndroid Build Coastguard Worker 1985*795d594fSAndroid Build Coastguard Worker// Helper macros for Baker CC read barrier mark introspection (BRBMI). 1986*795d594fSAndroid Build Coastguard Worker.macro BRBMI_FOR_REGISTERS macro_for_register, macro_for_reserved_register 1987*795d594fSAndroid Build Coastguard Worker \macro_for_register r0 1988*795d594fSAndroid Build Coastguard Worker \macro_for_register r1 1989*795d594fSAndroid Build Coastguard Worker \macro_for_register r2 1990*795d594fSAndroid Build Coastguard Worker \macro_for_register r3 1991*795d594fSAndroid Build Coastguard Worker \macro_for_register r4 1992*795d594fSAndroid Build Coastguard Worker \macro_for_register r5 1993*795d594fSAndroid Build Coastguard Worker \macro_for_register r6 1994*795d594fSAndroid Build Coastguard Worker \macro_for_register r7 1995*795d594fSAndroid Build Coastguard Worker \macro_for_reserved_register // r8 (rMR) is the marking register. 1996*795d594fSAndroid Build Coastguard Worker \macro_for_register r9 1997*795d594fSAndroid Build Coastguard Worker \macro_for_register r10 1998*795d594fSAndroid Build Coastguard Worker \macro_for_register r11 1999*795d594fSAndroid Build Coastguard Worker \macro_for_reserved_register // IP is reserved. 2000*795d594fSAndroid Build Coastguard Worker \macro_for_reserved_register // SP is reserved. 2001*795d594fSAndroid Build Coastguard Worker \macro_for_reserved_register // LR is reserved. 2002*795d594fSAndroid Build Coastguard Worker \macro_for_reserved_register // PC is reserved. 2003*795d594fSAndroid Build Coastguard Worker.endm 2004*795d594fSAndroid Build Coastguard Worker 2005*795d594fSAndroid Build Coastguard Worker.macro BRBMI_RETURN_SWITCH_CASE reg 2006*795d594fSAndroid Build Coastguard Worker .balign 8 2007*795d594fSAndroid Build Coastguard Worker.Lmark_introspection_return_switch_case_\reg: 2008*795d594fSAndroid Build Coastguard Worker mov rMR, #1 2009*795d594fSAndroid Build Coastguard Worker mov \reg, ip 2010*795d594fSAndroid Build Coastguard Worker bx lr 2011*795d594fSAndroid Build Coastguard Worker.endm 2012*795d594fSAndroid Build Coastguard Worker 2013*795d594fSAndroid Build Coastguard Worker.macro BRBMI_RETURN_SWITCH_CASE_OFFSET reg 2014*795d594fSAndroid Build Coastguard Worker .byte (.Lmark_introspection_return_switch_case_\reg - .Lmark_introspection_return_table) / 2 2015*795d594fSAndroid Build Coastguard Worker.endm 2016*795d594fSAndroid Build Coastguard Worker 2017*795d594fSAndroid Build Coastguard Worker.macro BRBMI_BAD_RETURN_SWITCH_CASE_OFFSET 2018*795d594fSAndroid Build Coastguard Worker .byte (.Lmark_introspection_return_switch_case_bad - .Lmark_introspection_return_table) / 2 2019*795d594fSAndroid Build Coastguard Worker.endm 2020*795d594fSAndroid Build Coastguard Worker 2021*795d594fSAndroid Build Coastguard Worker#if BAKER_MARK_INTROSPECTION_FIELD_LDR_WIDE_OFFSET != BAKER_MARK_INTROSPECTION_ARRAY_LDR_OFFSET 2022*795d594fSAndroid Build Coastguard Worker#error "Array and field introspection code sharing requires same LDR offset." 2023*795d594fSAndroid Build Coastguard Worker#endif 2024*795d594fSAndroid Build Coastguard Worker.macro BRBMI_ARRAY_LOAD index_reg 2025*795d594fSAndroid Build Coastguard Worker ldr ip, [ip, \index_reg, lsl #2] // 4 bytes. 2026*795d594fSAndroid Build Coastguard Worker b art_quick_read_barrier_mark_introspection // Should be 2 bytes, encoding T2. 2027*795d594fSAndroid Build Coastguard Worker .balign 8 // Add padding to 8 bytes. 2028*795d594fSAndroid Build Coastguard Worker.endm 2029*795d594fSAndroid Build Coastguard Worker 2030*795d594fSAndroid Build Coastguard Worker.macro BRBMI_BKPT_FILL_4B 2031*795d594fSAndroid Build Coastguard Worker bkpt 0 2032*795d594fSAndroid Build Coastguard Worker bkpt 0 2033*795d594fSAndroid Build Coastguard Worker.endm 2034*795d594fSAndroid Build Coastguard Worker 2035*795d594fSAndroid Build Coastguard Worker.macro BRBMI_BKPT_FILL_8B 2036*795d594fSAndroid Build Coastguard Worker BRBMI_BKPT_FILL_4B 2037*795d594fSAndroid Build Coastguard Worker BRBMI_BKPT_FILL_4B 2038*795d594fSAndroid Build Coastguard Worker.endm 2039*795d594fSAndroid Build Coastguard Worker 2040*795d594fSAndroid Build Coastguard Worker.macro BRBMI_RUNTIME_CALL 2041*795d594fSAndroid Build Coastguard Worker // Note: This macro generates exactly 22 bytes of code. The core register 2042*795d594fSAndroid Build Coastguard Worker // PUSH and the MOVs are 16-bit instructions, the rest is 32-bit instructions. 2043*795d594fSAndroid Build Coastguard Worker 2044*795d594fSAndroid Build Coastguard Worker push {r0-r3, r7, lr} // Save return address and caller-save registers. 2045*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 24 2046*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r0, 0 2047*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r1, 4 2048*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r2, 8 2049*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r3, 12 2050*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset r7, 16 2051*795d594fSAndroid Build Coastguard Worker .cfi_rel_offset lr, 20 2052*795d594fSAndroid Build Coastguard Worker 2053*795d594fSAndroid Build Coastguard Worker mov r0, ip // Pass the reference. 2054*795d594fSAndroid Build Coastguard Worker vpush {s0-s15} // save floating-point caller-save registers 2055*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 64 2056*795d594fSAndroid Build Coastguard Worker bl artReadBarrierMark // r0 <- artReadBarrierMark(obj) 2057*795d594fSAndroid Build Coastguard Worker vpop {s0-s15} // restore floating-point registers 2058*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -64 2059*795d594fSAndroid Build Coastguard Worker mov ip, r0 // Move reference to ip in preparation for return switch. 2060*795d594fSAndroid Build Coastguard Worker 2061*795d594fSAndroid Build Coastguard Worker pop {r0-r3, r7, lr} // Restore registers. 2062*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset -24 2063*795d594fSAndroid Build Coastguard Worker .cfi_restore r0 2064*795d594fSAndroid Build Coastguard Worker .cfi_restore r1 2065*795d594fSAndroid Build Coastguard Worker .cfi_restore r2 2066*795d594fSAndroid Build Coastguard Worker .cfi_restore r3 2067*795d594fSAndroid Build Coastguard Worker .cfi_restore r7 2068*795d594fSAndroid Build Coastguard Worker .cfi_restore lr 2069*795d594fSAndroid Build Coastguard Worker.endm 2070*795d594fSAndroid Build Coastguard Worker 2071*795d594fSAndroid Build Coastguard Worker.macro BRBMI_CHECK_NULL_AND_MARKED label_suffix 2072*795d594fSAndroid Build Coastguard Worker // If reference is null, just return it in the right register. 2073*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2074*795d594fSAndroid Build Coastguard Worker beq .Lmark_introspection_return\label_suffix 2075*795d594fSAndroid Build Coastguard Worker // Use rMR as temp and check the mark bit of the reference. 2076*795d594fSAndroid Build Coastguard Worker ldr rMR, [ip, #MIRROR_OBJECT_LOCK_WORD_OFFSET] 2077*795d594fSAndroid Build Coastguard Worker tst rMR, #LOCK_WORD_MARK_BIT_MASK_SHIFTED 2078*795d594fSAndroid Build Coastguard Worker beq .Lmark_introspection_unmarked\label_suffix 2079*795d594fSAndroid Build Coastguard Worker.Lmark_introspection_return\label_suffix: 2080*795d594fSAndroid Build Coastguard Worker.endm 2081*795d594fSAndroid Build Coastguard Worker 2082*795d594fSAndroid Build Coastguard Worker.macro BRBMI_UNMARKED_FORWARDING_ADDRESS_CHECK label_suffix 2083*795d594fSAndroid Build Coastguard Worker.Lmark_introspection_unmarked\label_suffix: 2084*795d594fSAndroid Build Coastguard Worker // Check if the top two bits are one, if this is the case it is a forwarding address. 2085*795d594fSAndroid Build Coastguard Worker#if (LOCK_WORD_STATE_SHIFT != 30) || (LOCK_WORD_STATE_FORWARDING_ADDRESS != 3) 2086*795d594fSAndroid Build Coastguard Worker // To use "CMP ip, #modified-immediate; BHS", we need the lock word state in 2087*795d594fSAndroid Build Coastguard Worker // the highest bits and the "forwarding address" state to have all bits set. 2088*795d594fSAndroid Build Coastguard Worker#error "Unexpected lock word state shift or forwarding address state value." 2089*795d594fSAndroid Build Coastguard Worker#endif 2090*795d594fSAndroid Build Coastguard Worker cmp rMR, #(LOCK_WORD_STATE_FORWARDING_ADDRESS << LOCK_WORD_STATE_SHIFT) 2091*795d594fSAndroid Build Coastguard Worker bhs .Lmark_introspection_forwarding_address\label_suffix 2092*795d594fSAndroid Build Coastguard Worker.endm 2093*795d594fSAndroid Build Coastguard Worker 2094*795d594fSAndroid Build Coastguard Worker.macro BRBMI_EXTRACT_FORWARDING_ADDRESS label_suffix 2095*795d594fSAndroid Build Coastguard Worker.Lmark_introspection_forwarding_address\label_suffix: 2096*795d594fSAndroid Build Coastguard Worker // Note: This macro generates exactly 22 bytes of code, the branch is near. 2097*795d594fSAndroid Build Coastguard Worker 2098*795d594fSAndroid Build Coastguard Worker // Shift left by the forwarding address shift. This clears out the state bits since they are 2099*795d594fSAndroid Build Coastguard Worker // in the top 2 bits of the lock word. 2100*795d594fSAndroid Build Coastguard Worker lsl ip, rMR, #LOCK_WORD_STATE_FORWARDING_ADDRESS_SHIFT 2101*795d594fSAndroid Build Coastguard Worker b .Lmark_introspection_return\label_suffix 2102*795d594fSAndroid Build Coastguard Worker.endm 2103*795d594fSAndroid Build Coastguard Worker 2104*795d594fSAndroid Build Coastguard Worker.macro BRBMI_LOAD_RETURN_REG_FROM_CODE_wide ldr_offset 2105*795d594fSAndroid Build Coastguard Worker // Load the half of the instruction that contains Rt. Adjust for the thumb state in LR. 2106*795d594fSAndroid Build Coastguard Worker ldrh rMR, [lr, #(-1 + \ldr_offset + 2)] 2107*795d594fSAndroid Build Coastguard Worker.endm 2108*795d594fSAndroid Build Coastguard Worker 2109*795d594fSAndroid Build Coastguard Worker.macro BRBMI_LOAD_RETURN_REG_FROM_CODE_narrow ldr_offset 2110*795d594fSAndroid Build Coastguard Worker // Load the 16-bit instruction. Adjust for the thumb state in LR. 2111*795d594fSAndroid Build Coastguard Worker ldrh rMR, [lr, #(-1 + \ldr_offset)] 2112*795d594fSAndroid Build Coastguard Worker.endm 2113*795d594fSAndroid Build Coastguard Worker 2114*795d594fSAndroid Build Coastguard Worker.macro BRBMI_EXTRACT_RETURN_REG_wide 2115*795d594fSAndroid Build Coastguard Worker lsr rMR, rMR, #12 // Extract `ref_reg`. 2116*795d594fSAndroid Build Coastguard Worker.endm 2117*795d594fSAndroid Build Coastguard Worker 2118*795d594fSAndroid Build Coastguard Worker.macro BRBMI_EXTRACT_RETURN_REG_narrow 2119*795d594fSAndroid Build Coastguard Worker and rMR, rMR, #7 // Extract `ref_reg`. 2120*795d594fSAndroid Build Coastguard Worker.endm 2121*795d594fSAndroid Build Coastguard Worker 2122*795d594fSAndroid Build Coastguard Worker.macro BRBMI_LOAD_AND_EXTRACT_RETURN_REG ldr_offset, label_suffix 2123*795d594fSAndroid Build Coastguard Worker BRBMI_LOAD_RETURN_REG_FROM_CODE\label_suffix \ldr_offset 2124*795d594fSAndroid Build Coastguard Worker BRBMI_EXTRACT_RETURN_REG\label_suffix 2125*795d594fSAndroid Build Coastguard Worker.endm 2126*795d594fSAndroid Build Coastguard Worker 2127*795d594fSAndroid Build Coastguard Worker.macro BRBMI_GC_ROOT gc_root_ldr_offset, label_suffix 2128*795d594fSAndroid Build Coastguard Worker .balign 32 2129*795d594fSAndroid Build Coastguard Worker .thumb_func 2130*795d594fSAndroid Build Coastguard Worker .type art_quick_read_barrier_mark_introspection_gc_roots\label_suffix, #function 2131*795d594fSAndroid Build Coastguard Worker .hidden art_quick_read_barrier_mark_introspection_gc_roots\label_suffix 2132*795d594fSAndroid Build Coastguard Worker .global art_quick_read_barrier_mark_introspection_gc_roots\label_suffix 2133*795d594fSAndroid Build Coastguard Workerart_quick_read_barrier_mark_introspection_gc_roots\label_suffix: 2134*795d594fSAndroid Build Coastguard Worker BRBMI_LOAD_AND_EXTRACT_RETURN_REG \gc_root_ldr_offset, \label_suffix 2135*795d594fSAndroid Build Coastguard Worker.endm 2136*795d594fSAndroid Build Coastguard Worker 2137*795d594fSAndroid Build Coastguard Worker.macro BRBMI_FIELD_SLOW_PATH ldr_offset, label_suffix 2138*795d594fSAndroid Build Coastguard Worker .balign 16 2139*795d594fSAndroid Build Coastguard Worker // Note: Generates exactly 16 bytes of code. 2140*795d594fSAndroid Build Coastguard Worker BRBMI_UNMARKED_FORWARDING_ADDRESS_CHECK \label_suffix 2141*795d594fSAndroid Build Coastguard Worker BRBMI_LOAD_AND_EXTRACT_RETURN_REG \ldr_offset, \label_suffix 2142*795d594fSAndroid Build Coastguard Worker b .Lmark_introspection_runtime_call 2143*795d594fSAndroid Build Coastguard Worker.endm 2144*795d594fSAndroid Build Coastguard Worker 2145*795d594fSAndroid Build Coastguard Worker /* 2146*795d594fSAndroid Build Coastguard Worker * Use introspection to load a reference from the same address as the LDR 2147*795d594fSAndroid Build Coastguard Worker * instruction in generated code would load (unless loaded by the thunk, 2148*795d594fSAndroid Build Coastguard Worker * see below), call ReadBarrier::Mark() with that reference if needed 2149*795d594fSAndroid Build Coastguard Worker * and return it in the same register as the LDR instruction would load. 2150*795d594fSAndroid Build Coastguard Worker * 2151*795d594fSAndroid Build Coastguard Worker * The entrypoint is called through a thunk that differs across load kinds. 2152*795d594fSAndroid Build Coastguard Worker * For field and array loads the LDR instruction in generated code follows 2153*795d594fSAndroid Build Coastguard Worker * the branch to the thunk, i.e. the LDR is (ignoring the heap poisoning) 2154*795d594fSAndroid Build Coastguard Worker * at [LR, #(-4 - 1)] (encoding T3) or [LR, #(-2 - 1)] (encoding T1) where 2155*795d594fSAndroid Build Coastguard Worker * the -1 is an adjustment for the Thumb mode bit in LR, and the thunk 2156*795d594fSAndroid Build Coastguard Worker * knows the holder and performs the gray bit check, returning to the LDR 2157*795d594fSAndroid Build Coastguard Worker * instruction if the object is not gray, so this entrypoint no longer 2158*795d594fSAndroid Build Coastguard Worker * needs to know anything about the holder. For GC root loads, the LDR 2159*795d594fSAndroid Build Coastguard Worker * instruction in generated code precedes the branch to the thunk, i.e. the 2160*795d594fSAndroid Build Coastguard Worker * LDR is at [LR, #(-8 - 1)] (encoding T3) or [LR, #(-6 - 1)] (encoding T1) 2161*795d594fSAndroid Build Coastguard Worker * where the -1 is again the Thumb mode bit adjustment, and the thunk does 2162*795d594fSAndroid Build Coastguard Worker * not do the gray bit check. 2163*795d594fSAndroid Build Coastguard Worker * 2164*795d594fSAndroid Build Coastguard Worker * For field accesses and array loads with a constant index the thunk loads 2165*795d594fSAndroid Build Coastguard Worker * the reference into IP using introspection and calls the main entrypoint 2166*795d594fSAndroid Build Coastguard Worker * ("wide", for 32-bit LDR) art_quick_read_barrier_mark_introspection or 2167*795d594fSAndroid Build Coastguard Worker * the "narrow" entrypoint (for 16-bit LDR). The latter is at a known 2168*795d594fSAndroid Build Coastguard Worker * offset (BAKER_MARK_INTROSPECTION_FIELD_LDR_NARROW_ENTRYPOINT_OFFSET) 2169*795d594fSAndroid Build Coastguard Worker * from the main entrypoint and the thunk adjusts the entrypoint pointer. 2170*795d594fSAndroid Build Coastguard Worker * With heap poisoning enabled, the passed reference is poisoned. 2171*795d594fSAndroid Build Coastguard Worker * 2172*795d594fSAndroid Build Coastguard Worker * For array accesses with non-constant index, the thunk inserts the bits 2173*795d594fSAndroid Build Coastguard Worker * 0-5 of the LDR instruction to the entrypoint address, effectively 2174*795d594fSAndroid Build Coastguard Worker * calculating a switch case label based on the index register (bits 0-3) 2175*795d594fSAndroid Build Coastguard Worker * and adding an extra offset (bits 4-5 hold the shift which is always 2 2176*795d594fSAndroid Build Coastguard Worker * for reference loads) to differentiate from the main entrypoint, then 2177*795d594fSAndroid Build Coastguard Worker * moves the base register to IP and jumps to the switch case. Therefore 2178*795d594fSAndroid Build Coastguard Worker * we need to align the main entrypoint to 512 bytes, accounting for 2179*795d594fSAndroid Build Coastguard Worker * a 256-byte offset followed by 16 array entrypoints starting at 2180*795d594fSAndroid Build Coastguard Worker * art_quick_read_barrier_mark_introspection_arrays, each containing an LDR 2181*795d594fSAndroid Build Coastguard Worker * (register) and a branch to the main entrypoint. 2182*795d594fSAndroid Build Coastguard Worker * 2183*795d594fSAndroid Build Coastguard Worker * For GC root accesses we cannot use the main entrypoint because of the 2184*795d594fSAndroid Build Coastguard Worker * different offset where the LDR instruction in generated code is located. 2185*795d594fSAndroid Build Coastguard Worker * (And even with heap poisoning enabled, GC roots are not poisoned.) 2186*795d594fSAndroid Build Coastguard Worker * To re-use the same entrypoint pointer in generated code, we make sure 2187*795d594fSAndroid Build Coastguard Worker * that the gc root entrypoint (a copy of the entrypoint with a different 2188*795d594fSAndroid Build Coastguard Worker * offset for introspection loads) is located at a known offset (0xc0/0xe0 2189*795d594fSAndroid Build Coastguard Worker * bytes, or BAKER_MARK_INTROSPECTION_GC_ROOT_LDR_WIDE_ENTRYPOINT_OFFSET/ 2190*795d594fSAndroid Build Coastguard Worker * BAKER_MARK_INTROSPECTION_GC_ROOT_LDR_NARROW_ENTRYPOINT_OFFSET) from the 2191*795d594fSAndroid Build Coastguard Worker * main entrypoint and the GC root thunk adjusts the entrypoint pointer, 2192*795d594fSAndroid Build Coastguard Worker * moves the root register to IP and jumps to the customized entrypoint, 2193*795d594fSAndroid Build Coastguard Worker * art_quick_read_barrier_mark_introspection_gc_roots_{wide,narrow}. 2194*795d594fSAndroid Build Coastguard Worker * The thunk also performs all the fast-path checks, so we need just the 2195*795d594fSAndroid Build Coastguard Worker * slow path. 2196*795d594fSAndroid Build Coastguard Worker * 2197*795d594fSAndroid Build Coastguard Worker * Intrinsic CAS operations (VarHandle*CompareAnd{Set,Exchange}* and 2198*795d594fSAndroid Build Coastguard Worker * UnsafeCASObject) use similar code to the GC roots wide load but using 2199*795d594fSAndroid Build Coastguard Worker * MOV (register, T3) instead of the LDR (immediate, T3), with destination 2200*795d594fSAndroid Build Coastguard Worker * register in bits 8-11 rather than 12-15. Therefore they have their own 2201*795d594fSAndroid Build Coastguard Worker * entrypoint, art_quick_read_barrier_mark_introspection_intrinsic_cas 2202*795d594fSAndroid Build Coastguard Worker * at the offset BAKER_MARK_INTROSPECTION_INTRINSIC_CAS_ENTRYPOINT_OFFSET. 2203*795d594fSAndroid Build Coastguard Worker * This is used only for high registers, low registers reuse the GC roots 2204*795d594fSAndroid Build Coastguard Worker * narrow load entrypoint as the low 3 bits of the destination register 2205*795d594fSAndroid Build Coastguard Worker * for MOV (register) encoding T1 match the LDR (immediate) encoding T1. 2206*795d594fSAndroid Build Coastguard Worker * 2207*795d594fSAndroid Build Coastguard Worker * The code structure is 2208*795d594fSAndroid Build Coastguard Worker * art_quick_read_barrier_mark_introspection: // @0x00 2209*795d594fSAndroid Build Coastguard Worker * Up to 32 bytes code for main entrypoint fast-path code for fields 2210*795d594fSAndroid Build Coastguard Worker * (and array elements with constant offset) with LDR encoding T3; 2211*795d594fSAndroid Build Coastguard Worker * jumps to the switch in the "narrow" entrypoint. 2212*795d594fSAndroid Build Coastguard Worker * art_quick_read_barrier_mark_introspection_narrow: // @0x20 2213*795d594fSAndroid Build Coastguard Worker * Up to 48 bytes code for fast path code for fields (and array 2214*795d594fSAndroid Build Coastguard Worker * elements with constant offset) with LDR encoding T1, ending in the 2215*795d594fSAndroid Build Coastguard Worker * return switch instruction TBB and the table with switch offsets. 2216*795d594fSAndroid Build Coastguard Worker * .Lmark_introspection_return_switch_case_r0: // @0x50 2217*795d594fSAndroid Build Coastguard Worker * Exactly 88 bytes of code for the return switch cases (8 bytes per 2218*795d594fSAndroid Build Coastguard Worker * case, 11 cases; no code for reserved registers). 2219*795d594fSAndroid Build Coastguard Worker * .Lmark_introspection_forwarding_address_narrow: // @0xa8 2220*795d594fSAndroid Build Coastguard Worker * Exactly 6 bytes to extract the forwarding address and jump to the 2221*795d594fSAndroid Build Coastguard Worker * "narrow" entrypoint fast path. 2222*795d594fSAndroid Build Coastguard Worker * .Lmark_introspection_return_switch_case_bad: // @0xae 2223*795d594fSAndroid Build Coastguard Worker * Exactly 2 bytes, bkpt for unexpected return register. 2224*795d594fSAndroid Build Coastguard Worker * .Lmark_introspection_unmarked_narrow: // @0xb0 2225*795d594fSAndroid Build Coastguard Worker * Exactly 16 bytes for "narrow" entrypoint slow path. 2226*795d594fSAndroid Build Coastguard Worker * art_quick_read_barrier_mark_introspection_gc_roots_wide: // @0xc0 2227*795d594fSAndroid Build Coastguard Worker * GC root entrypoint code for LDR encoding T3 (10 bytes); loads and 2228*795d594fSAndroid Build Coastguard Worker * extracts the return register and jumps to the runtime call. 2229*795d594fSAndroid Build Coastguard Worker * .Lmark_introspection_forwarding_address_wide: // @0xca 2230*795d594fSAndroid Build Coastguard Worker * Exactly 6 bytes to extract the forwarding address and jump to the 2231*795d594fSAndroid Build Coastguard Worker * "wide" entrypoint fast path. 2232*795d594fSAndroid Build Coastguard Worker * .Lmark_introspection_unmarked_wide: // @0xd0 2233*795d594fSAndroid Build Coastguard Worker * Exactly 16 bytes for "wide" entrypoint slow path. 2234*795d594fSAndroid Build Coastguard Worker * art_quick_read_barrier_mark_introspection_gc_roots_narrow: // @0xe0 2235*795d594fSAndroid Build Coastguard Worker * GC root entrypoint code for LDR encoding T1 (8 bytes); loads and 2236*795d594fSAndroid Build Coastguard Worker * extracts the return register and falls through to the runtime call. 2237*795d594fSAndroid Build Coastguard Worker * .Lmark_introspection_runtime_call: // @0xe8 2238*795d594fSAndroid Build Coastguard Worker * Exactly 24 bytes for the runtime call to MarkReg() and jump to the 2239*795d594fSAndroid Build Coastguard Worker * return switch. 2240*795d594fSAndroid Build Coastguard Worker * art_quick_read_barrier_mark_introspection_arrays: // @0x100 2241*795d594fSAndroid Build Coastguard Worker * Exactly 128 bytes for array load switch cases (16x2 instructions). 2242*795d594fSAndroid Build Coastguard Worker * art_quick_read_barrier_mark_introspection_intrinsic_cas: // @0x180 2243*795d594fSAndroid Build Coastguard Worker * Intrinsic CAS entrypoint for MOV (register) encoding T3 (6 bytes). 2244*795d594fSAndroid Build Coastguard Worker * Loads the return register and jumps to the runtime call. 2245*795d594fSAndroid Build Coastguard Worker */ 2246*795d594fSAndroid Build Coastguard Worker#if defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) 2247*795d594fSAndroid Build Coastguard WorkerENTRY_ALIGNED art_quick_read_barrier_mark_introspection, 512 2248*795d594fSAndroid Build Coastguard Worker // At this point, IP contains the reference, rMR is clobbered by the thunk 2249*795d594fSAndroid Build Coastguard Worker // and can be freely used as it will be set back to 1 before returning. 2250*795d594fSAndroid Build Coastguard Worker // For heap poisoning, the reference is poisoned, so unpoison it first. 2251*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF ip 2252*795d594fSAndroid Build Coastguard Worker // Check for null or marked, lock word is loaded into rMR. 2253*795d594fSAndroid Build Coastguard Worker BRBMI_CHECK_NULL_AND_MARKED _wide 2254*795d594fSAndroid Build Coastguard Worker // Load and extract the return register from the instruction. 2255*795d594fSAndroid Build Coastguard Worker BRBMI_LOAD_AND_EXTRACT_RETURN_REG BAKER_MARK_INTROSPECTION_FIELD_LDR_WIDE_OFFSET, _wide 2256*795d594fSAndroid Build Coastguard Worker b .Lmark_introspection_return_switch 2257*795d594fSAndroid Build Coastguard Worker 2258*795d594fSAndroid Build Coastguard Worker .balign 32 2259*795d594fSAndroid Build Coastguard Worker .thumb_func 2260*795d594fSAndroid Build Coastguard Worker .type art_quick_read_barrier_mark_introspection_narrow, #function 2261*795d594fSAndroid Build Coastguard Worker .hidden art_quick_read_barrier_mark_introspection_narrow 2262*795d594fSAndroid Build Coastguard Worker .global art_quick_read_barrier_mark_introspection_narrow 2263*795d594fSAndroid Build Coastguard Workerart_quick_read_barrier_mark_introspection_narrow: 2264*795d594fSAndroid Build Coastguard Worker // At this point, IP contains the reference, rMR is clobbered by the thunk 2265*795d594fSAndroid Build Coastguard Worker // and can be freely used as it will be set back to 1 before returning. 2266*795d594fSAndroid Build Coastguard Worker // For heap poisoning, the reference is poisoned, so unpoison it first. 2267*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF ip 2268*795d594fSAndroid Build Coastguard Worker // Check for null or marked, lock word is loaded into rMR. 2269*795d594fSAndroid Build Coastguard Worker BRBMI_CHECK_NULL_AND_MARKED _narrow 2270*795d594fSAndroid Build Coastguard Worker // Load and extract the return register from the instruction. 2271*795d594fSAndroid Build Coastguard Worker BRBMI_LOAD_AND_EXTRACT_RETURN_REG BAKER_MARK_INTROSPECTION_FIELD_LDR_NARROW_OFFSET, _narrow 2272*795d594fSAndroid Build Coastguard Worker.Lmark_introspection_return_switch: 2273*795d594fSAndroid Build Coastguard Worker tbb [pc, rMR] // Jump to the switch case. 2274*795d594fSAndroid Build Coastguard Worker.Lmark_introspection_return_table: 2275*795d594fSAndroid Build Coastguard Worker BRBMI_FOR_REGISTERS BRBMI_RETURN_SWITCH_CASE_OFFSET, BRBMI_BAD_RETURN_SWITCH_CASE_OFFSET 2276*795d594fSAndroid Build Coastguard Worker BRBMI_FOR_REGISTERS BRBMI_RETURN_SWITCH_CASE, /* no code */ 2277*795d594fSAndroid Build Coastguard Worker 2278*795d594fSAndroid Build Coastguard Worker .balign 8 2279*795d594fSAndroid Build Coastguard Worker BRBMI_EXTRACT_FORWARDING_ADDRESS _narrow // 6 bytes 2280*795d594fSAndroid Build Coastguard Worker.Lmark_introspection_return_switch_case_bad: 2281*795d594fSAndroid Build Coastguard Worker bkpt // 2 bytes 2282*795d594fSAndroid Build Coastguard Worker 2283*795d594fSAndroid Build Coastguard Worker BRBMI_FIELD_SLOW_PATH BAKER_MARK_INTROSPECTION_FIELD_LDR_NARROW_OFFSET, _narrow 2284*795d594fSAndroid Build Coastguard Worker 2285*795d594fSAndroid Build Coastguard Worker // 8 bytes for the loading and extracting of the return register. 2286*795d594fSAndroid Build Coastguard Worker BRBMI_GC_ROOT BAKER_MARK_INTROSPECTION_GC_ROOT_LDR_WIDE_OFFSET, _wide 2287*795d594fSAndroid Build Coastguard Worker // 2 bytes for near branch to the runtime call. 2288*795d594fSAndroid Build Coastguard Worker b .Lmark_introspection_runtime_call 2289*795d594fSAndroid Build Coastguard Worker 2290*795d594fSAndroid Build Coastguard Worker BRBMI_EXTRACT_FORWARDING_ADDRESS _wide // Not even 4-byte aligned. 2291*795d594fSAndroid Build Coastguard Worker 2292*795d594fSAndroid Build Coastguard Worker BRBMI_FIELD_SLOW_PATH BAKER_MARK_INTROSPECTION_FIELD_LDR_WIDE_OFFSET, _wide 2293*795d594fSAndroid Build Coastguard Worker 2294*795d594fSAndroid Build Coastguard Worker // 8 bytes for the loading and extracting of the return register. 2295*795d594fSAndroid Build Coastguard Worker BRBMI_GC_ROOT BAKER_MARK_INTROSPECTION_GC_ROOT_LDR_NARROW_OFFSET, _narrow 2296*795d594fSAndroid Build Coastguard Worker // And the runtime call and branch to the switch taking exactly 24 bytes 2297*795d594fSAndroid Build Coastguard Worker // (22 bytes for BRBMI_RUNTIME_CALL and 2 bytes for the near branch) 2298*795d594fSAndroid Build Coastguard Worker // shall take the rest of the 32-byte section (within a cache line). 2299*795d594fSAndroid Build Coastguard Worker.Lmark_introspection_runtime_call: 2300*795d594fSAndroid Build Coastguard Worker BRBMI_RUNTIME_CALL 2301*795d594fSAndroid Build Coastguard Worker b .Lmark_introspection_return_switch 2302*795d594fSAndroid Build Coastguard Worker 2303*795d594fSAndroid Build Coastguard Worker .balign 256 2304*795d594fSAndroid Build Coastguard Worker .thumb_func 2305*795d594fSAndroid Build Coastguard Worker .type art_quick_read_barrier_mark_introspection_arrays, #function 2306*795d594fSAndroid Build Coastguard Worker .hidden art_quick_read_barrier_mark_introspection_arrays 2307*795d594fSAndroid Build Coastguard Worker .global art_quick_read_barrier_mark_introspection_arrays 2308*795d594fSAndroid Build Coastguard Workerart_quick_read_barrier_mark_introspection_arrays: 2309*795d594fSAndroid Build Coastguard Worker BRBMI_FOR_REGISTERS BRBMI_ARRAY_LOAD, BRBMI_BKPT_FILL_8B 2310*795d594fSAndroid Build Coastguard Worker 2311*795d594fSAndroid Build Coastguard Worker .balign 8 2312*795d594fSAndroid Build Coastguard Worker .thumb_func 2313*795d594fSAndroid Build Coastguard Worker .type art_quick_read_barrier_mark_introspection_intrinsic_cas, #function 2314*795d594fSAndroid Build Coastguard Worker .hidden art_quick_read_barrier_mark_introspection_intrinsic_cas 2315*795d594fSAndroid Build Coastguard Worker .global art_quick_read_barrier_mark_introspection_intrinsic_cas 2316*795d594fSAndroid Build Coastguard Workerart_quick_read_barrier_mark_introspection_intrinsic_cas: 2317*795d594fSAndroid Build Coastguard Worker // Load the byte of the MOV instruction that contains Rd. Adjust for the thumb state in LR. 2318*795d594fSAndroid Build Coastguard Worker // The MOV (register, T3) is |11101010010|S|1111|(0)000|Rd|0000|Rm|, so the byte we read 2319*795d594fSAndroid Build Coastguard Worker // here, i.e. |(0)000|Rd|, contains only the register number, the top 4 bits are 0. 2320*795d594fSAndroid Build Coastguard Worker ldrb rMR, [lr, #(-1 + BAKER_MARK_INTROSPECTION_INTRINSIC_CAS_MOV_OFFSET + 3)] 2321*795d594fSAndroid Build Coastguard Worker b .Lmark_introspection_runtime_call 2322*795d594fSAndroid Build Coastguard WorkerEND art_quick_read_barrier_mark_introspection 2323*795d594fSAndroid Build Coastguard Worker#else // defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) 2324*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_read_barrier_mark_introspection 2325*795d594fSAndroid Build Coastguard Worker bkpt // Unreachable. 2326*795d594fSAndroid Build Coastguard WorkerEND art_quick_read_barrier_mark_introspection 2327*795d594fSAndroid Build Coastguard Worker#endif // defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) 2328*795d594fSAndroid Build Coastguard Worker 2329*795d594fSAndroid Build Coastguard Worker.extern artInvokePolymorphic 2330*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_invoke_polymorphic 2331*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_AND_ARGS_FRAME r2 2332*795d594fSAndroid Build Coastguard Worker mov r0, r1 @ r0 := receiver 2333*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ r1 := Thread::Current 2334*795d594fSAndroid Build Coastguard Worker mov r2, sp @ r2 := SP 2335*795d594fSAndroid Build Coastguard Worker bl artInvokePolymorphic @ artInvokePolymorphic(receiver, Thread*, SP) 2336*795d594fSAndroid Build Coastguard Worker str r1, [sp, 72] @ r0:r1 := Result. Copy r1 to context. 2337*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_AND_ARGS_FRAME 2338*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 2339*795d594fSAndroid Build Coastguard Worker vmov d0, r0, r1 @ Put result r0:r1 into floating point return register. 2340*795d594fSAndroid Build Coastguard Worker RETURN_OR_DELIVER_PENDING_EXCEPTION_REG r2 2341*795d594fSAndroid Build Coastguard WorkerEND art_quick_invoke_polymorphic 2342*795d594fSAndroid Build Coastguard Worker 2343*795d594fSAndroid Build Coastguard Worker.extern artInvokeCustom 2344*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_invoke_custom 2345*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_REFS_AND_ARGS_FRAME r1 2346*795d594fSAndroid Build Coastguard Worker @ r0 := call_site_idx 2347*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ r1 := Thread::Current 2348*795d594fSAndroid Build Coastguard Worker mov r2, sp @ r2 := SP 2349*795d594fSAndroid Build Coastguard Worker bl artInvokeCustom @ artInvokeCustom(call_site_idx, Thread*, SP) 2350*795d594fSAndroid Build Coastguard Worker str r1, [sp, #72] @ Save r1 to context (r0:r1 = result) 2351*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_REFS_AND_ARGS_FRAME 2352*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 2353*795d594fSAndroid Build Coastguard Worker vmov d0, r0, r1 @ Put result r0:r1 into floating point return register. 2354*795d594fSAndroid Build Coastguard Worker RETURN_OR_DELIVER_PENDING_EXCEPTION_REG r2 2355*795d594fSAndroid Build Coastguard WorkerEND art_quick_invoke_custom 2356*795d594fSAndroid Build Coastguard Worker 2357*795d594fSAndroid Build Coastguard Worker// r0 contains the class, r4 contains the inline cache. We can use ip as temporary. 2358*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_update_inline_cache 2359*795d594fSAndroid Build Coastguard Worker#if (INLINE_CACHE_SIZE != 5) 2360*795d594fSAndroid Build Coastguard Worker#error "INLINE_CACHE_SIZE not as expected." 2361*795d594fSAndroid Build Coastguard Worker#endif 2362*795d594fSAndroid Build Coastguard Worker#if defined(USE_READ_BARRIER) && defined(USE_BAKER_READ_BARRIER) 2363*795d594fSAndroid Build Coastguard Worker // Don't update the cache if we are marking. 2364*795d594fSAndroid Build Coastguard Worker cmp rMR, #0 2365*795d594fSAndroid Build Coastguard Worker bne .Ldone 2366*795d594fSAndroid Build Coastguard Worker#endif 2367*795d594fSAndroid Build Coastguard Worker.Lentry1: 2368*795d594fSAndroid Build Coastguard Worker ldr ip, [r4, #INLINE_CACHE_CLASSES_OFFSET] 2369*795d594fSAndroid Build Coastguard Worker cmp ip, r0 2370*795d594fSAndroid Build Coastguard Worker beq .Ldone 2371*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2372*795d594fSAndroid Build Coastguard Worker bne .Lentry2 2373*795d594fSAndroid Build Coastguard Worker ldrex ip, [r4, #INLINE_CACHE_CLASSES_OFFSET] 2374*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2375*795d594fSAndroid Build Coastguard Worker bne .Lentry1 2376*795d594fSAndroid Build Coastguard Worker strex ip, r0, [r4, #INLINE_CACHE_CLASSES_OFFSET] 2377*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2378*795d594fSAndroid Build Coastguard Worker bne .Ldone 2379*795d594fSAndroid Build Coastguard Worker b .Lentry1 2380*795d594fSAndroid Build Coastguard Worker.Lentry2: 2381*795d594fSAndroid Build Coastguard Worker ldr ip, [r4, #INLINE_CACHE_CLASSES_OFFSET+4] 2382*795d594fSAndroid Build Coastguard Worker cmp ip, r0 2383*795d594fSAndroid Build Coastguard Worker beq .Ldone 2384*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2385*795d594fSAndroid Build Coastguard Worker bne .Lentry3 2386*795d594fSAndroid Build Coastguard Worker ldrex ip, [r4, #INLINE_CACHE_CLASSES_OFFSET+4] 2387*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2388*795d594fSAndroid Build Coastguard Worker bne .Lentry2 2389*795d594fSAndroid Build Coastguard Worker strex ip, r0, [r4, #INLINE_CACHE_CLASSES_OFFSET+4] 2390*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2391*795d594fSAndroid Build Coastguard Worker bne .Ldone 2392*795d594fSAndroid Build Coastguard Worker b .Lentry2 2393*795d594fSAndroid Build Coastguard Worker.Lentry3: 2394*795d594fSAndroid Build Coastguard Worker ldr ip, [r4, #INLINE_CACHE_CLASSES_OFFSET+8] 2395*795d594fSAndroid Build Coastguard Worker cmp ip, r0 2396*795d594fSAndroid Build Coastguard Worker beq .Ldone 2397*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2398*795d594fSAndroid Build Coastguard Worker bne .Lentry4 2399*795d594fSAndroid Build Coastguard Worker ldrex ip, [r4, #INLINE_CACHE_CLASSES_OFFSET+8] 2400*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2401*795d594fSAndroid Build Coastguard Worker bne .Lentry3 2402*795d594fSAndroid Build Coastguard Worker strex ip, r0, [r4, #INLINE_CACHE_CLASSES_OFFSET+8] 2403*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2404*795d594fSAndroid Build Coastguard Worker bne .Ldone 2405*795d594fSAndroid Build Coastguard Worker b .Lentry3 2406*795d594fSAndroid Build Coastguard Worker.Lentry4: 2407*795d594fSAndroid Build Coastguard Worker ldr ip, [r4, #INLINE_CACHE_CLASSES_OFFSET+12] 2408*795d594fSAndroid Build Coastguard Worker cmp ip, r0 2409*795d594fSAndroid Build Coastguard Worker beq .Ldone 2410*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2411*795d594fSAndroid Build Coastguard Worker bne .Lentry5 2412*795d594fSAndroid Build Coastguard Worker ldrex ip, [r4, #INLINE_CACHE_CLASSES_OFFSET+12] 2413*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2414*795d594fSAndroid Build Coastguard Worker bne .Lentry4 2415*795d594fSAndroid Build Coastguard Worker strex ip, r0, [r4, #INLINE_CACHE_CLASSES_OFFSET+12] 2416*795d594fSAndroid Build Coastguard Worker cmp ip, #0 2417*795d594fSAndroid Build Coastguard Worker bne .Ldone 2418*795d594fSAndroid Build Coastguard Worker b .Lentry4 2419*795d594fSAndroid Build Coastguard Worker.Lentry5: 2420*795d594fSAndroid Build Coastguard Worker // Unconditionally store, the inline cache is megamorphic. 2421*795d594fSAndroid Build Coastguard Worker str r0, [r4, #INLINE_CACHE_CLASSES_OFFSET+16] 2422*795d594fSAndroid Build Coastguard Worker.Ldone: 2423*795d594fSAndroid Build Coastguard Worker blx lr 2424*795d594fSAndroid Build Coastguard WorkerEND art_quick_update_inline_cache 2425*795d594fSAndroid Build Coastguard Worker 2426*795d594fSAndroid Build Coastguard Worker// On entry, method is at the bottom of the stack. 2427*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_compile_optimized 2428*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_EVERYTHING_FRAME r0 2429*795d594fSAndroid Build Coastguard Worker ldr r0, [sp, FRAME_SIZE_SAVE_EVERYTHING] @ pass ArtMethod 2430*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ pass Thread::Current 2431*795d594fSAndroid Build Coastguard Worker bl artCompileOptimized @ (ArtMethod*, Thread*) 2432*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_EVERYTHING_FRAME 2433*795d594fSAndroid Build Coastguard Worker // We don't need to restore the marking register here, as 2434*795d594fSAndroid Build Coastguard Worker // artCompileOptimized doesn't allow thread suspension. 2435*795d594fSAndroid Build Coastguard Worker blx lr 2436*795d594fSAndroid Build Coastguard WorkerEND art_quick_compile_optimized 2437*795d594fSAndroid Build Coastguard Worker 2438*795d594fSAndroid Build Coastguard Worker// On entry, method is at the bottom of the stack. 2439*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_method_entry_hook 2440*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_EVERYTHING_FRAME r0 2441*795d594fSAndroid Build Coastguard Worker ldr r0, [sp, FRAME_SIZE_SAVE_EVERYTHING] @ pass ArtMethod 2442*795d594fSAndroid Build Coastguard Worker mov r1, rSELF @ pass Thread::Current 2443*795d594fSAndroid Build Coastguard Worker mov r2, sp @ pass SP 2444*795d594fSAndroid Build Coastguard Worker bl artMethodEntryHook @ (ArtMethod*, Thread*, SP) 2445*795d594fSAndroid Build Coastguard Worker 2446*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 2447*795d594fSAndroid Build Coastguard Worker cbnz r0, .Lentryhook_deopt 2448*795d594fSAndroid Build Coastguard Worker 2449*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_EVERYTHING_FRAME 2450*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 2451*795d594fSAndroid Build Coastguard Worker blx lr 2452*795d594fSAndroid Build Coastguard Worker 2453*795d594fSAndroid Build Coastguard Worker.Lentryhook_deopt: 2454*795d594fSAndroid Build Coastguard Worker // Deoptimize 2455*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_EVERYTHING 2456*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 2457*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 2458*795d594fSAndroid Build Coastguard WorkerEND art_quick_method_entry_hook 2459*795d594fSAndroid Build Coastguard Worker 2460*795d594fSAndroid Build Coastguard WorkerENTRY art_quick_method_exit_hook 2461*795d594fSAndroid Build Coastguard Worker SETUP_SAVE_EVERYTHING_FRAME r5 2462*795d594fSAndroid Build Coastguard Worker 2463*795d594fSAndroid Build Coastguard Worker INCREASE_FRAME 4 @ align stack 2464*795d594fSAndroid Build Coastguard Worker push {r2} @ pass frame_size stack 2465*795d594fSAndroid Build Coastguard Worker .cfi_adjust_cfa_offset 4 2466*795d594fSAndroid Build Coastguard Worker add r3, sp, #(8 + 8) @ store fpr_res pointer, in kSaveEverything frame 2467*795d594fSAndroid Build Coastguard Worker add r2, sp, #(136 + 8) @ store gpr_res pointer, in kSaveEverything frame 2468*795d594fSAndroid Build Coastguard Worker add r1, sp, #(FRAME_SIZE_SAVE_EVERYTHING + 8) @ pass ArtMethod** 2469*795d594fSAndroid Build Coastguard Worker mov r0, rSELF @ pass Thread::Current 2470*795d594fSAndroid Build Coastguard Worker blx artMethodExitHook @ (Thread*, ArtMethod**, gpr_res*, fpr_res*, 2471*795d594fSAndroid Build Coastguard Worker @ frame_size) 2472*795d594fSAndroid Build Coastguard Worker DECREASE_FRAME 8 @ pop arguments on stack 2473*795d594fSAndroid Build Coastguard Worker 2474*795d594fSAndroid Build Coastguard Worker CFI_REMEMBER_STATE 2475*795d594fSAndroid Build Coastguard Worker cbnz r0, .Lexithook_deopt_or_exception 2476*795d594fSAndroid Build Coastguard Worker 2477*795d594fSAndroid Build Coastguard Worker RESTORE_SAVE_EVERYTHING_FRAME 2478*795d594fSAndroid Build Coastguard Worker REFRESH_MARKING_REGISTER 2479*795d594fSAndroid Build Coastguard Worker blx lr 2480*795d594fSAndroid Build Coastguard Worker 2481*795d594fSAndroid Build Coastguard Worker.Lexithook_deopt_or_exception: 2482*795d594fSAndroid Build Coastguard Worker // Deoptimize or exception thrown. 2483*795d594fSAndroid Build Coastguard Worker CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_EVERYTHING 2484*795d594fSAndroid Build Coastguard Worker bl art_quick_do_long_jump @ (Context*) 2485*795d594fSAndroid Build Coastguard Worker bkpt // Unreached 2486*795d594fSAndroid Build Coastguard WorkerEND art_quick_method_exit_hook 2487