src/share/vm/oops/klassVtable.cpp

Print this page


   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