src/cpu/x86/vm/interp_masm_x86_64.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/cpu/x86/vm

src/cpu/x86/vm/interp_masm_x86_64.cpp

Print this page
rev 5400 : 8023657: New type profiling points: arguments to call
Summary: x86 interpreter and c1 type profiling for arguments at calls
Reviewed-by: kvn, twisti
rev 5401 : 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:


1103   xorptr(obj, mdo_addr);
1104   testptr(obj, TypeEntries::type_klass_mask);
1105   jccb(Assembler::zero, next);
1106 
1107   // different than before. Cannot keep accurate profile.
1108   orptr(mdo_addr, TypeEntries::type_unknown);
1109   jmpb(next);
1110 
1111   bind(none);
1112   // first time here. Set profile type.
1113   movptr(mdo_addr, obj);
1114 
1115   bind(next);
1116 }
1117 
1118 void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) {
1119   if (!ProfileInterpreter) {
1120     return;
1121   }
1122 
1123   if (MethodData::profile_arguments()) {
1124     Label profile_continue;
1125 
1126     test_method_data_pointer(mdp, profile_continue);
1127 
1128     int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size());
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);
1131     jcc(Assembler::notEqual, profile_continue);
1132 

1133     Label done;
1134     int off_to_args = in_bytes(TypeStackSlotEntries::args_data_offset());
1135     addptr(mdp, off_to_args);
1136 
1137     for (int i = 0; i < TypeProfileArgsLimit; i++) {
1138       if (i > 0) {
1139         movq(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::cell_count_offset())-off_to_args));

1140         subl(tmp, i*TypeStackSlotEntries::per_arg_count());
1141         cmpl(tmp, TypeStackSlotEntries::per_arg_count());
1142         jcc(Assembler::less, done);
1143       }
1144       movptr(tmp, Address(callee, Method::const_offset()));
1145       load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset()));
1146       subq(tmp, Address(mdp, in_bytes(TypeStackSlotEntries::stack_slot_offset(i))-off_to_args));
1147       subl(tmp, 1);
1148       Address arg_addr = argument_address(tmp);
1149       movptr(tmp, arg_addr);
1150 
1151       Address mdo_arg_addr(mdp, in_bytes(TypeStackSlotEntries::type_offset(i))-off_to_args);
1152       profile_obj_type(tmp, mdo_arg_addr);
1153 
1154       int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
1155       addptr(mdp, to_add);
1156       off_to_args += to_add;
1157     }
1158 





1159     bind(done);
1160 









1161     movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp);






















1162 
1163     bind(profile_continue);
1164   }
1165 }
1166 
1167 void InterpreterMacroAssembler::profile_call(Register mdp) {
1168   if (ProfileInterpreter) {
1169     Label profile_continue;
1170 
1171     // If no method data exists, go to profile_continue.
1172     test_method_data_pointer(mdp, profile_continue);
1173 
1174     // We are making a call.  Increment the count.
1175     increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1176 
1177     // The method data pointer needs to be updated to reflect the new target.
1178     update_mdp_by_constant(mdp, in_bytes(CounterData::counter_data_size()));
1179     bind(profile_continue);
1180   }
1181 }




1103   xorptr(obj, mdo_addr);
1104   testptr(obj, TypeEntries::type_klass_mask);
1105   jccb(Assembler::zero, next);
1106 
1107   // different than before. Cannot keep accurate profile.
1108   orptr(mdo_addr, TypeEntries::type_unknown);
1109   jmpb(next);
1110 
1111   bind(none);
1112   // first time here. Set profile type.
1113   movptr(mdo_addr, obj);
1114 
1115   bind(next);
1116 }
1117 
1118 void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) {
1119   if (!ProfileInterpreter) {
1120     return;
1121   }
1122 
1123   if (MethodData::profile_arguments() || MethodData::profile_return()) {
1124     Label profile_continue;
1125 
1126     test_method_data_pointer(mdp, profile_continue);
1127 
1128     int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size());
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);
1131     jcc(Assembler::notEqual, profile_continue);
1132 
1133     if (MethodData::profile_arguments()) {
1134       Label done;
1135       int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset());
1136       addptr(mdp, off_to_args);
1137 
1138       for (int i = 0; i < TypeProfileArgsLimit; i++) {
1139         if (i > 0 || MethodData::profile_return()) {
1140           // If return value type is profiled we may have no argument to profile
1141           movq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
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;
1159       }
1160 
1161       if (MethodData::profile_return()) {
1162         movq(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
1163         subl(tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());
1164       }
1165 
1166       bind(done);
1167 
1168       if (MethodData::profile_return()) {
1169         // We're right after the type profile for the last
1170         // argument. tmp is the number of cell left in the
1171         // CallTypeData/VirtualCallTypeData to reach its end. Non null
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()));
1181     }
1182 
1183     // mdp points right after the end of the
1184     // CallTypeData/VirtualCallTypeData, right after the cells for the
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   if (ProfileInterpreter && MethodData::profile_return()) {
1193     Label profile_continue, done;
1194 
1195     test_method_data_pointer(mdp, profile_continue);
1196 
1197     Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size()));
1198     mov(tmp, ret);
1199     profile_obj_type(tmp, mdo_ret_addr);
1200 
1201     bind(profile_continue);
1202   }
1203 }
1204 
1205 void InterpreterMacroAssembler::profile_call(Register mdp) {
1206   if (ProfileInterpreter) {
1207     Label profile_continue;
1208 
1209     // If no method data exists, go to profile_continue.
1210     test_method_data_pointer(mdp, profile_continue);
1211 
1212     // We are making a call.  Increment the count.
1213     increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
1214 
1215     // The method data pointer needs to be updated to reflect the new target.
1216     update_mdp_by_constant(mdp, in_bytes(CounterData::counter_data_size()));
1217     bind(profile_continue);
1218   }
1219 }


src/cpu/x86/vm/interp_masm_x86_64.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File