/* *Jnidlsymlookupstubfor@CriticalNative.
*/
ENTRY art_jni_dlsym_lookup_critical_stub
// The hidden arg holding the tagged method (bit 0set means GenericJNI) is x15.
// For Generic JNI we already have a managed frame, so we reuse the art_jni_dlsym_lookup_stub.
// Note: 'tbnz' doesn't always have enough range (+/-32KB) to reach art_jni_dlsym_lookup_stub
// so 'b' (+/-128MB) is used instead.
tbz x15, #0, .Lcritical_not_generic_jni
BRANCH_SYMBOL art_jni_dlsym_lookup_stub
.Lcritical_not_generic_jni:
// Save args, the hidden arg and caller PC. No CFI needed for args and the hidden arg.
SAVE_ALL_ARGS_INCREASE_FRAME 2 * 8
stp x15, lr, [sp, #ALL_ARGS_SIZE]
.cfi_rel_offset lr, ALL_ARGS_SIZE + 8
// Restore args, the hidden arg and caller PC.
ldp x15, lr, [sp, #128]
.cfi_restore lr
RESTORE_ALL_ARGS_DECREASE_FRAME 2 * 8
// Reserve space for a SaveRefsAndArgs managed frame, either for the actual runtime
// method or for a GenericJNI frame which is similar but has a native method and a tag.
INCREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS
// Calculate the base address of the managed frame.
add x13, sp, x14
// Prepare the return address for managed stack walk of the SaveRefsAndArgs frame.
// If we're coming from JNI stub with tail call, it is LR. If we're coming from
// JNI stub that saved the return address, it will be the last value we copy below.
// If we're coming directly from compiled code, it is LR, set further down.
mov xIP1, lr
// Spill registers for the SaveRefsAndArgs frame above the stack args.
// Note that the runtime shall not examine the args here, otherwise we would have to
// move them in registers and stack to account for the difference between managed and
// native ABIs. Do not update CFI while we hold the frame address in x13 and the values
// in registers are unchanged.
stp d0, d1, [x13, #16]
stp d2, d3, [x13, #32]
stp d4, d5, [x13, #48]
stp d6, d7, [x13, #64]
stp x1, x2, [x13, #80]
stp x3, x4, [x13, #96]
stp x5, x6, [x13, #112]
stp x7, x20, [x13, #128]
stp x21, x22, [x13, #144]
stp x23, x24, [x13, #160]
stp x25, x26, [x13, #176]
stp x27, x28, [x13, #192]
stp x29, xIP1, [x13, #208] // xIP1: Save return address for tail call from JNI stub.
// (If there were any stack args, we're storing the value that's already there.
// For direct calls from compiled managed code, we shall overwrite this below.)
// Move the managed frame address to native callee-save register x29 and update CFI.
mov x29, x13
// Skip args d0-d7, x1-x7
CFI_EXPRESSION_BREG 20, 29, 136
CFI_EXPRESSION_BREG 21, 29, 144
CFI_EXPRESSION_BREG 22, 29, 152
CFI_EXPRESSION_BREG 23, 29, 160
CFI_EXPRESSION_BREG 24, 29, 168
CFI_EXPRESSION_BREG 25, 29, 176
CFI_EXPRESSION_BREG 26, 29, 184
CFI_EXPRESSION_BREG 27, 29, 192
CFI_EXPRESSION_BREG 28, 29, 200
CFI_EXPRESSION_BREG 29, 29, 208
// The saved return PC for managed stack walk is not necessarily our LR.
// Save our return PC in the padding.
str lr, [x29, #__SIZEOF_POINTER__]
CFI_EXPRESSION_BREG 30, 29, __SIZEOF_POINTER__
// When coming from a compiled method, the return PC for managed stack walk is LR.
// (When coming from a compiled stub, the correct return PC is already stored above.)
str lr, [x29, #(FRAME_SIZE_SAVE_REFS_AND_ARGS - __SIZEOF_POINTER__)]
// Replace the target method with the SaveRefsAndArgs runtime method.
LOAD_RUNTIME_INSTANCE x15
ldr x15, [x15, #RUNTIME_SAVE_REFS_AND_ARGS_METHOD_OFFSET]
mov x14, x29 // Prepare untagged managed SP for the runtime method.
.Lcritical_skip_prepare_runtime_method:
// Store the method on the bottom of the managed frame.
str x15, [x29]
// Place (maybe tagged) managed SP in Thread::Current()->top_quick_frame.
str x14, [xSELF, #THREAD_TOP_QUICK_FRAME_OFFSET]
// Preserve the native arg register x0 in callee-save register x28 which was saved above.
mov x28, x0
// Check for exception before moving args back to keep the return PC for managed stack walk.
CFI_REMEMBER_STATE
cbz x13, .Lcritical_deliver_exception
// Move stack args to their original place.
cbz x14, .Lcritical_skip_copy_args_back sub x12, sp, x14
.Lcritical_copy_args_back_loop:
ldp xIP0, xIP1, [x12, #-16]!
adds x14, x14, #16
stp xIP0, xIP1, [x12, #FRAME_SIZE_SAVE_REFS_AND_ARGS]
bne .Lcritical_copy_args_back_loop
.Lcritical_skip_copy_args_back:
// Remove the frame reservation.
DECREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS
// Do the tail call.
br x13
.Lcritical_deliver_exception:
CFI_RESTORE_STATE_AND_DEF_CFA sp, FRAME_SIZE_SAVE_REFS_AND_ARGS
// The exception delivery checks that xSELF was saved but the SaveRefsAndArgs
// frame does not save it, so we cannot use the existing SaveRefsAndArgs frame.
// That's why we checked for exception after restoring registers from it.
// We need to build a SaveAllCalleeSaves frame instead. Args are irrelevant at this
// point but keep the area allocated for stack args to keep CFA definition simple.
DECREASE_FRAME FRAME_SIZE_SAVE_REFS_AND_ARGS - FRAME_SIZE_SAVE_ALL_CALLEE_SAVES
// Calculate the base address of the managed frame. sub x13, sp, x14
// Spill registers for the SaveAllCalleeSaves frame above the stack args area. Do not update
// CFI while we hold the frame address in x13 and the values in registers are unchanged.
stp d8, d9, [x13, #16]
stp d10, d11, [x13, #32]
stp d12, d13, [x13, #48]
stp d14, d15, [x13, #64]
stp x19, x20, [x13, #80]
stp x21, x22, [x13, #96]
stp x23, x24, [x13, #112]
stp x25, x26, [x13, #128]
stp x27, x28, [x13, #144]
str x29, [x13, #160]
// Keep the caller PC for managed stack walk.
// Move the managed frame address to native callee-save register x29 and update CFI.
mov x29, x13
CFI_EXPRESSION_BREG 19, 29, 80
CFI_EXPRESSION_BREG 20, 29, 88
CFI_EXPRESSION_BREG 21, 29, 96
CFI_EXPRESSION_BREG 22, 29, 104
CFI_EXPRESSION_BREG 23, 29, 112
CFI_EXPRESSION_BREG 24, 29, 120
CFI_EXPRESSION_BREG 25, 29, 128
CFI_EXPRESSION_BREG 26, 29, 136
CFI_EXPRESSION_BREG 27, 29, 144
CFI_EXPRESSION_BREG 28, 29, 152
CFI_EXPRESSION_BREG 29, 29, 160
// The saved return PC for managed stack walk is not necessarily our LR.
// Save our return PC in the padding.
str lr, [x29, #__SIZEOF_POINTER__]
CFI_EXPRESSION_BREG 30, 29, __SIZEOF_POINTER__
// Store ArtMethod* Runtime::callee_save_methods_[kSaveAllCalleeSaves] to the managed frame.
LOAD_RUNTIME_INSTANCE xIP0
ldr xIP0, [xIP0, #RUNTIME_SAVE_ALL_CALLEE_SAVES_METHOD_OFFSET]
str xIP0, [x29]
// Place the managed frame SP in Thread::Current()->top_quick_frame.
str x29, [xSELF, #THREAD_TOP_QUICK_FRAME_OFFSET]
DELIVER_PENDING_EXCEPTION_FRAME_READY
END art_jni_dlsym_lookup_critical_stub
/* *Readbarrierforthemethod'sdeclaringclassneededbyJNIstubforstaticmethods. *(We'reusingapointertothedeclaringclassin`ArtMethod`as`jclass`.)
*/
// The method argument is already in x0 for call to `artJniReadBarrier(ArtMethod*)`.
JNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_read_barrier, artJniReadBarrier
/* *EntryfromJNIstubthatcalls`artJniUnlockObject()`.Notethatfailureto *unlockisfatal,sowedonotneedtocheckforexceptions. *Customcallingconvention: *x15holdsthenon-nullobjecttounlock. *Callee-saveregistershavebeensavedandcanbeusedastemporaries. *Returnregistersr0andd0needtobepreserved.
*/
// This is also the slow path for art_jni_unlock_object.
JNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_unlock_object_no_inline, artJniUnlockObject, x15, xSELF
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-29)
¤
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.