comparison src/share/vm/oops/cpCache.cpp @ 22886:fdde6a70ea85

8046246: the constantPoolCacheOopDesc::adjust_method_entries() used in RedefineClasses does not scale Summary: optimize the adjust_method_entries functions by using the orig_method_idnum() function Reviewed-by: coleenp, dcubed
author sspitsyn
date Tue, 17 Mar 2015 17:11:14 -0700
parents 367427923e39
children 157895117ad5
comparison
equal deleted inserted replaced
22885:367427923e39 22886:fdde6a70ea85
447 // RC_TRACE macro has an embedded ResourceMark 447 // RC_TRACE macro has an embedded ResourceMark
448 RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)", 448 RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)",
449 new_method->name()->as_C_string(), 449 new_method->name()->as_C_string(),
450 new_method->signature()->as_C_string())); 450 new_method->signature()->as_C_string()));
451 } 451 }
452
453 return true; 452 return true;
454 } 453 }
455 454
456 // f1() is not used with virtual entries so bail out 455 // f1() is not used with virtual entries so bail out
457 return false; 456 return false;
475 // RC_TRACE macro has an embedded ResourceMark 474 // RC_TRACE macro has an embedded ResourceMark
476 RC_TRACE(0x00400000, ("cpc entry update: %s(%s)", 475 RC_TRACE(0x00400000, ("cpc entry update: %s(%s)",
477 new_method->name()->as_C_string(), 476 new_method->name()->as_C_string(),
478 new_method->signature()->as_C_string())); 477 new_method->signature()->as_C_string()));
479 } 478 }
480
481 return true; 479 return true;
482 } 480 }
483 481
484 return false; 482 return false;
485 } 483 }
502 return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() && 500 return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() &&
503 (f1_as_method()->is_deleted() || 501 (f1_as_method()->is_deleted() ||
504 (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete()))); 502 (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete())));
505 } 503 }
506 504
507 bool ConstantPoolCacheEntry::is_interesting_method_entry(Klass* k) { 505 Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) {
508 if (!is_method_entry()) { 506 if (!is_method_entry()) {
509 // not a method entry so not interesting by default 507 // not a method entry so not interesting by default
510 return false; 508 return NULL;
511 } 509 }
512
513 Method* m = NULL; 510 Method* m = NULL;
514 if (is_vfinal()) { 511 if (is_vfinal()) {
515 // virtual and final so _f2 contains method ptr instead of vtable index 512 // virtual and final so _f2 contains method ptr instead of vtable index
516 m = f2_as_vfinal_method(); 513 m = f2_as_vfinal_method();
517 } else if (is_f1_null()) { 514 } else if (is_f1_null()) {
518 // NULL _f1 means this is a virtual entry so also not interesting 515 // NULL _f1 means this is a virtual entry so also not interesting
519 return false; 516 return NULL;
520 } else { 517 } else {
521 if (!(_f1->is_method())) { 518 if (!(_f1->is_method())) {
522 // _f1 can also contain a Klass* for an interface 519 // _f1 can also contain a Klass* for an interface
523 return false; 520 return NULL;
524 } 521 }
525 m = f1_as_method(); 522 m = f1_as_method();
526 } 523 }
527
528 assert(m != NULL && m->is_method(), "sanity check"); 524 assert(m != NULL && m->is_method(), "sanity check");
529 if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) { 525 if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) {
530 // robustness for above sanity checks or method is not in 526 // robustness for above sanity checks or method is not in
531 // the interesting class 527 // the interesting class
532 return false; 528 return NULL;
533 } 529 }
534
535 // the method is in the interesting class so the entry is interesting 530 // the method is in the interesting class so the entry is interesting
536 return true; 531 return m;
537 } 532 }
538 #endif // INCLUDE_JVMTI 533 #endif // INCLUDE_JVMTI
539 534
540 void ConstantPoolCacheEntry::print(outputStream* st, int index) const { 535 void ConstantPoolCacheEntry::print(outputStream* st, int index) const {
541 // print separator 536 // print separator
608 #if INCLUDE_JVMTI 603 #if INCLUDE_JVMTI
609 // RedefineClasses() API support: 604 // RedefineClasses() API support:
610 // If any entry of this ConstantPoolCache points to any of 605 // If any entry of this ConstantPoolCache points to any of
611 // old_methods, replace it with the corresponding new_method. 606 // old_methods, replace it with the corresponding new_method.
612 void ConstantPoolCache::adjust_method_entries(Method** old_methods, Method** new_methods, 607 void ConstantPoolCache::adjust_method_entries(Method** old_methods, Method** new_methods,
613 int methods_length, bool * trace_name_printed) { 608 int methods_length, bool * trace_name_printed) {
614 609
615 if (methods_length == 0) { 610 if (methods_length == 0) {
616 // nothing to do if there are no methods 611 // nothing to do if there are no methods
617 return; 612 return;
618 } 613 }
619 614
620 // get shorthand for the interesting class 615 // get shorthand for the interesting class
621 Klass* old_holder = old_methods[0]->method_holder(); 616 Klass* old_holder = old_methods[0]->method_holder();
622 617
623 for (int i = 0; i < length(); i++) { 618 for (int i = 0; i < length(); i++) {
624 if (!entry_at(i)->is_interesting_method_entry(old_holder)) { 619 if (entry_at(i)->get_interesting_method_entry(old_holder) == NULL) {
625 // skip uninteresting methods 620 // skip uninteresting methods
626 continue; 621 continue;
627 } 622 }
628 623
629 // The ConstantPoolCache contains entries for several different 624 // The ConstantPoolCache contains entries for several different
643 } 638 }
644 } 639 }
645 } 640 }
646 } 641 }
647 642
643 // If any entry of this ConstantPoolCache points to any of
644 // old_methods, replace it with the corresponding new_method.
645 void ConstantPoolCache::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
646 for (int i = 0; i < length(); i++) {
647 ConstantPoolCacheEntry* entry = entry_at(i);
648 Method* old_method = entry->get_interesting_method_entry(holder);
649 if (old_method == NULL || !old_method->is_old()) {
650 continue; // skip uninteresting entries
651 }
652 if (old_method->is_deleted()) {
653 // clean up entries with deleted methods
654 entry->initialize_entry(entry->constant_pool_index());
655 continue;
656 }
657 Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
658
659 assert(new_method != NULL, "method_with_idnum() should not be NULL");
660 assert(old_method != new_method, "sanity check");
661
662 entry_at(i)->adjust_method_entry(old_method, new_method, trace_name_printed);
663 }
664 }
665
648 // the constant pool cache should never contain old or obsolete methods 666 // the constant pool cache should never contain old or obsolete methods
649 bool ConstantPoolCache::check_no_old_or_obsolete_entries() { 667 bool ConstantPoolCache::check_no_old_or_obsolete_entries() {
650 for (int i = 1; i < length(); i++) { 668 for (int i = 1; i < length(); i++) {
651 if (entry_at(i)->is_interesting_method_entry(NULL) && 669 if (entry_at(i)->get_interesting_method_entry(NULL) != NULL &&
652 !entry_at(i)->check_no_old_or_obsolete_entries()) { 670 !entry_at(i)->check_no_old_or_obsolete_entries()) {
653 return false; 671 return false;
654 } 672 }
655 } 673 }
656 return true; 674 return true;
657 } 675 }
658 676
659 void ConstantPoolCache::dump_cache() { 677 void ConstantPoolCache::dump_cache() {
660 for (int i = 1; i < length(); i++) { 678 for (int i = 1; i < length(); i++) {
661 if (entry_at(i)->is_interesting_method_entry(NULL)) { 679 if (entry_at(i)->get_interesting_method_entry(NULL) != NULL) {
662 entry_at(i)->print(tty, i); 680 entry_at(i)->print(tty, i);
663 } 681 }
664 } 682 }
665 } 683 }
666 #endif // INCLUDE_JVMTI 684 #endif // INCLUDE_JVMTI