4141#include " prims/jvmtiExport.hpp"
4242#include " prims/jvmtiThreadState.hpp"
4343#include " runtime/basicLock.hpp"
44+ #include " runtime/continuationEntry.hpp"
4445#include " runtime/frame.inline.hpp"
4546#include " runtime/javaThread.hpp"
4647#include " runtime/safepointMechanism.hpp"
@@ -456,11 +457,43 @@ void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) {
456457 dispatch_base (state, table);
457458}
458459
460+ void InterpreterMacroAssembler::call_VM_with_sender_Java_fp_entry (address entry_point) {
461+ mov (c_rarg0, rthread);
462+ MacroAssembler::call_VM_leaf_base (entry_point, 0 );
463+ }
464+
465+ void InterpreterMacroAssembler::set_last_Java_frame_with_sender_fp (Register last_java_sp,
466+ Register last_java_fp,
467+ address last_java_pc,
468+ Register scratch) {
469+ assert_different_registers (last_java_fp, rfp);
470+
471+ #if INCLUDE_JFR
472+ Label L_ljf, L_valid_rfp;
473+ cbnz (rfp, L_valid_rfp);
474+ mov (scratch, 1 );
475+ str (scratch, Address (rthread, JavaThread::last_sender_Java_fp_offset ()));
476+ b (L_ljf);
477+ bind (L_valid_rfp);
478+ str (rfp, Address (rthread, JavaThread::last_sender_Java_fp_offset ()));
479+ bind (L_ljf);
480+ #endif
481+
482+ set_last_Java_frame (last_java_sp, last_java_fp, last_java_pc, scratch);
483+ }
484+
485+ void InterpreterMacroAssembler::reset_last_Java_frame_with_sender_fp (Register fp_reg) {
486+ // Restore the fp_reg.
487+ ldr (fp_reg, Address (rthread, JavaThread::last_Java_fp_offset ()));
488+ reset_last_Java_frame (true );
489+ JFR_ONLY (str (zr, Address (rthread, JavaThread::last_sender_Java_fp_offset ()));)
490+ }
491+
459492// remove activation
460493//
461- // Apply stack watermark barrier.
462494// Unlock the receiver if this is a synchronized method.
463495// Unlock any Java monitors from synchronized blocks.
496+ // Apply stack watermark barrier.
464497// Remove the activation from the stack.
465498//
466499// If there are locked Java monitors
@@ -470,30 +503,14 @@ void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) {
470503// installs IllegalMonitorStateException
471504// Else
472505// no error processing
473- void InterpreterMacroAssembler::remove_activation (
474- TosState state,
475- bool throw_monitor_exception,
476- bool install_monitor_exception,
477- bool notify_jvmdi) {
506+ void InterpreterMacroAssembler::remove_activation (TosState state,
507+ bool throw_monitor_exception,
508+ bool install_monitor_exception,
509+ bool notify_jvmdi) {
478510 // Note: Registers r3 xmm0 may be in use for the
479511 // result check if synchronized method
480512 Label unlocked, unlock, no_unlock;
481513
482- // The below poll is for the stack watermark barrier. It allows fixing up frames lazily,
483- // that would normally not be safe to use. Such bad returns into unsafe territory of
484- // the stack, will call InterpreterRuntime::at_unwind.
485- Label slow_path;
486- Label fast_path;
487- safepoint_poll (slow_path, true /* at_return */ , false /* acquire */ , false /* in_nmethod */ );
488- br (Assembler::AL, fast_path);
489- bind (slow_path);
490- push (state);
491- set_last_Java_frame (esp, rfp, (address)pc (), rscratch1);
492- super_call_VM_leaf (CAST_FROM_FN_PTR (address, InterpreterRuntime::at_unwind), rthread);
493- reset_last_Java_frame (true );
494- pop (state);
495- bind (fast_path);
496-
497514 // get the value of _do_not_unlock_if_synchronized into r3
498515 const Address do_not_unlock_if_synchronized (rthread,
499516 in_bytes (JavaThread::do_not_unlock_if_synchronized_offset ()));
@@ -647,17 +664,70 @@ void InterpreterMacroAssembler::remove_activation(
647664 bind (no_reserved_zone_enabling);
648665 }
649666
650- // restore sender esp
651- mov (esp, rscratch2);
652- // remove frame anchor
653- leave ();
667+ // For asynchronous profiling to work correctly, we must remove the
668+ // activation frame _before_ we test the method return safepoint poll.
669+ // This is equivalent to how it is done for compiled frames.
670+ // Removing an interpreter activation frame from a sampling perspective means
671+ // updating the frame link. But since we are unwinding the current frame,
672+ // we must save the current rfp in a temporary register, this_fp, for use
673+ // as the last java fp should we decide to unwind.
674+ // The asynchronous profiler will only see the updated rfp, either using the
675+ // CPU context or by reading the last_sender_Java_fp() field as part of the ljf.
676+ const Register this_fp = rscratch2;
677+ make_sender_fp_current (this_fp, rscratch1);
678+
679+ // The interpreter frame is now unwound from a sampling perspective,
680+ // meaning it sees the sender frame as the current frame from this point onwards.
681+
682+ // The below poll is for the stack watermark barrier. It allows fixing up frames lazily,
683+ // that would normally not be safe to use. Such bad returns into unsafe territory of
684+ // the stack, will call InterpreterRuntime::at_unwind.
685+ Label slow_path;
686+ Label fast_path;
687+ safepoint_poll (slow_path, this_fp, true /* at_return */ , false /* acquire */ , false /* in_nmethod */ );
688+ br (Assembler::AL, fast_path);
689+ bind (slow_path);
690+ save_bcp (this_fp); // need to save bcp but not restore it.
691+ push (state);
692+ set_last_Java_frame_with_sender_fp (esp, this_fp, (address)pc (), rscratch1);
693+ call_VM_with_sender_Java_fp_entry (CAST_FROM_FN_PTR (address, InterpreterRuntime::at_unwind));
694+ reset_last_Java_frame_with_sender_fp (this_fp);
695+ pop (state);
696+ bind (fast_path);
697+
698+ ldr (esp, Address (this_fp, frame::interpreter_frame_sender_sp_offset * wordSize));
699+ ldr (lr, Address (this_fp, wordSize));
700+ authenticate_return_address ();
701+ lea (sp, Address (this_fp, 2 * wordSize));
702+
654703 // If we're returning to interpreted code we will shortly be
655704 // adjusting SP to allow some space for ESP. If we're returning to
656705 // compiled code the saved sender SP was saved in sender_sp, so this
657706 // restores it.
658707 andr (sp, esp, -16 );
659708}
660709
710+ void InterpreterMacroAssembler::make_sender_fp_current (Register save_this_fp, Register tmp) {
711+ const Register return_addr = save_this_fp;
712+ const Register continuation_return_pc = tmp;
713+ const Register sender_sp = tmp;
714+ ldr (return_addr, Address (rfp, wordSize)); // return address
715+ // Load address of ContinuationEntry return pc
716+ lea (continuation_return_pc, ExternalAddress (ContinuationEntry::return_pc_address ()));
717+ // Load the ContinuationEntry return pc
718+ ldr (continuation_return_pc, Address (continuation_return_pc));
719+ Label L_continuation, L_end;
720+ cmp (continuation_return_pc, return_addr);
721+ mov (save_this_fp, rfp); // Save current fp in temporary register.
722+ br (Assembler::EQ, L_continuation);
723+ ldr (rfp, Address (rfp)); // Update the frame link.
724+ b (L_end);
725+ bind (L_continuation);
726+ lea (sender_sp, Address (rfp, frame::sender_sp_offset * wordSize));
727+ ldr (rfp, Address (sender_sp, (int )(ContinuationEntry::size ()))); // Update the frame link.
728+ bind (L_end);
729+ }
730+
661731// Lock object
662732//
663733// Args:
0 commit comments