Mercurial > hg > graal-jvmci-8
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 |