@@ -793,19 +793,27 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
793793}
794794
795795// Support function for remove_activation & Co.
796- void InterpreterMacroAssembler::merge_frames (Register Rsender_sp, Register return_pc,
797- Register Rscratch1, Register Rscratch2) {
798- // Pop interpreter frame.
799- ld (Rscratch1, 0 , R1_SP); // *SP
800- ld (Rsender_sp, _ijava_state_neg (sender_sp), Rscratch1); // top_frame_sp
801- ld (Rscratch2, 0 , Rscratch1); // **SP
802- if (return_pc!=noreg) {
803- ld (return_pc, _abi0 (lr), Rscratch1); // LR
796+ void InterpreterMacroAssembler::load_fp (Register fp) {
797+ ld (fp, _abi0 (callers_sp), R1_SP); // *SP
798+ }
799+
800+ void InterpreterMacroAssembler::remove_top_frame_given_fp (Register fp, Register sender_sp, Register sender_fp,
801+ Register return_pc, Register temp) {
802+ assert_different_registers (sender_sp, sender_fp, return_pc, temp);
803+ ld (sender_sp, _ijava_state_neg (sender_sp), fp);
804+ ld (sender_fp, _abi0 (callers_sp), fp); // **SP
805+ if (return_pc != noreg) {
806+ ld (return_pc, _abi0 (lr), fp); // last usage of fp, register can be reused
804807 }
808+ subf (temp, R1_SP, sender_sp); // sender_sp - SP
809+ stdux (sender_fp, R1_SP, temp); // atomically set *(SP = sender_sp) = sender_fp
810+ }
805811
806- // Merge top frames.
807- subf (Rscratch1, R1_SP, Rsender_sp); // top_frame_sp - SP
808- stdux (Rscratch2, R1_SP, Rscratch1); // atomically set *(SP = top_frame_sp) = **SP
812+ void InterpreterMacroAssembler::merge_frames (Register sender_sp, Register return_pc,
813+ Register temp1, Register temp2) {
814+ Register fp = temp1, sender_fp = temp2;
815+ load_fp (fp);
816+ remove_top_frame_given_fp (fp, sender_sp, sender_fp, return_pc, /* temp */ fp);
809817}
810818
811819void InterpreterMacroAssembler::narrow (Register result) {
@@ -864,11 +872,16 @@ void InterpreterMacroAssembler::remove_activation(TosState state,
864872 bool install_monitor_exception) {
865873 BLOCK_COMMENT (" remove_activation {" );
866874
875+ unlock_if_synchronized_method (state, throw_monitor_exception, install_monitor_exception);
876+
867877 // The below poll is for the stack watermark barrier. It allows fixing up frames lazily,
868878 // that would normally not be safe to use. Such bad returns into unsafe territory of
869879 // the stack, will call InterpreterRuntime::at_unwind.
870- Label slow_path;
871- Label fast_path;
880+ Label slow_path, fast_path;
881+ Register fp = R22_tmp2;
882+ load_fp (fp);
883+
884+ JFR_ONLY (enter_jfr_critical_section ();)
872885 safepoint_poll (slow_path, R11_scratch1, true /* at_return */ , false /* in_nmethod */ );
873886 b (fast_path);
874887 bind (slow_path);
@@ -880,8 +893,6 @@ void InterpreterMacroAssembler::remove_activation(TosState state,
880893 align (32 );
881894 bind (fast_path);
882895
883- unlock_if_synchronized_method (state, throw_monitor_exception, install_monitor_exception);
884-
885896 // Save result (push state before jvmti call and pop it afterwards) and notify jvmti.
886897 notify_method_exit (false , state, NotifyJVMTI, true );
887898
@@ -901,10 +912,11 @@ void InterpreterMacroAssembler::remove_activation(TosState state,
901912 // call could have a smaller SP, so that this compare succeeds for an
902913 // inner call of the method annotated with ReservedStack.
903914 ld_ptr (R0, JavaThread::reserved_stack_activation_offset (), R16_thread);
904- ld_ptr (R11_scratch1, _abi0 (callers_sp), R1_SP); // Load frame pointer.
905- cmpld (CR0, R11_scratch1, R0);
915+ cmpld (CR0, fp, R0);
906916 blt_predict_taken (CR0, no_reserved_zone_enabling);
907917
918+ JFR_ONLY (leave_jfr_critical_section ();)
919+
908920 // Enable reserved zone again, throw stack overflow exception.
909921 call_VM_leaf (CAST_FROM_FN_PTR (address, SharedRuntime::enable_stack_reserved_zone), R16_thread);
910922 call_VM (noreg, CAST_FROM_FN_PTR (address, InterpreterRuntime::throw_delayed_StackOverflowError));
@@ -916,12 +928,26 @@ void InterpreterMacroAssembler::remove_activation(TosState state,
916928
917929 verify_oop (R17_tos, state);
918930
919- merge_frames ( /* top_frame_sp */ R21_sender_SP, /* return_pc*/ R0, R11_scratch1, R12_scratch2 );
931+ remove_top_frame_given_fp (fp, R21_sender_SP, R23_tmp3, /* return_pc*/ R0, R11_scratch1);
920932 mtlr (R0);
921933 pop_cont_fastpath ();
934+ JFR_ONLY (leave_jfr_critical_section ();)
935+
922936 BLOCK_COMMENT (" } remove_activation" );
923937}
924938
939+ #if INCLUDE_JFR
940+ void InterpreterMacroAssembler::enter_jfr_critical_section () {
941+ li (R0, 1 );
942+ stb (R0, in_bytes (SAMPLING_CRITICAL_SECTION_OFFSET_JFR), R16_thread);
943+ }
944+
945+ void InterpreterMacroAssembler::leave_jfr_critical_section () {
946+ li (R0, 0 );
947+ stb (R0, in_bytes (SAMPLING_CRITICAL_SECTION_OFFSET_JFR), R16_thread);
948+ }
949+ #endif // INCLUDE_JFR
950+
925951// Lock object
926952//
927953// Registers alive
0 commit comments