453 // RC_TRACE macro has an embedded ResourceMark |
453 // RC_TRACE macro has an embedded ResourceMark |
454 RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)", |
454 RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)", |
455 new_method->name()->as_C_string(), |
455 new_method->name()->as_C_string(), |
456 new_method->signature()->as_C_string())); |
456 new_method->signature()->as_C_string())); |
457 } |
457 } |
458 |
|
459 return true; |
458 return true; |
460 } |
459 } |
461 |
460 |
462 // f1() is not used with virtual entries so bail out |
461 // f1() is not used with virtual entries so bail out |
463 return false; |
462 return false; |
481 // RC_TRACE macro has an embedded ResourceMark |
480 // RC_TRACE macro has an embedded ResourceMark |
482 RC_TRACE(0x00400000, ("cpc entry update: %s(%s)", |
481 RC_TRACE(0x00400000, ("cpc entry update: %s(%s)", |
483 new_method->name()->as_C_string(), |
482 new_method->name()->as_C_string(), |
484 new_method->signature()->as_C_string())); |
483 new_method->signature()->as_C_string())); |
485 } |
484 } |
486 |
|
487 return true; |
485 return true; |
488 } |
486 } |
489 |
487 |
490 return false; |
488 return false; |
491 } |
489 } |
508 return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() && |
506 return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() && |
509 (f1_as_method()->is_deleted() || |
507 (f1_as_method()->is_deleted() || |
510 (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete()))); |
508 (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete()))); |
511 } |
509 } |
512 |
510 |
513 bool ConstantPoolCacheEntry::is_interesting_method_entry(Klass* k) { |
511 Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) { |
514 if (!is_method_entry()) { |
512 if (!is_method_entry()) { |
515 // not a method entry so not interesting by default |
513 // not a method entry so not interesting by default |
516 return false; |
514 return NULL; |
517 } |
515 } |
518 |
|
519 Method* m = NULL; |
516 Method* m = NULL; |
520 if (is_vfinal()) { |
517 if (is_vfinal()) { |
521 // virtual and final so _f2 contains method ptr instead of vtable index |
518 // virtual and final so _f2 contains method ptr instead of vtable index |
522 m = f2_as_vfinal_method(); |
519 m = f2_as_vfinal_method(); |
523 } else if (is_f1_null()) { |
520 } else if (is_f1_null()) { |
524 // NULL _f1 means this is a virtual entry so also not interesting |
521 // NULL _f1 means this is a virtual entry so also not interesting |
525 return false; |
522 return NULL; |
526 } else { |
523 } else { |
527 if (!(_f1->is_method())) { |
524 if (!(_f1->is_method())) { |
528 // _f1 can also contain a Klass* for an interface |
525 // _f1 can also contain a Klass* for an interface |
529 return false; |
526 return NULL; |
530 } |
527 } |
531 m = f1_as_method(); |
528 m = f1_as_method(); |
532 } |
529 } |
533 |
|
534 assert(m != NULL && m->is_method(), "sanity check"); |
530 assert(m != NULL && m->is_method(), "sanity check"); |
535 if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) { |
531 if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) { |
536 // robustness for above sanity checks or method is not in |
532 // robustness for above sanity checks or method is not in |
537 // the interesting class |
533 // the interesting class |
538 return false; |
534 return NULL; |
539 } |
535 } |
540 |
|
541 // the method is in the interesting class so the entry is interesting |
536 // the method is in the interesting class so the entry is interesting |
542 return true; |
537 return m; |
543 } |
538 } |
544 #endif // INCLUDE_JVMTI |
539 #endif // INCLUDE_JVMTI |
545 |
540 |
546 void ConstantPoolCacheEntry::print(outputStream* st, int index) const { |
541 void ConstantPoolCacheEntry::print(outputStream* st, int index) const { |
547 // print separator |
542 // print separator |
614 #if INCLUDE_JVMTI |
609 #if INCLUDE_JVMTI |
615 // RedefineClasses() API support: |
610 // RedefineClasses() API support: |
616 // If any entry of this ConstantPoolCache points to any of |
611 // If any entry of this ConstantPoolCache points to any of |
617 // old_methods, replace it with the corresponding new_method. |
612 // old_methods, replace it with the corresponding new_method. |
618 void ConstantPoolCache::adjust_method_entries(Method** old_methods, Method** new_methods, |
613 void ConstantPoolCache::adjust_method_entries(Method** old_methods, Method** new_methods, |
619 int methods_length, bool * trace_name_printed) { |
614 int methods_length, bool * trace_name_printed) { |
620 |
615 |
621 if (methods_length == 0) { |
616 if (methods_length == 0) { |
622 // nothing to do if there are no methods |
617 // nothing to do if there are no methods |
623 return; |
618 return; |
624 } |
619 } |
625 |
620 |
626 // get shorthand for the interesting class |
621 // get shorthand for the interesting class |
627 Klass* old_holder = old_methods[0]->method_holder(); |
622 Klass* old_holder = old_methods[0]->method_holder(); |
628 |
623 |
629 for (int i = 0; i < length(); i++) { |
624 for (int i = 0; i < length(); i++) { |
630 if (!entry_at(i)->is_interesting_method_entry(old_holder)) { |
625 if (entry_at(i)->get_interesting_method_entry(old_holder) == NULL) { |
631 // skip uninteresting methods |
626 // skip uninteresting methods |
632 continue; |
627 continue; |
633 } |
628 } |
634 |
629 |
635 // The ConstantPoolCache contains entries for several different |
630 // The ConstantPoolCache contains entries for several different |
649 } |
644 } |
650 } |
645 } |
651 } |
646 } |
652 } |
647 } |
653 |
648 |
|
649 // If any entry of this ConstantPoolCache points to any of |
|
650 // old_methods, replace it with the corresponding new_method. |
|
651 void ConstantPoolCache::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) { |
|
652 for (int i = 0; i < length(); i++) { |
|
653 ConstantPoolCacheEntry* entry = entry_at(i); |
|
654 Method* old_method = entry->get_interesting_method_entry(holder); |
|
655 if (old_method == NULL || !old_method->is_old()) { |
|
656 continue; // skip uninteresting entries |
|
657 } |
|
658 if (old_method->is_deleted()) { |
|
659 // clean up entries with deleted methods |
|
660 entry->initialize_entry(entry->constant_pool_index()); |
|
661 continue; |
|
662 } |
|
663 Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum()); |
|
664 |
|
665 assert(new_method != NULL, "method_with_idnum() should not be NULL"); |
|
666 assert(old_method != new_method, "sanity check"); |
|
667 |
|
668 entry_at(i)->adjust_method_entry(old_method, new_method, trace_name_printed); |
|
669 } |
|
670 } |
|
671 |
654 // the constant pool cache should never contain old or obsolete methods |
672 // the constant pool cache should never contain old or obsolete methods |
655 bool ConstantPoolCache::check_no_old_or_obsolete_entries() { |
673 bool ConstantPoolCache::check_no_old_or_obsolete_entries() { |
656 for (int i = 1; i < length(); i++) { |
674 for (int i = 1; i < length(); i++) { |
657 if (entry_at(i)->is_interesting_method_entry(NULL) && |
675 if (entry_at(i)->get_interesting_method_entry(NULL) != NULL && |
658 !entry_at(i)->check_no_old_or_obsolete_entries()) { |
676 !entry_at(i)->check_no_old_or_obsolete_entries()) { |
659 return false; |
677 return false; |
660 } |
678 } |
661 } |
679 } |
662 return true; |
680 return true; |
663 } |
681 } |
664 |
682 |
665 void ConstantPoolCache::dump_cache() { |
683 void ConstantPoolCache::dump_cache() { |
666 for (int i = 1; i < length(); i++) { |
684 for (int i = 1; i < length(); i++) { |
667 if (entry_at(i)->is_interesting_method_entry(NULL)) { |
685 if (entry_at(i)->get_interesting_method_entry(NULL) != NULL) { |
668 entry_at(i)->print(tty, i); |
686 entry_at(i)->print(tty, i); |
669 } |
687 } |
670 } |
688 } |
671 } |
689 } |
672 #endif // INCLUDE_JVMTI |
690 #endif // INCLUDE_JVMTI |