blob: ef9a04353e7fcd241dd7b00e50c4e6a29578d104 [file] [log] [blame]
/*
* 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