@@ -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,8 +912,7 @@ 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
908918 // Enable reserved zone again, throw stack overflow exception.
@@ -916,12 +926,26 @@ void InterpreterMacroAssembler::remove_activation(TosState state,
916926
917927 verify_oop (R17_tos, state);
918928
919- merge_frames ( /* top_frame_sp */ R21_sender_SP, /* return_pc*/ R0, R11_scratch1, R12_scratch2 );
929+ remove_top_frame_given_fp (fp, R21_sender_SP, R23_tmp3, /* return_pc*/ R0, R11_scratch1);
920930 mtlr (R0);
921931 pop_cont_fastpath ();
932+ JFR_ONLY (leave_jfr_critical_section ();)
933+
922934 BLOCK_COMMENT (" } remove_activation" );
923935}
924936
937+ #if INCLUDE_JFR
938+ void InterpreterMacroAssembler::enter_jfr_critical_section () {
939+ li (R0, 1 );
940+ stb (R0, in_bytes (SAMPLING_CRITICAL_SECTION_OFFSET_JFR), R16_thread);
941+ }
942+
943+ void InterpreterMacroAssembler::leave_jfr_critical_section () {
944+ li (R0, 0 );
945+ stb (R0, in_bytes (SAMPLING_CRITICAL_SECTION_OFFSET_JFR), R16_thread);
946+ }
947+ #endif // INCLUDE_JFR
948+
925949// Lock object
926950//
927951// Registers alive
0 commit comments