src/share/vm/oops/methodData.cpp

changeset 5921
ce0cc25bc5e2
parent 5914
d13d7aba8c12
child 5987
5ccbab1c69f3
equal deleted inserted replaced
5920:ed2c74787eb5 5921:ce0cc25bc5e2
154 print_shared(st, "JumpData"); 154 print_shared(st, "JumpData");
155 st->print_cr("taken(%u) displacement(%d)", taken(), displacement()); 155 st->print_cr("taken(%u) displacement(%d)", taken(), displacement());
156 } 156 }
157 #endif // !PRODUCT 157 #endif // !PRODUCT
158 158
159 int TypeStackSlotEntries::compute_cell_count(BytecodeStream* stream) { 159 int TypeStackSlotEntries::compute_cell_count(Symbol* signature, int max) {
160 int max = TypeProfileArgsLimit; 160 ResourceMark rm;
161 SignatureStream ss(signature);
162 int args_count = MIN2(ss.reference_parameter_count(), max);
163 return args_count * per_arg_cell_count;
164 }
165
166 int TypeEntriesAtCall::compute_cell_count(BytecodeStream* stream) {
161 assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); 167 assert(Bytecodes::is_invoke(stream->code()), "should be invoke");
168 assert(TypeStackSlotEntries::per_arg_count() > ReturnTypeEntry::static_cell_count(), "code to test for arguments/results broken");
162 Bytecode_invoke inv(stream->method(), stream->bci()); 169 Bytecode_invoke inv(stream->method(), stream->bci());
163 170 int args_cell = 0;
164 ResourceMark rm; 171 if (arguments_profiling_enabled()) {
165 SignatureStream ss(inv.signature()); 172 args_cell = TypeStackSlotEntries::compute_cell_count(inv.signature(), TypeProfileArgsLimit);
166 int args_count = MIN2(ss.reference_parameter_count(), max); 173 }
167 174 int ret_cell = 0;
168 return args_count * per_arg_cell_count + (args_count > 0 ? header_cell_count() : 0); 175 if (return_profiling_enabled() && (inv.result_type() == T_OBJECT || inv.result_type() == T_ARRAY)) {
176 ret_cell = ReturnTypeEntry::static_cell_count();
177 }
178 int header_cell = 0;
179 if (args_cell + ret_cell > 0) {
180 header_cell = header_cell_count();
181 }
182
183 return header_cell + args_cell + ret_cell;
169 } 184 }
170 185
171 class ArgumentOffsetComputer : public SignatureInfo { 186 class ArgumentOffsetComputer : public SignatureInfo {
172 private: 187 private:
173 int _max; 188 int _max;
195 int total() { lazy_iterate_parameters(); return _size; } 210 int total() { lazy_iterate_parameters(); return _size; }
196 211
197 int off_at(int i) const { return _offsets.at(i); } 212 int off_at(int i) const { return _offsets.at(i); }
198 }; 213 };
199 214
200 void TypeStackSlotEntries::post_initialize(BytecodeStream* stream) { 215 void TypeStackSlotEntries::post_initialize(Symbol* signature, bool has_receiver) {
201 ResourceMark rm; 216 ResourceMark rm;
202 217 ArgumentOffsetComputer aos(signature, _number_of_entries);
218 aos.total();
219 for (int i = 0; i < _number_of_entries; i++) {
220 set_stack_slot(i, aos.off_at(i) + (has_receiver ? 1 : 0));
221 set_type(i, type_none());
222 }
223 }
224
225 void CallTypeData::post_initialize(BytecodeStream* stream, MethodData* mdo) {
203 assert(Bytecodes::is_invoke(stream->code()), "should be invoke"); 226 assert(Bytecodes::is_invoke(stream->code()), "should be invoke");
204 Bytecode_invoke inv(stream->method(), stream->bci()); 227 Bytecode_invoke inv(stream->method(), stream->bci());
205 228
229 SignatureStream ss(inv.signature());
230 if (has_arguments()) {
206 #ifdef ASSERT 231 #ifdef ASSERT
207 SignatureStream ss(inv.signature()); 232 ResourceMark rm;
208 int count = MIN2(ss.reference_parameter_count(), (int)TypeProfileArgsLimit); 233 int count = MIN2(ss.reference_parameter_count(), (int)TypeProfileArgsLimit);
209 assert(count > 0, "room for args type but none found?"); 234 assert(count > 0, "room for args type but none found?");
210 check_number_of_arguments(count); 235 check_number_of_arguments(count);
211 #endif 236 #endif
212 237 _args.post_initialize(inv.signature(), inv.has_receiver());
213 int start = 0; 238 }
214 ArgumentOffsetComputer aos(inv.signature(), number_of_arguments()-start); 239
215 aos.total(); 240 if (has_return()) {
216 bool has_receiver = inv.has_receiver(); 241 assert(inv.result_type() == T_OBJECT || inv.result_type() == T_ARRAY, "room for a ret type but doesn't return obj?");
217 for (int i = start; i < number_of_arguments(); i++) { 242 _ret.post_initialize();
218 set_stack_slot(i, aos.off_at(i-start) + (has_receiver ? 1 : 0)); 243 }
219 set_type(i, type_none()); 244 }
245
246 void VirtualCallTypeData::post_initialize(BytecodeStream* stream, MethodData* mdo) {
247 assert(Bytecodes::is_invoke(stream->code()), "should be invoke");
248 Bytecode_invoke inv(stream->method(), stream->bci());
249
250 if (has_arguments()) {
251 #ifdef ASSERT
252 ResourceMark rm;
253 SignatureStream ss(inv.signature());
254 int count = MIN2(ss.reference_parameter_count(), (int)TypeProfileArgsLimit);
255 assert(count > 0, "room for args type but none found?");
256 check_number_of_arguments(count);
257 #endif
258 _args.post_initialize(inv.signature(), inv.has_receiver());
259 }
260
261 if (has_return()) {
262 assert(inv.result_type() == T_OBJECT || inv.result_type() == T_ARRAY, "room for a ret type but doesn't return obj?");
263 _ret.post_initialize();
220 } 264 }
221 } 265 }
222 266
223 bool TypeEntries::is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p) { 267 bool TypeEntries::is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p) {
224 return !is_type_none(p) && 268 return !is_type_none(p) &&
225 !((Klass*)klass_part(p))->is_loader_alive(is_alive_cl); 269 !((Klass*)klass_part(p))->is_loader_alive(is_alive_cl);
226 } 270 }
227 271
228 void TypeStackSlotEntries::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) { 272 void TypeStackSlotEntries::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
229 for (int i = 0; i < number_of_arguments(); i++) { 273 for (int i = 0; i < _number_of_entries; i++) {
230 intptr_t p = type(i); 274 intptr_t p = type(i);
231 if (is_loader_alive(is_alive_cl, p)) { 275 if (is_loader_alive(is_alive_cl, p)) {
232 set_type(i, type_none()); 276 set_type(i, type_none());
233 } 277 }
234 } 278 }
235 } 279 }
236 280
237 bool TypeStackSlotEntries::arguments_profiling_enabled() { 281 void ReturnTypeEntry::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
282 intptr_t p = type();
283 if (is_loader_alive(is_alive_cl, p)) {
284 set_type(type_none());
285 }
286 }
287
288 bool TypeEntriesAtCall::return_profiling_enabled() {
289 return MethodData::profile_return();
290 }
291
292 bool TypeEntriesAtCall::arguments_profiling_enabled() {
238 return MethodData::profile_arguments(); 293 return MethodData::profile_arguments();
239 } 294 }
240 295
241 #ifndef PRODUCT 296 #ifndef PRODUCT
242 void TypeEntries::print_klass(outputStream* st, intptr_t k) { 297 void TypeEntries::print_klass(outputStream* st, intptr_t k) {
251 st->print(" (null seen)"); 306 st->print(" (null seen)");
252 } 307 }
253 } 308 }
254 309
255 void TypeStackSlotEntries::print_data_on(outputStream* st) const { 310 void TypeStackSlotEntries::print_data_on(outputStream* st) const {
256 _pd->tab(st, true); 311 for (int i = 0; i < _number_of_entries; i++) {
257 st->print("argument types");
258 for (int i = 0; i < number_of_arguments(); i++) {
259 _pd->tab(st); 312 _pd->tab(st);
260 st->print("%d: stack(%u) ", i, stack_slot(i)); 313 st->print("%d: stack(%u) ", i, stack_slot(i));
261 print_klass(st, type(i)); 314 print_klass(st, type(i));
262 st->cr(); 315 st->cr();
263 } 316 }
264 } 317 }
265 318
319 void ReturnTypeEntry::print_data_on(outputStream* st) const {
320 _pd->tab(st);
321 print_klass(st, type());
322 st->cr();
323 }
324
266 void CallTypeData::print_data_on(outputStream* st) const { 325 void CallTypeData::print_data_on(outputStream* st) const {
267 CounterData::print_data_on(st); 326 CounterData::print_data_on(st);
268 _args.print_data_on(st); 327 if (has_arguments()) {
328 tab(st, true);
329 st->print("argument types");
330 _args.print_data_on(st);
331 }
332 if (has_return()) {
333 tab(st, true);
334 st->print("return type");
335 _ret.print_data_on(st);
336 }
269 } 337 }
270 338
271 void VirtualCallTypeData::print_data_on(outputStream* st) const { 339 void VirtualCallTypeData::print_data_on(outputStream* st) const {
272 VirtualCallData::print_data_on(st); 340 VirtualCallData::print_data_on(st);
273 _args.print_data_on(st); 341 if (has_arguments()) {
342 tab(st, true);
343 st->print("argument types");
344 _args.print_data_on(st);
345 }
346 if (has_return()) {
347 tab(st, true);
348 st->print("return type");
349 _ret.print_data_on(st);
350 }
274 } 351 }
275 #endif 352 #endif
276 353
277 // ================================================================== 354 // ==================================================================
278 // ReceiverTypeData 355 // ReceiverTypeData
528 } else { 605 } else {
529 return BitData::static_cell_count(); 606 return BitData::static_cell_count();
530 } 607 }
531 case Bytecodes::_invokespecial: 608 case Bytecodes::_invokespecial:
532 case Bytecodes::_invokestatic: 609 case Bytecodes::_invokestatic:
533 if (MethodData::profile_arguments()) { 610 if (MethodData::profile_arguments() || MethodData::profile_return()) {
534 return variable_cell_count; 611 return variable_cell_count;
535 } else { 612 } else {
536 return CounterData::static_cell_count(); 613 return CounterData::static_cell_count();
537 } 614 }
538 case Bytecodes::_goto: 615 case Bytecodes::_goto:
540 case Bytecodes::_jsr: 617 case Bytecodes::_jsr:
541 case Bytecodes::_jsr_w: 618 case Bytecodes::_jsr_w:
542 return JumpData::static_cell_count(); 619 return JumpData::static_cell_count();
543 case Bytecodes::_invokevirtual: 620 case Bytecodes::_invokevirtual:
544 case Bytecodes::_invokeinterface: 621 case Bytecodes::_invokeinterface:
545 if (MethodData::profile_arguments()) { 622 if (MethodData::profile_arguments() || MethodData::profile_return()) {
546 return variable_cell_count; 623 return variable_cell_count;
547 } else { 624 } else {
548 return VirtualCallData::static_cell_count(); 625 return VirtualCallData::static_cell_count();
549 } 626 }
550 case Bytecodes::_invokedynamic: 627 case Bytecodes::_invokedynamic:
551 if (MethodData::profile_arguments()) { 628 if (MethodData::profile_arguments() || MethodData::profile_return()) {
552 return variable_cell_count; 629 return variable_cell_count;
553 } else { 630 } else {
554 return CounterData::static_cell_count(); 631 return CounterData::static_cell_count();
555 } 632 }
556 case Bytecodes::_ret: 633 case Bytecodes::_ret:
594 cell_count = MultiBranchData::compute_cell_count(stream); 671 cell_count = MultiBranchData::compute_cell_count(stream);
595 break; 672 break;
596 case Bytecodes::_invokespecial: 673 case Bytecodes::_invokespecial:
597 case Bytecodes::_invokestatic: 674 case Bytecodes::_invokestatic:
598 case Bytecodes::_invokedynamic: 675 case Bytecodes::_invokedynamic:
599 assert(MethodData::profile_arguments(), "should be collecting args profile"); 676 assert(MethodData::profile_arguments() || MethodData::profile_return(), "should be collecting args profile");
600 if (profile_arguments_for_invoke(stream->method(), stream->bci())) { 677 if (profile_arguments_for_invoke(stream->method(), stream->bci()) ||
678 profile_return_for_invoke(stream->method(), stream->bci())) {
601 cell_count = CallTypeData::compute_cell_count(stream); 679 cell_count = CallTypeData::compute_cell_count(stream);
602 } else { 680 } else {
603 cell_count = CounterData::static_cell_count(); 681 cell_count = CounterData::static_cell_count();
604 } 682 }
605 break; 683 break;
606 case Bytecodes::_invokevirtual: 684 case Bytecodes::_invokevirtual:
607 case Bytecodes::_invokeinterface: { 685 case Bytecodes::_invokeinterface: {
608 assert(MethodData::profile_arguments(), "should be collecting args profile"); 686 assert(MethodData::profile_arguments() || MethodData::profile_return(), "should be collecting args profile");
609 if (profile_arguments_for_invoke(stream->method(), stream->bci())) { 687 if (profile_arguments_for_invoke(stream->method(), stream->bci()) ||
688 profile_return_for_invoke(stream->method(), stream->bci())) {
610 cell_count = VirtualCallTypeData::compute_cell_count(stream); 689 cell_count = VirtualCallTypeData::compute_cell_count(stream);
611 } else { 690 } else {
612 cell_count = VirtualCallData::static_cell_count(); 691 cell_count = VirtualCallData::static_cell_count();
613 } 692 }
614 break; 693 break;
697 } 776 }
698 break; 777 break;
699 case Bytecodes::_invokespecial: 778 case Bytecodes::_invokespecial:
700 case Bytecodes::_invokestatic: { 779 case Bytecodes::_invokestatic: {
701 int counter_data_cell_count = CounterData::static_cell_count(); 780 int counter_data_cell_count = CounterData::static_cell_count();
702 if (profile_arguments_for_invoke(stream->method(), stream->bci())) { 781 if (profile_arguments_for_invoke(stream->method(), stream->bci()) ||
782 profile_return_for_invoke(stream->method(), stream->bci())) {
703 cell_count = CallTypeData::compute_cell_count(stream); 783 cell_count = CallTypeData::compute_cell_count(stream);
704 } else { 784 } else {
705 cell_count = counter_data_cell_count; 785 cell_count = counter_data_cell_count;
706 } 786 }
707 if (cell_count > counter_data_cell_count) { 787 if (cell_count > counter_data_cell_count) {
719 tag = DataLayout::jump_data_tag; 799 tag = DataLayout::jump_data_tag;
720 break; 800 break;
721 case Bytecodes::_invokevirtual: 801 case Bytecodes::_invokevirtual:
722 case Bytecodes::_invokeinterface: { 802 case Bytecodes::_invokeinterface: {
723 int virtual_call_data_cell_count = VirtualCallData::static_cell_count(); 803 int virtual_call_data_cell_count = VirtualCallData::static_cell_count();
724 if (profile_arguments_for_invoke(stream->method(), stream->bci())) { 804 if (profile_arguments_for_invoke(stream->method(), stream->bci()) ||
805 profile_return_for_invoke(stream->method(), stream->bci())) {
725 cell_count = VirtualCallTypeData::compute_cell_count(stream); 806 cell_count = VirtualCallTypeData::compute_cell_count(stream);
726 } else { 807 } else {
727 cell_count = virtual_call_data_cell_count; 808 cell_count = virtual_call_data_cell_count;
728 } 809 }
729 if (cell_count > virtual_call_data_cell_count) { 810 if (cell_count > virtual_call_data_cell_count) {
734 break; 815 break;
735 } 816 }
736 case Bytecodes::_invokedynamic: { 817 case Bytecodes::_invokedynamic: {
737 // %%% should make a type profile for any invokedynamic that takes a ref argument 818 // %%% should make a type profile for any invokedynamic that takes a ref argument
738 int counter_data_cell_count = CounterData::static_cell_count(); 819 int counter_data_cell_count = CounterData::static_cell_count();
739 if (profile_arguments_for_invoke(stream->method(), stream->bci())) { 820 if (profile_arguments_for_invoke(stream->method(), stream->bci()) ||
821 profile_return_for_invoke(stream->method(), stream->bci())) {
740 cell_count = CallTypeData::compute_cell_count(stream); 822 cell_count = CallTypeData::compute_cell_count(stream);
741 } else { 823 } else {
742 cell_count = counter_data_cell_count; 824 cell_count = counter_data_cell_count;
743 } 825 }
744 if (cell_count > counter_data_cell_count) { 826 if (cell_count > counter_data_cell_count) {
776 cell_count = MultiBranchData::compute_cell_count(stream); 858 cell_count = MultiBranchData::compute_cell_count(stream);
777 tag = DataLayout::multi_branch_data_tag; 859 tag = DataLayout::multi_branch_data_tag;
778 break; 860 break;
779 } 861 }
780 assert(tag == DataLayout::multi_branch_data_tag || 862 assert(tag == DataLayout::multi_branch_data_tag ||
781 (MethodData::profile_arguments() && 863 ((MethodData::profile_arguments() || MethodData::profile_return()) &&
782 (tag == DataLayout::call_type_data_tag || 864 (tag == DataLayout::call_type_data_tag ||
783 tag == DataLayout::counter_data_tag || 865 tag == DataLayout::counter_data_tag ||
784 tag == DataLayout::virtual_call_type_data_tag || 866 tag == DataLayout::virtual_call_type_data_tag ||
785 tag == DataLayout::virtual_call_data_tag)) || 867 tag == DataLayout::virtual_call_data_tag)) ||
786 cell_count == bytecode_cell_count(c), "cell counts must agree"); 868 cell_count == bytecode_cell_count(c), "cell counts must agree");
1109 Bytecode_invoke inv(m , bci); 1191 Bytecode_invoke inv(m , bci);
1110 return inv.is_invokedynamic() || inv.is_invokehandle(); 1192 return inv.is_invokedynamic() || inv.is_invokehandle();
1111 } 1193 }
1112 1194
1113 int MethodData::profile_arguments_flag() { 1195 int MethodData::profile_arguments_flag() {
1114 return TypeProfileLevel; 1196 return TypeProfileLevel % 10;
1115 } 1197 }
1116 1198
1117 bool MethodData::profile_arguments() { 1199 bool MethodData::profile_arguments() {
1118 return profile_arguments_flag() > no_type_profile && profile_arguments_flag() <= type_profile_all; 1200 return profile_arguments_flag() > no_type_profile && profile_arguments_flag() <= type_profile_all;
1119 } 1201 }
1137 1219
1138 assert(profile_arguments_jsr292_only(), "inconsistent"); 1220 assert(profile_arguments_jsr292_only(), "inconsistent");
1139 return profile_jsr292(m, bci); 1221 return profile_jsr292(m, bci);
1140 } 1222 }
1141 1223
1224 int MethodData::profile_return_flag() {
1225 return TypeProfileLevel / 10;
1226 }
1227
1228 bool MethodData::profile_return() {
1229 return profile_return_flag() > no_type_profile && profile_return_flag() <= type_profile_all;
1230 }
1231
1232 bool MethodData::profile_return_jsr292_only() {
1233 return profile_return_flag() == type_profile_jsr292;
1234 }
1235
1236 bool MethodData::profile_all_return() {
1237 return profile_return_flag() == type_profile_all;
1238 }
1239
1240 bool MethodData::profile_return_for_invoke(methodHandle m, int bci) {
1241 if (!profile_return()) {
1242 return false;
1243 }
1244
1245 if (profile_all_return()) {
1246 return true;
1247 }
1248
1249 assert(profile_return_jsr292_only(), "inconsistent");
1250 return profile_jsr292(m, bci);
1251 }

mercurial