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 


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

 904   }


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


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





1197 
1198   itableMethodEntry* ime = method_entry(0);
1199   for (int i = 0; i < _size_method_table; i++, ime++) {
1200     Method* old_method = ime->method();
1201     if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) {
1202       continue; // skip uninteresting entries
1203     }
1204     assert(!old_method->is_deleted(), "itable methods may not be deleted");
1205     Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
1206     assert(new_method != NULL, "method_with_idnum() should not be NULL");
1207     if (old_method == new_method) {
1208       continue;
1209     }
1210     ime->initialize(new_method);
1211 
1212     if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
1213       if (!(*trace_name_printed)) {
1214         // RC_TRACE_MESG macro has an embedded ResourceMark
1215         RC_TRACE_MESG(("adjust: name=%s",
1216           old_method->method_holder()->external_name()));
1217         *trace_name_printed = true;
1218       }
1219       // RC_TRACE macro has an embedded ResourceMark
1220       RC_TRACE(0x00200000, ("itable method update: %s(%s)",
1221         new_method->name()->as_C_string(),
1222         new_method->signature()->as_C_string()));
1223     }

1224   }



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