1 /*
2 * Copyright (c) 1997, 2011, 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 *
623 // by using: old_method->vtable_index()
624 // However, there are rare cases, eg. sun.awt.X11.XDecoratedPeer.getX()
625 // in sun.awt.X11.XFramePeer where methods occur more than once in the
626 // vtable, so, alas, we must do an exhaustive search.
627 for (int index = 0; index < length(); index++) {
628 if (unchecked_method_at(index) == old_method) {
629 put_method_at(new_method, index);
630
631 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
632 if (!(*trace_name_printed)) {
633 // RC_TRACE_MESG macro has an embedded ResourceMark
634 RC_TRACE_MESG(("adjust: name=%s",
635 Klass::cast(old_method->method_holder())->external_name()));
636 *trace_name_printed = true;
637 }
638 // RC_TRACE macro has an embedded ResourceMark
639 RC_TRACE(0x00100000, ("vtable method update: %s(%s)",
640 new_method->name()->as_C_string(),
641 new_method->signature()->as_C_string()));
642 }
643 }
644 }
645 }
646 }
647
648 // CDS/RedefineClasses support - clear vtables so they can be reinitialized
649 void klassVtable::clear_vtable() {
650 for (int i = 0; i < _length; i++) table()[i].clear();
651 }
652
653 bool klassVtable::is_initialized() {
654 return _length == 0 || table()[0].method() != NULL;
655 }
656
657
658 // Garbage collection
659 void klassVtable::oop_follow_contents() {
660 int len = length();
661 for (int i = 0; i < len; i++) {
662 MarkSweep::mark_and_push(adr_method_at(i));
663 }
664 }
665
666 #ifndef SERIALGC
667 void klassVtable::oop_follow_contents(ParCompactionManager* cm) {
977 // The itable can describe more than one interface and the same
978 // method signature can be specified by more than one interface.
979 // This means we have to do an exhaustive search to find all the
980 // old_method references.
981 for (int i = 0; i < _size_method_table; i++) {
982 if (ime->method() == old_method) {
983 ime->initialize(new_method);
984
985 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
986 if (!(*trace_name_printed)) {
987 // RC_TRACE_MESG macro has an embedded ResourceMark
988 RC_TRACE_MESG(("adjust: name=%s",
989 Klass::cast(old_method->method_holder())->external_name()));
990 *trace_name_printed = true;
991 }
992 // RC_TRACE macro has an embedded ResourceMark
993 RC_TRACE(0x00200000, ("itable method update: %s(%s)",
994 new_method->name()->as_C_string(),
995 new_method->signature()->as_C_string()));
996 }
997 break;
998 }
999 ime++;
1000 }
1001 }
1002 }
1003
1004
1005 // Setup
1006 class InterfaceVisiterClosure : public StackObj {
1007 public:
1008 virtual void doit(klassOop intf, int method_count) = 0;
1009 };
1010
1011 // Visit all interfaces with at-least one method (excluding <clinit>)
1012 void visit_all_interfaces(objArrayOop transitive_intf, InterfaceVisiterClosure *blk) {
1013 // Handle array argument
1014 for(int i = 0; i < transitive_intf->length(); i++) {
1015 klassOop intf = (klassOop)transitive_intf->obj_at(i);
1016 assert(Klass::cast(intf)->is_interface(), "sanity check");
1017
1018 // Find no. of methods excluding a <clinit>
1019 int method_count = instanceKlass::cast(intf)->methods()->length();
1020 if (method_count > 0) {
1021 methodOop m = (methodOop)instanceKlass::cast(intf)->methods()->obj_at(0);
1022 assert(m != NULL && m->is_method(), "sanity check");
1023 if (m->name() == vmSymbols::object_initializer_name()) {
1024 method_count--;
1270 int VtableStats::sum_of_vtable_len = 0;
1271 int VtableStats::sum_of_array_vtable_len = 0;
1272 int VtableStats::fixed = 0;
1273 int VtableStats::filler = 0;
1274 int VtableStats::entries = 0;
1275 int VtableStats::array_entries = 0;
1276
1277 void klassVtable::print_statistics() {
1278 ResourceMark rm;
1279 HandleMark hm;
1280 VtableStats::compute();
1281 tty->print_cr("vtable statistics:");
1282 tty->print_cr("%6d classes (%d instance, %d array)", VtableStats::no_klasses, VtableStats::no_instance_klasses, VtableStats::no_array_klasses);
1283 int total = VtableStats::fixed + VtableStats::filler + VtableStats::entries;
1284 tty->print_cr("%6d bytes fixed overhead (refs + vtable object header)", VtableStats::fixed);
1285 tty->print_cr("%6d bytes filler overhead", VtableStats::filler);
1286 tty->print_cr("%6d bytes for vtable entries (%d for arrays)", VtableStats::entries, VtableStats::array_entries);
1287 tty->print_cr("%6d bytes total", total);
1288 }
1289
1290 bool klassVtable::check_no_old_entries() {
1291 // Check that there really is no entry
1292 for (int i = 0; i < length(); i++) {
1293 methodOop m = unchecked_method_at(i);
1294 if (m != NULL) {
1295 if (m->is_old()) {
1296 return false;
1297 }
1298 }
1299 }
1300 return true;
1301 }
1302
1303 void klassVtable::dump_vtable() {
1304 tty->print_cr("vtable dump --");
1305 for (int i = 0; i < length(); i++) {
1306 methodOop m = unchecked_method_at(i);
1307 if (m != NULL) {
1308 tty->print(" (%5d) ", i);
1309 m->access_flags().print_on(tty);
1310 tty->print(" -- ");
1311 m->print_name(tty);
1312 tty->cr();
1313 }
1314 }
1315 }
1316
1317 int klassItable::_total_classes; // Total no. of classes with itables
1318 long klassItable::_total_size; // Total no. of bytes used for itables
1319
1320 void klassItable::print_statistics() {
1321 tty->print_cr("itable statistics:");
1322 tty->print_cr("%6d classes with itables", _total_classes);
1323 tty->print_cr("%6d K uses for itables (average by class: %d bytes)", _total_size / K, _total_size / _total_classes);
1324 }
1325
1326 #endif // PRODUCT
|
1 /*
2 * Copyright (c) 1997, 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 *
623 // by using: old_method->vtable_index()
624 // However, there are rare cases, eg. sun.awt.X11.XDecoratedPeer.getX()
625 // in sun.awt.X11.XFramePeer where methods occur more than once in the
626 // vtable, so, alas, we must do an exhaustive search.
627 for (int index = 0; index < length(); index++) {
628 if (unchecked_method_at(index) == old_method) {
629 put_method_at(new_method, index);
630
631 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
632 if (!(*trace_name_printed)) {
633 // RC_TRACE_MESG macro has an embedded ResourceMark
634 RC_TRACE_MESG(("adjust: name=%s",
635 Klass::cast(old_method->method_holder())->external_name()));
636 *trace_name_printed = true;
637 }
638 // RC_TRACE macro has an embedded ResourceMark
639 RC_TRACE(0x00100000, ("vtable method update: %s(%s)",
640 new_method->name()->as_C_string(),
641 new_method->signature()->as_C_string()));
642 }
643 // cannot 'break' here; see for-loop comment above.
644 }
645 }
646 }
647 }
648
649 // a vtable should never contain old or obsolete methods
650 bool klassVtable::check_no_old_or_obsolete_entries() {
651 for (int i = 0; i < length(); i++) {
652 methodOop m = unchecked_method_at(i);
653 if (m != NULL && (m->is_old() || m->is_obsolete())) {
654 return false;
655 }
656 }
657 return true;
658 }
659
660 void klassVtable::dump_vtable() {
661 tty->print_cr("vtable dump --");
662 for (int i = 0; i < length(); i++) {
663 methodOop m = unchecked_method_at(i);
664 if (m != NULL) {
665 tty->print(" (%5d) ", i);
666 m->access_flags().print_on(tty);
667 tty->print(" -- ");
668 m->print_name(tty);
669 tty->cr();
670 }
671 }
672 }
673
674 // CDS/RedefineClasses support - clear vtables so they can be reinitialized
675 void klassVtable::clear_vtable() {
676 for (int i = 0; i < _length; i++) table()[i].clear();
677 }
678
679 bool klassVtable::is_initialized() {
680 return _length == 0 || table()[0].method() != NULL;
681 }
682
683
684 // Garbage collection
685 void klassVtable::oop_follow_contents() {
686 int len = length();
687 for (int i = 0; i < len; i++) {
688 MarkSweep::mark_and_push(adr_method_at(i));
689 }
690 }
691
692 #ifndef SERIALGC
693 void klassVtable::oop_follow_contents(ParCompactionManager* cm) {
1003 // The itable can describe more than one interface and the same
1004 // method signature can be specified by more than one interface.
1005 // This means we have to do an exhaustive search to find all the
1006 // old_method references.
1007 for (int i = 0; i < _size_method_table; i++) {
1008 if (ime->method() == old_method) {
1009 ime->initialize(new_method);
1010
1011 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
1012 if (!(*trace_name_printed)) {
1013 // RC_TRACE_MESG macro has an embedded ResourceMark
1014 RC_TRACE_MESG(("adjust: name=%s",
1015 Klass::cast(old_method->method_holder())->external_name()));
1016 *trace_name_printed = true;
1017 }
1018 // RC_TRACE macro has an embedded ResourceMark
1019 RC_TRACE(0x00200000, ("itable method update: %s(%s)",
1020 new_method->name()->as_C_string(),
1021 new_method->signature()->as_C_string()));
1022 }
1023 // cannot 'break' here; see for-loop comment above.
1024 }
1025 ime++;
1026 }
1027 }
1028 }
1029
1030 // an itable should never contain old or obsolete methods
1031 bool klassItable::check_no_old_or_obsolete_entries() {
1032 itableMethodEntry* ime = method_entry(0);
1033 for (int i = 0; i < _size_method_table; i++) {
1034 methodOop m = ime->method();
1035 if (m != NULL && (m->is_old() || m->is_obsolete())) {
1036 return false;
1037 }
1038 ime++;
1039 }
1040 return true;
1041 }
1042
1043 void klassItable::dump_itable() {
1044 itableMethodEntry* ime = method_entry(0);
1045 tty->print_cr("itable dump --");
1046 for (int i = 0; i < _size_method_table; i++) {
1047 methodOop m = ime->method();
1048 if (m != NULL) {
1049 tty->print(" (%5d) ", i);
1050 m->access_flags().print_on(tty);
1051 tty->print(" -- ");
1052 m->print_name(tty);
1053 tty->cr();
1054 }
1055 ime++;
1056 }
1057 }
1058
1059
1060 // Setup
1061 class InterfaceVisiterClosure : public StackObj {
1062 public:
1063 virtual void doit(klassOop intf, int method_count) = 0;
1064 };
1065
1066 // Visit all interfaces with at-least one method (excluding <clinit>)
1067 void visit_all_interfaces(objArrayOop transitive_intf, InterfaceVisiterClosure *blk) {
1068 // Handle array argument
1069 for(int i = 0; i < transitive_intf->length(); i++) {
1070 klassOop intf = (klassOop)transitive_intf->obj_at(i);
1071 assert(Klass::cast(intf)->is_interface(), "sanity check");
1072
1073 // Find no. of methods excluding a <clinit>
1074 int method_count = instanceKlass::cast(intf)->methods()->length();
1075 if (method_count > 0) {
1076 methodOop m = (methodOop)instanceKlass::cast(intf)->methods()->obj_at(0);
1077 assert(m != NULL && m->is_method(), "sanity check");
1078 if (m->name() == vmSymbols::object_initializer_name()) {
1079 method_count--;
1325 int VtableStats::sum_of_vtable_len = 0;
1326 int VtableStats::sum_of_array_vtable_len = 0;
1327 int VtableStats::fixed = 0;
1328 int VtableStats::filler = 0;
1329 int VtableStats::entries = 0;
1330 int VtableStats::array_entries = 0;
1331
1332 void klassVtable::print_statistics() {
1333 ResourceMark rm;
1334 HandleMark hm;
1335 VtableStats::compute();
1336 tty->print_cr("vtable statistics:");
1337 tty->print_cr("%6d classes (%d instance, %d array)", VtableStats::no_klasses, VtableStats::no_instance_klasses, VtableStats::no_array_klasses);
1338 int total = VtableStats::fixed + VtableStats::filler + VtableStats::entries;
1339 tty->print_cr("%6d bytes fixed overhead (refs + vtable object header)", VtableStats::fixed);
1340 tty->print_cr("%6d bytes filler overhead", VtableStats::filler);
1341 tty->print_cr("%6d bytes for vtable entries (%d for arrays)", VtableStats::entries, VtableStats::array_entries);
1342 tty->print_cr("%6d bytes total", total);
1343 }
1344
1345 int klassItable::_total_classes; // Total no. of classes with itables
1346 long klassItable::_total_size; // Total no. of bytes used for itables
1347
1348 void klassItable::print_statistics() {
1349 tty->print_cr("itable statistics:");
1350 tty->print_cr("%6d classes with itables", _total_classes);
1351 tty->print_cr("%6d K uses for itables (average by class: %d bytes)", _total_size / K, _total_size / _total_classes);
1352 }
1353
1354 #endif // PRODUCT
|