1 /*
2 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
558 _f1 = new_method;
559 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
560 if (!(*trace_name_printed)) {
561 // RC_TRACE_MESG macro has an embedded ResourceMark
562 RC_TRACE_MESG(("adjust: name=%s",
563 Klass::cast(old_method->method_holder())->external_name()));
564 *trace_name_printed = true;
565 }
566 // RC_TRACE macro has an embedded ResourceMark
567 RC_TRACE(0x00400000, ("cpc entry update: %s(%s)",
568 new_method->name()->as_C_string(),
569 new_method->signature()->as_C_string()));
570 }
571
572 return true;
573 }
574
575 return false;
576 }
577
578 bool ConstantPoolCacheEntry::is_interesting_method_entry(klassOop k) {
579 if (!is_method_entry()) {
580 // not a method entry so not interesting by default
581 return false;
582 }
583
584 methodOop m = NULL;
585 if (is_vfinal()) {
586 // virtual and final so _f2 contains method ptr instead of vtable index
587 m = f2_as_vfinal_method();
588 } else if (is_f1_null()) {
589 // NULL _f1 means this is a virtual entry so also not interesting
590 return false;
591 } else {
592 oop f1 = _f1; // _f1 is volatile
593 if (!f1->is_method()) {
594 // _f1 can also contain a klassOop for an interface
595 return false;
596 }
597 m = f1_as_method();
598 }
599
600 assert(m != NULL && m->is_method(), "sanity check");
601 if (m == NULL || !m->is_method() || m->method_holder() != k) {
602 // robustness for above sanity checks or method is not in
603 // the interesting class
604 return false;
605 }
606
607 // the method is in the interesting class so the entry is interesting
608 return true;
609 }
610
611 void ConstantPoolCacheEntry::print(outputStream* st, int index) const {
612 // print separator
613 if (index == 0) st->print_cr(" -------------");
614 // print entry
615 st->print("%3d ("PTR_FORMAT") ", index, (intptr_t)this);
616 if (is_secondary_entry())
617 st->print_cr("[%5d|secondary]", main_entry_index());
618 else
619 st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index());
620 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)(oop)_f1);
621 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f2);
622 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_flags);
623 st->print_cr(" -------------");
624 }
625
626 void ConstantPoolCacheEntry::verify(outputStream* st) const {
627 // not implemented yet
628 }
629
630 // Implementation of ConstantPoolCache
631
632 void constantPoolCacheOopDesc::initialize(intArray& inverse_index_map) {
633 assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
634 for (int i = 0; i < length(); i++) {
635 ConstantPoolCacheEntry* e = entry_at(i);
636 int original_index = inverse_index_map[i];
637 if ((original_index & Rewriter::_secondary_entry_tag) != 0) {
638 int main_index = (original_index - Rewriter::_secondary_entry_tag);
639 assert(!entry_at(main_index)->is_secondary_entry(), "valid main index");
640 e->initialize_secondary_entry(main_index);
641 } else {
642 e->initialize_entry(original_index);
665 continue;
666 }
667
668 // The constantPoolCache contains entries for several different
669 // things, but we only care about methods. In fact, we only care
670 // about methods in the same class as the one that contains the
671 // old_methods. At this point, we have an interesting entry.
672
673 for (int j = 0; j < methods_length; j++) {
674 methodOop old_method = old_methods[j];
675 methodOop new_method = new_methods[j];
676
677 if (entry_at(i)->adjust_method_entry(old_method, new_method,
678 trace_name_printed)) {
679 // current old_method matched this entry and we updated it so
680 // break out and get to the next interesting entry if there one
681 break;
682 }
683 }
684 }
685 }
|
1 /*
2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
558 _f1 = new_method;
559 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
560 if (!(*trace_name_printed)) {
561 // RC_TRACE_MESG macro has an embedded ResourceMark
562 RC_TRACE_MESG(("adjust: name=%s",
563 Klass::cast(old_method->method_holder())->external_name()));
564 *trace_name_printed = true;
565 }
566 // RC_TRACE macro has an embedded ResourceMark
567 RC_TRACE(0x00400000, ("cpc entry update: %s(%s)",
568 new_method->name()->as_C_string(),
569 new_method->signature()->as_C_string()));
570 }
571
572 return true;
573 }
574
575 return false;
576 }
577
578 // a constant pool cache entry should never contain old or obsolete methods
579 bool ConstantPoolCacheEntry::check_no_old_or_obsolete_entries() {
580 if (is_vfinal()) {
581 methodOop m = (methodOop)_f2;
582 // Return false if _f2 refers to an old or an obsolete method.
583 // _f2 == NULL || !m->is_method() are just as unexpected here.
584 return (m != NULL && m->is_method() && !m->is_old() && !m->is_obsolete());
585 } else if ((oop)_f1 == NULL || !((oop)_f1)->is_method()) {
586 // _f1 == NULL || !_f1->is_method() are OK here
587 return true;
588 }
589
590 methodOop m = (methodOop)_f1;
591 // return false if _f1 refers to an old or an obsolete method
592 return (!m->is_old() && !m->is_obsolete());
593 }
594
595 bool ConstantPoolCacheEntry::is_interesting_method_entry(klassOop k) {
596 if (!is_method_entry()) {
597 // not a method entry so not interesting by default
598 return false;
599 }
600
601 methodOop m = NULL;
602 if (is_vfinal()) {
603 // virtual and final so _f2 contains method ptr instead of vtable index
604 m = f2_as_vfinal_method();
605 } else if (is_f1_null()) {
606 // NULL _f1 means this is a virtual entry so also not interesting
607 return false;
608 } else {
609 oop f1 = _f1; // _f1 is volatile
610 if (!f1->is_method()) {
611 // _f1 can also contain a klassOop for an interface
612 return false;
613 }
614 m = f1_as_method();
615 }
616
617 assert(m != NULL && m->is_method(), "sanity check");
618 if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) {
619 // robustness for above sanity checks or method is not in
620 // the interesting class
621 return false;
622 }
623
624 // the method is in the interesting class so the entry is interesting
625 return true;
626 }
627
628 void ConstantPoolCacheEntry::print(outputStream* st, int index) const {
629 // print separator
630 if (index == 0) {
631 // adds a searchable prefix when RedefineClasses() tracing is enabled
632 RC_TRACE_NO_CR(0x00004000, (""));
633 st->print_cr(" -------------");
634 }
635 // print entry
636 RC_TRACE_NO_CR(0x00004000, (""));
637 st->print("%3d ("PTR_FORMAT") ", index, (intptr_t)this);
638 if (is_secondary_entry())
639 st->print_cr("[%5d|secondary]", main_entry_index());
640 else
641 st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index());
642 RC_TRACE_NO_CR(0x00004000, (""));
643 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)(oop)_f1);
644 RC_TRACE_NO_CR(0x00004000, (""));
645 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f2);
646 RC_TRACE_NO_CR(0x00004000, (""));
647 st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_flags);
648 RC_TRACE_NO_CR(0x00004000, (""));
649 st->print_cr(" -------------");
650 }
651
652 void ConstantPoolCacheEntry::verify(outputStream* st) const {
653 // not implemented yet
654 }
655
656 // Implementation of ConstantPoolCache
657
658 void constantPoolCacheOopDesc::initialize(intArray& inverse_index_map) {
659 assert(inverse_index_map.length() == length(), "inverse index map must have same length as cache");
660 for (int i = 0; i < length(); i++) {
661 ConstantPoolCacheEntry* e = entry_at(i);
662 int original_index = inverse_index_map[i];
663 if ((original_index & Rewriter::_secondary_entry_tag) != 0) {
664 int main_index = (original_index - Rewriter::_secondary_entry_tag);
665 assert(!entry_at(main_index)->is_secondary_entry(), "valid main index");
666 e->initialize_secondary_entry(main_index);
667 } else {
668 e->initialize_entry(original_index);
691 continue;
692 }
693
694 // The constantPoolCache contains entries for several different
695 // things, but we only care about methods. In fact, we only care
696 // about methods in the same class as the one that contains the
697 // old_methods. At this point, we have an interesting entry.
698
699 for (int j = 0; j < methods_length; j++) {
700 methodOop old_method = old_methods[j];
701 methodOop new_method = new_methods[j];
702
703 if (entry_at(i)->adjust_method_entry(old_method, new_method,
704 trace_name_printed)) {
705 // current old_method matched this entry and we updated it so
706 // break out and get to the next interesting entry if there one
707 break;
708 }
709 }
710 }
711 }
712
713 // the constant pool cache should never contain old or obsolete methods
714 bool constantPoolCacheOopDesc::check_no_old_or_obsolete_entries() {
715 for (int i = 1; i < length(); i++) {
716 if (entry_at(i)->is_interesting_method_entry(NULL) &&
717 !entry_at(i)->check_no_old_or_obsolete_entries()) {
718 return false;
719 }
720 }
721 return true;
722 }
723
724 void constantPoolCacheOopDesc::dump_cache() {
725 for (int i = 1; i < length(); i++) {
726 if (entry_at(i)->is_interesting_method_entry(NULL)) {
727 // adds a searchable prefix when RedefineClasses() tracing is enabled
728 RC_TRACE_NO_CR(0x00004000, (""));
729 entry_at(i)->print(tty, i);
730 }
731 }
732 }
|