277 __ mov(rsp, new_sp_reg); |
277 __ mov(rsp, new_sp_reg); |
278 BLOCK_COMMENT("} end_ricochet_frame"); |
278 BLOCK_COMMENT("} end_ricochet_frame"); |
279 } |
279 } |
280 |
280 |
281 // Emit code to verify that RBP is pointing at a valid ricochet frame. |
281 // Emit code to verify that RBP is pointing at a valid ricochet frame. |
282 #ifdef ASSERT |
282 #ifndef PRODUCT |
283 enum { |
283 enum { |
284 ARG_LIMIT = 255, SLOP = 4, |
284 ARG_LIMIT = 255, SLOP = 4, |
285 // use this parameter for checking for garbage stack movements: |
285 // use this parameter for checking for garbage stack movements: |
286 UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP) |
286 UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP) |
287 // the slop defends against false alarms due to fencepost errors |
287 // the slop defends against false alarms due to fencepost errors |
288 }; |
288 }; |
289 |
289 #endif |
|
290 |
|
291 #ifdef ASSERT |
290 void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) { |
292 void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) { |
291 // The stack should look like this: |
293 // The stack should look like this: |
292 // ... keep1 | dest=42 | keep2 | RF | magic | handler | magic | recursive args | |
294 // ... keep1 | dest=42 | keep2 | RF | magic | handler | magic | recursive args | |
293 // Check various invariants. |
295 // Check various invariants. |
294 verify_offsets(); |
296 verify_offsets(); |
988 ShouldNotReachHere(); |
990 ShouldNotReachHere(); |
989 } |
991 } |
990 BLOCK_COMMENT("} move_return_value"); |
992 BLOCK_COMMENT("} move_return_value"); |
991 } |
993 } |
992 |
994 |
993 #ifdef ASSERT |
995 #ifndef PRODUCT |
994 #define DESCRIBE_RICOCHET_OFFSET(rf, name) \ |
996 #define DESCRIBE_RICOCHET_OFFSET(rf, name) \ |
995 values.describe(frame_no, (intptr_t *) (((uintptr_t)rf) + MethodHandles::RicochetFrame::name##_offset_in_bytes()), #name) |
997 values.describe(frame_no, (intptr_t *) (((uintptr_t)rf) + MethodHandles::RicochetFrame::name##_offset_in_bytes()), #name) |
996 |
998 |
997 void MethodHandles::RicochetFrame::describe(const frame* fr, FrameValues& values, int frame_no) { |
999 void MethodHandles::RicochetFrame::describe(const frame* fr, FrameValues& values, int frame_no) { |
998 address bp = (address) fr->fp(); |
1000 address bp = (address) fr->fp(); |
1019 intptr_t* entry_sp, |
1021 intptr_t* entry_sp, |
1020 intptr_t* saved_sp, |
1022 intptr_t* saved_sp, |
1021 intptr_t* saved_bp) { |
1023 intptr_t* saved_bp) { |
1022 // called as a leaf from native code: do not block the JVM! |
1024 // called as a leaf from native code: do not block the JVM! |
1023 bool has_mh = (strstr(adaptername, "return/") == NULL); // return adapters don't have rcx_mh |
1025 bool has_mh = (strstr(adaptername, "return/") == NULL); // return adapters don't have rcx_mh |
|
1026 |
1024 intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset]; |
1027 intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset]; |
1025 intptr_t* base_sp = last_sp; |
1028 intptr_t* base_sp = last_sp; |
1026 typedef MethodHandles::RicochetFrame RicochetFrame; |
1029 typedef MethodHandles::RicochetFrame RicochetFrame; |
1027 RicochetFrame* rfp = (RicochetFrame*)((address)saved_bp - RicochetFrame::sender_link_offset_in_bytes()); |
1030 RicochetFrame* rfp = (RicochetFrame*)((address)saved_bp - RicochetFrame::sender_link_offset_in_bytes()); |
1028 if (Universe::heap()->is_in((address) rfp->saved_args_base())) { |
1031 if (Universe::heap()->is_in((address) rfp->saved_args_base())) { |
1048 tty->print(" %d: "PTR_FORMAT, i, saved_regs[i]); |
1051 tty->print(" %d: "PTR_FORMAT, i, saved_regs[i]); |
1049 } |
1052 } |
1050 tty->cr(); |
1053 tty->cr(); |
1051 if (last_sp != saved_sp && last_sp != NULL) |
1054 if (last_sp != saved_sp && last_sp != NULL) |
1052 tty->print_cr("*** last_sp="PTR_FORMAT, (intptr_t)last_sp); |
1055 tty->print_cr("*** last_sp="PTR_FORMAT, (intptr_t)last_sp); |
1053 int stack_dump_count = 16; |
1056 |
1054 if (stack_dump_count < (int)(saved_bp + 2 - saved_sp)) |
1057 { |
1055 stack_dump_count = (int)(saved_bp + 2 - saved_sp); |
1058 // dumping last frame with frame::describe |
1056 if (stack_dump_count > 64) stack_dump_count = 48; |
1059 |
1057 for (i = 0; i < stack_dump_count; i += 4) { |
1060 JavaThread* p = JavaThread::active(); |
1058 tty->print_cr(" dump at SP[%d] "PTR_FORMAT": "PTR_FORMAT" "PTR_FORMAT" "PTR_FORMAT" "PTR_FORMAT, |
1061 |
1059 i, (intptr_t) &entry_sp[i+0], entry_sp[i+0], entry_sp[i+1], entry_sp[i+2], entry_sp[i+3]); |
1062 ResourceMark rm; |
|
1063 PRESERVE_EXCEPTION_MARK; // may not be needed by safer and unexpensive here |
|
1064 FrameValues values; |
|
1065 |
|
1066 // Note: We want to allow trace_method_handle from any call site. |
|
1067 // While trace_method_handle creates a frame, it may be entered |
|
1068 // without a PC on the stack top (e.g. not just after a call). |
|
1069 // Walking that frame could lead to failures due to that invalid PC. |
|
1070 // => carefully detect that frame when doing the stack walking |
|
1071 |
|
1072 // Current C frame |
|
1073 frame cur_frame = os::current_frame(); |
|
1074 |
|
1075 // Robust search of trace_calling_frame (independant of inlining). |
|
1076 // Assumes saved_regs comes from a pusha in the trace_calling_frame. |
|
1077 assert(cur_frame.sp() < saved_regs, "registers not saved on stack ?"); |
|
1078 frame trace_calling_frame = os::get_sender_for_C_frame(&cur_frame); |
|
1079 while (trace_calling_frame.fp() < saved_regs) { |
|
1080 trace_calling_frame = os::get_sender_for_C_frame(&trace_calling_frame); |
|
1081 } |
|
1082 |
|
1083 // safely create a frame and call frame::describe |
|
1084 intptr_t *dump_sp = trace_calling_frame.sender_sp(); |
|
1085 intptr_t *dump_fp = trace_calling_frame.link(); |
|
1086 |
|
1087 bool walkable = has_mh; // whether the traced frame shoud be walkable |
|
1088 |
|
1089 if (walkable) { |
|
1090 // The previous definition of walkable may have to be refined |
|
1091 // if new call sites cause the next frame constructor to start |
|
1092 // failing. Alternatively, frame constructors could be |
|
1093 // modified to support the current or future non walkable |
|
1094 // frames (but this is more intrusive and is not considered as |
|
1095 // part of this RFE, which will instead use a simpler output). |
|
1096 frame dump_frame = frame(dump_sp, dump_fp); |
|
1097 dump_frame.describe(values, 1); |
|
1098 } else { |
|
1099 // Stack may not be walkable (invalid PC above FP): |
|
1100 // Add descriptions without building a Java frame to avoid issues |
|
1101 values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>"); |
|
1102 values.describe(-1, dump_sp, "sp for #1"); |
|
1103 } |
|
1104 |
|
1105 // mark saved_sp if seems valid |
|
1106 if (has_mh) { |
|
1107 if ((saved_sp >= dump_sp - UNREASONABLE_STACK_MOVE) && (saved_sp < dump_fp)) { |
|
1108 values.describe(-1, saved_sp, "*saved_sp"); |
|
1109 } |
|
1110 } |
|
1111 |
|
1112 tty->print_cr(" stack layout:"); |
|
1113 values.print(p); |
1060 } |
1114 } |
1061 if (has_mh) |
1115 if (has_mh) |
1062 print_method_handle(mh); |
1116 print_method_handle(mh); |
1063 } |
1117 } |
1064 } |
1118 } |
1084 } |
1138 } |
1085 |
1139 |
1086 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { |
1140 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { |
1087 if (!TraceMethodHandles) return; |
1141 if (!TraceMethodHandles) return; |
1088 BLOCK_COMMENT("trace_method_handle {"); |
1142 BLOCK_COMMENT("trace_method_handle {"); |
1089 __ push(rax); |
1143 __ enter(); |
1090 __ lea(rax, Address(rsp, wordSize * NOT_LP64(6) LP64_ONLY(14))); // entry_sp __ pusha(); |
1144 __ andptr(rsp, -16); // align stack if needed for FPU state |
1091 __ pusha(); |
1145 __ pusha(); |
1092 __ mov(rbx, rsp); |
1146 __ mov(rbx, rsp); // for retreiving saved_regs |
1093 __ enter(); |
1147 // Note: saved_regs must be in the entered frame for the |
|
1148 // robust stack walking implemented in trace_method_handle_stub. |
|
1149 |
|
1150 // save FP result, valid at some call sites (adapter_opt_return_float, ...) |
|
1151 __ increment(rsp, -2 * wordSize); |
|
1152 if (UseSSE >= 2) { |
|
1153 __ movdbl(Address(rsp, 0), xmm0); |
|
1154 } else if (UseSSE == 1) { |
|
1155 __ movflt(Address(rsp, 0), xmm0); |
|
1156 } else { |
|
1157 __ fst_d(Address(rsp, 0)); |
|
1158 } |
|
1159 |
1094 // incoming state: |
1160 // incoming state: |
1095 // rcx: method handle |
1161 // rcx: method handle |
1096 // r13 or rsi: saved sp |
1162 // r13 or rsi: saved sp |
1097 // To avoid calling convention issues, build a record on the stack and pass the pointer to that instead. |
1163 // To avoid calling convention issues, build a record on the stack and pass the pointer to that instead. |
|
1164 // Note: fix the increment below if pushing more arguments |
1098 __ push(rbp); // saved_bp |
1165 __ push(rbp); // saved_bp |
1099 __ push(rsi); // saved_sp |
1166 __ push(saved_last_sp_register()); // saved_sp |
1100 __ push(rax); // entry_sp |
1167 __ push(rbp); // entry_sp (with extra align space) |
1101 __ push(rbx); // pusha saved_regs |
1168 __ push(rbx); // pusha saved_regs |
1102 __ push(rcx); // mh |
1169 __ push(rcx); // mh |
1103 __ push(rcx); // adaptername |
1170 __ push(rcx); // slot for adaptername |
1104 __ movptr(Address(rsp, 0), (intptr_t) adaptername); |
1171 __ movptr(Address(rsp, 0), (intptr_t) adaptername); |
1105 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub_wrapper), rsp); |
1172 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub_wrapper), rsp); |
|
1173 __ increment(rsp, 6 * wordSize); // MethodHandleStubArguments |
|
1174 |
|
1175 if (UseSSE >= 2) { |
|
1176 __ movdbl(xmm0, Address(rsp, 0)); |
|
1177 } else if (UseSSE == 1) { |
|
1178 __ movflt(xmm0, Address(rsp, 0)); |
|
1179 } else { |
|
1180 __ fld_d(Address(rsp, 0)); |
|
1181 } |
|
1182 __ increment(rsp, 2 * wordSize); |
|
1183 |
|
1184 __ popa(); |
1106 __ leave(); |
1185 __ leave(); |
1107 __ popa(); |
|
1108 __ pop(rax); |
|
1109 BLOCK_COMMENT("} trace_method_handle"); |
1186 BLOCK_COMMENT("} trace_method_handle"); |
1110 } |
1187 } |
1111 #endif //PRODUCT |
1188 #endif //PRODUCT |
1112 |
1189 |
1113 // which conversion op types are implemented here? |
1190 // which conversion op types are implemented here? |