1/* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "asm_support_riscv64.S" 18#include "interpreter/cfi_asm_support.h" 19 20 21// Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding. 22// Argument 0: a0: The context pointer for ExecuteSwitchImpl. 23// Argument 1: a1: Pointer to the templated ExecuteSwitchImpl to call. 24// Argument 2: a2: The value of DEX PC (memory address of the methods bytecode). 25ENTRY ExecuteSwitchImplAsm 26 INCREASE_FRAME 16 27 SAVE_GPR s1, 0 28 SAVE_GPR ra, 8 29 30 mv s1, a2 // s1 = DEX PC 31 CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* a0 */, 9 /* s1, a.k.a. x9 */, 0) 32 jalr a1 // Call the wrapped method. 33 34 RESTORE_GPR s1, 0 35 RESTORE_GPR ra, 8 36 DECREASE_FRAME 16 37 ret 38END ExecuteSwitchImplAsm 39 40 41.macro INVOKE_STUB_CREATE_FRAME 42 // Save ra, fp, xSELF (current thread) a4, a5 (they will be needed in the invoke stub return) 43 // and callee-save regs s3 - s5 that are clobbered here and in art_quick_invoke_(static_)_stub. 44 INCREASE_FRAME 48 45 SAVE_GPR fp, (8*0) 46 SAVE_GPR xSELF, (8*1) 47 SAVE_GPR a4, (8*2) 48 SAVE_GPR a5, (8*3) 49 SAVE_GPR s3, (8*4) 50 SAVE_GPR ra, (8*5) 51 52 mv fp, sp // save frame pointer 53 .cfi_def_cfa_register fp 54 55 addi t0, a2, (__SIZEOF_POINTER__ + 0xf) // Reserve space for ArtMethod*, arguments and 56 andi t0, t0, ~0xf // round up for 16-byte stack alignment. 57 sub sp, sp, t0 58 59 mv xSELF, a3 60 61 // Copy arguments on stack (4 bytes per slot): 62 // a1: source address 63 // a2: arguments length 64 // s3: destination address. 65 66 add s3, sp, 8 // destination address is bottom of the stack + 8 bytes for ArtMethod* (null) 67 68 beqz a2, 2f // loop through 4-byte arguments from the last to the first 691: 70 addi a2, a2, -4 71 add t0, a1, a2 // t0 is the source address of the next copied argument 72 lw t1, (t0) // t1 is the 4 bytes at address t0 73 add t0, s3, a2 // t0 is the destination address of the next copied argument 74 sw t1, (t0) // save t1 at the destination address t0 75 bnez a2, 1b 762: 77 sd zero, (sp) // Store null into ArtMethod* at bottom of frame. 78.endm 79 80 81.macro INVOKE_STUB_CALL_AND_RETURN 82 // Call the method. 83 ld t0, ART_METHOD_QUICK_CODE_OFFSET_64(a0) 84 jalr t0 85 86 mv sp, fp // restore frame pointer 87 .cfi_def_cfa_register sp 88 89 // Restore ra, fp, xSELF (current thread) a4 (shorty), a5 (result pointer) and callee-save 90 // regs s3 - s5 from stack. 91 RESTORE_GPR fp, (8*0) 92 RESTORE_GPR xSELF, (8*1) 93 RESTORE_GPR a4, (8*2) 94 RESTORE_GPR a5, (8*3) 95 RESTORE_GPR s3, (8*4) 96 RESTORE_GPR ra, (8*5) 97 DECREASE_FRAME 48 98 99 // Load result type (1-byte symbol) from a5. 100 // Check result type and store the correct register into the jvalue in memory at a4 address. 101 lbu t0, (a5) 102 103 li t1, 'V' // void (do not store result at all) 104 beq t1, t0, 1f 105 106 li t1, 'D' // double 107 beq t1, t0, 2f 108 109 li t1, 'F' // float 110 beq t1, t0, 3f 111 112 // Otherwise, result is in a0 (either 8 or 4 bytes, but it is fine to store 8 bytes as the 113 // upper bytes in a0 in that case are zero, and jvalue has enough space). 114 sd a0, (a4) 1151: 116 ret 117 1182: // double: result in fa0 (8 bytes) 119 fsd fa0, (a4) 120 ret 121 1223: // float: result in fa0 (4 bytes) 123 fsw fa0, (a4) 124 ret 125.endm 126 127 128ENTRY art_deliver_pending_exception 129 DELIVER_PENDING_EXCEPTION 130END art_deliver_pending_exception 131 132 133// Macros for loading an argument into a register. 134// label - the base name of the label of the load routine, 135// reg - the register to load, 136// args - pointer to current argument, incremented by size, 137// size - the size of the register - 4 or 8 bytes, 138// load - instruction used for loading, 139// nh4_reg - the register to fill with the address of the next handler for 4-byte values, 140// nh4_l - the base name of the label of the next handler for 4-byte values, 141// nh8_reg - the register to fill with the address of the next handler for 8-byte values, 142// nh8_l - the base name of the label of the next handler for 8-byte values, 143// cont - the base name of the label for continuing the shorty processing loop, 144// sfx - suffix added to all labels to make labels unique for different users. 145.macro INVOKE_STUB_LOAD_REG label, reg, args, size, load, nh4_reg, nh4_l, nh8_reg, nh8_l, cont, sfx 146\label\sfx: 147 \load \reg, (\args) 148 addi \args, \args, \size 149 la \nh4_reg, \nh4_l\sfx 150 la \nh8_reg, \nh8_l\sfx 151 j \cont\sfx 152.endm 153 154 155// Macro for skipping an argument that does not fit into argument registers. 156// label - the base name of the label of the skip routine, 157// args - pointer to current argument, incremented by size, 158// size - the size of the argument - 4 or 8 bytes, 159// cont - the base name of the label for continuing the shorty processing loop, 160// sfx - suffix added to all labels to make labels unique for different users. 161.macro INVOKE_STUB_SKIP_ARG label, args, size, cont, sfx 162\label\sfx: 163 addi \args, \args, \size 164 j \cont\sfx 165.endm 166 167 168// Fill registers a1 to a7 and fa0 to fa7 with parameters. 169// Parse the passed shorty to determine which register to load. 170// a5 - shorty, 171// s3 - points to arguments on the stack, 172// sfx - suffix added to all labels to make labels unique for different users. 173.macro INVOKE_STUB_LOAD_ALL_ARGS sfx 174 mv t0, a5 // Load shorty address, 175 addi t0, t0, 1 // plus one to skip the return type. 176 177 // Load this (if instance method) and addresses for routines that load argument GPRs and FPRs. 178 .ifc \sfx, _instance 179 lw a1, (s3) // Load "this" parameter, 180 addi s3, s3, 4 // and increment arg pointer. 181 la t3, .Lload4i2\sfx 182 la t4, .Lload8i2\sfx 183 .else 184 la t3, .Lload4i1\sfx 185 la t4, .Lload8i1\sfx 186 .endif 187 la t5, .Lload4f0\sfx 188 la t6, .Lload8f0\sfx 189 190 // Loop to fill registers. 191.Lfill_regs\sfx: 192 lb t1, (t0) // Load next character in signature, and increment. 193 addi t0, t0, 1 // and increment. 194 beqz t1, .Lcall_method\sfx // Exit at end of signature. Shorty 0 terminated. 195 196 li t2, 'J' 197 beq t1, t2, .Lload_long\sfx // Is this a long? 198 199 li t2, 'F' 200 beq t1, t2, .Lload_float\sfx // Is this a float? 201 202 li t2, 'D' 203 beq t1, t2, .Lload_double\sfx // Is this a double? 204 205 // Everything else uses a 4-byte GPR. 206 jr t3 207 208.Lload_long\sfx: 209 jr t4 210 211.Lload_float\sfx: 212 jr t5 213 214.Lload_double\sfx: 215 jr t6 216 217// Handlers for loading other args (not float/double/long) into 4-byte GPRs. 218 .ifnc \sfx, _instance 219 INVOKE_STUB_LOAD_REG \ 220 .Lload4i1, a1, s3, 4, lw, t3, .Lload4i2, t4, .Lload8i2, .Lfill_regs, \sfx 221 .endif 222 INVOKE_STUB_LOAD_REG .Lload4i2, a2, s3, 4, lw, t3, .Lload4i3, t4, .Lload8i3, .Lfill_regs, \sfx 223 INVOKE_STUB_LOAD_REG .Lload4i3, a3, s3, 4, lw, t3, .Lload4i4, t4, .Lload8i4, .Lfill_regs, \sfx 224 INVOKE_STUB_LOAD_REG .Lload4i4, a4, s3, 4, lw, t3, .Lload4i5, t4, .Lload8i5, .Lfill_regs, \sfx 225 INVOKE_STUB_LOAD_REG .Lload4i5, a5, s3, 4, lw, t3, .Lload4i6, t4, .Lload8i6, .Lfill_regs, \sfx 226 INVOKE_STUB_LOAD_REG .Lload4i6, a6, s3, 4, lw, t3, .Lload4i7, t4, .Lload8i7, .Lfill_regs, \sfx 227 INVOKE_STUB_LOAD_REG .Lload4i7, a7, s3, 4, lw, t3, .Lskip4, t4, .Lskip8, .Lfill_regs, \sfx 228 229// Handlers for loading longs into 8-byte GPRs. 230 .ifnc \sfx, _instance 231 INVOKE_STUB_LOAD_REG \ 232 .Lload8i1, a1, s3, 8, ld, t3, .Lload4i2, t4, .Lload8i2, .Lfill_regs, \sfx 233 .endif 234 INVOKE_STUB_LOAD_REG .Lload8i2, a2, s3, 8, ld, t3, .Lload4i3, t4, .Lload8i3, .Lfill_regs, \sfx 235 INVOKE_STUB_LOAD_REG .Lload8i3, a3, s3, 8, ld, t3, .Lload4i4, t4, .Lload8i4, .Lfill_regs, \sfx 236 INVOKE_STUB_LOAD_REG .Lload8i4, a4, s3, 8, ld, t3, .Lload4i5, t4, .Lload8i5, .Lfill_regs, \sfx 237 INVOKE_STUB_LOAD_REG .Lload8i5, a5, s3, 8, ld, t3, .Lload4i6, t4, .Lload8i6, .Lfill_regs, \sfx 238 INVOKE_STUB_LOAD_REG .Lload8i6, a6, s3, 8, ld, t3, .Lload4i7, t4, .Lload8i7, .Lfill_regs, \sfx 239 INVOKE_STUB_LOAD_REG .Lload8i7, a7, s3, 8, ld, t3, .Lskip4, t4, .Lskip8, .Lfill_regs, \sfx 240 241// Handlers for loading floats into FPRs. 242 INVOKE_STUB_LOAD_REG .Lload4f0, fa0, s3, 4, flw, t5, .Lload4f1, t6, .Lload8f1, .Lfill_regs, \sfx 243 INVOKE_STUB_LOAD_REG .Lload4f1, fa1, s3, 4, flw, t5, .Lload4f2, t6, .Lload8f2, .Lfill_regs, \sfx 244 INVOKE_STUB_LOAD_REG .Lload4f2, fa2, s3, 4, flw, t5, .Lload4f3, t6, .Lload8f3, .Lfill_regs, \sfx 245 INVOKE_STUB_LOAD_REG .Lload4f3, fa3, s3, 4, flw, t5, .Lload4f4, t6, .Lload8f4, .Lfill_regs, \sfx 246 INVOKE_STUB_LOAD_REG .Lload4f4, fa4, s3, 4, flw, t5, .Lload4f5, t6, .Lload8f5, .Lfill_regs, \sfx 247 INVOKE_STUB_LOAD_REG .Lload4f5, fa5, s3, 4, flw, t5, .Lload4f6, t6, .Lload8f6, .Lfill_regs, \sfx 248 INVOKE_STUB_LOAD_REG .Lload4f6, fa6, s3, 4, flw, t5, .Lload4f7, t6, .Lload8f7, .Lfill_regs, \sfx 249 INVOKE_STUB_LOAD_REG .Lload4f7, fa7, s3, 4, flw, t5, .Lskip4, t6, .Lskip8, .Lfill_regs, \sfx 250 251// Handlers for loading doubles into FPRs. 252 INVOKE_STUB_LOAD_REG .Lload8f0, fa0, s3, 8, fld, t5, .Lload4f1, t6, .Lload8f1, .Lfill_regs, \sfx 253 INVOKE_STUB_LOAD_REG .Lload8f1, fa1, s3, 8, fld, t5, .Lload4f2, t6, .Lload8f2, .Lfill_regs, \sfx 254 INVOKE_STUB_LOAD_REG .Lload8f2, fa2, s3, 8, fld, t5, .Lload4f3, t6, .Lload8f3, .Lfill_regs, \sfx 255 INVOKE_STUB_LOAD_REG .Lload8f3, fa3, s3, 8, fld, t5, .Lload4f4, t6, .Lload8f4, .Lfill_regs, \sfx 256 INVOKE_STUB_LOAD_REG .Lload8f4, fa4, s3, 8, fld, t5, .Lload4f5, t6, .Lload8f5, .Lfill_regs, \sfx 257 INVOKE_STUB_LOAD_REG .Lload8f5, fa5, s3, 8, fld, t5, .Lload4f6, t6, .Lload8f6, .Lfill_regs, \sfx 258 INVOKE_STUB_LOAD_REG .Lload8f6, fa6, s3, 8, fld, t5, .Lload4f7, t6, .Lload8f7, .Lfill_regs, \sfx 259 INVOKE_STUB_LOAD_REG .Lload8f7, fa7, s3, 8, fld, t5, .Lskip4, t6, .Lskip8, .Lfill_regs, \sfx 260 261// Handlers for skipping arguments that do not fit into registers. 262 INVOKE_STUB_SKIP_ARG .Lskip4, s3, 4, .Lfill_regs, \sfx 263 INVOKE_STUB_SKIP_ARG .Lskip8, s3, 8, .Lfill_regs, \sfx 264 265.Lcall_method\sfx: 266.endm 267 268 269// void art_quick_invoke_stub(ArtMethod* method, // a0 270// uint32_t* args, // a1 271// uint32_t argsize, // a2 272// Thread* self, // a3 273// JValue* result, // a4 274// char* shorty) // a5 275ENTRY art_quick_invoke_stub 276 INVOKE_STUB_CREATE_FRAME 277 278 // Load args into registers. 279 INVOKE_STUB_LOAD_ALL_ARGS _instance 280 281 // Call the method and return. 282 INVOKE_STUB_CALL_AND_RETURN 283END art_quick_invoke_stub 284 285 286// void art_quick_invoke_static_stub(ArtMethod* method, // a0 287// uint32_t* args, // a1 288// uint32_t argsize, // a2 289// Thread* self, // a3 290// JValue* result, // a4 291// char* shorty) // a5 292ENTRY art_quick_invoke_static_stub 293 INVOKE_STUB_CREATE_FRAME 294 295 // Load args into registers. 296 INVOKE_STUB_LOAD_ALL_ARGS _static 297 298 // Call the method and return. 299 INVOKE_STUB_CALL_AND_RETURN 300END art_quick_invoke_static_stub 301 302 303ENTRY art_quick_generic_jni_trampoline 304 SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_A0 305 306 // Save sp, so we can have static CFI info. 307 mv fp, sp 308 .cfi_def_cfa_register fp 309 310 li t0, GENERIC_JNI_TRAMPOLINE_RESERVED_AREA 311 sub sp, sp, t0 312 313 mv a0, xSELF // Thread* 314 mv a1, fp // SP for the managed frame. 315 mv a2, sp // reserved area for arguments and other saved data (up to managed frame) 316 call artQuickGenericJniTrampoline 317 318 // Check for error (class init check or locking for synchronized native method can throw). 319 beqz a0, .Lexception_in_native 320 321 mv t0, a0 // save pointer to native method code into temporary 322 323 // Load argument GPRs from stack (saved there by artQuickGenericJniTrampoline). 324 ld a0, 8*0(sp) // JniEnv* for the native method 325 ld a1, 8*1(sp) 326 ld a2, 8*2(sp) 327 ld a3, 8*3(sp) 328 ld a4, 8*4(sp) 329 ld a5, 8*5(sp) 330 ld a6, 8*6(sp) 331 ld a7, 8*7(sp) 332 333 // Load argument FPRs from stack (saved there by artQuickGenericJniTrampoline). 334 fld fa0, 8*8(sp) 335 fld fa1, 8*9(sp) 336 fld fa2, 8*10(sp) 337 fld fa3, 8*11(sp) 338 fld fa4, 8*12(sp) 339 fld fa5, 8*13(sp) 340 fld fa6, 8*14(sp) 341 fld fa7, 8*15(sp) 342 343 ld t6, 8*16(sp) // @CriticalNative arg, used by art_jni_dlsym_lookup_critical_stub 344 345 ld t1, 8*17(sp) // restore stack 346 mv sp, t1 347 348 jalr t0 // call native method 349 350 // result sign extension is handled in C code, prepare for artQuickGenericJniEndTrampoline call: 351 // uint64_t artQuickGenericJniEndTrampoline(Thread* self, // a0 352 // jvalue result, // a1 (need to move from a0) 353 // uint64_t result_f) // a2 (need to move from fa0) 354 mv a1, a0 355 mv a0, xSELF 356 fmv.x.d a2, fa0 357 call artQuickGenericJniEndTrampoline 358 359 // Pending exceptions possible. 360 ld t0, THREAD_EXCEPTION_OFFSET(xSELF) 361 bnez t0, .Lexception_in_native 362 363 // Tear down the alloca. 364 mv sp, fp 365 .cfi_remember_state 366 .cfi_def_cfa_register sp 367 368 LOAD_RUNTIME_INSTANCE a1 369 lb a1, RUN_EXIT_HOOKS_OFFSET_FROM_RUNTIME_INSTANCE(a1) 370 bnez a1, .Lcall_method_exit_hook 371 372.Lcall_method_exit_hook_done: 373 // This does not clobber the result register a0. a1 is not used for result as the managed code 374 // does not have a 128-bit type. Alternatively we could restore a subset of these registers. 375 RESTORE_SAVE_REFS_AND_ARGS_FRAME 376 fmv.d.x fa0, a0 377 ret 378 CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_AND_ARGS 379 380.Lcall_method_exit_hook: 381 fmv.d.x fa0, a0 382 li a4, FRAME_SIZE_SAVE_REFS_AND_ARGS 383 jal art_quick_method_exit_hook 384 j .Lcall_method_exit_hook_done 385 386.Lexception_in_native: 387 // Move to a1 then sp to please assembler. 388 ld a1, THREAD_TOP_QUICK_FRAME_OFFSET(xSELF) 389 addi sp, a1, -1 // Remove the GenericJNI tag. 390 call art_deliver_pending_exception 391END art_quick_generic_jni_trampoline 392 393 394ENTRY art_quick_to_interpreter_bridge 395 SETUP_SAVE_REFS_AND_ARGS_FRAME 396 397 // uint64_t artQuickToInterpreterBridge(ArtMethod* method, Thread* self, ArtMethod** sp) 398 // a0 will contain ArtMethod* 399 mv a1, xSELF 400 mv a2, sp 401 call artQuickToInterpreterBridge 402 403 // TODO: no need to restore arguments in this case. 404 RESTORE_SAVE_REFS_AND_ARGS_FRAME 405 406 fmv.d.x fa0, a0 // copy the result to FP result register 407 408 RETURN_OR_DELIVER_PENDING_EXCEPTION_REG t0 409END art_quick_to_interpreter_bridge 410 411 412 .extern artMethodExitHook 413ENTRY art_quick_method_exit_hook 414 SETUP_SAVE_EVERYTHING_FRAME 415 416 addi a3, sp, SAVE_EVERYTHING_FRAME_OFFSET_FA0 // FP result ptr in kSaveEverything frame 417 addi a2, sp, SAVE_EVERYTHING_FRAME_OFFSET_A0 // integer result ptr in kSaveEverything frame 418 addi a1, sp, FRAME_SIZE_SAVE_EVERYTHING // ArtMethod** 419 mv a0, xSELF // Thread::Current 420 call artMethodExitHook // (Thread*, ArtMethod**, gpr_res*, fpr_res*, 421 // frame_size) 422 423 // Normal return. 424 RESTORE_SAVE_EVERYTHING_FRAME 425 ret 426END art_quick_method_exit_hook 427 428 429// On entry a0 is uintptr_t* gprs_ and a1 is uint64_t* fprs_. 430// Both must reside on the stack, between current sp and target sp. 431ENTRY art_quick_do_long_jump 432 // Load FPRs 433 fld ft0, 8*0(a1) // f0 434 fld ft1, 8*1(a1) // f1 435 fld ft2, 8*2(a1) // f2 436 fld ft3, 8*3(a1) // f3 437 fld ft4, 8*4(a1) // f4 438 fld ft5, 8*5(a1) // f5 439 fld ft6, 8*6(a1) // f6 440 fld ft7, 8*7(a1) // f7 441 fld fs0, 8*8(a1) // f8 442 fld fs1, 8*9(a1) // f9 443 fld fa0, 8*10(a1) // f10 444 fld fa1, 8*11(a1) // f11 445 fld fa2, 8*12(a1) // f12 446 fld fa3, 8*13(a1) // f13 447 fld fa4, 8*14(a1) // f14 448 fld fa5, 8*15(a1) // f15 449 fld fa6, 8*16(a1) // f16 450 fld fa7, 8*17(a1) // f17 451 fld fs2, 8*18(a1) // f18 452 fld fs3, 8*19(a1) // f19 453 fld fs4, 8*20(a1) // f20 454 fld fs5, 8*21(a1) // f21 455 fld fs6, 8*22(a1) // f22 456 fld fs7, 8*23(a1) // f23 457 fld fs8, 8*24(a1) // f24 458 fld fs9, 8*25(a1) // f25 459 fld fs10, 8*26(a1) // f26 460 fld fs11, 8*27(a1) // f27 461 fld ft8, 8*28(a1) // f28 462 fld ft9, 8*29(a1) // f29 463 fld ft10, 8*30(a1) // f30 464 fld ft11, 8*31(a1) // f31 465 466 // Load GPRs. 467 // Skip slot 8*0(a0) for zero/x0 as it is hard-wired zero. 468 ld ra, 8*1(a0) // x1 469 // Skip slot 8*2(a0) for sp/x2 as it is set below. 470 // Skip slot 8*3(a0) for platform-specific thread pointer gp/x3. 471 // Skip slot 8*4(a0) for platform-specific global pointer tp/x4. 472 // Skip slot 8*5(a0) for t0/x5 as it is clobbered below. 473 // Skip slot 8*6(a0) for t1/x6 as it is clobbered below. 474 ld t2, 8*7(a0) // x7 475 ld s0, 8*8(a0) // x8 476 ld s1, 8*9(a0) // x9 477 // Delay loading a0 as the base is in a0. 478 ld a1, 8*11(a0) // x11 479 ld a2, 8*12(a0) // x12 480 ld a3, 8*13(a0) // x13 481 ld a4, 8*14(a0) // x14 482 ld a5, 8*15(a0) // x15 483 ld a6, 8*16(a0) // x16 484 ld a7, 8*17(a0) // x17 485 ld s2, 8*18(a0) // x18 486 ld s3, 8*19(a0) // x19 487 ld s4, 8*20(a0) // x20 488 ld s5, 8*21(a0) // x21 489 ld s6, 8*22(a0) // x22 490 ld s7, 8*23(a0) // x23 491 ld s8, 8*24(a0) // x24 492 ld s9, 8*25(a0) // x25 493 ld s10, 8*26(a0) // x26 494 ld s11, 8*27(a0) // x27 495 ld t3, 8*28(a0) // x28 496 ld t4, 8*29(a0) // x29 497 ld t5, 8*30(a0) // x30 498 ld t6, 8*31(a0) // x31 499 500 // Load sp to t0. 501 ld t0, 8*2(a0) 502 503 // Load PC to t1, it is in the last stack slot. 504 ld t1, 8*32(a0) 505 506 // Now load a0. 507 ld a0, 8*10(a0) // x10 508 509 // Set sp. Do not access fprs_ and gprs_ from now, they are below sp. 510 mv sp, t0 511 512 jr t1 513END art_quick_do_long_jump 514 515 516// Called by managed code that is attempting to call a method on a proxy class. On entry a0 holds 517// the proxy method and a1 holds the receiver. The frame size of the invoked proxy method agrees 518// with kSaveRefsAndArgs frame. 519.extern artQuickProxyInvokeHandler 520ENTRY art_quick_proxy_invoke_handler 521 SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_A0 522 523 // uint64_t artQuickProxyInvokeHandler(ArtMethod* proxy_method, // a0 524 // mirror::Object* receiver, // a1 525 // Thread* self, // a2 526 // ArtMethod** sp) // a3 527 mv a2, xSELF // pass Thread::Current 528 mv a3, sp // pass sp 529 call artQuickProxyInvokeHandler // (Method* proxy method, receiver, Thread*, sp) 530 531 ld a2, THREAD_EXCEPTION_OFFSET(xSELF) 532 bnez a2, .Lexception_in_proxy // success if no exception is pending 533 .cfi_remember_state 534 RESTORE_SAVE_REFS_AND_ARGS_FRAME // Restore frame 535 fmv.d.x fa0, a0 // Store result in fa0 in case it was float or double 536 ret // return on success 537 538.Lexception_in_proxy: 539 CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_AND_ARGS 540 RESTORE_SAVE_REFS_AND_ARGS_FRAME 541 DELIVER_PENDING_EXCEPTION 542END art_quick_proxy_invoke_handler 543 544 545.macro ONE_ARG_RUNTIME_EXCEPTION c_name, cxx_name 546.extern \cxx_name 547ENTRY \c_name 548 SETUP_SAVE_ALL_CALLEE_SAVES_FRAME // save all registers as basis for long jump context. 549 mv a1, xSELF // pass Thread::Current. 550 jal \cxx_name // \cxx_name(arg, Thread*). 551 ebreak 552END \c_name 553.endm 554 555 556// Called to attempt to execute an obsolete method. 557ONE_ARG_RUNTIME_EXCEPTION art_invoke_obsolete_method_stub, artInvokeObsoleteMethod 558 559 560ENTRY art_quick_resolution_trampoline 561 SETUP_SAVE_REFS_AND_ARGS_FRAME 562 563 // const void* artQuickResolutionTrampoline(ArtMethod* called, // a0 564 // mirror::Object* receiver, // a1 565 // Thread* self, // a2 566 // ArtMethod** sp) // a3 567 mv a2, xSELF 568 mv a3, sp 569 call artQuickResolutionTrampoline 570 571 beqz a0, 1f 572 .cfi_remember_state 573 mv t0, a0 // Remember returned code pointer in t0. 574 ld a0, (sp) // artQuickResolutionTrampoline puts called method in *sp. 575 576 RESTORE_SAVE_REFS_AND_ARGS_FRAME 577 jr t0 5781: 579 CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_AND_ARGS 580 RESTORE_SAVE_REFS_AND_ARGS_FRAME 581 DELIVER_PENDING_EXCEPTION 582END art_quick_resolution_trampoline 583 584 585UNDEFINED art_quick_imt_conflict_trampoline 586UNDEFINED art_quick_deoptimize_from_compiled_code 587UNDEFINED art_quick_string_builder_append 588UNDEFINED art_quick_compile_optimized 589UNDEFINED art_quick_method_entry_hook 590UNDEFINED art_quick_check_instance_of 591UNDEFINED art_quick_osr_stub 592 593UNDEFINED art_quick_alloc_array_resolved_dlmalloc 594UNDEFINED art_quick_alloc_array_resolved_dlmalloc_instrumented 595UNDEFINED art_quick_alloc_array_resolved8_dlmalloc 596UNDEFINED art_quick_alloc_array_resolved8_dlmalloc_instrumented 597UNDEFINED art_quick_alloc_array_resolved16_dlmalloc 598UNDEFINED art_quick_alloc_array_resolved16_dlmalloc_instrumented 599UNDEFINED art_quick_alloc_array_resolved32_dlmalloc 600UNDEFINED art_quick_alloc_array_resolved32_dlmalloc_instrumented 601UNDEFINED art_quick_alloc_array_resolved64_dlmalloc 602UNDEFINED art_quick_alloc_array_resolved64_dlmalloc_instrumented 603UNDEFINED art_quick_alloc_object_resolved_dlmalloc 604UNDEFINED art_quick_alloc_object_resolved_dlmalloc_instrumented 605UNDEFINED art_quick_alloc_object_initialized_dlmalloc 606UNDEFINED art_quick_alloc_object_initialized_dlmalloc_instrumented 607UNDEFINED art_quick_alloc_object_with_checks_dlmalloc 608UNDEFINED art_quick_alloc_object_with_checks_dlmalloc_instrumented 609UNDEFINED art_quick_alloc_string_object_dlmalloc 610UNDEFINED art_quick_alloc_string_object_dlmalloc_instrumented 611UNDEFINED art_quick_alloc_string_from_bytes_dlmalloc 612UNDEFINED art_quick_alloc_string_from_bytes_dlmalloc_instrumented 613UNDEFINED art_quick_alloc_string_from_chars_dlmalloc 614UNDEFINED art_quick_alloc_string_from_chars_dlmalloc_instrumented 615UNDEFINED art_quick_alloc_string_from_string_dlmalloc 616UNDEFINED art_quick_alloc_string_from_string_dlmalloc_instrumented 617UNDEFINED art_quick_alloc_array_resolved_rosalloc 618UNDEFINED art_quick_alloc_array_resolved_rosalloc_instrumented 619UNDEFINED art_quick_alloc_array_resolved8_rosalloc 620UNDEFINED art_quick_alloc_array_resolved8_rosalloc_instrumented 621UNDEFINED art_quick_alloc_array_resolved16_rosalloc 622UNDEFINED art_quick_alloc_array_resolved16_rosalloc_instrumented 623UNDEFINED art_quick_alloc_array_resolved32_rosalloc 624UNDEFINED art_quick_alloc_array_resolved32_rosalloc_instrumented 625UNDEFINED art_quick_alloc_array_resolved64_rosalloc 626UNDEFINED art_quick_alloc_array_resolved64_rosalloc_instrumented 627UNDEFINED art_quick_alloc_object_resolved_rosalloc 628UNDEFINED art_quick_alloc_object_resolved_rosalloc_instrumented 629UNDEFINED art_quick_alloc_object_initialized_rosalloc 630UNDEFINED art_quick_alloc_object_initialized_rosalloc_instrumented 631UNDEFINED art_quick_alloc_object_with_checks_rosalloc 632UNDEFINED art_quick_alloc_object_with_checks_rosalloc_instrumented 633UNDEFINED art_quick_alloc_string_object_rosalloc 634UNDEFINED art_quick_alloc_string_object_rosalloc_instrumented 635UNDEFINED art_quick_alloc_string_from_bytes_rosalloc 636UNDEFINED art_quick_alloc_string_from_bytes_rosalloc_instrumented 637UNDEFINED art_quick_alloc_string_from_chars_rosalloc 638UNDEFINED art_quick_alloc_string_from_chars_rosalloc_instrumented 639UNDEFINED art_quick_alloc_string_from_string_rosalloc 640UNDEFINED art_quick_alloc_string_from_string_rosalloc_instrumented 641UNDEFINED art_quick_alloc_array_resolved_bump_pointer 642UNDEFINED art_quick_alloc_array_resolved_bump_pointer_instrumented 643UNDEFINED art_quick_alloc_array_resolved8_bump_pointer 644UNDEFINED art_quick_alloc_array_resolved8_bump_pointer_instrumented 645UNDEFINED art_quick_alloc_array_resolved16_bump_pointer 646UNDEFINED art_quick_alloc_array_resolved16_bump_pointer_instrumented 647UNDEFINED art_quick_alloc_array_resolved32_bump_pointer 648UNDEFINED art_quick_alloc_array_resolved32_bump_pointer_instrumented 649UNDEFINED art_quick_alloc_array_resolved64_bump_pointer 650UNDEFINED art_quick_alloc_array_resolved64_bump_pointer_instrumented 651UNDEFINED art_quick_alloc_object_resolved_bump_pointer 652UNDEFINED art_quick_alloc_object_resolved_bump_pointer_instrumented 653UNDEFINED art_quick_alloc_object_initialized_bump_pointer 654UNDEFINED art_quick_alloc_object_initialized_bump_pointer_instrumented 655UNDEFINED art_quick_alloc_object_with_checks_bump_pointer 656UNDEFINED art_quick_alloc_object_with_checks_bump_pointer_instrumented 657UNDEFINED art_quick_alloc_string_object_bump_pointer 658UNDEFINED art_quick_alloc_string_object_bump_pointer_instrumented 659UNDEFINED art_quick_alloc_string_from_bytes_bump_pointer 660UNDEFINED art_quick_alloc_string_from_bytes_bump_pointer_instrumented 661UNDEFINED art_quick_alloc_string_from_chars_bump_pointer 662UNDEFINED art_quick_alloc_string_from_chars_bump_pointer_instrumented 663UNDEFINED art_quick_alloc_string_from_string_bump_pointer 664UNDEFINED art_quick_alloc_string_from_string_bump_pointer_instrumented 665UNDEFINED art_quick_alloc_array_resolved_tlab 666UNDEFINED art_quick_alloc_array_resolved_tlab_instrumented 667UNDEFINED art_quick_alloc_array_resolved8_tlab 668UNDEFINED art_quick_alloc_array_resolved8_tlab_instrumented 669UNDEFINED art_quick_alloc_array_resolved16_tlab 670UNDEFINED art_quick_alloc_array_resolved16_tlab_instrumented 671UNDEFINED art_quick_alloc_array_resolved32_tlab 672UNDEFINED art_quick_alloc_array_resolved32_tlab_instrumented 673UNDEFINED art_quick_alloc_array_resolved64_tlab 674UNDEFINED art_quick_alloc_array_resolved64_tlab_instrumented 675UNDEFINED art_quick_alloc_object_resolved_tlab 676UNDEFINED art_quick_alloc_object_resolved_tlab_instrumented 677UNDEFINED art_quick_alloc_object_initialized_tlab 678UNDEFINED art_quick_alloc_object_initialized_tlab_instrumented 679UNDEFINED art_quick_alloc_object_with_checks_tlab 680UNDEFINED art_quick_alloc_object_with_checks_tlab_instrumented 681UNDEFINED art_quick_alloc_string_object_tlab 682UNDEFINED art_quick_alloc_string_object_tlab_instrumented 683UNDEFINED art_quick_alloc_string_from_bytes_tlab 684UNDEFINED art_quick_alloc_string_from_bytes_tlab_instrumented 685UNDEFINED art_quick_alloc_string_from_chars_tlab 686UNDEFINED art_quick_alloc_string_from_chars_tlab_instrumented 687UNDEFINED art_quick_alloc_string_from_string_tlab 688UNDEFINED art_quick_alloc_string_from_string_tlab_instrumented 689UNDEFINED art_quick_alloc_array_resolved_region 690UNDEFINED art_quick_alloc_array_resolved_region_instrumented 691UNDEFINED art_quick_alloc_array_resolved8_region 692UNDEFINED art_quick_alloc_array_resolved8_region_instrumented 693UNDEFINED art_quick_alloc_array_resolved16_region 694UNDEFINED art_quick_alloc_array_resolved16_region_instrumented 695UNDEFINED art_quick_alloc_array_resolved32_region 696UNDEFINED art_quick_alloc_array_resolved32_region_instrumented 697UNDEFINED art_quick_alloc_array_resolved64_region 698UNDEFINED art_quick_alloc_array_resolved64_region_instrumented 699UNDEFINED art_quick_alloc_object_resolved_region 700UNDEFINED art_quick_alloc_object_resolved_region_instrumented 701UNDEFINED art_quick_alloc_object_initialized_region 702UNDEFINED art_quick_alloc_object_initialized_region_instrumented 703UNDEFINED art_quick_alloc_object_with_checks_region 704UNDEFINED art_quick_alloc_object_with_checks_region_instrumented 705UNDEFINED art_quick_alloc_string_object_region 706UNDEFINED art_quick_alloc_string_object_region_instrumented 707UNDEFINED art_quick_alloc_string_from_bytes_region 708UNDEFINED art_quick_alloc_string_from_bytes_region_instrumented 709UNDEFINED art_quick_alloc_string_from_chars_region 710UNDEFINED art_quick_alloc_string_from_chars_region_instrumented 711UNDEFINED art_quick_alloc_string_from_string_region 712UNDEFINED art_quick_alloc_string_from_string_region_instrumented 713UNDEFINED art_quick_alloc_array_resolved_region_tlab 714UNDEFINED art_quick_alloc_array_resolved_region_tlab_instrumented 715UNDEFINED art_quick_alloc_array_resolved8_region_tlab 716UNDEFINED art_quick_alloc_array_resolved8_region_tlab_instrumented 717UNDEFINED art_quick_alloc_array_resolved16_region_tlab 718UNDEFINED art_quick_alloc_array_resolved16_region_tlab_instrumented 719UNDEFINED art_quick_alloc_array_resolved32_region_tlab 720UNDEFINED art_quick_alloc_array_resolved32_region_tlab_instrumented 721UNDEFINED art_quick_alloc_array_resolved64_region_tlab 722UNDEFINED art_quick_alloc_array_resolved64_region_tlab_instrumented 723UNDEFINED art_quick_alloc_object_resolved_region_tlab 724UNDEFINED art_quick_alloc_object_resolved_region_tlab_instrumented 725UNDEFINED art_quick_alloc_object_initialized_region_tlab 726UNDEFINED art_quick_alloc_object_initialized_region_tlab_instrumented 727UNDEFINED art_quick_alloc_object_with_checks_region_tlab 728UNDEFINED art_quick_alloc_object_with_checks_region_tlab_instrumented 729UNDEFINED art_quick_alloc_string_object_region_tlab 730UNDEFINED art_quick_alloc_string_object_region_tlab_instrumented 731UNDEFINED art_quick_alloc_string_from_bytes_region_tlab 732UNDEFINED art_quick_alloc_string_from_bytes_region_tlab_instrumented 733UNDEFINED art_quick_alloc_string_from_chars_region_tlab 734UNDEFINED art_quick_alloc_string_from_chars_region_tlab_instrumented 735UNDEFINED art_quick_alloc_string_from_string_region_tlab 736UNDEFINED art_quick_alloc_string_from_string_region_tlab_instrumented 737UNDEFINED art_quick_initialize_static_storage 738UNDEFINED art_quick_resolve_type_and_verify_access 739UNDEFINED art_quick_resolve_type 740UNDEFINED art_quick_resolve_method_handle 741UNDEFINED art_quick_resolve_method_type 742UNDEFINED art_quick_resolve_string 743UNDEFINED art_quick_set8_instance 744UNDEFINED art_quick_set8_static 745UNDEFINED art_quick_set16_instance 746UNDEFINED art_quick_set16_static 747UNDEFINED art_quick_set32_instance 748UNDEFINED art_quick_set32_static 749UNDEFINED art_quick_set64_instance 750UNDEFINED art_quick_set64_static 751UNDEFINED art_quick_set_obj_instance 752UNDEFINED art_quick_set_obj_static 753UNDEFINED art_quick_get_byte_instance 754UNDEFINED art_quick_get_boolean_instance 755UNDEFINED art_quick_get_short_instance 756UNDEFINED art_quick_get_char_instance 757UNDEFINED art_quick_get32_instance 758UNDEFINED art_quick_get64_instance 759UNDEFINED art_quick_get_obj_instance 760UNDEFINED art_quick_get_byte_static 761UNDEFINED art_quick_get_boolean_static 762UNDEFINED art_quick_get_short_static 763UNDEFINED art_quick_get_char_static 764UNDEFINED art_quick_get32_static 765UNDEFINED art_quick_get64_static 766UNDEFINED art_quick_get_obj_static 767UNDEFINED art_quick_aput_obj 768UNDEFINED art_quick_lock_object_no_inline 769UNDEFINED art_quick_lock_object 770UNDEFINED art_quick_unlock_object_no_inline 771UNDEFINED art_quick_unlock_object 772UNDEFINED art_quick_invoke_direct_trampoline_with_access_check 773UNDEFINED art_quick_invoke_interface_trampoline_with_access_check 774UNDEFINED art_quick_invoke_static_trampoline_with_access_check 775UNDEFINED art_quick_invoke_super_trampoline_with_access_check 776UNDEFINED art_quick_invoke_virtual_trampoline_with_access_check 777UNDEFINED art_quick_invoke_polymorphic 778UNDEFINED art_quick_invoke_custom 779UNDEFINED art_quick_test_suspend 780UNDEFINED art_quick_deliver_exception 781UNDEFINED art_quick_throw_array_bounds 782UNDEFINED art_quick_throw_div_zero 783UNDEFINED art_quick_throw_null_pointer_exception 784UNDEFINED art_quick_throw_stack_overflow 785UNDEFINED art_quick_throw_string_bounds 786UNDEFINED art_quick_update_inline_cache 787UNDEFINED art_jni_monitored_method_start 788UNDEFINED art_jni_monitored_method_end 789UNDEFINED art_quick_indexof 790