/* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "asm_support_riscv64.S" #include "interpreter/cfi_asm_support.h" // Wrap ExecuteSwitchImpl in assembly method which specifies DEX PC for unwinding. // Argument 0: a0: The context pointer for ExecuteSwitchImpl. // Argument 1: a1: Pointer to the templated ExecuteSwitchImpl to call. // Argument 2: a2: The value of DEX PC (memory address of the methods bytecode). ENTRY ExecuteSwitchImplAsm INCREASE_FRAME 16 SAVE_GPR s1, 0 SAVE_GPR ra, 8 mv s1, a2 // s1 = DEX PC CFI_DEFINE_DEX_PC_WITH_OFFSET(0 /* a0 */, 9 /* s1, a.k.a. x9 */, 0) jalr a1 // Call the wrapped method. RESTORE_GPR s1, 0 RESTORE_GPR ra, 8 DECREASE_FRAME 16 ret END ExecuteSwitchImplAsm .macro INVOKE_STUB_CREATE_FRAME // Save ra, fp, xSELF (current thread) a4, a5 (they will be needed in the invoke stub return) // and callee-save regs s3 - s5 that are clobbered here and in art_quick_invoke_(static_)_stub. INCREASE_FRAME 48 SAVE_GPR fp, (8*0) SAVE_GPR xSELF, (8*1) SAVE_GPR a4, (8*2) SAVE_GPR a5, (8*3) SAVE_GPR s3, (8*4) SAVE_GPR ra, (8*5) mv fp, sp // save frame pointer .cfi_def_cfa_register fp addi t0, a2, (__SIZEOF_POINTER__ + 0xf) // Reserve space for ArtMethod*, arguments and andi t0, t0, ~0xf // round up for 16-byte stack alignment. sub sp, sp, t0 mv xSELF, a3 // Copy arguments on stack (4 bytes per slot): // a1: source address // a2: arguments length // s3: destination address. add s3, sp, 8 // destination address is bottom of the stack + 8 bytes for ArtMethod* (null) beqz a2, 2f // loop through 4-byte arguments from the last to the first 1: addi a2, a2, -4 add t0, a1, a2 // t0 is the source address of the next copied argument lw t1, (t0) // t1 is the 4 bytes at address t0 add t0, s3, a2 // t0 is the destination address of the next copied argument sw t1, (t0) // save t1 at the destination address t0 bnez a2, 1b 2: sd zero, (sp) // Store null into ArtMethod* at bottom of frame. .endm .macro INVOKE_STUB_CALL_AND_RETURN // Call the method. ld t0, ART_METHOD_QUICK_CODE_OFFSET_64(a0) jalr t0 mv sp, fp // restore frame pointer .cfi_def_cfa_register sp // Restore ra, fp, xSELF (current thread) a4 (shorty), a5 (result pointer) and callee-save // regs s3 - s5 from stack. RESTORE_GPR fp, (8*0) RESTORE_GPR xSELF, (8*1) RESTORE_GPR a4, (8*2) RESTORE_GPR a5, (8*3) RESTORE_GPR s3, (8*4) RESTORE_GPR ra, (8*5) DECREASE_FRAME 48 // Load result type (1-byte symbol) from a5. // Check result type and store the correct register into the jvalue in memory at a4 address. lbu t0, (a5) li t1, 'V' // void (do not store result at all) beq t1, t0, 1f li t1, 'D' // double beq t1, t0, 2f li t1, 'F' // float beq t1, t0, 3f // Otherwise, result is in a0 (either 8 or 4 bytes, but it is fine to store 8 bytes as the // upper bytes in a0 in that case are zero, and jvalue has enough space). sd a0, (a4) 1: ret 2: // double: result in fa0 (8 bytes) fsd fa0, (a4) ret 3: // float: result in fa0 (4 bytes) fsw fa0, (a4) ret .endm ENTRY art_deliver_pending_exception DELIVER_PENDING_EXCEPTION END art_deliver_pending_exception // Macros for loading an argument into a register. // label - the base name of the label of the load routine, // reg - the register to load, // args - pointer to current argument, incremented by size, // size - the size of the register - 4 or 8 bytes, // load - instruction used for loading, // nh4_reg - the register to fill with the address of the next handler for 4-byte values, // nh4_l - the base name of the label of the next handler for 4-byte values, // nh8_reg - the register to fill with the address of the next handler for 8-byte values, // nh8_l - the base name of the label of the next handler for 8-byte values, // cont - the base name of the label for continuing the shorty processing loop, // sfx - suffix added to all labels to make labels unique for different users. .macro INVOKE_STUB_LOAD_REG label, reg, args, size, load, nh4_reg, nh4_l, nh8_reg, nh8_l, cont, sfx \label\sfx: \load \reg, (\args) addi \args, \args, \size la \nh4_reg, \nh4_l\sfx la \nh8_reg, \nh8_l\sfx j \cont\sfx .endm // Macro for skipping an argument that does not fit into argument registers. // label - the base name of the label of the skip routine, // args - pointer to current argument, incremented by size, // size - the size of the argument - 4 or 8 bytes, // cont - the base name of the label for continuing the shorty processing loop, // sfx - suffix added to all labels to make labels unique for different users. .macro INVOKE_STUB_SKIP_ARG label, args, size, cont, sfx \label\sfx: addi \args, \args, \size j \cont\sfx .endm // Fill registers a1 to a7 and fa0 to fa7 with parameters. // Parse the passed shorty to determine which register to load. // a5 - shorty, // s3 - points to arguments on the stack, // sfx - suffix added to all labels to make labels unique for different users. .macro INVOKE_STUB_LOAD_ALL_ARGS sfx mv t0, a5 // Load shorty address, addi t0, t0, 1 // plus one to skip the return type. // Load this (if instance method) and addresses for routines that load argument GPRs and FPRs. .ifc \sfx, _instance lw a1, (s3) // Load "this" parameter, addi s3, s3, 4 // and increment arg pointer. la t3, .Lload4i2\sfx la t4, .Lload8i2\sfx .else la t3, .Lload4i1\sfx la t4, .Lload8i1\sfx .endif la t5, .Lload4f0\sfx la t6, .Lload8f0\sfx // Loop to fill registers. .Lfill_regs\sfx: lb t1, (t0) // Load next character in signature, and increment. addi t0, t0, 1 // and increment. beqz t1, .Lcall_method\sfx // Exit at end of signature. Shorty 0 terminated. li t2, 'J' beq t1, t2, .Lload_long\sfx // Is this a long? li t2, 'F' beq t1, t2, .Lload_float\sfx // Is this a float? li t2, 'D' beq t1, t2, .Lload_double\sfx // Is this a double? // Everything else uses a 4-byte GPR. jr t3 .Lload_long\sfx: jr t4 .Lload_float\sfx: jr t5 .Lload_double\sfx: jr t6 // Handlers for loading other args (not float/double/long) into 4-byte GPRs. .ifnc \sfx, _instance INVOKE_STUB_LOAD_REG \ .Lload4i1, a1, s3, 4, lw, t3, .Lload4i2, t4, .Lload8i2, .Lfill_regs, \sfx .endif INVOKE_STUB_LOAD_REG .Lload4i2, a2, s3, 4, lw, t3, .Lload4i3, t4, .Lload8i3, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload4i3, a3, s3, 4, lw, t3, .Lload4i4, t4, .Lload8i4, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload4i4, a4, s3, 4, lw, t3, .Lload4i5, t4, .Lload8i5, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload4i5, a5, s3, 4, lw, t3, .Lload4i6, t4, .Lload8i6, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload4i6, a6, s3, 4, lw, t3, .Lload4i7, t4, .Lload8i7, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload4i7, a7, s3, 4, lw, t3, .Lskip4, t4, .Lskip8, .Lfill_regs, \sfx // Handlers for loading longs into 8-byte GPRs. .ifnc \sfx, _instance INVOKE_STUB_LOAD_REG \ .Lload8i1, a1, s3, 8, ld, t3, .Lload4i2, t4, .Lload8i2, .Lfill_regs, \sfx .endif INVOKE_STUB_LOAD_REG .Lload8i2, a2, s3, 8, ld, t3, .Lload4i3, t4, .Lload8i3, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload8i3, a3, s3, 8, ld, t3, .Lload4i4, t4, .Lload8i4, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload8i4, a4, s3, 8, ld, t3, .Lload4i5, t4, .Lload8i5, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload8i5, a5, s3, 8, ld, t3, .Lload4i6, t4, .Lload8i6, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload8i6, a6, s3, 8, ld, t3, .Lload4i7, t4, .Lload8i7, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload8i7, a7, s3, 8, ld, t3, .Lskip4, t4, .Lskip8, .Lfill_regs, \sfx // Handlers for loading floats into FPRs. INVOKE_STUB_LOAD_REG .Lload4f0, fa0, s3, 4, flw, t5, .Lload4f1, t6, .Lload8f1, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload4f1, fa1, s3, 4, flw, t5, .Lload4f2, t6, .Lload8f2, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload4f2, fa2, s3, 4, flw, t5, .Lload4f3, t6, .Lload8f3, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload4f3, fa3, s3, 4, flw, t5, .Lload4f4, t6, .Lload8f4, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload4f4, fa4, s3, 4, flw, t5, .Lload4f5, t6, .Lload8f5, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload4f5, fa5, s3, 4, flw, t5, .Lload4f6, t6, .Lload8f6, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload4f6, fa6, s3, 4, flw, t5, .Lload4f7, t6, .Lload8f7, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload4f7, fa7, s3, 4, flw, t5, .Lskip4, t6, .Lskip8, .Lfill_regs, \sfx // Handlers for loading doubles into FPRs. INVOKE_STUB_LOAD_REG .Lload8f0, fa0, s3, 8, fld, t5, .Lload4f1, t6, .Lload8f1, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload8f1, fa1, s3, 8, fld, t5, .Lload4f2, t6, .Lload8f2, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload8f2, fa2, s3, 8, fld, t5, .Lload4f3, t6, .Lload8f3, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload8f3, fa3, s3, 8, fld, t5, .Lload4f4, t6, .Lload8f4, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload8f4, fa4, s3, 8, fld, t5, .Lload4f5, t6, .Lload8f5, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload8f5, fa5, s3, 8, fld, t5, .Lload4f6, t6, .Lload8f6, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload8f6, fa6, s3, 8, fld, t5, .Lload4f7, t6, .Lload8f7, .Lfill_regs, \sfx INVOKE_STUB_LOAD_REG .Lload8f7, fa7, s3, 8, fld, t5, .Lskip4, t6, .Lskip8, .Lfill_regs, \sfx // Handlers for skipping arguments that do not fit into registers. INVOKE_STUB_SKIP_ARG .Lskip4, s3, 4, .Lfill_regs, \sfx INVOKE_STUB_SKIP_ARG .Lskip8, s3, 8, .Lfill_regs, \sfx .Lcall_method\sfx: .endm // void art_quick_invoke_stub(ArtMethod* method, // a0 // uint32_t* args, // a1 // uint32_t argsize, // a2 // Thread* self, // a3 // JValue* result, // a4 // char* shorty) // a5 ENTRY art_quick_invoke_stub INVOKE_STUB_CREATE_FRAME // Load args into registers. INVOKE_STUB_LOAD_ALL_ARGS _instance // Call the method and return. INVOKE_STUB_CALL_AND_RETURN END art_quick_invoke_stub // void art_quick_invoke_static_stub(ArtMethod* method, // a0 // uint32_t* args, // a1 // uint32_t argsize, // a2 // Thread* self, // a3 // JValue* result, // a4 // char* shorty) // a5 ENTRY art_quick_invoke_static_stub INVOKE_STUB_CREATE_FRAME // Load args into registers. INVOKE_STUB_LOAD_ALL_ARGS _static // Call the method and return. INVOKE_STUB_CALL_AND_RETURN END art_quick_invoke_static_stub ENTRY art_quick_generic_jni_trampoline SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_A0 // Save sp, so we can have static CFI info. mv fp, sp .cfi_def_cfa_register fp li t0, GENERIC_JNI_TRAMPOLINE_RESERVED_AREA sub sp, sp, t0 mv a0, xSELF // Thread* mv a1, fp // SP for the managed frame. mv a2, sp // reserved area for arguments and other saved data (up to managed frame) call artQuickGenericJniTrampoline // Check for error (class init check or locking for synchronized native method can throw). beqz a0, .Lexception_in_native mv t0, a0 // save pointer to native method code into temporary // Load argument GPRs from stack (saved there by artQuickGenericJniTrampoline). ld a0, 8*0(sp) // JniEnv* for the native method ld a1, 8*1(sp) ld a2, 8*2(sp) ld a3, 8*3(sp) ld a4, 8*4(sp) ld a5, 8*5(sp) ld a6, 8*6(sp) ld a7, 8*7(sp) // Load argument FPRs from stack (saved there by artQuickGenericJniTrampoline). fld fa0, 8*8(sp) fld fa1, 8*9(sp) fld fa2, 8*10(sp) fld fa3, 8*11(sp) fld fa4, 8*12(sp) fld fa5, 8*13(sp) fld fa6, 8*14(sp) fld fa7, 8*15(sp) ld t6, 8*16(sp) // @CriticalNative arg, used by art_jni_dlsym_lookup_critical_stub ld t1, 8*17(sp) // restore stack mv sp, t1 jalr t0 // call native method // result sign extension is handled in C code, prepare for artQuickGenericJniEndTrampoline call: // uint64_t artQuickGenericJniEndTrampoline(Thread* self, // a0 // jvalue result, // a1 (need to move from a0) // uint64_t result_f) // a2 (need to move from fa0) mv a1, a0 mv a0, xSELF fmv.x.d a2, fa0 call artQuickGenericJniEndTrampoline // Pending exceptions possible. ld t0, THREAD_EXCEPTION_OFFSET(xSELF) bnez t0, .Lexception_in_native // Tear down the alloca. mv sp, fp .cfi_remember_state .cfi_def_cfa_register sp LOAD_RUNTIME_INSTANCE a1 lb a1, RUN_EXIT_HOOKS_OFFSET_FROM_RUNTIME_INSTANCE(a1) bnez a1, .Lcall_method_exit_hook .Lcall_method_exit_hook_done: // This does not clobber the result register a0. a1 is not used for result as the managed code // does not have a 128-bit type. Alternatively we could restore a subset of these registers. RESTORE_SAVE_REFS_AND_ARGS_FRAME fmv.d.x fa0, a0 ret CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_AND_ARGS .Lcall_method_exit_hook: fmv.d.x fa0, a0 li a4, FRAME_SIZE_SAVE_REFS_AND_ARGS jal art_quick_method_exit_hook j .Lcall_method_exit_hook_done .Lexception_in_native: // Move to a1 then sp to please assembler. ld a1, THREAD_TOP_QUICK_FRAME_OFFSET(xSELF) addi sp, a1, -1 // Remove the GenericJNI tag. call art_deliver_pending_exception END art_quick_generic_jni_trampoline ENTRY art_quick_to_interpreter_bridge SETUP_SAVE_REFS_AND_ARGS_FRAME // uint64_t artQuickToInterpreterBridge(ArtMethod* method, Thread* self, ArtMethod** sp) // a0 will contain ArtMethod* mv a1, xSELF mv a2, sp call artQuickToInterpreterBridge // TODO: no need to restore arguments in this case. RESTORE_SAVE_REFS_AND_ARGS_FRAME fmv.d.x fa0, a0 // copy the result to FP result register RETURN_OR_DELIVER_PENDING_EXCEPTION_REG t0 END art_quick_to_interpreter_bridge .extern artMethodExitHook ENTRY art_quick_method_exit_hook SETUP_SAVE_EVERYTHING_FRAME addi a3, sp, SAVE_EVERYTHING_FRAME_OFFSET_FA0 // FP result ptr in kSaveEverything frame addi a2, sp, SAVE_EVERYTHING_FRAME_OFFSET_A0 // integer result ptr in kSaveEverything frame addi a1, sp, FRAME_SIZE_SAVE_EVERYTHING // ArtMethod** mv a0, xSELF // Thread::Current call artMethodExitHook // (Thread*, ArtMethod**, gpr_res*, fpr_res*, // frame_size) // Normal return. RESTORE_SAVE_EVERYTHING_FRAME ret END art_quick_method_exit_hook // On entry a0 is uintptr_t* gprs_ and a1 is uint64_t* fprs_. // Both must reside on the stack, between current sp and target sp. ENTRY art_quick_do_long_jump // Load FPRs fld ft0, 8*0(a1) // f0 fld ft1, 8*1(a1) // f1 fld ft2, 8*2(a1) // f2 fld ft3, 8*3(a1) // f3 fld ft4, 8*4(a1) // f4 fld ft5, 8*5(a1) // f5 fld ft6, 8*6(a1) // f6 fld ft7, 8*7(a1) // f7 fld fs0, 8*8(a1) // f8 fld fs1, 8*9(a1) // f9 fld fa0, 8*10(a1) // f10 fld fa1, 8*11(a1) // f11 fld fa2, 8*12(a1) // f12 fld fa3, 8*13(a1) // f13 fld fa4, 8*14(a1) // f14 fld fa5, 8*15(a1) // f15 fld fa6, 8*16(a1) // f16 fld fa7, 8*17(a1) // f17 fld fs2, 8*18(a1) // f18 fld fs3, 8*19(a1) // f19 fld fs4, 8*20(a1) // f20 fld fs5, 8*21(a1) // f21 fld fs6, 8*22(a1) // f22 fld fs7, 8*23(a1) // f23 fld fs8, 8*24(a1) // f24 fld fs9, 8*25(a1) // f25 fld fs10, 8*26(a1) // f26 fld fs11, 8*27(a1) // f27 fld ft8, 8*28(a1) // f28 fld ft9, 8*29(a1) // f29 fld ft10, 8*30(a1) // f30 fld ft11, 8*31(a1) // f31 // Load GPRs. // Skip slot 8*0(a0) for zero/x0 as it is hard-wired zero. ld ra, 8*1(a0) // x1 // Skip slot 8*2(a0) for sp/x2 as it is set below. // Skip slot 8*3(a0) for platform-specific thread pointer gp/x3. // Skip slot 8*4(a0) for platform-specific global pointer tp/x4. // Skip slot 8*5(a0) for t0/x5 as it is clobbered below. // Skip slot 8*6(a0) for t1/x6 as it is clobbered below. ld t2, 8*7(a0) // x7 ld s0, 8*8(a0) // x8 ld s1, 8*9(a0) // x9 // Delay loading a0 as the base is in a0. ld a1, 8*11(a0) // x11 ld a2, 8*12(a0) // x12 ld a3, 8*13(a0) // x13 ld a4, 8*14(a0) // x14 ld a5, 8*15(a0) // x15 ld a6, 8*16(a0) // x16 ld a7, 8*17(a0) // x17 ld s2, 8*18(a0) // x18 ld s3, 8*19(a0) // x19 ld s4, 8*20(a0) // x20 ld s5, 8*21(a0) // x21 ld s6, 8*22(a0) // x22 ld s7, 8*23(a0) // x23 ld s8, 8*24(a0) // x24 ld s9, 8*25(a0) // x25 ld s10, 8*26(a0) // x26 ld s11, 8*27(a0) // x27 ld t3, 8*28(a0) // x28 ld t4, 8*29(a0) // x29 ld t5, 8*30(a0) // x30 ld t6, 8*31(a0) // x31 // Load sp to t0. ld t0, 8*2(a0) // Load PC to t1, it is in the last stack slot. ld t1, 8*32(a0) // Now load a0. ld a0, 8*10(a0) // x10 // Set sp. Do not access fprs_ and gprs_ from now, they are below sp. mv sp, t0 jr t1 END art_quick_do_long_jump // Called by managed code that is attempting to call a method on a proxy class. On entry a0 holds // the proxy method and a1 holds the receiver. The frame size of the invoked proxy method agrees // with kSaveRefsAndArgs frame. .extern artQuickProxyInvokeHandler ENTRY art_quick_proxy_invoke_handler SETUP_SAVE_REFS_AND_ARGS_FRAME_WITH_METHOD_IN_A0 // uint64_t artQuickProxyInvokeHandler(ArtMethod* proxy_method, // a0 // mirror::Object* receiver, // a1 // Thread* self, // a2 // ArtMethod** sp) // a3 mv a2, xSELF // pass Thread::Current mv a3, sp // pass sp call artQuickProxyInvokeHandler // (Method* proxy method, receiver, Thread*, sp) ld a2, THREAD_EXCEPTION_OFFSET(xSELF) bnez a2, .Lexception_in_proxy // success if no exception is pending .cfi_remember_state RESTORE_SAVE_REFS_AND_ARGS_FRAME // Restore frame fmv.d.x fa0, a0 // Store result in fa0 in case it was float or double ret // return on success .Lexception_in_proxy: CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_AND_ARGS RESTORE_SAVE_REFS_AND_ARGS_FRAME DELIVER_PENDING_EXCEPTION END art_quick_proxy_invoke_handler .macro ONE_ARG_RUNTIME_EXCEPTION c_name, cxx_name .extern \cxx_name ENTRY \c_name SETUP_SAVE_ALL_CALLEE_SAVES_FRAME // save all registers as basis for long jump context. mv a1, xSELF // pass Thread::Current. jal \cxx_name // \cxx_name(arg, Thread*). ebreak END \c_name .endm // Called to attempt to execute an obsolete method. ONE_ARG_RUNTIME_EXCEPTION art_invoke_obsolete_method_stub, artInvokeObsoleteMethod ENTRY art_quick_resolution_trampoline SETUP_SAVE_REFS_AND_ARGS_FRAME // const void* artQuickResolutionTrampoline(ArtMethod* called, // a0 // mirror::Object* receiver, // a1 // Thread* self, // a2 // ArtMethod** sp) // a3 mv a2, xSELF mv a3, sp call artQuickResolutionTrampoline beqz a0, 1f .cfi_remember_state mv t0, a0 // Remember returned code pointer in t0. ld a0, (sp) // artQuickResolutionTrampoline puts called method in *sp. RESTORE_SAVE_REFS_AND_ARGS_FRAME jr t0 1: CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_AND_ARGS RESTORE_SAVE_REFS_AND_ARGS_FRAME DELIVER_PENDING_EXCEPTION END art_quick_resolution_trampoline UNDEFINED art_quick_imt_conflict_trampoline UNDEFINED art_quick_deoptimize_from_compiled_code UNDEFINED art_quick_string_builder_append UNDEFINED art_quick_compile_optimized UNDEFINED art_quick_method_entry_hook UNDEFINED art_quick_check_instance_of UNDEFINED art_quick_osr_stub UNDEFINED art_quick_alloc_array_resolved_dlmalloc UNDEFINED art_quick_alloc_array_resolved_dlmalloc_instrumented UNDEFINED art_quick_alloc_array_resolved8_dlmalloc UNDEFINED art_quick_alloc_array_resolved8_dlmalloc_instrumented UNDEFINED art_quick_alloc_array_resolved16_dlmalloc UNDEFINED art_quick_alloc_array_resolved16_dlmalloc_instrumented UNDEFINED art_quick_alloc_array_resolved32_dlmalloc UNDEFINED art_quick_alloc_array_resolved32_dlmalloc_instrumented UNDEFINED art_quick_alloc_array_resolved64_dlmalloc UNDEFINED art_quick_alloc_array_resolved64_dlmalloc_instrumented UNDEFINED art_quick_alloc_object_resolved_dlmalloc UNDEFINED art_quick_alloc_object_resolved_dlmalloc_instrumented UNDEFINED art_quick_alloc_object_initialized_dlmalloc UNDEFINED art_quick_alloc_object_initialized_dlmalloc_instrumented UNDEFINED art_quick_alloc_object_with_checks_dlmalloc UNDEFINED art_quick_alloc_object_with_checks_dlmalloc_instrumented UNDEFINED art_quick_alloc_string_object_dlmalloc UNDEFINED art_quick_alloc_string_object_dlmalloc_instrumented UNDEFINED art_quick_alloc_string_from_bytes_dlmalloc UNDEFINED art_quick_alloc_string_from_bytes_dlmalloc_instrumented UNDEFINED art_quick_alloc_string_from_chars_dlmalloc UNDEFINED art_quick_alloc_string_from_chars_dlmalloc_instrumented UNDEFINED art_quick_alloc_string_from_string_dlmalloc UNDEFINED art_quick_alloc_string_from_string_dlmalloc_instrumented UNDEFINED art_quick_alloc_array_resolved_rosalloc UNDEFINED art_quick_alloc_array_resolved_rosalloc_instrumented UNDEFINED art_quick_alloc_array_resolved8_rosalloc UNDEFINED art_quick_alloc_array_resolved8_rosalloc_instrumented UNDEFINED art_quick_alloc_array_resolved16_rosalloc UNDEFINED art_quick_alloc_array_resolved16_rosalloc_instrumented UNDEFINED art_quick_alloc_array_resolved32_rosalloc UNDEFINED art_quick_alloc_array_resolved32_rosalloc_instrumented UNDEFINED art_quick_alloc_array_resolved64_rosalloc UNDEFINED art_quick_alloc_array_resolved64_rosalloc_instrumented UNDEFINED art_quick_alloc_object_resolved_rosalloc UNDEFINED art_quick_alloc_object_resolved_rosalloc_instrumented UNDEFINED art_quick_alloc_object_initialized_rosalloc UNDEFINED art_quick_alloc_object_initialized_rosalloc_instrumented UNDEFINED art_quick_alloc_object_with_checks_rosalloc UNDEFINED art_quick_alloc_object_with_checks_rosalloc_instrumented UNDEFINED art_quick_alloc_string_object_rosalloc UNDEFINED art_quick_alloc_string_object_rosalloc_instrumented UNDEFINED art_quick_alloc_string_from_bytes_rosalloc UNDEFINED art_quick_alloc_string_from_bytes_rosalloc_instrumented UNDEFINED art_quick_alloc_string_from_chars_rosalloc UNDEFINED art_quick_alloc_string_from_chars_rosalloc_instrumented UNDEFINED art_quick_alloc_string_from_string_rosalloc UNDEFINED art_quick_alloc_string_from_string_rosalloc_instrumented UNDEFINED art_quick_alloc_array_resolved_bump_pointer UNDEFINED art_quick_alloc_array_resolved_bump_pointer_instrumented UNDEFINED art_quick_alloc_array_resolved8_bump_pointer UNDEFINED art_quick_alloc_array_resolved8_bump_pointer_instrumented UNDEFINED art_quick_alloc_array_resolved16_bump_pointer UNDEFINED art_quick_alloc_array_resolved16_bump_pointer_instrumented UNDEFINED art_quick_alloc_array_resolved32_bump_pointer UNDEFINED art_quick_alloc_array_resolved32_bump_pointer_instrumented UNDEFINED art_quick_alloc_array_resolved64_bump_pointer UNDEFINED art_quick_alloc_array_resolved64_bump_pointer_instrumented UNDEFINED art_quick_alloc_object_resolved_bump_pointer UNDEFINED art_quick_alloc_object_resolved_bump_pointer_instrumented UNDEFINED art_quick_alloc_object_initialized_bump_pointer UNDEFINED art_quick_alloc_object_initialized_bump_pointer_instrumented UNDEFINED art_quick_alloc_object_with_checks_bump_pointer UNDEFINED art_quick_alloc_object_with_checks_bump_pointer_instrumented UNDEFINED art_quick_alloc_string_object_bump_pointer UNDEFINED art_quick_alloc_string_object_bump_pointer_instrumented UNDEFINED art_quick_alloc_string_from_bytes_bump_pointer UNDEFINED art_quick_alloc_string_from_bytes_bump_pointer_instrumented UNDEFINED art_quick_alloc_string_from_chars_bump_pointer UNDEFINED art_quick_alloc_string_from_chars_bump_pointer_instrumented UNDEFINED art_quick_alloc_string_from_string_bump_pointer UNDEFINED art_quick_alloc_string_from_string_bump_pointer_instrumented UNDEFINED art_quick_alloc_array_resolved_tlab UNDEFINED art_quick_alloc_array_resolved_tlab_instrumented UNDEFINED art_quick_alloc_array_resolved8_tlab UNDEFINED art_quick_alloc_array_resolved8_tlab_instrumented UNDEFINED art_quick_alloc_array_resolved16_tlab UNDEFINED art_quick_alloc_array_resolved16_tlab_instrumented UNDEFINED art_quick_alloc_array_resolved32_tlab UNDEFINED art_quick_alloc_array_resolved32_tlab_instrumented UNDEFINED art_quick_alloc_array_resolved64_tlab UNDEFINED art_quick_alloc_array_resolved64_tlab_instrumented UNDEFINED art_quick_alloc_object_resolved_tlab UNDEFINED art_quick_alloc_object_resolved_tlab_instrumented UNDEFINED art_quick_alloc_object_initialized_tlab UNDEFINED art_quick_alloc_object_initialized_tlab_instrumented UNDEFINED art_quick_alloc_object_with_checks_tlab UNDEFINED art_quick_alloc_object_with_checks_tlab_instrumented UNDEFINED art_quick_alloc_string_object_tlab UNDEFINED art_quick_alloc_string_object_tlab_instrumented UNDEFINED art_quick_alloc_string_from_bytes_tlab UNDEFINED art_quick_alloc_string_from_bytes_tlab_instrumented UNDEFINED art_quick_alloc_string_from_chars_tlab UNDEFINED art_quick_alloc_string_from_chars_tlab_instrumented UNDEFINED art_quick_alloc_string_from_string_tlab UNDEFINED art_quick_alloc_string_from_string_tlab_instrumented UNDEFINED art_quick_alloc_array_resolved_region UNDEFINED art_quick_alloc_array_resolved_region_instrumented UNDEFINED art_quick_alloc_array_resolved8_region UNDEFINED art_quick_alloc_array_resolved8_region_instrumented UNDEFINED art_quick_alloc_array_resolved16_region UNDEFINED art_quick_alloc_array_resolved16_region_instrumented UNDEFINED art_quick_alloc_array_resolved32_region UNDEFINED art_quick_alloc_array_resolved32_region_instrumented UNDEFINED art_quick_alloc_array_resolved64_region UNDEFINED art_quick_alloc_array_resolved64_region_instrumented UNDEFINED art_quick_alloc_object_resolved_region UNDEFINED art_quick_alloc_object_resolved_region_instrumented UNDEFINED art_quick_alloc_object_initialized_region UNDEFINED art_quick_alloc_object_initialized_region_instrumented UNDEFINED art_quick_alloc_object_with_checks_region UNDEFINED art_quick_alloc_object_with_checks_region_instrumented UNDEFINED art_quick_alloc_string_object_region UNDEFINED art_quick_alloc_string_object_region_instrumented UNDEFINED art_quick_alloc_string_from_bytes_region UNDEFINED art_quick_alloc_string_from_bytes_region_instrumented UNDEFINED art_quick_alloc_string_from_chars_region UNDEFINED art_quick_alloc_string_from_chars_region_instrumented UNDEFINED art_quick_alloc_string_from_string_region UNDEFINED art_quick_alloc_string_from_string_region_instrumented UNDEFINED art_quick_alloc_array_resolved_region_tlab UNDEFINED art_quick_alloc_array_resolved_region_tlab_instrumented UNDEFINED art_quick_alloc_array_resolved8_region_tlab UNDEFINED art_quick_alloc_array_resolved8_region_tlab_instrumented UNDEFINED art_quick_alloc_array_resolved16_region_tlab UNDEFINED art_quick_alloc_array_resolved16_region_tlab_instrumented UNDEFINED art_quick_alloc_array_resolved32_region_tlab UNDEFINED art_quick_alloc_array_resolved32_region_tlab_instrumented UNDEFINED art_quick_alloc_array_resolved64_region_tlab UNDEFINED art_quick_alloc_array_resolved64_region_tlab_instrumented UNDEFINED art_quick_alloc_object_resolved_region_tlab UNDEFINED art_quick_alloc_object_resolved_region_tlab_instrumented UNDEFINED art_quick_alloc_object_initialized_region_tlab UNDEFINED art_quick_alloc_object_initialized_region_tlab_instrumented UNDEFINED art_quick_alloc_object_with_checks_region_tlab UNDEFINED art_quick_alloc_object_with_checks_region_tlab_instrumented UNDEFINED art_quick_alloc_string_object_region_tlab UNDEFINED art_quick_alloc_string_object_region_tlab_instrumented UNDEFINED art_quick_alloc_string_from_bytes_region_tlab UNDEFINED art_quick_alloc_string_from_bytes_region_tlab_instrumented UNDEFINED art_quick_alloc_string_from_chars_region_tlab UNDEFINED art_quick_alloc_string_from_chars_region_tlab_instrumented UNDEFINED art_quick_alloc_string_from_string_region_tlab UNDEFINED art_quick_alloc_string_from_string_region_tlab_instrumented UNDEFINED art_quick_initialize_static_storage UNDEFINED art_quick_resolve_type_and_verify_access UNDEFINED art_quick_resolve_type UNDEFINED art_quick_resolve_method_handle UNDEFINED art_quick_resolve_method_type UNDEFINED art_quick_resolve_string UNDEFINED art_quick_set8_instance UNDEFINED art_quick_set8_static UNDEFINED art_quick_set16_instance UNDEFINED art_quick_set16_static UNDEFINED art_quick_set32_instance UNDEFINED art_quick_set32_static UNDEFINED art_quick_set64_instance UNDEFINED art_quick_set64_static UNDEFINED art_quick_set_obj_instance UNDEFINED art_quick_set_obj_static UNDEFINED art_quick_get_byte_instance UNDEFINED art_quick_get_boolean_instance UNDEFINED art_quick_get_short_instance UNDEFINED art_quick_get_char_instance UNDEFINED art_quick_get32_instance UNDEFINED art_quick_get64_instance UNDEFINED art_quick_get_obj_instance UNDEFINED art_quick_get_byte_static UNDEFINED art_quick_get_boolean_static UNDEFINED art_quick_get_short_static UNDEFINED art_quick_get_char_static UNDEFINED art_quick_get32_static UNDEFINED art_quick_get64_static UNDEFINED art_quick_get_obj_static UNDEFINED art_quick_aput_obj UNDEFINED art_quick_lock_object_no_inline UNDEFINED art_quick_lock_object UNDEFINED art_quick_unlock_object_no_inline UNDEFINED art_quick_unlock_object UNDEFINED art_quick_invoke_direct_trampoline_with_access_check UNDEFINED art_quick_invoke_interface_trampoline_with_access_check UNDEFINED art_quick_invoke_static_trampoline_with_access_check UNDEFINED art_quick_invoke_super_trampoline_with_access_check UNDEFINED art_quick_invoke_virtual_trampoline_with_access_check UNDEFINED art_quick_invoke_polymorphic UNDEFINED art_quick_invoke_custom UNDEFINED art_quick_test_suspend UNDEFINED art_quick_deliver_exception UNDEFINED art_quick_throw_array_bounds UNDEFINED art_quick_throw_div_zero UNDEFINED art_quick_throw_null_pointer_exception UNDEFINED art_quick_throw_stack_overflow UNDEFINED art_quick_throw_string_bounds UNDEFINED art_quick_update_inline_cache UNDEFINED art_jni_monitored_method_start UNDEFINED art_jni_monitored_method_end UNDEFINED art_quick_indexof