Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/interp_masm_x86_64.cpp @ 12882:ce0cc25bc5e2
8026054: New type profiling points: type of return values at calls
Summary: x86 interpreter and c1 type profiling for return values at calls
Reviewed-by: kvn, twisti
author | roland |
---|---|
date | Sat, 12 Oct 2013 12:12:59 +0200 |
parents | d13d7aba8c12 |
children | 5ccbab1c69f3 |
comparison
equal
deleted
inserted
replaced
12881:ed2c74787eb5 | 12882:ce0cc25bc5e2 |
---|---|
1118 void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) { | 1118 void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) { |
1119 if (!ProfileInterpreter) { | 1119 if (!ProfileInterpreter) { |
1120 return; | 1120 return; |
1121 } | 1121 } |
1122 | 1122 |
1123 if (MethodData::profile_arguments()) { | 1123 if (MethodData::profile_arguments() || MethodData::profile_return()) { |
1124 Label profile_continue; | 1124 Label profile_continue; |
1125 | 1125 |
1126 test_method_data_pointer(mdp, profile_continue); | 1126 test_method_data_pointer(mdp, profile_continue); |
1127 | 1127 |
1128 int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size()); | 1128 int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size()); |
1129 | 1129 |
1130 cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag); | 1130 cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag); |
1131 jcc(Assembler::notEqual, profile_continue); | 1131 jcc(Assembler::notEqual, profile_continue); |
1132 | 1132 |
1133 Label done; | 1133 if (MethodData::profile_arguments()) { |
1134 int off_to_args = in_bytes(TypeStackSlotEntries::args_data_offset()); | 1134 Label done; |
1135 addptr(mdp, off_to_args); | 1135 int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset()); |
1136 | 1136 addptr(mdp, off_to_args); |
1137 for (int i = 0; i < TypeProfileArgsLimit; i++) { | 1137 |
1138 if (i > 0) { | 1138 for (int i = 0; i < TypeProfileArgsLimit; i++) { |
1139 movq(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::cell_count_offset())-off_to_args)); | 1139 if (i > 0 || MethodData::profile_return()) { |
1140 subl(tmp, i*TypeStackSlotEntries::per_arg_count()); | 1140 // If return value type is profiled we may have no argument to profile |
1141 cmpl(tmp, TypeStackSlotEntries::per_arg_count()); | 1141 movq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args)); |
1142 jcc(Assembler::less, done); | 1142 subl(tmp, i*TypeStackSlotEntries::per_arg_count()); |
1143 cmpl(tmp, TypeStackSlotEntries::per_arg_count()); | |
1144 jcc(Assembler::less, done); | |
1145 } | |
1146 movptr(tmp, Address(callee, Method::const_offset())); | |
1147 load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset())); | |
1148 subq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args)); | |
1149 subl(tmp, 1); | |
1150 Address arg_addr = argument_address(tmp); | |
1151 movptr(tmp, arg_addr); | |
1152 | |
1153 Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args); | |
1154 profile_obj_type(tmp, mdo_arg_addr); | |
1155 | |
1156 int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); | |
1157 addptr(mdp, to_add); | |
1158 off_to_args += to_add; | |
1143 } | 1159 } |
1144 movptr(tmp, Address(callee, Method::const_offset())); | 1160 |
1145 load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset())); | 1161 if (MethodData::profile_return()) { |
1146 subq(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::stack_slot_offset(i))-off_to_args)); | 1162 movq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args)); |
1147 subl(tmp, 1); | 1163 subl(tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count()); |
1148 Address arg_addr = argument_address(tmp); | 1164 } |
1149 movptr(tmp, arg_addr); | 1165 |
1150 | 1166 bind(done); |
1151 Address mdo_arg_addr(mdp, in_bytes(TypeStackSlotEntries::type_offset(i))-off_to_args); | 1167 |
1152 profile_obj_type(tmp, mdo_arg_addr); | 1168 if (MethodData::profile_return()) { |
1153 | 1169 // We're right after the type profile for the last |
1154 int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); | 1170 // argument. tmp is the number of cell left in the |
1155 addptr(mdp, to_add); | 1171 // CallTypeData/VirtualCallTypeData to reach its end. Non null |
1156 off_to_args += to_add; | 1172 // if there's a return to profile. |
1173 assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type"); | |
1174 shll(tmp, exact_log2(DataLayout::cell_size)); | |
1175 addptr(mdp, tmp); | |
1176 } | |
1177 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp); | |
1178 } else { | |
1179 assert(MethodData::profile_return(), "either profile call args or call ret"); | |
1180 update_mdp_by_constant(mdp, in_bytes(ReturnTypeEntry::size())); | |
1157 } | 1181 } |
1158 | 1182 |
1159 bind(done); | 1183 // mdp points right after the end of the |
1160 | 1184 // CallTypeData/VirtualCallTypeData, right after the cells for the |
1161 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp); | 1185 // return value type if there's one |
1186 | |
1187 bind(profile_continue); | |
1188 } | |
1189 } | |
1190 | |
1191 void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) { | |
1192 assert_different_registers(mdp, ret, tmp, r13); | |
1193 if (ProfileInterpreter && MethodData::profile_return()) { | |
1194 Label profile_continue, done; | |
1195 | |
1196 test_method_data_pointer(mdp, profile_continue); | |
1197 | |
1198 if (MethodData::profile_return_jsr292_only()) { | |
1199 // If we don't profile all invoke bytecodes we must make sure | |
1200 // it's a bytecode we indeed profile. We can't go back to the | |
1201 // begining of the ProfileData we intend to update to check its | |
1202 // type because we're right after it and we don't known its | |
1203 // length | |
1204 Label do_profile; | |
1205 cmpb(Address(r13, 0), Bytecodes::_invokedynamic); | |
1206 jcc(Assembler::equal, do_profile); | |
1207 cmpb(Address(r13, 0), Bytecodes::_invokehandle); | |
1208 jcc(Assembler::equal, do_profile); | |
1209 get_method(tmp); | |
1210 cmpb(Address(tmp, Method::intrinsic_id_offset_in_bytes()), vmIntrinsics::_compiledLambdaForm); | |
1211 jcc(Assembler::notEqual, profile_continue); | |
1212 | |
1213 bind(do_profile); | |
1214 } | |
1215 | |
1216 Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size())); | |
1217 mov(tmp, ret); | |
1218 profile_obj_type(tmp, mdo_ret_addr); | |
1162 | 1219 |
1163 bind(profile_continue); | 1220 bind(profile_continue); |
1164 } | 1221 } |
1165 } | 1222 } |
1166 | 1223 |