src/share/vm/oops/methodData.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/oops

src/share/vm/oops/methodData.cpp

Print this page
rev 6132 : 8037970: make PrintMethodData a diagnostic options
Summary: make PrintMethodData a diagnostic options for performance investigation
Reviewed-by:


  97         ss.print("(%s) ", Deoptimization::format_trap_state(buf, sizeof(buf), trap));
  98       }
  99       break;
 100     case DataLayout::bit_data_tag:
 101       break;
 102     case DataLayout::no_tag:
 103     case DataLayout::arg_info_data_tag:
 104       return ss.as_string();
 105       break;
 106     default:
 107       fatal(err_msg("unexpected tag %d", dp->tag()));
 108     }
 109   }
 110   return NULL;
 111 }
 112 
 113 void ProfileData::print_data_on(outputStream* st, const MethodData* md) const {
 114   print_data_on(st, print_data_on_helper(md));
 115 }
 116 
 117 #ifndef PRODUCT
 118 void ProfileData::print_shared(outputStream* st, const char* name, const char* extra) const {
 119   st->print("bci: %d", bci());
 120   st->fill_to(tab_width_one);
 121   st->print("%s", name);
 122   tab(st);
 123   int trap = trap_state();
 124   if (trap != 0) {
 125     char buf[100];
 126     st->print("trap(%s) ", Deoptimization::format_trap_state(buf, sizeof(buf), trap));
 127   }
 128   if (extra != NULL) {
 129     st->print(extra);
 130   }
 131   int flags = data()->flags();
 132   if (flags != 0) {
 133     st->print("flags(%d) ", flags);
 134   }
 135 }
 136 
 137 void ProfileData::tab(outputStream* st, bool first) const {
 138   st->fill_to(first ? tab_width_one : tab_width_two);
 139 }
 140 #endif // !PRODUCT
 141 
 142 // ==================================================================
 143 // BitData
 144 //
 145 // A BitData corresponds to a one-bit flag.  This is used to indicate
 146 // whether a checkcast bytecode has seen a null value.
 147 
 148 
 149 #ifndef PRODUCT
 150 void BitData::print_data_on(outputStream* st, const char* extra) const {
 151   print_shared(st, "BitData", extra);
 152 }
 153 #endif // !PRODUCT
 154 
 155 // ==================================================================
 156 // CounterData
 157 //
 158 // A CounterData corresponds to a simple counter.
 159 
 160 #ifndef PRODUCT
 161 void CounterData::print_data_on(outputStream* st, const char* extra) const {
 162   print_shared(st, "CounterData", extra);
 163   st->print_cr("count(%u)", count());
 164 }
 165 #endif // !PRODUCT
 166 
 167 // ==================================================================
 168 // JumpData
 169 //
 170 // A JumpData is used to access profiling information for a direct
 171 // branch.  It is a counter, used for counting the number of branches,
 172 // plus a data displacement, used for realigning the data pointer to
 173 // the corresponding target bci.
 174 
 175 void JumpData::post_initialize(BytecodeStream* stream, MethodData* mdo) {
 176   assert(stream->bci() == bci(), "wrong pos");
 177   int target;
 178   Bytecodes::Code c = stream->code();
 179   if (c == Bytecodes::_goto_w || c == Bytecodes::_jsr_w) {
 180     target = stream->dest_w();
 181   } else {
 182     target = stream->dest();
 183   }
 184   int my_di = mdo->dp_to_di(dp());
 185   int target_di = mdo->bci_to_di(target);
 186   int offset = target_di - my_di;
 187   set_displacement(offset);
 188 }
 189 
 190 #ifndef PRODUCT
 191 void JumpData::print_data_on(outputStream* st, const char* extra) const {
 192   print_shared(st, "JumpData", extra);
 193   st->print_cr("taken(%u) displacement(%d)", taken(), displacement());
 194 }
 195 #endif // !PRODUCT
 196 
 197 int TypeStackSlotEntries::compute_cell_count(Symbol* signature, bool include_receiver, int max) {
 198   // Parameter profiling include the receiver
 199   int args_count = include_receiver ? 1 : 0;
 200   ResourceMark rm;
 201   SignatureStream ss(signature);
 202   args_count += ss.reference_parameter_count();
 203   args_count = MIN2(args_count, max);
 204   return args_count * per_arg_cell_count;
 205 }
 206 
 207 int TypeEntriesAtCall::compute_cell_count(BytecodeStream* stream) {
 208   assert(Bytecodes::is_invoke(stream->code()), "should be invoke");
 209   assert(TypeStackSlotEntries::per_arg_count() > ReturnTypeEntry::static_cell_count(), "code to test for arguments/results broken");
 210   Bytecode_invoke inv(stream->method(), stream->bci());
 211   int args_cell = 0;
 212   if (arguments_profiling_enabled()) {
 213     args_cell = TypeStackSlotEntries::compute_cell_count(inv.signature(), false, TypeProfileArgsLimit);
 214   }
 215   int ret_cell = 0;


 324       set_type(i, with_status((Klass*)NULL, p));
 325     }
 326   }
 327 }
 328 
 329 void ReturnTypeEntry::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
 330   intptr_t p = type();
 331   if (!is_loader_alive(is_alive_cl, p)) {
 332     set_type(with_status((Klass*)NULL, p));
 333   }
 334 }
 335 
 336 bool TypeEntriesAtCall::return_profiling_enabled() {
 337   return MethodData::profile_return();
 338 }
 339 
 340 bool TypeEntriesAtCall::arguments_profiling_enabled() {
 341   return MethodData::profile_arguments();
 342 }
 343 
 344 #ifndef PRODUCT
 345 void TypeEntries::print_klass(outputStream* st, intptr_t k) {
 346   if (is_type_none(k)) {
 347     st->print("none");
 348   } else if (is_type_unknown(k)) {
 349     st->print("unknown");
 350   } else {
 351     valid_klass(k)->print_value_on(st);
 352   }
 353   if (was_null_seen(k)) {
 354     st->print(" (null seen)");
 355   }
 356 }
 357 
 358 void TypeStackSlotEntries::print_data_on(outputStream* st) const {
 359   for (int i = 0; i < _number_of_entries; i++) {
 360     _pd->tab(st);
 361     st->print("%d: stack(%u) ", i, stack_slot(i));
 362     print_klass(st, type(i));
 363     st->cr();
 364   }


 380   if (has_return()) {
 381     tab(st, true);
 382     st->print("return type");
 383     _ret.print_data_on(st);
 384   }
 385 }
 386 
 387 void VirtualCallTypeData::print_data_on(outputStream* st, const char* extra) const {
 388   VirtualCallData::print_data_on(st, extra);
 389   if (has_arguments()) {
 390     tab(st, true);
 391     st->print("argument types");
 392     _args.print_data_on(st);
 393   }
 394   if (has_return()) {
 395     tab(st, true);
 396     st->print("return type");
 397     _ret.print_data_on(st);
 398   }
 399 }
 400 #endif
 401 
 402 // ==================================================================
 403 // ReceiverTypeData
 404 //
 405 // A ReceiverTypeData is used to access profiling information about a
 406 // dynamic type check.  It consists of a counter which counts the total times
 407 // that the check is reached, and a series of (Klass*, count) pairs
 408 // which are used to store a type profile for the receiver of the check.
 409 
 410 void ReceiverTypeData::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
 411     for (uint row = 0; row < row_limit(); row++) {
 412     Klass* p = receiver(row);
 413     if (p != NULL && !p->is_loader_alive(is_alive_cl)) {
 414       clear_row(row);
 415     }
 416   }
 417 }
 418 
 419 #ifndef PRODUCT
 420 void ReceiverTypeData::print_receiver_data_on(outputStream* st) const {
 421   uint row;
 422   int entries = 0;
 423   for (row = 0; row < row_limit(); row++) {
 424     if (receiver(row) != NULL)  entries++;
 425   }
 426   st->print_cr("count(%u) entries(%u)", count(), entries);
 427   int total = count();
 428   for (row = 0; row < row_limit(); row++) {
 429     if (receiver(row) != NULL) {
 430       total += receiver_count(row);
 431     }
 432   }
 433   for (row = 0; row < row_limit(); row++) {
 434     if (receiver(row) != NULL) {
 435       tab(st);
 436       receiver(row)->print_value_on(st);
 437       st->print_cr("(%u %4.2f)", receiver_count(row), (float) receiver_count(row) / (float) total);
 438     }
 439   }
 440 }
 441 void ReceiverTypeData::print_data_on(outputStream* st, const char* extra) const {
 442   print_shared(st, "ReceiverTypeData", extra);
 443   print_receiver_data_on(st);
 444 }
 445 void VirtualCallData::print_data_on(outputStream* st, const char* extra) const {
 446   print_shared(st, "VirtualCallData", extra);
 447   print_receiver_data_on(st);
 448 }
 449 #endif // !PRODUCT
 450 
 451 // ==================================================================
 452 // RetData
 453 //
 454 // A RetData is used to access profiling information for a ret bytecode.
 455 // It is composed of a count of the number of times that the ret has
 456 // been executed, followed by a series of triples of the form
 457 // (bci, count, di) which count the number of times that some bci was the
 458 // target of the ret and cache a corresponding displacement.
 459 
 460 void RetData::post_initialize(BytecodeStream* stream, MethodData* mdo) {
 461   for (uint row = 0; row < row_limit(); row++) {
 462     set_bci_displacement(row, -1);
 463     set_bci(row, no_bci);
 464   }
 465   // release so other threads see a consistent state.  bci is used as
 466   // a valid flag for bci_displacement.
 467   OrderAccess::release();
 468 }
 469 


 481   // Now check to see if any of the cache slots are open.
 482   for (uint row = 0; row < row_limit(); row++) {
 483     if (bci(row) == no_bci) {
 484       set_bci_displacement(row, mdp - dp());
 485       set_bci_count(row, DataLayout::counter_increment);
 486       // Barrier to ensure displacement is written before the bci; allows
 487       // the interpreter to read displacement without fear of race condition.
 488       release_set_bci(row, return_bci);
 489       break;
 490     }
 491   }
 492   return mdp;
 493 }
 494 
 495 #ifdef CC_INTERP
 496 DataLayout* RetData::advance(MethodData *md, int bci) {
 497   return (DataLayout*) md->bci_to_dp(bci);
 498 }
 499 #endif // CC_INTERP
 500 
 501 #ifndef PRODUCT
 502 void RetData::print_data_on(outputStream* st, const char* extra) const {
 503   print_shared(st, "RetData", extra);
 504   uint row;
 505   int entries = 0;
 506   for (row = 0; row < row_limit(); row++) {
 507     if (bci(row) != no_bci)  entries++;
 508   }
 509   st->print_cr("count(%u) entries(%u)", count(), entries);
 510   for (row = 0; row < row_limit(); row++) {
 511     if (bci(row) != no_bci) {
 512       tab(st);
 513       st->print_cr("bci(%d: count(%u) displacement(%d))",
 514                    bci(row), bci_count(row), bci_displacement(row));
 515     }
 516   }
 517 }
 518 #endif // !PRODUCT
 519 
 520 // ==================================================================
 521 // BranchData
 522 //
 523 // A BranchData is used to access profiling data for a two-way branch.
 524 // It consists of taken and not_taken counts as well as a data displacement
 525 // for the taken case.
 526 
 527 void BranchData::post_initialize(BytecodeStream* stream, MethodData* mdo) {
 528   assert(stream->bci() == bci(), "wrong pos");
 529   int target = stream->dest();
 530   int my_di = mdo->dp_to_di(dp());
 531   int target_di = mdo->bci_to_di(target);
 532   int offset = target_di - my_di;
 533   set_displacement(offset);
 534 }
 535 
 536 #ifndef PRODUCT
 537 void BranchData::print_data_on(outputStream* st, const char* extra) const {
 538   print_shared(st, "BranchData", extra);
 539   st->print_cr("taken(%u) displacement(%d)",
 540                taken(), displacement());
 541   tab(st);
 542   st->print_cr("not taken(%u)", not_taken());
 543 }
 544 #endif
 545 
 546 // ==================================================================
 547 // MultiBranchData
 548 //
 549 // A MultiBranchData is used to access profiling information for
 550 // a multi-way branch (*switch bytecodes).  It consists of a series
 551 // of (count, displacement) pairs, which count the number of times each
 552 // case was taken and specify the data displacment for each branch target.
 553 
 554 int MultiBranchData::compute_cell_count(BytecodeStream* stream) {
 555   int cell_count = 0;
 556   if (stream->code() == Bytecodes::_tableswitch) {
 557     Bytecode_tableswitch sw(stream->method()(), stream->bcp());
 558     cell_count = 1 + per_case_cell_count * (1 + sw.length()); // 1 for default
 559   } else {
 560     Bytecode_lookupswitch sw(stream->method()(), stream->bcp());
 561     cell_count = 1 + per_case_cell_count * (sw.number_of_pairs() + 1); // 1 for default
 562   }
 563   return cell_count;
 564 }


 590   } else {
 591     Bytecode_lookupswitch sw(stream->method()(), stream->bcp());
 592     int npairs = sw.number_of_pairs();
 593     assert(array_len() == per_case_cell_count * (npairs + 1), "wrong len");
 594     for (int count = 0; count < npairs; count++) {
 595       LookupswitchPair pair = sw.pair_at(count);
 596       target = pair.offset() + bci();
 597       my_di = mdo->dp_to_di(dp());
 598       target_di = mdo->bci_to_di(target);
 599       offset = target_di - my_di;
 600       set_displacement_at(count, offset);
 601     }
 602     target = sw.default_offset() + bci();
 603     my_di = mdo->dp_to_di(dp());
 604     target_di = mdo->bci_to_di(target);
 605     offset = target_di - my_di;
 606     set_default_displacement(offset);
 607   }
 608 }
 609 
 610 #ifndef PRODUCT
 611 void MultiBranchData::print_data_on(outputStream* st, const char* extra) const {
 612   print_shared(st, "MultiBranchData", extra);
 613   st->print_cr("default_count(%u) displacement(%d)",
 614                default_count(), default_displacement());
 615   int cases = number_of_cases();
 616   for (int i = 0; i < cases; i++) {
 617     tab(st);
 618     st->print_cr("count(%u) displacement(%d)",
 619                  count_at(i), displacement_at(i));
 620   }
 621 }
 622 #endif
 623 
 624 #ifndef PRODUCT
 625 void ArgInfoData::print_data_on(outputStream* st, const char* extra) const {
 626   print_shared(st, "ArgInfoData", extra);
 627   int nargs = number_of_args();
 628   for (int i = 0; i < nargs; i++) {
 629     st->print("  0x%x", arg_modified(i));
 630   }
 631   st->cr();
 632 }
 633 
 634 #endif
 635 
 636 int ParametersTypeData::compute_cell_count(Method* m) {
 637   if (!MethodData::profile_parameters_for_method(m)) {
 638     return 0;
 639   }
 640   int max = TypeProfileParmsLimit == -1 ? INT_MAX : TypeProfileParmsLimit;
 641   int obj_args = TypeStackSlotEntries::compute_cell_count(m->signature(), !m->is_static(), max);
 642   if (obj_args > 0) {
 643     return obj_args + 1; // 1 cell for array len
 644   }
 645   return 0;
 646 }
 647 
 648 void ParametersTypeData::post_initialize(BytecodeStream* stream, MethodData* mdo) {
 649   _parameters.post_initialize(mdo->method()->signature(), !mdo->method()->is_static(), true);
 650 }
 651 
 652 bool ParametersTypeData::profiling_enabled() {
 653   return MethodData::profile_parameters();
 654 }
 655 
 656 #ifndef PRODUCT
 657 void ParametersTypeData::print_data_on(outputStream* st, const char* extra) const {
 658   st->print("parameter types", extra);
 659   _parameters.print_data_on(st);
 660 }
 661 
 662 void SpeculativeTrapData::print_data_on(outputStream* st, const char* extra) const {
 663   print_shared(st, "SpeculativeTrapData", extra);
 664   tab(st);
 665   method()->print_short_name(st);
 666   st->cr();
 667 }
 668 #endif
 669 
 670 // ==================================================================
 671 // MethodData*
 672 //
 673 // A MethodData* holds information which has been collected about
 674 // a method.
 675 
 676 MethodData* MethodData::allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS) {
 677   int size = MethodData::compute_allocation_size_in_words(method);
 678 
 679   return new (loader_data, size, false, MetaspaceObj::MethodDataType, THREAD)
 680     MethodData(method(), size, CHECK_NULL);
 681 }
 682 
 683 int MethodData::bytecode_cell_count(Bytecodes::Code code) {
 684 #if defined(COMPILER1) && !defined(COMPILER2)
 685   return no_profile_data;
 686 #else
 687   switch (code) {
 688   case Bytecodes::_checkcast:


1324       SpeculativeTrapData* data = new SpeculativeTrapData(dp);
1325       data->set_method(m);
1326       return data;
1327     }
1328   }
1329   return NULL;
1330 }
1331 
1332 ArgInfoData *MethodData::arg_info() {
1333   DataLayout* dp    = extra_data_base();
1334   DataLayout* end   = extra_data_limit();
1335   for (; dp < end; dp = next_extra(dp)) {
1336     if (dp->tag() == DataLayout::arg_info_data_tag)
1337       return new ArgInfoData(dp);
1338   }
1339   return NULL;
1340 }
1341 
1342 // Printing
1343 
1344 #ifndef PRODUCT
1345 
1346 void MethodData::print_on(outputStream* st) const {
1347   assert(is_methodData(), "should be method data");
1348   st->print("method data for ");
1349   method()->print_value_on(st);
1350   st->cr();
1351   print_data_on(st);
1352 }
1353 
1354 #endif //PRODUCT
1355 
1356 void MethodData::print_value_on(outputStream* st) const {
1357   assert(is_methodData(), "should be method data");
1358   st->print("method data for ");
1359   method()->print_value_on(st);
1360 }
1361 
1362 #ifndef PRODUCT
1363 void MethodData::print_data_on(outputStream* st) const {
1364   ResourceMark rm;
1365   ProfileData* data = first_data();
1366   if (_parameters_type_data_di != -1) {
1367     parameters_type_data()->print_data_on(st);
1368   }
1369   for ( ; is_valid(data); data = next_data(data)) {
1370     st->print("%d", dp_to_di(data->dp()));
1371     st->fill_to(6);
1372     data->print_data_on(st, this);
1373   }
1374   st->print_cr("--- Extra data:");
1375   DataLayout* dp    = extra_data_base();
1376   DataLayout* end   = extra_data_limit();
1377   for (;; dp = next_extra(dp)) {
1378     assert(dp < end, "moved past end of extra data");
1379     // No need for "OrderAccess::load_acquire" ops,
1380     // since the data structure is monotonic.
1381     switch(dp->tag()) {
1382     case DataLayout::no_tag:
1383       continue;
1384     case DataLayout::bit_data_tag:
1385       data = new BitData(dp);
1386       break;
1387     case DataLayout::speculative_trap_data_tag:
1388       data = new SpeculativeTrapData(dp);
1389       break;
1390     case DataLayout::arg_info_data_tag:
1391       data = new ArgInfoData(dp);
1392       dp = end; // ArgInfoData is at the end of extra data section.
1393       break;
1394     default:
1395       fatal(err_msg("unexpected tag %d", dp->tag()));
1396     }
1397     st->print("%d", dp_to_di(data->dp()));
1398     st->fill_to(6);
1399     data->print_data_on(st);
1400     if (dp >= end) return;
1401   }
1402 }
1403 #endif
1404 
1405 #if INCLUDE_SERVICES
1406 // Size Statistics
1407 void MethodData::collect_statistics(KlassSizeStats *sz) const {
1408   int n = sz->count(this);
1409   sz->_method_data_bytes += n;
1410   sz->_method_all_bytes += n;
1411   sz->_rw_bytes += n;
1412 }
1413 #endif // INCLUDE_SERVICES
1414 
1415 // Verification
1416 
1417 void MethodData::verify_on(outputStream* st) {
1418   guarantee(is_methodData(), "object must be method data");
1419   // guarantee(m->is_perm(), "should be in permspace");
1420   this->verify_data_on(st);
1421 }
1422 
1423 void MethodData::verify_data_on(outputStream* st) {




  97         ss.print("(%s) ", Deoptimization::format_trap_state(buf, sizeof(buf), trap));
  98       }
  99       break;
 100     case DataLayout::bit_data_tag:
 101       break;
 102     case DataLayout::no_tag:
 103     case DataLayout::arg_info_data_tag:
 104       return ss.as_string();
 105       break;
 106     default:
 107       fatal(err_msg("unexpected tag %d", dp->tag()));
 108     }
 109   }
 110   return NULL;
 111 }
 112 
 113 void ProfileData::print_data_on(outputStream* st, const MethodData* md) const {
 114   print_data_on(st, print_data_on_helper(md));
 115 }
 116 

 117 void ProfileData::print_shared(outputStream* st, const char* name, const char* extra) const {
 118   st->print("bci: %d", bci());
 119   st->fill_to(tab_width_one);
 120   st->print("%s", name);
 121   tab(st);
 122   int trap = trap_state();
 123   if (trap != 0) {
 124     char buf[100];
 125     st->print("trap(%s) ", Deoptimization::format_trap_state(buf, sizeof(buf), trap));
 126   }
 127   if (extra != NULL) {
 128     st->print(extra);
 129   }
 130   int flags = data()->flags();
 131   if (flags != 0) {
 132     st->print("flags(%d) ", flags);
 133   }
 134 }
 135 
 136 void ProfileData::tab(outputStream* st, bool first) const {
 137   st->fill_to(first ? tab_width_one : tab_width_two);
 138 }

 139 
 140 // ==================================================================
 141 // BitData
 142 //
 143 // A BitData corresponds to a one-bit flag.  This is used to indicate
 144 // whether a checkcast bytecode has seen a null value.
 145 
 146 

 147 void BitData::print_data_on(outputStream* st, const char* extra) const {
 148   print_shared(st, "BitData", extra);
 149 }

 150 
 151 // ==================================================================
 152 // CounterData
 153 //
 154 // A CounterData corresponds to a simple counter.
 155 

 156 void CounterData::print_data_on(outputStream* st, const char* extra) const {
 157   print_shared(st, "CounterData", extra);
 158   st->print_cr("count(%u)", count());
 159 }

 160 
 161 // ==================================================================
 162 // JumpData
 163 //
 164 // A JumpData is used to access profiling information for a direct
 165 // branch.  It is a counter, used for counting the number of branches,
 166 // plus a data displacement, used for realigning the data pointer to
 167 // the corresponding target bci.
 168 
 169 void JumpData::post_initialize(BytecodeStream* stream, MethodData* mdo) {
 170   assert(stream->bci() == bci(), "wrong pos");
 171   int target;
 172   Bytecodes::Code c = stream->code();
 173   if (c == Bytecodes::_goto_w || c == Bytecodes::_jsr_w) {
 174     target = stream->dest_w();
 175   } else {
 176     target = stream->dest();
 177   }
 178   int my_di = mdo->dp_to_di(dp());
 179   int target_di = mdo->bci_to_di(target);
 180   int offset = target_di - my_di;
 181   set_displacement(offset);
 182 }
 183 

 184 void JumpData::print_data_on(outputStream* st, const char* extra) const {
 185   print_shared(st, "JumpData", extra);
 186   st->print_cr("taken(%u) displacement(%d)", taken(), displacement());
 187 }

 188 
 189 int TypeStackSlotEntries::compute_cell_count(Symbol* signature, bool include_receiver, int max) {
 190   // Parameter profiling include the receiver
 191   int args_count = include_receiver ? 1 : 0;
 192   ResourceMark rm;
 193   SignatureStream ss(signature);
 194   args_count += ss.reference_parameter_count();
 195   args_count = MIN2(args_count, max);
 196   return args_count * per_arg_cell_count;
 197 }
 198 
 199 int TypeEntriesAtCall::compute_cell_count(BytecodeStream* stream) {
 200   assert(Bytecodes::is_invoke(stream->code()), "should be invoke");
 201   assert(TypeStackSlotEntries::per_arg_count() > ReturnTypeEntry::static_cell_count(), "code to test for arguments/results broken");
 202   Bytecode_invoke inv(stream->method(), stream->bci());
 203   int args_cell = 0;
 204   if (arguments_profiling_enabled()) {
 205     args_cell = TypeStackSlotEntries::compute_cell_count(inv.signature(), false, TypeProfileArgsLimit);
 206   }
 207   int ret_cell = 0;


 316       set_type(i, with_status((Klass*)NULL, p));
 317     }
 318   }
 319 }
 320 
 321 void ReturnTypeEntry::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
 322   intptr_t p = type();
 323   if (!is_loader_alive(is_alive_cl, p)) {
 324     set_type(with_status((Klass*)NULL, p));
 325   }
 326 }
 327 
 328 bool TypeEntriesAtCall::return_profiling_enabled() {
 329   return MethodData::profile_return();
 330 }
 331 
 332 bool TypeEntriesAtCall::arguments_profiling_enabled() {
 333   return MethodData::profile_arguments();
 334 }
 335 

 336 void TypeEntries::print_klass(outputStream* st, intptr_t k) {
 337   if (is_type_none(k)) {
 338     st->print("none");
 339   } else if (is_type_unknown(k)) {
 340     st->print("unknown");
 341   } else {
 342     valid_klass(k)->print_value_on(st);
 343   }
 344   if (was_null_seen(k)) {
 345     st->print(" (null seen)");
 346   }
 347 }
 348 
 349 void TypeStackSlotEntries::print_data_on(outputStream* st) const {
 350   for (int i = 0; i < _number_of_entries; i++) {
 351     _pd->tab(st);
 352     st->print("%d: stack(%u) ", i, stack_slot(i));
 353     print_klass(st, type(i));
 354     st->cr();
 355   }


 371   if (has_return()) {
 372     tab(st, true);
 373     st->print("return type");
 374     _ret.print_data_on(st);
 375   }
 376 }
 377 
 378 void VirtualCallTypeData::print_data_on(outputStream* st, const char* extra) const {
 379   VirtualCallData::print_data_on(st, extra);
 380   if (has_arguments()) {
 381     tab(st, true);
 382     st->print("argument types");
 383     _args.print_data_on(st);
 384   }
 385   if (has_return()) {
 386     tab(st, true);
 387     st->print("return type");
 388     _ret.print_data_on(st);
 389   }
 390 }

 391 
 392 // ==================================================================
 393 // ReceiverTypeData
 394 //
 395 // A ReceiverTypeData is used to access profiling information about a
 396 // dynamic type check.  It consists of a counter which counts the total times
 397 // that the check is reached, and a series of (Klass*, count) pairs
 398 // which are used to store a type profile for the receiver of the check.
 399 
 400 void ReceiverTypeData::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
 401     for (uint row = 0; row < row_limit(); row++) {
 402     Klass* p = receiver(row);
 403     if (p != NULL && !p->is_loader_alive(is_alive_cl)) {
 404       clear_row(row);
 405     }
 406   }
 407 }
 408 

 409 void ReceiverTypeData::print_receiver_data_on(outputStream* st) const {
 410   uint row;
 411   int entries = 0;
 412   for (row = 0; row < row_limit(); row++) {
 413     if (receiver(row) != NULL)  entries++;
 414   }
 415   st->print_cr("count(%u) entries(%u)", count(), entries);
 416   int total = count();
 417   for (row = 0; row < row_limit(); row++) {
 418     if (receiver(row) != NULL) {
 419       total += receiver_count(row);
 420     }
 421   }
 422   for (row = 0; row < row_limit(); row++) {
 423     if (receiver(row) != NULL) {
 424       tab(st);
 425       receiver(row)->print_value_on(st);
 426       st->print_cr("(%u %4.2f)", receiver_count(row), (float) receiver_count(row) / (float) total);
 427     }
 428   }
 429 }
 430 void ReceiverTypeData::print_data_on(outputStream* st, const char* extra) const {
 431   print_shared(st, "ReceiverTypeData", extra);
 432   print_receiver_data_on(st);
 433 }
 434 void VirtualCallData::print_data_on(outputStream* st, const char* extra) const {
 435   print_shared(st, "VirtualCallData", extra);
 436   print_receiver_data_on(st);
 437 }

 438 
 439 // ==================================================================
 440 // RetData
 441 //
 442 // A RetData is used to access profiling information for a ret bytecode.
 443 // It is composed of a count of the number of times that the ret has
 444 // been executed, followed by a series of triples of the form
 445 // (bci, count, di) which count the number of times that some bci was the
 446 // target of the ret and cache a corresponding displacement.
 447 
 448 void RetData::post_initialize(BytecodeStream* stream, MethodData* mdo) {
 449   for (uint row = 0; row < row_limit(); row++) {
 450     set_bci_displacement(row, -1);
 451     set_bci(row, no_bci);
 452   }
 453   // release so other threads see a consistent state.  bci is used as
 454   // a valid flag for bci_displacement.
 455   OrderAccess::release();
 456 }
 457 


 469   // Now check to see if any of the cache slots are open.
 470   for (uint row = 0; row < row_limit(); row++) {
 471     if (bci(row) == no_bci) {
 472       set_bci_displacement(row, mdp - dp());
 473       set_bci_count(row, DataLayout::counter_increment);
 474       // Barrier to ensure displacement is written before the bci; allows
 475       // the interpreter to read displacement without fear of race condition.
 476       release_set_bci(row, return_bci);
 477       break;
 478     }
 479   }
 480   return mdp;
 481 }
 482 
 483 #ifdef CC_INTERP
 484 DataLayout* RetData::advance(MethodData *md, int bci) {
 485   return (DataLayout*) md->bci_to_dp(bci);
 486 }
 487 #endif // CC_INTERP
 488 

 489 void RetData::print_data_on(outputStream* st, const char* extra) const {
 490   print_shared(st, "RetData", extra);
 491   uint row;
 492   int entries = 0;
 493   for (row = 0; row < row_limit(); row++) {
 494     if (bci(row) != no_bci)  entries++;
 495   }
 496   st->print_cr("count(%u) entries(%u)", count(), entries);
 497   for (row = 0; row < row_limit(); row++) {
 498     if (bci(row) != no_bci) {
 499       tab(st);
 500       st->print_cr("bci(%d: count(%u) displacement(%d))",
 501                    bci(row), bci_count(row), bci_displacement(row));
 502     }
 503   }
 504 }

 505 
 506 // ==================================================================
 507 // BranchData
 508 //
 509 // A BranchData is used to access profiling data for a two-way branch.
 510 // It consists of taken and not_taken counts as well as a data displacement
 511 // for the taken case.
 512 
 513 void BranchData::post_initialize(BytecodeStream* stream, MethodData* mdo) {
 514   assert(stream->bci() == bci(), "wrong pos");
 515   int target = stream->dest();
 516   int my_di = mdo->dp_to_di(dp());
 517   int target_di = mdo->bci_to_di(target);
 518   int offset = target_di - my_di;
 519   set_displacement(offset);
 520 }
 521 

 522 void BranchData::print_data_on(outputStream* st, const char* extra) const {
 523   print_shared(st, "BranchData", extra);
 524   st->print_cr("taken(%u) displacement(%d)",
 525                taken(), displacement());
 526   tab(st);
 527   st->print_cr("not taken(%u)", not_taken());
 528 }

 529 
 530 // ==================================================================
 531 // MultiBranchData
 532 //
 533 // A MultiBranchData is used to access profiling information for
 534 // a multi-way branch (*switch bytecodes).  It consists of a series
 535 // of (count, displacement) pairs, which count the number of times each
 536 // case was taken and specify the data displacment for each branch target.
 537 
 538 int MultiBranchData::compute_cell_count(BytecodeStream* stream) {
 539   int cell_count = 0;
 540   if (stream->code() == Bytecodes::_tableswitch) {
 541     Bytecode_tableswitch sw(stream->method()(), stream->bcp());
 542     cell_count = 1 + per_case_cell_count * (1 + sw.length()); // 1 for default
 543   } else {
 544     Bytecode_lookupswitch sw(stream->method()(), stream->bcp());
 545     cell_count = 1 + per_case_cell_count * (sw.number_of_pairs() + 1); // 1 for default
 546   }
 547   return cell_count;
 548 }


 574   } else {
 575     Bytecode_lookupswitch sw(stream->method()(), stream->bcp());
 576     int npairs = sw.number_of_pairs();
 577     assert(array_len() == per_case_cell_count * (npairs + 1), "wrong len");
 578     for (int count = 0; count < npairs; count++) {
 579       LookupswitchPair pair = sw.pair_at(count);
 580       target = pair.offset() + bci();
 581       my_di = mdo->dp_to_di(dp());
 582       target_di = mdo->bci_to_di(target);
 583       offset = target_di - my_di;
 584       set_displacement_at(count, offset);
 585     }
 586     target = sw.default_offset() + bci();
 587     my_di = mdo->dp_to_di(dp());
 588     target_di = mdo->bci_to_di(target);
 589     offset = target_di - my_di;
 590     set_default_displacement(offset);
 591   }
 592 }
 593 

 594 void MultiBranchData::print_data_on(outputStream* st, const char* extra) const {
 595   print_shared(st, "MultiBranchData", extra);
 596   st->print_cr("default_count(%u) displacement(%d)",
 597                default_count(), default_displacement());
 598   int cases = number_of_cases();
 599   for (int i = 0; i < cases; i++) {
 600     tab(st);
 601     st->print_cr("count(%u) displacement(%d)",
 602                  count_at(i), displacement_at(i));
 603   }
 604 }

 605 

 606 void ArgInfoData::print_data_on(outputStream* st, const char* extra) const {
 607   print_shared(st, "ArgInfoData", extra);
 608   int nargs = number_of_args();
 609   for (int i = 0; i < nargs; i++) {
 610     st->print("  0x%x", arg_modified(i));
 611   }
 612   st->cr();
 613 }
 614 


 615 int ParametersTypeData::compute_cell_count(Method* m) {
 616   if (!MethodData::profile_parameters_for_method(m)) {
 617     return 0;
 618   }
 619   int max = TypeProfileParmsLimit == -1 ? INT_MAX : TypeProfileParmsLimit;
 620   int obj_args = TypeStackSlotEntries::compute_cell_count(m->signature(), !m->is_static(), max);
 621   if (obj_args > 0) {
 622     return obj_args + 1; // 1 cell for array len
 623   }
 624   return 0;
 625 }
 626 
 627 void ParametersTypeData::post_initialize(BytecodeStream* stream, MethodData* mdo) {
 628   _parameters.post_initialize(mdo->method()->signature(), !mdo->method()->is_static(), true);
 629 }
 630 
 631 bool ParametersTypeData::profiling_enabled() {
 632   return MethodData::profile_parameters();
 633 }
 634 

 635 void ParametersTypeData::print_data_on(outputStream* st, const char* extra) const {
 636   st->print("parameter types", extra);
 637   _parameters.print_data_on(st);
 638 }
 639 
 640 void SpeculativeTrapData::print_data_on(outputStream* st, const char* extra) const {
 641   print_shared(st, "SpeculativeTrapData", extra);
 642   tab(st);
 643   method()->print_short_name(st);
 644   st->cr();
 645 }

 646 
 647 // ==================================================================
 648 // MethodData*
 649 //
 650 // A MethodData* holds information which has been collected about
 651 // a method.
 652 
 653 MethodData* MethodData::allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS) {
 654   int size = MethodData::compute_allocation_size_in_words(method);
 655 
 656   return new (loader_data, size, false, MetaspaceObj::MethodDataType, THREAD)
 657     MethodData(method(), size, CHECK_NULL);
 658 }
 659 
 660 int MethodData::bytecode_cell_count(Bytecodes::Code code) {
 661 #if defined(COMPILER1) && !defined(COMPILER2)
 662   return no_profile_data;
 663 #else
 664   switch (code) {
 665   case Bytecodes::_checkcast:


1301       SpeculativeTrapData* data = new SpeculativeTrapData(dp);
1302       data->set_method(m);
1303       return data;
1304     }
1305   }
1306   return NULL;
1307 }
1308 
1309 ArgInfoData *MethodData::arg_info() {
1310   DataLayout* dp    = extra_data_base();
1311   DataLayout* end   = extra_data_limit();
1312   for (; dp < end; dp = next_extra(dp)) {
1313     if (dp->tag() == DataLayout::arg_info_data_tag)
1314       return new ArgInfoData(dp);
1315   }
1316   return NULL;
1317 }
1318 
1319 // Printing
1320 


1321 void MethodData::print_on(outputStream* st) const {
1322   assert(is_methodData(), "should be method data");
1323   st->print("method data for ");
1324   method()->print_value_on(st);
1325   st->cr();
1326   print_data_on(st);
1327 }
1328 


1329 void MethodData::print_value_on(outputStream* st) const {
1330   assert(is_methodData(), "should be method data");
1331   st->print("method data for ");
1332   method()->print_value_on(st);
1333 }
1334 

1335 void MethodData::print_data_on(outputStream* st) const {
1336   ResourceMark rm;
1337   ProfileData* data = first_data();
1338   if (_parameters_type_data_di != -1) {
1339     parameters_type_data()->print_data_on(st);
1340   }
1341   for ( ; is_valid(data); data = next_data(data)) {
1342     st->print("%d", dp_to_di(data->dp()));
1343     st->fill_to(6);
1344     data->print_data_on(st, this);
1345   }
1346   st->print_cr("--- Extra data:");
1347   DataLayout* dp    = extra_data_base();
1348   DataLayout* end   = extra_data_limit();
1349   for (;; dp = next_extra(dp)) {
1350     assert(dp < end, "moved past end of extra data");
1351     // No need for "OrderAccess::load_acquire" ops,
1352     // since the data structure is monotonic.
1353     switch(dp->tag()) {
1354     case DataLayout::no_tag:
1355       continue;
1356     case DataLayout::bit_data_tag:
1357       data = new BitData(dp);
1358       break;
1359     case DataLayout::speculative_trap_data_tag:
1360       data = new SpeculativeTrapData(dp);
1361       break;
1362     case DataLayout::arg_info_data_tag:
1363       data = new ArgInfoData(dp);
1364       dp = end; // ArgInfoData is at the end of extra data section.
1365       break;
1366     default:
1367       fatal(err_msg("unexpected tag %d", dp->tag()));
1368     }
1369     st->print("%d", dp_to_di(data->dp()));
1370     st->fill_to(6);
1371     data->print_data_on(st);
1372     if (dp >= end) return;
1373   }
1374 }

1375 
1376 #if INCLUDE_SERVICES
1377 // Size Statistics
1378 void MethodData::collect_statistics(KlassSizeStats *sz) const {
1379   int n = sz->count(this);
1380   sz->_method_data_bytes += n;
1381   sz->_method_all_bytes += n;
1382   sz->_rw_bytes += n;
1383 }
1384 #endif // INCLUDE_SERVICES
1385 
1386 // Verification
1387 
1388 void MethodData::verify_on(outputStream* st) {
1389   guarantee(is_methodData(), "object must be method data");
1390   // guarantee(m->is_perm(), "should be in permspace");
1391   this->verify_data_on(st);
1392 }
1393 
1394 void MethodData::verify_data_on(outputStream* st) {


src/share/vm/oops/methodData.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File