Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  jni_entrypoints_arm64.S

  Sprache: Sparc
 

/*
 * Copyright (C) 2014 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_arm64.S"

.macro JNI_SAVE_MANAGED_ARGS_TRAMPOLINE name, cxx_name, arg1 = "none"
    .extern \cxx_name
ENTRY \name
    // Save args and LR.
    SAVE_ALL_ARGS_INCREASE_FRAME /*padding*/ 8 + /*LR*/ 8
    str    lr, [sp, #(ALL_ARGS_SIZE + /*padding*/ 8)]
    .cfi_rel_offset lr, ALL_ARGS_SIZE + /*padding*/ 8
    // Call `cxx_name()`.
    .ifnc \arg1, none
        mov x0, \arg1                          // Pass arg1.
    .endif
    CALL_SYMBOL \cxx_name                      // Call cxx_name(...).
    // Restore LR and args and return.
    ldr    lr, [sp, #(ALL_ARGS_SIZE + /*padding*/ 8)]
    .cfi_restore lr
    RESTORE_ALL_ARGS_DECREASE_FRAME /*padding*/ 8 + /*LR*/ 8
    ret
END \name
.endm

.macro JNI_SAVE_RETURN_VALUE_TRAMPOLINE name, cxx_name, arg1, arg2 = "none"
    .extern \cxx_name
ENTRY \name
    // Save return registers and return address.
    stp    x0, lr, [sp, #-32]!
    .cfi_adjust_cfa_offset 32
    .cfi_rel_offset lr, 8
    str    d0, [sp, #16]
    // Call `cxx_name()`.
    mov    x0, \arg1                           // Pass arg1.
    .ifnc \arg2, none
        mov x1, \arg2                          // Pass arg2.
    .endif
    CALL_SYMBOL \cxx_name                      // Call cxx_name(...).
    // Restore return registers and return.
    ldr    d0, [sp, #16]
    ldp    x0, lr, [sp], #32
    .cfi_adjust_cfa_offset -32
    .cfi_restore lr
    ret
END \name
.endm

    /*
     * Jni dlsym lookup stub for @CriticalNative.
     */

ENTRY art_jni_dlsym_lookup_critical_stub
    // The hidden arg holding the tagged method (bit 0 set 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

    // Call artCriticalNativeFrameSize(method, caller_pc)
    mov   x0, x15  // x0 := method (from hidden arg)
    mov   x1, lr   // x1 := caller_pc
    CALL_SYMBOL artCriticalNativeFrameSize

    // Move frame size to x14.
    mov   x14, x0

    // 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

    // Move the stack args if any.
    cbz   x14, .Lcritical_skip_copy_args
    mov   x12, sp
.Lcritical_copy_args_loop:
    ldp   xIP0, xIP1, [x12, #FRAME_SIZE_SAVE_REFS_AND_ARGS]
    subs  x14, x14, #16
    stp   xIP0, xIP1, [x12], #16
    bne   .Lcritical_copy_args_loop
.Lcritical_skip_copy_args:

    // 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 2029136
    CFI_EXPRESSION_BREG 2129144
    CFI_EXPRESSION_BREG 2229152
    CFI_EXPRESSION_BREG 2329160
    CFI_EXPRESSION_BREG 2429168
    CFI_EXPRESSION_BREG 2529176
    CFI_EXPRESSION_BREG 2629184
    CFI_EXPRESSION_BREG 2729192
    CFI_EXPRESSION_BREG 2829200
    CFI_EXPRESSION_BREG 2929208
    // 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 3029, __SIZEOF_POINTER__

    ldr   wIP0, [x15, #ART_METHOD_ACCESS_FLAGS_OFFSET]  // Load access flags.
    add   x14, x29, #1            // Prepare managed SP tagged for a GenericJNI frame.
    tbnz  wIP0, #ACCESS_FLAGS_METHOD_IS_NATIVE_BIT, .Lcritical_skip_prepare_runtime_method

    // 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

    // Call artFindNativeMethodRunnable()
    mov   x0, xSELF   // pass Thread::Current()
    CALL_SYMBOL artFindNativeMethodRunnable

    // Store result in scratch reg.
    mov   x13, x0

    // Restore the native arg register x0.
    mov   x0, x28

    // Restore our return PC.
    RESTORE_REG_BASE x29, lr, __SIZEOF_POINTER__

    // Remember the stack args size, negated because SP cannot be on the right-hand side in SUB.
    sub   x14, sp, x29

    // Restore the frame. We shall not need the method anymore.
    ldp   d0, d1, [x29, #16]
    ldp   d2, d3, [x29, #32]
    ldp   d4, d5, [x29, #48]
    ldp   d6, d7, [x29, #64]
    ldp   x1, x2, [x29, #80]
    ldp   x3, x4, [x29, #96]
    ldp   x5, x6, [x29, #112]
    ldp   x7, x20, [x29, #128]
    .cfi_restore x20
    RESTORE_TWO_REGS_BASE x29, x21, x22, 144
    RESTORE_TWO_REGS_BASE x29, x23, x24, 160
    RESTORE_TWO_REGS_BASE x29, x25, x26, 176
    RESTORE_TWO_REGS_BASE x29, x27, x28, 192
    RESTORE_REG_BASE x29, x29, 208

    REFRESH_MARKING_REGISTER

    // 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 192980
    CFI_EXPRESSION_BREG 202988
    CFI_EXPRESSION_BREG 212996
    CFI_EXPRESSION_BREG 2229104
    CFI_EXPRESSION_BREG 2329112
    CFI_EXPRESSION_BREG 2429120
    CFI_EXPRESSION_BREG 2529128
    CFI_EXPRESSION_BREG 2629136
    CFI_EXPRESSION_BREG 2729144
    CFI_EXPRESSION_BREG 2829152
    CFI_EXPRESSION_BREG 2929160
    // 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 3029, __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

    /*
     * Read barrier for the method's declaring class needed by JNI stub for static methods.
     * (We're using a pointer to the declaring class in `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

    /*
     * Trampoline to `artJniMethodStart()` that preserves all managed arguments.
     */

JNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_method_start, artJniMethodStart, xSELF

    /*
     * Trampoline to `artJniMethodEntryHook` that preserves all managed arguments.
     */

JNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_method_entry_hook, artJniMethodEntryHook, xSELF

    /*
     * Trampoline to `artJniMonitoredMethodStart()` that preserves all managed arguments.
     */

JNI_SAVE_MANAGED_ARGS_TRAMPOLINE art_jni_monitored_method_start, artJniMonitoredMethodStart, xSELF

    /*
     * Trampoline to `artJniMethodEnd()` that preserves all return registers.
     */

JNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_method_end, artJniMethodEnd, xSELF

    /*
     * Trampoline to `artJniMonitoredMethodEnd()` that preserves all return registers.
     */

JNI_SAVE_RETURN_VALUE_TRAMPOLINE art_jni_monitored_method_end, artJniMonitoredMethodEnd, xSELF

    /*
     * Entry from JNI stub that tries to lock the object in a fast path and
     * calls `artLockObjectFromCode()` (the same as for managed code) for the
     * difficult cases, may block for GC.
     * Custom calling convention:
     *     x15 holds the non-null object to lock.
     *     Callee-save registers have been saved and can be used as temporaries.
     *     All argument registers need to be preserved.
     */

ENTRY art_jni_lock_object
    LOCK_OBJECT_FAST_PATH x15, art_jni_lock_object_no_inline, /*can_be_null*/ 0, /*use_lse*/ 0
END art_jni_lock_object

    /*
     * Entry from JNI stub that tries to lock the object in a fast path and
     * calls `artLockObjectFromCode()` (the same as for managed code) for the
     * difficult cases, may block for GC.
     * Used only if runtime LSE support is detected.
     * Custom calling convention:
     *     x15 holds the non-null object to lock.
     *     Callee-save registers have been saved and can be used as temporaries.
     *     All argument registers need to be preserved.
     */

ENTRY art_jni_lock_object_lse
    LOCK_OBJECT_FAST_PATH x15, art_jni_lock_object_no_inline, /*can_be_null*/ 0, /*use_lse*/ 1
END art_jni_lock_object_lse

    /*
     * Entry from JNI stub that calls `artLockObjectFromCode()`
     * (the same as for managed code), may block for GC.
     * Custom calling convention:
     *     x15 holds the non-null object to lock.
     *     Callee-save registers have been saved and can be used as temporaries.
     *     All argument registers need to be preserved.
     */

    .extern artLockObjectFromCode
ENTRY art_jni_lock_object_no_inline
    // This is also the slow path for art_jni_lock_object.
    // Save args and LR.
    SAVE_ALL_ARGS_INCREASE_FRAME /*padding*/ 8 + /*LR*/ 8
    str    lr, [sp, #(ALL_ARGS_SIZE + /*padding*/ 8)]
    .cfi_rel_offset lr, ALL_ARGS_SIZE + /*padding*/ 8
    // Call `artLockObjectFromCode()`.
    mov    x0, x15                                   // Pass the object to lock.
    mov    x1, xSELF                                 // Pass Thread::Current().
    CALL_SYMBOL artLockObjectFromCode                // (Object* obj, Thread*)
    // Restore return address.
    ldr    lr, [sp, #(ALL_ARGS_SIZE + /*padding*/ 8)]
    .cfi_restore lr
    // Check result.
    cbnz   x0, 1f
    // Restore register args x0-x7, d0-d7 and return.
    RESTORE_ALL_ARGS_DECREASE_FRAME /*padding*/ 8 + /*LR*/ 8
    ret
    .cfi_adjust_cfa_offset (ALL_ARGS_SIZE + /*padding*/ 8 + /*LR*/ 8)
1:
    // All args are irrelevant when throwing an exception. Remove the spill area.
    DECREASE_FRAME (ALL_ARGS_SIZE + /*padding*/ 8 + /*LR*/ 8)
    // Make a call to `artDeliverPendingExceptionFromCode()`.
    // Rely on the JNI transition frame constructed in the JNI stub.
    mov    x0, xSELF                                 // Pass Thread::Current().
    CALL_SYMBOL artDeliverPendingExceptionFromCode   // (Thread*)
    CALL_SYMBOL art_quick_do_long_jump               // (Context*)
    brk 0  // Unreached
END art_jni_lock_object_no_inline

    /*
     * Entry from JNI stub that tries to unlock the object in a fast path and calls
     * `artJniUnlockObject()` for the difficult cases. Note that failure to unlock
     * is fatal, so we do not need to check for exceptions in the slow path.
     * Custom calling convention:
     *     x15 holds the non-null object to unlock.
     *     Callee-save registers have been saved and can be used as temporaries.
     *     Return registers r0 and d0 need to be preserved.
     */

ENTRY art_jni_unlock_object
    UNLOCK_OBJECT_FAST_PATH x15, art_jni_unlock_object_no_inline, /*can_be_null*/ 0, /*use_lse*/ 0
END art_jni_unlock_object

    /*
     * Entry from JNI stub that tries to unlock the object in a fast path and calls
     * `artJniUnlockObject()` for the difficult cases. Note that failure to unlock
     * is fatal, so we do not need to check for exceptions in the slow path.
     * Used only if runtime LSE support is detected.
     * Custom calling convention:
     *     x15 holds the non-null object to unlock.
     *     Callee-save registers have been saved and can be used as temporaries.
     *     Return registers r0 and d0 need to be preserved.
     */

ENTRY art_jni_unlock_object_lse
    UNLOCK_OBJECT_FAST_PATH x15, art_jni_unlock_object_no_inline, /*can_be_null*/ 0, /*use_lse*/ 1
END art_jni_unlock_object_lse

    /*
     * Entry from JNI stub that calls `artJniUnlockObject()`. Note that failure to
     * unlock is fatal, so we do not need to check for exceptions.
     * Custom calling convention:
     *     x15 holds the non-null object to unlock.
     *     Callee-save registers have been saved and can be used as temporaries.
     *     Return registers r0 and d0 need to be preserved.
     */

    // 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
C=88 H=96 G=91

¤ Dauer der Verarbeitung: 0.25 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik