1001 RicochetFrame* rf = (RicochetFrame*)(bp - sender_link_offset_in_bytes()); 1002 1003 // ricochet slots 1004 DESCRIBE_RICOCHET_OFFSET(rf, exact_sender_sp); 1005 DESCRIBE_RICOCHET_OFFSET(rf, conversion); 1006 DESCRIBE_RICOCHET_OFFSET(rf, saved_args_base); 1007 DESCRIBE_RICOCHET_OFFSET(rf, saved_args_layout); 1008 DESCRIBE_RICOCHET_OFFSET(rf, saved_target); 1009 DESCRIBE_RICOCHET_OFFSET(rf, continuation); 1010 1011 // relevant ricochet targets (in caller frame) 1012 values.describe(-1, rf->saved_args_base(), err_msg("*saved_args_base for #%d", frame_no)); 1013 } 1014 #endif // ASSERT 1015 1016 #ifndef PRODUCT 1017 extern "C" void print_method_handle(oop mh); 1018 void trace_method_handle_stub(const char* adaptername, 1019 oop mh, 1020 intptr_t* saved_regs, 1021 intptr_t* entry_sp, 1022 intptr_t* saved_sp, 1023 intptr_t* saved_bp) { 1024 // called as a leaf from native code: do not block the JVM! 1025 bool has_mh = (strstr(adaptername, "return/") == NULL); // return adapters don't have rcx_mh 1026 1027 intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset]; 1028 intptr_t* base_sp = last_sp; 1029 typedef MethodHandles::RicochetFrame RicochetFrame; 1030 RicochetFrame* rfp = (RicochetFrame*)((address)saved_bp - RicochetFrame::sender_link_offset_in_bytes()); 1031 if (Universe::heap()->is_in((address) rfp->saved_args_base())) { 1032 // Probably an interpreter frame. 1033 base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset]; 1034 } 1035 intptr_t mh_reg = (intptr_t)mh; 1036 const char* mh_reg_name = "rcx_mh"; 1037 if (!has_mh) mh_reg_name = "rcx"; 1038 tty->print_cr("MH %s %s="PTR_FORMAT" sp=("PTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="PTR_FORMAT, 1039 adaptername, mh_reg_name, mh_reg, 1040 (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp); 1041 if (Verbose) { 1042 tty->print(" reg dump: "); 1043 int saved_regs_count = (entry_sp-1) - saved_regs; 1044 // 32 bit: rdi rsi rbp rsp; rbx rdx rcx (*) rax 1045 int i; 1046 for (i = 0; i <= saved_regs_count; i++) { 1047 if (i > 0 && i % 4 == 0 && i != saved_regs_count) { 1048 tty->cr(); 1049 tty->print(" + dump: "); 1050 } 1051 tty->print(" %d: "PTR_FORMAT, i, saved_regs[i]); 1052 } 1053 tty->cr(); 1054 if (last_sp != saved_sp && last_sp != NULL) 1055 tty->print_cr("*** last_sp="PTR_FORMAT, (intptr_t)last_sp); 1056 1057 { 1058 // dumping last frame with frame::describe 1059 1060 JavaThread* p = JavaThread::active(); 1061 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). 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); 1114 } 1115 if (has_mh) 1116 print_method_handle(mh); 1117 } 1118 } 1119 1120 // The stub wraps the arguments in a struct on the stack to avoid 1121 // dealing with the different calling conventions for passing 6 1122 // arguments. 1123 struct MethodHandleStubArguments { 1124 const char* adaptername; 1125 oopDesc* mh; 1126 intptr_t* saved_regs; 1127 intptr_t* entry_sp; 1128 intptr_t* saved_sp; 1129 intptr_t* saved_bp; 1130 }; 1131 void trace_method_handle_stub_wrapper(MethodHandleStubArguments* args) { 1132 trace_method_handle_stub(args->adaptername, 1133 args->mh, 1134 args->saved_regs, 1135 args->entry_sp, 1136 args->saved_sp, 1137 args->saved_bp); 1138 } 1139 1140 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { 1141 if (!TraceMethodHandles) return; 1142 BLOCK_COMMENT("trace_method_handle {"); 1143 __ enter(); 1144 __ andptr(rsp, -16); // align stack if needed for FPU state 1145 __ pusha(); 1146 __ mov(rbx, rsp); // for retreiving saved_regs 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 1160 // incoming state: 1161 // rcx: method handle 1162 // r13 or rsi: saved sp 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 1165 __ push(rbp); // saved_bp 1166 __ push(saved_last_sp_register()); // saved_sp 1167 __ push(rbp); // entry_sp (with extra align space) 1168 __ push(rbx); // pusha saved_regs 1169 __ push(rcx); // mh 1170 __ push(rcx); // slot for adaptername 1171 __ movptr(Address(rsp, 0), (intptr_t) adaptername); 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(); 1185 __ leave(); 1186 BLOCK_COMMENT("} trace_method_handle"); 1187 } 1188 #endif //PRODUCT 1189 1190 // which conversion op types are implemented here? 1191 int MethodHandles::adapter_conversion_ops_supported_mask() { 1192 return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY) 1193 |(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW) | 1001 RicochetFrame* rf = (RicochetFrame*)(bp - sender_link_offset_in_bytes()); 1002 1003 // ricochet slots 1004 DESCRIBE_RICOCHET_OFFSET(rf, exact_sender_sp); 1005 DESCRIBE_RICOCHET_OFFSET(rf, conversion); 1006 DESCRIBE_RICOCHET_OFFSET(rf, saved_args_base); 1007 DESCRIBE_RICOCHET_OFFSET(rf, saved_args_layout); 1008 DESCRIBE_RICOCHET_OFFSET(rf, saved_target); 1009 DESCRIBE_RICOCHET_OFFSET(rf, continuation); 1010 1011 // relevant ricochet targets (in caller frame) 1012 values.describe(-1, rf->saved_args_base(), err_msg("*saved_args_base for #%d", frame_no)); 1013 } 1014 #endif // ASSERT 1015 1016 #ifndef PRODUCT 1017 extern "C" void print_method_handle(oop mh); 1018 void trace_method_handle_stub(const char* adaptername, 1019 oop mh, 1020 intptr_t* saved_regs, 1021 intptr_t* entry_sp) { 1022 // 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 1024 const char* mh_reg_name = has_mh ? "rcx_mh" : "rcx"; 1025 tty->print_cr("MH %s %s="PTR_FORMAT" sp="PTR_FORMAT, adaptername, mh_reg_name, mh, entry_sp); 1026 1027 if (Verbose) { 1028 tty->print_cr("Registers:"); 1029 const int saved_regs_count = RegisterImpl::number_of_registers; 1030 for (int i = 0; i < saved_regs_count; i++) { 1031 Register r = as_Register(i); 1032 // The registers are stored in reverse order on the stack (by pusha). 1033 tty->print("%3s=" PTR_FORMAT, r->name(), saved_regs[((saved_regs_count - 1) - i)]); 1034 if ((i + 1) % 4 == 0) { 1035 tty->cr(); 1036 } else { 1037 tty->print(", "); 1038 } 1039 } 1040 tty->cr(); 1041 1042 { 1043 // dumping last frame with frame::describe 1044 1045 JavaThread* p = JavaThread::active(); 1046 1047 ResourceMark rm; 1048 PRESERVE_EXCEPTION_MARK; // may not be needed by safer and unexpensive here 1049 FrameValues values; 1050 1051 // Note: We want to allow trace_method_handle from any call site. 1052 // While trace_method_handle creates a frame, it may be entered 1053 // without a PC on the stack top (e.g. not just after a call). 1054 // Walking that frame could lead to failures due to that invalid PC. 1055 // => carefully detect that frame when doing the stack walking 1056 1057 // Current C frame 1058 frame cur_frame = os::current_frame(); 1059 1060 // Robust search of trace_calling_frame (independant of inlining). 1070 intptr_t *dump_fp = trace_calling_frame.link(); 1071 1072 bool walkable = has_mh; // whether the traced frame shoud be walkable 1073 1074 if (walkable) { 1075 // The previous definition of walkable may have to be refined 1076 // if new call sites cause the next frame constructor to start 1077 // failing. Alternatively, frame constructors could be 1078 // modified to support the current or future non walkable 1079 // frames (but this is more intrusive and is not considered as 1080 // part of this RFE, which will instead use a simpler output). 1081 frame dump_frame = frame(dump_sp, dump_fp); 1082 dump_frame.describe(values, 1); 1083 } else { 1084 // Stack may not be walkable (invalid PC above FP): 1085 // Add descriptions without building a Java frame to avoid issues 1086 values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>"); 1087 values.describe(-1, dump_sp, "sp for #1"); 1088 } 1089 1090 tty->print_cr("Stack layout:"); 1091 values.print(p); 1092 } 1093 if (has_mh) 1094 print_method_handle(mh); 1095 } 1096 } 1097 1098 // The stub wraps the arguments in a struct on the stack to avoid 1099 // dealing with the different calling conventions for passing 6 1100 // arguments. 1101 struct MethodHandleStubArguments { 1102 const char* adaptername; 1103 oopDesc* mh; 1104 intptr_t* saved_regs; 1105 intptr_t* entry_sp; 1106 }; 1107 void trace_method_handle_stub_wrapper(MethodHandleStubArguments* args) { 1108 trace_method_handle_stub(args->adaptername, 1109 args->mh, 1110 args->saved_regs, 1111 args->entry_sp); 1112 } 1113 1114 void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) { 1115 if (!TraceMethodHandles) return; 1116 BLOCK_COMMENT("trace_method_handle {"); 1117 __ enter(); 1118 __ andptr(rsp, -16); // align stack if needed for FPU state 1119 __ pusha(); 1120 __ mov(rbx, rsp); // for retreiving saved_regs 1121 // Note: saved_regs must be in the entered frame for the 1122 // robust stack walking implemented in trace_method_handle_stub. 1123 1124 // save FP result, valid at some call sites (adapter_opt_return_float, ...) 1125 __ increment(rsp, -2 * wordSize); 1126 if (UseSSE >= 2) { 1127 __ movdbl(Address(rsp, 0), xmm0); 1128 } else if (UseSSE == 1) { 1129 __ movflt(Address(rsp, 0), xmm0); 1130 } else { 1131 __ fst_d(Address(rsp, 0)); 1132 } 1133 1134 // Incoming state: 1135 // rcx: method handle 1136 // 1137 // To avoid calling convention issues, build a record on the stack 1138 // and pass the pointer to that instead. 1139 __ push(rbp); // entry_sp (with extra align space) 1140 __ push(rbx); // pusha saved_regs 1141 __ push(rcx); // mh 1142 __ push(rcx); // slot for adaptername 1143 __ movptr(Address(rsp, 0), (intptr_t) adaptername); 1144 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub_wrapper), rsp); 1145 __ increment(rsp, sizeof(MethodHandleStubArguments)); 1146 1147 if (UseSSE >= 2) { 1148 __ movdbl(xmm0, Address(rsp, 0)); 1149 } else if (UseSSE == 1) { 1150 __ movflt(xmm0, Address(rsp, 0)); 1151 } else { 1152 __ fld_d(Address(rsp, 0)); 1153 } 1154 __ increment(rsp, 2 * wordSize); 1155 1156 __ popa(); 1157 __ leave(); 1158 BLOCK_COMMENT("} trace_method_handle"); 1159 } 1160 #endif //PRODUCT 1161 1162 // which conversion op types are implemented here? 1163 int MethodHandles::adapter_conversion_ops_supported_mask() { 1164 return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY) 1165 |(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW) |