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