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++) { |