266 __ mov(L2_saved_target, recv_reg); |
266 __ mov(L2_saved_target, recv_reg); |
267 BLOCK_COMMENT("} end_ricochet_frame"); |
267 BLOCK_COMMENT("} end_ricochet_frame"); |
268 } |
268 } |
269 |
269 |
270 // Emit code to verify that FP is pointing at a valid ricochet frame. |
270 // Emit code to verify that FP is pointing at a valid ricochet frame. |
271 #ifdef ASSERT |
271 #ifndef PRODUCT |
272 enum { |
272 enum { |
273 ARG_LIMIT = 255, SLOP = 45, |
273 ARG_LIMIT = 255, SLOP = 45, |
274 // use this parameter for checking for garbage stack movements: |
274 // use this parameter for checking for garbage stack movements: |
275 UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP) |
275 UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP) |
276 // the slop defends against false alarms due to fencepost errors |
276 // the slop defends against false alarms due to fencepost errors |
277 }; |
277 }; |
278 |
278 #endif |
|
279 |
|
280 #ifdef ASSERT |
279 void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) { |
281 void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) { |
280 // The stack should look like this: |
282 // The stack should look like this: |
281 // ... keep1 | dest=42 | keep2 | magic | handler | magic | recursive args | [RF] |
283 // ... keep1 | dest=42 | keep2 | magic | handler | magic | recursive args | [RF] |
282 // Check various invariants. |
284 // Check various invariants. |
283 |
285 |
1020 |
1022 |
1021 #ifndef PRODUCT |
1023 #ifndef PRODUCT |
1022 extern "C" void print_method_handle(oop mh); |
1024 extern "C" void print_method_handle(oop mh); |
1023 void trace_method_handle_stub(const char* adaptername, |
1025 void trace_method_handle_stub(const char* adaptername, |
1024 oopDesc* mh, |
1026 oopDesc* mh, |
1025 intptr_t* saved_sp) { |
1027 intptr_t* saved_sp, |
|
1028 intptr_t* args, |
|
1029 intptr_t* tracing_fp) { |
1026 bool has_mh = (strstr(adaptername, "return/") == NULL); // return adapters don't have mh |
1030 bool has_mh = (strstr(adaptername, "return/") == NULL); // return adapters don't have mh |
1027 tty->print_cr("MH %s mh="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT, adaptername, (intptr_t) mh, saved_sp); |
1031 |
1028 if (has_mh) |
1032 tty->print_cr("MH %s mh="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT, adaptername, (intptr_t) mh, saved_sp, args); |
|
1033 |
|
1034 if (Verbose) { |
|
1035 // dumping last frame with frame::describe |
|
1036 |
|
1037 JavaThread* p = JavaThread::active(); |
|
1038 |
|
1039 ResourceMark rm; |
|
1040 PRESERVE_EXCEPTION_MARK; // may not be needed by safer and unexpensive here |
|
1041 FrameValues values; |
|
1042 |
|
1043 // Note: We want to allow trace_method_handle from any call site. |
|
1044 // While trace_method_handle creates a frame, it may be entered |
|
1045 // without a valid return PC in O7 (e.g. not just after a call). |
|
1046 // Walking that frame could lead to failures due to that invalid PC. |
|
1047 // => carefully detect that frame when doing the stack walking |
|
1048 |
|
1049 // walk up to the right frame using the "tracing_fp" argument |
|
1050 intptr_t* cur_sp = StubRoutines::Sparc::flush_callers_register_windows_func()(); |
|
1051 frame cur_frame(cur_sp, frame::unpatchable, NULL); |
|
1052 |
|
1053 while (cur_frame.fp() != (intptr_t *)(STACK_BIAS+(uintptr_t)tracing_fp)) { |
|
1054 cur_frame = os::get_sender_for_C_frame(&cur_frame); |
|
1055 } |
|
1056 |
|
1057 // safely create a frame and call frame::describe |
|
1058 intptr_t *dump_sp = cur_frame.sender_sp(); |
|
1059 intptr_t *dump_fp = cur_frame.link(); |
|
1060 |
|
1061 bool walkable = has_mh; // whether the traced frame shoud be walkable |
|
1062 |
|
1063 // the sender for cur_frame is the caller of trace_method_handle |
|
1064 if (walkable) { |
|
1065 // The previous definition of walkable may have to be refined |
|
1066 // if new call sites cause the next frame constructor to start |
|
1067 // failing. Alternatively, frame constructors could be |
|
1068 // modified to support the current or future non walkable |
|
1069 // frames (but this is more intrusive and is not considered as |
|
1070 // part of this RFE, which will instead use a simpler output). |
|
1071 frame dump_frame = frame(dump_sp, |
|
1072 cur_frame.sp(), // younger_sp |
|
1073 false); // no adaptation |
|
1074 dump_frame.describe(values, 1); |
|
1075 } else { |
|
1076 // Robust dump for frames which cannot be constructed from sp/younger_sp |
|
1077 // Add descriptions without building a Java frame to avoid issues |
|
1078 values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>"); |
|
1079 values.describe(-1, dump_sp, "sp"); |
|
1080 } |
|
1081 |
|
1082 bool has_args = has_mh; // whether Gargs is meaningful |
|
1083 |
|
1084 // mark args, if seems valid (may not be valid for some adapters) |
|
1085 if (has_args) { |
|
1086 if ((args >= dump_sp) && (args < dump_fp)) { |
|
1087 values.describe(-1, args, "*G4_args"); |
|
1088 } |
|
1089 } |
|
1090 |
|
1091 // mark saved_sp, if seems valid (may not be valid for some adapters) |
|
1092 intptr_t *unbiased_sp = (intptr_t *)(STACK_BIAS+(uintptr_t)saved_sp); |
|
1093 if ((unbiased_sp >= dump_sp - UNREASONABLE_STACK_MOVE) && (unbiased_sp < dump_fp)) { |
|
1094 values.describe(-1, unbiased_sp, "*saved_sp+STACK_BIAS"); |
|
1095 } |
|
1096 |
|
1097 // Note: the unextended_sp may not be correct |
|
1098 tty->print_cr(" stack layout:"); |
|
1099 values.print(p); |
|
1100 } |
|
1101 |
|
1102 if (has_mh) { |
1029 print_method_handle(mh); |
1103 print_method_handle(mh); |
1030 } |
1104 } |
|
1105 } |
|
1106 |
1031 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { |
1107 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { |
1032 if (!TraceMethodHandles) return; |
1108 if (!TraceMethodHandles) return; |
1033 BLOCK_COMMENT("trace_method_handle {"); |
1109 BLOCK_COMMENT("trace_method_handle {"); |
1034 // save: Gargs, O5_savedSP |
1110 // save: Gargs, O5_savedSP |
1035 __ save_frame(16); |
1111 __ save_frame(16); // need space for saving required FPU state |
|
1112 |
1036 __ set((intptr_t) adaptername, O0); |
1113 __ set((intptr_t) adaptername, O0); |
1037 __ mov(G3_method_handle, O1); |
1114 __ mov(G3_method_handle, O1); |
1038 __ mov(I5_savedSP, O2); |
1115 __ mov(I5_savedSP, O2); |
|
1116 __ mov(Gargs, O3); |
|
1117 __ mov(I6, O4); // frame identifier for safe stack walking |
|
1118 |
|
1119 // Save scratched registers that might be needed. Robustness is more |
|
1120 // important than optimizing the saves for this debug only code. |
|
1121 |
|
1122 // save FP result, valid at some call sites (adapter_opt_return_float, ...) |
|
1123 Address d_save(FP, -sizeof(jdouble) + STACK_BIAS); |
|
1124 __ stf(FloatRegisterImpl::D, Ftos_d, d_save); |
|
1125 // Safely save all globals but G2 (handled by call_VM_leaf) and G7 |
|
1126 // (OS reserved). |
1039 __ mov(G3_method_handle, L3); |
1127 __ mov(G3_method_handle, L3); |
1040 __ mov(Gargs, L4); |
1128 __ mov(Gargs, L4); |
1041 __ mov(G5_method_type, L5); |
1129 __ mov(G5_method_type, L5); |
1042 __ call_VM_leaf(L7, CAST_FROM_FN_PTR(address, trace_method_handle_stub)); |
1130 __ mov(G6, L6); |
|
1131 __ mov(G1, L1); |
|
1132 |
|
1133 __ call_VM_leaf(L2 /* for G2 */, CAST_FROM_FN_PTR(address, trace_method_handle_stub)); |
1043 |
1134 |
1044 __ mov(L3, G3_method_handle); |
1135 __ mov(L3, G3_method_handle); |
1045 __ mov(L4, Gargs); |
1136 __ mov(L4, Gargs); |
1046 __ mov(L5, G5_method_type); |
1137 __ mov(L5, G5_method_type); |
|
1138 __ mov(L6, G6); |
|
1139 __ mov(L1, G1); |
|
1140 __ ldf(FloatRegisterImpl::D, d_save, Ftos_d); |
|
1141 |
1047 __ restore(); |
1142 __ restore(); |
1048 BLOCK_COMMENT("} trace_method_handle"); |
1143 BLOCK_COMMENT("} trace_method_handle"); |
1049 } |
1144 } |
1050 #endif // PRODUCT |
1145 #endif // PRODUCT |
1051 |
1146 |