comparison src/share/vm/oops/methodData.cpp @ 12875:d13d7aba8c12

8023657: New type profiling points: arguments to call Summary: x86 interpreter and c1 type profiling for arguments at calls Reviewed-by: kvn, twisti
author roland
date Wed, 09 Oct 2013 16:32:21 +0200
parents a1ebd310d5c1
children ce0cc25bc5e2
comparison
equal deleted inserted replaced
12874:46ef27bcacb3 12875:d13d7aba8c12
54 set_cell_at(i, (intptr_t)0); 54 set_cell_at(i, (intptr_t)0);
55 } 55 }
56 if (needs_array_len(tag)) { 56 if (needs_array_len(tag)) {
57 set_cell_at(ArrayData::array_len_off_set, cell_count - 1); // -1 for header. 57 set_cell_at(ArrayData::array_len_off_set, cell_count - 1); // -1 for header.
58 } 58 }
59 if (tag == call_type_data_tag) {
60 CallTypeData::initialize(this, cell_count);
61 } else if (tag == virtual_call_type_data_tag) {
62 VirtualCallTypeData::initialize(this, cell_count);
63 }
59 } 64 }
60 65
61 void DataLayout::clean_weak_klass_links(BoolObjectClosure* cl) { 66 void DataLayout::clean_weak_klass_links(BoolObjectClosure* cl) {
62 ResourceMark m; 67 ResourceMark m;
63 data_in()->clean_weak_klass_links(cl); 68 data_in()->clean_weak_klass_links(cl);
74 ProfileData::ProfileData() { 79 ProfileData::ProfileData() {
75 _data = NULL; 80 _data = NULL;
76 } 81 }
77 82
78 #ifndef PRODUCT 83 #ifndef PRODUCT
79 void ProfileData::print_shared(outputStream* st, const char* name) { 84 void ProfileData::print_shared(outputStream* st, const char* name) const {
80 st->print("bci: %d", bci()); 85 st->print("bci: %d", bci());
81 st->fill_to(tab_width_one); 86 st->fill_to(tab_width_one);
82 st->print("%s", name); 87 st->print("%s", name);
83 tab(st); 88 tab(st);
84 int trap = trap_state(); 89 int trap = trap_state();
89 int flags = data()->flags(); 94 int flags = data()->flags();
90 if (flags != 0) 95 if (flags != 0)
91 st->print("flags(%d) ", flags); 96 st->print("flags(%d) ", flags);
92 } 97 }
93 98
94 void ProfileData::tab(outputStream* st) { 99 void ProfileData::tab(outputStream* st, bool first) const {
95 st->fill_to(tab_width_two); 100 st->fill_to(first ? tab_width_one : tab_width_two);
96 } 101 }
97 #endif // !PRODUCT 102 #endif // !PRODUCT
98 103
99 // ================================================================== 104 // ==================================================================
100 // BitData 105 // BitData
102 // A BitData corresponds to a one-bit flag. This is used to indicate 107 // A BitData corresponds to a one-bit flag. This is used to indicate
103 // whether a checkcast bytecode has seen a null value. 108 // whether a checkcast bytecode has seen a null value.
104 109
105 110
106 #ifndef PRODUCT 111 #ifndef PRODUCT
107 void BitData::print_data_on(outputStream* st) { 112 void BitData::print_data_on(outputStream* st) const {
108 print_shared(st, "BitData"); 113 print_shared(st, "BitData");
109 } 114 }
110 #endif // !PRODUCT 115 #endif // !PRODUCT
111 116
112 // ================================================================== 117 // ==================================================================
113 // CounterData 118 // CounterData
114 // 119 //
115 // A CounterData corresponds to a simple counter. 120 // A CounterData corresponds to a simple counter.
116 121
117 #ifndef PRODUCT 122 #ifndef PRODUCT
118 void CounterData::print_data_on(outputStream* st) { 123 void CounterData::print_data_on(outputStream* st) const {
119 print_shared(st, "CounterData"); 124 print_shared(st, "CounterData");
120 st->print_cr("count(%u)", count()); 125 st->print_cr("count(%u)", count());
121 } 126 }
122 #endif // !PRODUCT 127 #endif // !PRODUCT
123 128
143 int offset = target_di - my_di; 148 int offset = target_di - my_di;
144 set_displacement(offset); 149 set_displacement(offset);
145 } 150 }
146 151
147 #ifndef PRODUCT 152 #ifndef PRODUCT
148 void JumpData::print_data_on(outputStream* st) { 153 void JumpData::print_data_on(outputStream* st) const {
149 print_shared(st, "JumpData"); 154 print_shared(st, "JumpData");
150 st->print_cr("taken(%u) displacement(%d)", taken(), displacement()); 155 st->print_cr("taken(%u) displacement(%d)", taken(), displacement());
151 } 156 }
152 #endif // !PRODUCT 157 #endif // !PRODUCT
158
159 int TypeStackSlotEntries::compute_cell_count(BytecodeStream* stream) {
160 int max = TypeProfileArgsLimit;
161 assert(Bytecodes::is_invoke(stream->code()), "should be invoke");
162 Bytecode_invoke inv(stream->method(), stream->bci());
163
164 ResourceMark rm;
165 SignatureStream ss(inv.signature());
166 int args_count = MIN2(ss.reference_parameter_count(), max);
167
168 return args_count * per_arg_cell_count + (args_count > 0 ? header_cell_count() : 0);
169 }
170
171 class ArgumentOffsetComputer : public SignatureInfo {
172 private:
173 int _max;
174 GrowableArray<int> _offsets;
175
176 void set(int size, BasicType type) { _size += size; }
177 void do_object(int begin, int end) {
178 if (_offsets.length() < _max) {
179 _offsets.push(_size);
180 }
181 SignatureInfo::do_object(begin, end);
182 }
183 void do_array (int begin, int end) {
184 if (_offsets.length() < _max) {
185 _offsets.push(_size);
186 }
187 SignatureInfo::do_array(begin, end);
188 }
189
190 public:
191 ArgumentOffsetComputer(Symbol* signature, int max)
192 : SignatureInfo(signature), _max(max), _offsets(Thread::current(), max) {
193 }
194
195 int total() { lazy_iterate_parameters(); return _size; }
196
197 int off_at(int i) const { return _offsets.at(i); }
198 };
199
200 void TypeStackSlotEntries::post_initialize(BytecodeStream* stream) {
201 ResourceMark rm;
202
203 assert(Bytecodes::is_invoke(stream->code()), "should be invoke");
204 Bytecode_invoke inv(stream->method(), stream->bci());
205
206 #ifdef ASSERT
207 SignatureStream ss(inv.signature());
208 int count = MIN2(ss.reference_parameter_count(), (int)TypeProfileArgsLimit);
209 assert(count > 0, "room for args type but none found?");
210 check_number_of_arguments(count);
211 #endif
212
213 int start = 0;
214 ArgumentOffsetComputer aos(inv.signature(), number_of_arguments()-start);
215 aos.total();
216 bool has_receiver = inv.has_receiver();
217 for (int i = start; i < number_of_arguments(); i++) {
218 set_stack_slot(i, aos.off_at(i-start) + (has_receiver ? 1 : 0));
219 set_type(i, type_none());
220 }
221 }
222
223 bool TypeEntries::is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p) {
224 return !is_type_none(p) &&
225 !((Klass*)klass_part(p))->is_loader_alive(is_alive_cl);
226 }
227
228 void TypeStackSlotEntries::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
229 for (int i = 0; i < number_of_arguments(); i++) {
230 intptr_t p = type(i);
231 if (is_loader_alive(is_alive_cl, p)) {
232 set_type(i, type_none());
233 }
234 }
235 }
236
237 bool TypeStackSlotEntries::arguments_profiling_enabled() {
238 return MethodData::profile_arguments();
239 }
240
241 #ifndef PRODUCT
242 void TypeEntries::print_klass(outputStream* st, intptr_t k) {
243 if (is_type_none(k)) {
244 st->print("none");
245 } else if (is_type_unknown(k)) {
246 st->print("unknown");
247 } else {
248 valid_klass(k)->print_value_on(st);
249 }
250 if (was_null_seen(k)) {
251 st->print(" (null seen)");
252 }
253 }
254
255 void TypeStackSlotEntries::print_data_on(outputStream* st) const {
256 _pd->tab(st, true);
257 st->print("argument types");
258 for (int i = 0; i < number_of_arguments(); i++) {
259 _pd->tab(st);
260 st->print("%d: stack(%u) ", i, stack_slot(i));
261 print_klass(st, type(i));
262 st->cr();
263 }
264 }
265
266 void CallTypeData::print_data_on(outputStream* st) const {
267 CounterData::print_data_on(st);
268 _args.print_data_on(st);
269 }
270
271 void VirtualCallTypeData::print_data_on(outputStream* st) const {
272 VirtualCallData::print_data_on(st);
273 _args.print_data_on(st);
274 }
275 #endif
153 276
154 // ================================================================== 277 // ==================================================================
155 // ReceiverTypeData 278 // ReceiverTypeData
156 // 279 //
157 // A ReceiverTypeData is used to access profiling information about a 280 // A ReceiverTypeData is used to access profiling information about a
167 } 290 }
168 } 291 }
169 } 292 }
170 293
171 #ifndef PRODUCT 294 #ifndef PRODUCT
172 void ReceiverTypeData::print_receiver_data_on(outputStream* st) { 295 void ReceiverTypeData::print_receiver_data_on(outputStream* st) const {
173 uint row; 296 uint row;
174 int entries = 0; 297 int entries = 0;
175 for (row = 0; row < row_limit(); row++) { 298 for (row = 0; row < row_limit(); row++) {
176 if (receiver(row) != NULL) entries++; 299 if (receiver(row) != NULL) entries++;
177 } 300 }
188 receiver(row)->print_value_on(st); 311 receiver(row)->print_value_on(st);
189 st->print_cr("(%u %4.2f)", receiver_count(row), (float) receiver_count(row) / (float) total); 312 st->print_cr("(%u %4.2f)", receiver_count(row), (float) receiver_count(row) / (float) total);
190 } 313 }
191 } 314 }
192 } 315 }
193 void ReceiverTypeData::print_data_on(outputStream* st) { 316 void ReceiverTypeData::print_data_on(outputStream* st) const {
194 print_shared(st, "ReceiverTypeData"); 317 print_shared(st, "ReceiverTypeData");
195 print_receiver_data_on(st); 318 print_receiver_data_on(st);
196 } 319 }
197 void VirtualCallData::print_data_on(outputStream* st) { 320 void VirtualCallData::print_data_on(outputStream* st) const {
198 print_shared(st, "VirtualCallData"); 321 print_shared(st, "VirtualCallData");
199 print_receiver_data_on(st); 322 print_receiver_data_on(st);
200 } 323 }
201 #endif // !PRODUCT 324 #endif // !PRODUCT
202 325
244 return mdp; 367 return mdp;
245 } 368 }
246 369
247 370
248 #ifndef PRODUCT 371 #ifndef PRODUCT
249 void RetData::print_data_on(outputStream* st) { 372 void RetData::print_data_on(outputStream* st) const {
250 print_shared(st, "RetData"); 373 print_shared(st, "RetData");
251 uint row; 374 uint row;
252 int entries = 0; 375 int entries = 0;
253 for (row = 0; row < row_limit(); row++) { 376 for (row = 0; row < row_limit(); row++) {
254 if (bci(row) != no_bci) entries++; 377 if (bci(row) != no_bci) entries++;
279 int offset = target_di - my_di; 402 int offset = target_di - my_di;
280 set_displacement(offset); 403 set_displacement(offset);
281 } 404 }
282 405
283 #ifndef PRODUCT 406 #ifndef PRODUCT
284 void BranchData::print_data_on(outputStream* st) { 407 void BranchData::print_data_on(outputStream* st) const {
285 print_shared(st, "BranchData"); 408 print_shared(st, "BranchData");
286 st->print_cr("taken(%u) displacement(%d)", 409 st->print_cr("taken(%u) displacement(%d)",
287 taken(), displacement()); 410 taken(), displacement());
288 tab(st); 411 tab(st);
289 st->print_cr("not taken(%u)", not_taken()); 412 st->print_cr("not taken(%u)", not_taken());
353 set_default_displacement(offset); 476 set_default_displacement(offset);
354 } 477 }
355 } 478 }
356 479
357 #ifndef PRODUCT 480 #ifndef PRODUCT
358 void MultiBranchData::print_data_on(outputStream* st) { 481 void MultiBranchData::print_data_on(outputStream* st) const {
359 print_shared(st, "MultiBranchData"); 482 print_shared(st, "MultiBranchData");
360 st->print_cr("default_count(%u) displacement(%d)", 483 st->print_cr("default_count(%u) displacement(%d)",
361 default_count(), default_displacement()); 484 default_count(), default_displacement());
362 int cases = number_of_cases(); 485 int cases = number_of_cases();
363 for (int i = 0; i < cases; i++) { 486 for (int i = 0; i < cases; i++) {
367 } 490 }
368 } 491 }
369 #endif 492 #endif
370 493
371 #ifndef PRODUCT 494 #ifndef PRODUCT
372 void ArgInfoData::print_data_on(outputStream* st) { 495 void ArgInfoData::print_data_on(outputStream* st) const {
373 print_shared(st, "ArgInfoData"); 496 print_shared(st, "ArgInfoData");
374 int nargs = number_of_args(); 497 int nargs = number_of_args();
375 for (int i = 0; i < nargs; i++) { 498 for (int i = 0; i < nargs; i++) {
376 st->print(" 0x%x", arg_modified(i)); 499 st->print(" 0x%x", arg_modified(i));
377 } 500 }
405 } else { 528 } else {
406 return BitData::static_cell_count(); 529 return BitData::static_cell_count();
407 } 530 }
408 case Bytecodes::_invokespecial: 531 case Bytecodes::_invokespecial:
409 case Bytecodes::_invokestatic: 532 case Bytecodes::_invokestatic:
410 return CounterData::static_cell_count(); 533 if (MethodData::profile_arguments()) {
534 return variable_cell_count;
535 } else {
536 return CounterData::static_cell_count();
537 }
411 case Bytecodes::_goto: 538 case Bytecodes::_goto:
412 case Bytecodes::_goto_w: 539 case Bytecodes::_goto_w:
413 case Bytecodes::_jsr: 540 case Bytecodes::_jsr:
414 case Bytecodes::_jsr_w: 541 case Bytecodes::_jsr_w:
415 return JumpData::static_cell_count(); 542 return JumpData::static_cell_count();
416 case Bytecodes::_invokevirtual: 543 case Bytecodes::_invokevirtual:
417 case Bytecodes::_invokeinterface: 544 case Bytecodes::_invokeinterface:
418 return VirtualCallData::static_cell_count(); 545 if (MethodData::profile_arguments()) {
546 return variable_cell_count;
547 } else {
548 return VirtualCallData::static_cell_count();
549 }
419 case Bytecodes::_invokedynamic: 550 case Bytecodes::_invokedynamic:
420 return CounterData::static_cell_count(); 551 if (MethodData::profile_arguments()) {
552 return variable_cell_count;
553 } else {
554 return CounterData::static_cell_count();
555 }
421 case Bytecodes::_ret: 556 case Bytecodes::_ret:
422 return RetData::static_cell_count(); 557 return RetData::static_cell_count();
423 case Bytecodes::_ifeq: 558 case Bytecodes::_ifeq:
424 case Bytecodes::_ifne: 559 case Bytecodes::_ifne:
425 case Bytecodes::_iflt: 560 case Bytecodes::_iflt:
451 int cell_count = bytecode_cell_count(stream->code()); 586 int cell_count = bytecode_cell_count(stream->code());
452 if (cell_count == no_profile_data) { 587 if (cell_count == no_profile_data) {
453 return 0; 588 return 0;
454 } 589 }
455 if (cell_count == variable_cell_count) { 590 if (cell_count == variable_cell_count) {
456 cell_count = MultiBranchData::compute_cell_count(stream); 591 switch (stream->code()) {
592 case Bytecodes::_lookupswitch:
593 case Bytecodes::_tableswitch:
594 cell_count = MultiBranchData::compute_cell_count(stream);
595 break;
596 case Bytecodes::_invokespecial:
597 case Bytecodes::_invokestatic:
598 case Bytecodes::_invokedynamic:
599 assert(MethodData::profile_arguments(), "should be collecting args profile");
600 if (profile_arguments_for_invoke(stream->method(), stream->bci())) {
601 cell_count = CallTypeData::compute_cell_count(stream);
602 } else {
603 cell_count = CounterData::static_cell_count();
604 }
605 break;
606 case Bytecodes::_invokevirtual:
607 case Bytecodes::_invokeinterface: {
608 assert(MethodData::profile_arguments(), "should be collecting args profile");
609 if (profile_arguments_for_invoke(stream->method(), stream->bci())) {
610 cell_count = VirtualCallTypeData::compute_cell_count(stream);
611 } else {
612 cell_count = VirtualCallData::static_cell_count();
613 }
614 break;
615 }
616 default:
617 fatal("unexpected bytecode for var length profile data");
618 }
457 } 619 }
458 // Note: cell_count might be zero, meaning that there is just 620 // Note: cell_count might be zero, meaning that there is just
459 // a DataLayout header, with no extra cells. 621 // a DataLayout header, with no extra cells.
460 assert(cell_count >= 0, "sanity"); 622 assert(cell_count >= 0, "sanity");
461 return DataLayout::compute_size_in_bytes(cell_count); 623 return DataLayout::compute_size_in_bytes(cell_count);
497 object_size += extra_data_count * DataLayout::compute_size_in_bytes(0); 659 object_size += extra_data_count * DataLayout::compute_size_in_bytes(0);
498 660
499 // Add a cell to record information about modified arguments. 661 // Add a cell to record information about modified arguments.
500 int arg_size = method->size_of_parameters(); 662 int arg_size = method->size_of_parameters();
501 object_size += DataLayout::compute_size_in_bytes(arg_size+1); 663 object_size += DataLayout::compute_size_in_bytes(arg_size+1);
664
502 return object_size; 665 return object_size;
503 } 666 }
504 667
505 // Compute the size of the MethodData* necessary to store 668 // Compute the size of the MethodData* necessary to store
506 // profiling information about a given method. Size is in words 669 // profiling information about a given method. Size is in words
532 cell_count = BitData::static_cell_count(); 695 cell_count = BitData::static_cell_count();
533 tag = DataLayout::bit_data_tag; 696 tag = DataLayout::bit_data_tag;
534 } 697 }
535 break; 698 break;
536 case Bytecodes::_invokespecial: 699 case Bytecodes::_invokespecial:
537 case Bytecodes::_invokestatic: 700 case Bytecodes::_invokestatic: {
538 cell_count = CounterData::static_cell_count(); 701 int counter_data_cell_count = CounterData::static_cell_count();
539 tag = DataLayout::counter_data_tag; 702 if (profile_arguments_for_invoke(stream->method(), stream->bci())) {
703 cell_count = CallTypeData::compute_cell_count(stream);
704 } else {
705 cell_count = counter_data_cell_count;
706 }
707 if (cell_count > counter_data_cell_count) {
708 tag = DataLayout::call_type_data_tag;
709 } else {
710 tag = DataLayout::counter_data_tag;
711 }
540 break; 712 break;
713 }
541 case Bytecodes::_goto: 714 case Bytecodes::_goto:
542 case Bytecodes::_goto_w: 715 case Bytecodes::_goto_w:
543 case Bytecodes::_jsr: 716 case Bytecodes::_jsr:
544 case Bytecodes::_jsr_w: 717 case Bytecodes::_jsr_w:
545 cell_count = JumpData::static_cell_count(); 718 cell_count = JumpData::static_cell_count();
546 tag = DataLayout::jump_data_tag; 719 tag = DataLayout::jump_data_tag;
547 break; 720 break;
548 case Bytecodes::_invokevirtual: 721 case Bytecodes::_invokevirtual:
549 case Bytecodes::_invokeinterface: 722 case Bytecodes::_invokeinterface: {
550 cell_count = VirtualCallData::static_cell_count(); 723 int virtual_call_data_cell_count = VirtualCallData::static_cell_count();
551 tag = DataLayout::virtual_call_data_tag; 724 if (profile_arguments_for_invoke(stream->method(), stream->bci())) {
725 cell_count = VirtualCallTypeData::compute_cell_count(stream);
726 } else {
727 cell_count = virtual_call_data_cell_count;
728 }
729 if (cell_count > virtual_call_data_cell_count) {
730 tag = DataLayout::virtual_call_type_data_tag;
731 } else {
732 tag = DataLayout::virtual_call_data_tag;
733 }
552 break; 734 break;
553 case Bytecodes::_invokedynamic: 735 }
736 case Bytecodes::_invokedynamic: {
554 // %%% should make a type profile for any invokedynamic that takes a ref argument 737 // %%% should make a type profile for any invokedynamic that takes a ref argument
555 cell_count = CounterData::static_cell_count(); 738 int counter_data_cell_count = CounterData::static_cell_count();
556 tag = DataLayout::counter_data_tag; 739 if (profile_arguments_for_invoke(stream->method(), stream->bci())) {
740 cell_count = CallTypeData::compute_cell_count(stream);
741 } else {
742 cell_count = counter_data_cell_count;
743 }
744 if (cell_count > counter_data_cell_count) {
745 tag = DataLayout::call_type_data_tag;
746 } else {
747 tag = DataLayout::counter_data_tag;
748 }
557 break; 749 break;
750 }
558 case Bytecodes::_ret: 751 case Bytecodes::_ret:
559 cell_count = RetData::static_cell_count(); 752 cell_count = RetData::static_cell_count();
560 tag = DataLayout::ret_data_tag; 753 tag = DataLayout::ret_data_tag;
561 break; 754 break;
562 case Bytecodes::_ifeq: 755 case Bytecodes::_ifeq:
583 cell_count = MultiBranchData::compute_cell_count(stream); 776 cell_count = MultiBranchData::compute_cell_count(stream);
584 tag = DataLayout::multi_branch_data_tag; 777 tag = DataLayout::multi_branch_data_tag;
585 break; 778 break;
586 } 779 }
587 assert(tag == DataLayout::multi_branch_data_tag || 780 assert(tag == DataLayout::multi_branch_data_tag ||
781 (MethodData::profile_arguments() &&
782 (tag == DataLayout::call_type_data_tag ||
783 tag == DataLayout::counter_data_tag ||
784 tag == DataLayout::virtual_call_type_data_tag ||
785 tag == DataLayout::virtual_call_data_tag)) ||
588 cell_count == bytecode_cell_count(c), "cell counts must agree"); 786 cell_count == bytecode_cell_count(c), "cell counts must agree");
589 if (cell_count >= 0) { 787 if (cell_count >= 0) {
590 assert(tag != DataLayout::no_tag, "bad tag"); 788 assert(tag != DataLayout::no_tag, "bad tag");
591 assert(bytecode_has_profile(c), "agree w/ BHP"); 789 assert(bytecode_has_profile(c), "agree w/ BHP");
592 data_layout->initialize(tag, stream->bci(), cell_count); 790 data_layout->initialize(tag, stream->bci(), cell_count);
629 return new BranchData(this); 827 return new BranchData(this);
630 case DataLayout::multi_branch_data_tag: 828 case DataLayout::multi_branch_data_tag:
631 return new MultiBranchData(this); 829 return new MultiBranchData(this);
632 case DataLayout::arg_info_data_tag: 830 case DataLayout::arg_info_data_tag:
633 return new ArgInfoData(this); 831 return new ArgInfoData(this);
832 case DataLayout::call_type_data_tag:
833 return new CallTypeData(this);
834 case DataLayout::virtual_call_type_data_tag:
835 return new VirtualCallTypeData(this);
634 }; 836 };
635 } 837 }
636 838
637 // Iteration over data. 839 // Iteration over data.
638 ProfileData* MethodData::next_data(ProfileData* current) const { 840 ProfileData* MethodData::next_data(ProfileData* current) const {
896 1098
897 void MethodData::verify_data_on(outputStream* st) { 1099 void MethodData::verify_data_on(outputStream* st) {
898 NEEDS_CLEANUP; 1100 NEEDS_CLEANUP;
899 // not yet implemented. 1101 // not yet implemented.
900 } 1102 }
1103
1104 bool MethodData::profile_jsr292(methodHandle m, int bci) {
1105 if (m->is_compiled_lambda_form()) {
1106 return true;
1107 }
1108
1109 Bytecode_invoke inv(m , bci);
1110 return inv.is_invokedynamic() || inv.is_invokehandle();
1111 }
1112
1113 int MethodData::profile_arguments_flag() {
1114 return TypeProfileLevel;
1115 }
1116
1117 bool MethodData::profile_arguments() {
1118 return profile_arguments_flag() > no_type_profile && profile_arguments_flag() <= type_profile_all;
1119 }
1120
1121 bool MethodData::profile_arguments_jsr292_only() {
1122 return profile_arguments_flag() == type_profile_jsr292;
1123 }
1124
1125 bool MethodData::profile_all_arguments() {
1126 return profile_arguments_flag() == type_profile_all;
1127 }
1128
1129 bool MethodData::profile_arguments_for_invoke(methodHandle m, int bci) {
1130 if (!profile_arguments()) {
1131 return false;
1132 }
1133
1134 if (profile_all_arguments()) {
1135 return true;
1136 }
1137
1138 assert(profile_arguments_jsr292_only(), "inconsistent");
1139 return profile_jsr292(m, bci);
1140 }
1141