src/share/vm/oops/klassVtable.cpp

Print this page




 847 bool klassVtable::adjust_default_method(int vtable_index, Method* old_method, Method* new_method) {
 848   // If old_method is default, find this vtable index in default_vtable_indices
 849   // and replace that method in the _default_methods list
 850   bool updated = false;
 851 
 852   Array<Method*>* default_methods = ik()->default_methods();
 853   if (default_methods != NULL) {
 854     int len = default_methods->length();
 855     for (int idx = 0; idx < len; idx++) {
 856       if (vtable_index == ik()->default_vtable_indices()->at(idx)) {
 857         if (default_methods->at(idx) == old_method) {
 858           default_methods->at_put(idx, new_method);
 859           updated = true;
 860         }
 861         break;
 862       }
 863     }
 864   }
 865   return updated;
 866 }
 867 void klassVtable::adjust_method_entries(Method** old_methods, Method** new_methods,
 868                                         int methods_length, bool * trace_name_printed) {
 869   // search the vtable for uses of either obsolete or EMCP methods
 870   for (int j = 0; j < methods_length; j++) {
 871     Method* old_method = old_methods[j];
 872     Method* new_method = new_methods[j];
 873 
 874     // In the vast majority of cases we could get the vtable index
 875     // by using:  old_method->vtable_index()
 876     // However, there are rare cases, eg. sun.awt.X11.XDecoratedPeer.getX()
 877     // in sun.awt.X11.XFramePeer where methods occur more than once in the
 878     // vtable, so, alas, we must do an exhaustive search.
 879     for (int index = 0; index < length(); index++) {
 880       if (unchecked_method_at(index) == old_method) {










 881         put_method_at(new_method, index);
 882           // For default methods, need to update the _default_methods array
 883           // which can only have one method entry for a given signature
 884           bool updated_default = false;
 885           if (old_method->is_default_method()) {
 886             updated_default = adjust_default_method(index, old_method, new_method);
 887           }
 888 
 889         if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
 890           if (!(*trace_name_printed)) {
 891             // RC_TRACE_MESG macro has an embedded ResourceMark
 892             RC_TRACE_MESG(("adjust: klassname=%s for methods from name=%s",
 893                            klass()->external_name(),
 894                            old_method->method_holder()->external_name()));
 895             *trace_name_printed = true;
 896           }
 897           // RC_TRACE macro has an embedded ResourceMark
 898           RC_TRACE(0x00100000, ("vtable method update: %s(%s), updated default = %s",
 899                                 new_method->name()->as_C_string(),
 900                                 new_method->signature()->as_C_string(),
 901                                 updated_default ? "true" : "false"));
 902         }
 903         // cannot 'break' here; see for-loop comment above.
 904       }
 905     }
 906   }
 907 }
 908 
 909 // a vtable should never contain old or obsolete methods
 910 bool klassVtable::check_no_old_or_obsolete_entries() {
 911   for (int i = 0; i < length(); i++) {
 912     Method* m = unchecked_method_at(i);
 913     if (m != NULL &&
 914         (NOT_PRODUCT(!m->is_valid() ||) m->is_old() || m->is_obsolete())) {
 915       return false;
 916     }
 917   }
 918   return true;
 919 }
 920 
 921 void klassVtable::dump_vtable() {
 922   tty->print_cr("vtable dump --");
 923   for (int i = 0; i < length(); i++) {
 924     Method* m = unchecked_method_at(i);
 925     if (m != NULL) {
 926       tty->print("      (%5d)  ", i);


1177           }
1178           tty->cr();
1179         }
1180       }
1181     }
1182   }
1183 }
1184 
1185 // Update entry for specific Method*
1186 void klassItable::initialize_with_method(Method* m) {
1187   itableMethodEntry* ime = method_entry(0);
1188   for(int i = 0; i < _size_method_table; i++) {
1189     if (ime->method() == m) {
1190       ime->initialize(m);
1191     }
1192     ime++;
1193   }
1194 }
1195 
1196 #if INCLUDE_JVMTI
1197 void klassItable::adjust_method_entries(Method** old_methods, Method** new_methods,
1198                                         int methods_length, bool * trace_name_printed) {
1199   // search the itable for uses of either obsolete or EMCP methods
1200   for (int j = 0; j < methods_length; j++) {
1201     Method* old_method = old_methods[j];
1202     Method* new_method = new_methods[j];
1203     itableMethodEntry* ime = method_entry(0);






1204 
1205     // The itable can describe more than one interface and the same
1206     // method signature can be specified by more than one interface.
1207     // This means we have to do an exhaustive search to find all the
1208     // old_method references.
1209     for (int i = 0; i < _size_method_table; i++) {
1210       if (ime->method() == old_method) {
1211         ime->initialize(new_method);
1212 
1213         if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
1214           if (!(*trace_name_printed)) {
1215             // RC_TRACE_MESG macro has an embedded ResourceMark
1216             RC_TRACE_MESG(("adjust: name=%s",
1217               old_method->method_holder()->external_name()));
1218             *trace_name_printed = true;
1219           }
1220           // RC_TRACE macro has an embedded ResourceMark
1221           RC_TRACE(0x00200000, ("itable method update: %s(%s)",
1222             new_method->name()->as_C_string(),
1223             new_method->signature()->as_C_string()));
1224         }
1225         // cannot 'break' here; see for-loop comment above.
1226       }
1227       ime++;
1228     }
1229   }
1230 }
1231 
1232 // an itable should never contain old or obsolete methods
1233 bool klassItable::check_no_old_or_obsolete_entries() {
1234   itableMethodEntry* ime = method_entry(0);
1235   for (int i = 0; i < _size_method_table; i++) {
1236     Method* m = ime->method();
1237     if (m != NULL &&
1238         (NOT_PRODUCT(!m->is_valid() ||) m->is_old() || m->is_obsolete())) {
1239       return false;
1240     }
1241     ime++;
1242   }
1243   return true;
1244 }
1245 
1246 void klassItable::dump_itable() {
1247   itableMethodEntry* ime = method_entry(0);
1248   tty->print_cr("itable dump --");
1249   for (int i = 0; i < _size_method_table; i++) {




 847 bool klassVtable::adjust_default_method(int vtable_index, Method* old_method, Method* new_method) {
 848   // If old_method is default, find this vtable index in default_vtable_indices
 849   // and replace that method in the _default_methods list
 850   bool updated = false;
 851 
 852   Array<Method*>* default_methods = ik()->default_methods();
 853   if (default_methods != NULL) {
 854     int len = default_methods->length();
 855     for (int idx = 0; idx < len; idx++) {
 856       if (vtable_index == ik()->default_vtable_indices()->at(idx)) {
 857         if (default_methods->at(idx) == old_method) {
 858           default_methods->at_put(idx, new_method);
 859           updated = true;
 860         }
 861         break;
 862       }
 863     }
 864   }
 865   return updated;
 866 }






 867 
 868 // search the vtable for uses of either obsolete or EMCP methods
 869 void klassVtable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
 870   int prn_enabled = 0;


 871   for (int index = 0; index < length(); index++) {
 872     Method* old_method = unchecked_method_at(index);
 873     if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) {
 874       continue; // skip uninteresting entries
 875     }
 876     assert(!old_method->is_deleted(), "vtable methods may not be deleted");
 877 
 878     Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
 879 
 880     assert(new_method != NULL, "method_with_idnum() should not be NULL");
 881     assert(old_method != new_method, "sanity check");
 882 
 883     put_method_at(new_method, index);
 884     // For default methods, need to update the _default_methods array
 885     // which can only have one method entry for a given signature
 886     bool updated_default = false;
 887     if (old_method->is_default_method()) {
 888       updated_default = adjust_default_method(index, old_method, new_method);
 889     }
 890 
 891     if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
 892       if (!(*trace_name_printed)) {
 893         // RC_TRACE_MESG macro has an embedded ResourceMark
 894         RC_TRACE_MESG(("adjust: klassname=%s for methods from name=%s",
 895                        klass()->external_name(),
 896                        old_method->method_holder()->external_name()));
 897         *trace_name_printed = true;
 898       }
 899       // RC_TRACE macro has an embedded ResourceMark
 900       RC_TRACE(0x00100000, ("vtable method update: %s(%s), updated default = %s",
 901                             new_method->name()->as_C_string(),
 902                             new_method->signature()->as_C_string(),
 903                             updated_default ? "true" : "false"));
 904     }

 905   }


 906 }
 907 
 908 // a vtable should never contain old or obsolete methods
 909 bool klassVtable::check_no_old_or_obsolete_entries() {
 910   for (int i = 0; i < length(); i++) {
 911     Method* m = unchecked_method_at(i);
 912     if (m != NULL &&
 913         (NOT_PRODUCT(!m->is_valid() ||) m->is_old() || m->is_obsolete())) {
 914       return false;
 915     }
 916   }
 917   return true;
 918 }
 919 
 920 void klassVtable::dump_vtable() {
 921   tty->print_cr("vtable dump --");
 922   for (int i = 0; i < length(); i++) {
 923     Method* m = unchecked_method_at(i);
 924     if (m != NULL) {
 925       tty->print("      (%5d)  ", i);


1176           }
1177           tty->cr();
1178         }
1179       }
1180     }
1181   }
1182 }
1183 
1184 // Update entry for specific Method*
1185 void klassItable::initialize_with_method(Method* m) {
1186   itableMethodEntry* ime = method_entry(0);
1187   for(int i = 0; i < _size_method_table; i++) {
1188     if (ime->method() == m) {
1189       ime->initialize(m);
1190     }
1191     ime++;
1192   }
1193 }
1194 
1195 #if INCLUDE_JVMTI
1196 // search the itable for uses of either obsolete or EMCP methods
1197 void klassItable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
1198 



1199   itableMethodEntry* ime = method_entry(0);
1200   for (int i = 0; i < _size_method_table; i++, ime++) {
1201     Method* old_method = ime->method();
1202     if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) {
1203       continue; // skip uninteresting entries
1204     }
1205     assert(!old_method->is_deleted(), "itable methods may not be deleted");
1206 
1207     Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
1208 
1209     assert(new_method != NULL, "method_with_idnum() should not be NULL");
1210     assert(old_method != new_method, "sanity check");
1211 

1212     ime->initialize(new_method);
1213 
1214     if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
1215       if (!(*trace_name_printed)) {
1216         // RC_TRACE_MESG macro has an embedded ResourceMark
1217         RC_TRACE_MESG(("adjust: name=%s",
1218           old_method->method_holder()->external_name()));
1219         *trace_name_printed = true;
1220       }
1221       // RC_TRACE macro has an embedded ResourceMark
1222       RC_TRACE(0x00200000, ("itable method update: %s(%s)",
1223         new_method->name()->as_C_string(),
1224         new_method->signature()->as_C_string()));
1225     }

1226   }



1227 }
1228 
1229 // an itable should never contain old or obsolete methods
1230 bool klassItable::check_no_old_or_obsolete_entries() {
1231   itableMethodEntry* ime = method_entry(0);
1232   for (int i = 0; i < _size_method_table; i++) {
1233     Method* m = ime->method();
1234     if (m != NULL &&
1235         (NOT_PRODUCT(!m->is_valid() ||) m->is_old() || m->is_obsolete())) {
1236       return false;
1237     }
1238     ime++;
1239   }
1240   return true;
1241 }
1242 
1243 void klassItable::dump_itable() {
1244   itableMethodEntry* ime = method_entry(0);
1245   tty->print_cr("itable dump --");
1246   for (int i = 0; i < _size_method_table; i++) {