%def op_invoke_custom():
EXPORT_PC
FETCH r0, 1 // call_site index, first argument of runtime call.
b NterpCommonInvokeCustom
%def op_invoke_custom_range():
EXPORT_PC
FETCH r0, 1 // call_site index, first argument of runtime call.
b NterpCommonInvokeCustomRange
%def invoke_direct_or_super(helper="", range=False, is_super=False):
// The slow path fits in the handler for `invoke-super{,/range}`.
% slow_path = '1f' if is_super else add_slow_path( \
% invoke_direct_or_super_slow_path, range, is_super)
EXPORT_PC
// Fast-path which gets the method from thread-local cache.
% fetch_from_thread_cache("r0", miss_label=slow_path)
.L${opcode}_resume:
// Load the first argument (the 'this' pointer).
FETCH r1, 2
% if not range:
and r1, r1, #0xf
GET_VREG r1, r1
cmp r1, #0
beq common_errNullObject // bail if null
b $helper
% if is_super: 1:
% invoke_direct_or_super_slow_path(range, is_super)
%def invoke_direct_or_super_slow_path(range, is_super):
mov r0, rSELF
ldr r1, [sp]
mov r2, rPC
mov r3, rFP
bl nterp_get_method
% if is_super:
b .L${opcode}_resume
% else:
tst r0, #1
beq .L${opcode}_resume
and r0, r0, #-2 // Remove the extra bit that marks it's a String.<init> method.
% if range:
b NterpHandleStringInitRange
% else:
b NterpHandleStringInit
%def op_invoke_polymorphic():
EXPORT_PC
// No need to fetch the target method.
// Load the first argument (the 'this' pointer).
FETCH r1, 2
and r1, r1, #0xf
GET_VREG r1, r1
cmp r1, #0
beq common_errNullObject // bail if null
b NterpCommonInvokePolymorphic
%def op_invoke_polymorphic_range():
EXPORT_PC
// No need to fetch the target method.
// Load the first argument (the 'this' pointer).
FETCH r1, 2
GET_VREG r1, r1
cmp r1, #0
beq common_errNullObject // bail if null
b NterpCommonInvokePolymorphicRange
%def invoke_interface(range=False):
% slow_path = add_slow_path(op_invoke_interface_slow_path, range)
EXPORT_PC
// Fast-path which gets the method from thread-local cache.
% fetch_from_thread_cache("r4", miss_label=slow_path)
.L${opcode}_resume:
// First argument is the 'this' pointer.
FETCH r1, 2
% if not range:
and r1, r1, #0xf
GET_VREG r1, r1
// Note: if r1 is null, this will be handled by our SIGSEGV handler.
ldr r2, [r1, #MIRROR_OBJECT_CLASS_OFFSET]
UNPOISON_HEAP_REF r2
// Test the first two bits of the fetched ArtMethod:
// - If the first bit is set, this is a method on j.l.Object
// - If the second bit is set, this is a default method.
tst r4, #3
bne .L${opcode}_slow_path_edge_cases
ldrh r3, [r4, #ART_METHOD_IMT_INDEX_OFFSET]
.L${opcode}_resume_with_imt_index:
ldr r2, [r2, #MIRROR_CLASS_IMT_PTR_OFFSET_32]
ldr r0, [r2, r3, lsl #2]
% if range:
b NterpCommonInvokeInterfaceRange
% else:
b NterpCommonInvokeInterface
% pass
%def op_invoke_interface_slow_path(range):
mov r0, rSELF
ldr r1, [sp]
mov r2, rPC
mov r3, rFP
bl nterp_get_method
mov r4, r0
b .L${opcode}_resume
.L${opcode}_slow_path_edge_cases:
tst r4, #1
bne 3f
and r4, r4, #-4
ldrh r3, [r4, #ART_METHOD_METHOD_INDEX_OFFSET]
and r3, r3, #ART_METHOD_IMT_MASK
b .L${opcode}_resume_with_imt_index 3:
lsr r4, r4, #16
add r2, r2, #MIRROR_CLASS_VTABLE_OFFSET_32
ldr r0, [r2, r4, lsl #2]
% if range:
b NterpCommonInvokeInstanceRange
% else:
b NterpCommonInvokeInstance
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.