862 } |
862 } |
863 } |
863 } |
864 } |
864 } |
865 return updated; |
865 return updated; |
866 } |
866 } |
867 void klassVtable::adjust_method_entries(Method** old_methods, Method** new_methods, |
867 |
868 int methods_length, bool * trace_name_printed) { |
868 // search the vtable for uses of either obsolete or EMCP methods |
869 // search the vtable for uses of either obsolete or EMCP methods |
869 void klassVtable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) { |
870 for (int j = 0; j < methods_length; j++) { |
870 int prn_enabled = 0; |
871 Method* old_method = old_methods[j]; |
871 for (int index = 0; index < length(); index++) { |
872 Method* new_method = new_methods[j]; |
872 Method* old_method = unchecked_method_at(index); |
873 |
873 if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) { |
874 // In the vast majority of cases we could get the vtable index |
874 continue; // skip uninteresting entries |
875 // by using: old_method->vtable_index() |
875 } |
876 // However, there are rare cases, eg. sun.awt.X11.XDecoratedPeer.getX() |
876 assert(!old_method->is_deleted(), "vtable methods may not be deleted"); |
877 // in sun.awt.X11.XFramePeer where methods occur more than once in the |
877 |
878 // vtable, so, alas, we must do an exhaustive search. |
878 Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum()); |
879 for (int index = 0; index < length(); index++) { |
879 |
880 if (unchecked_method_at(index) == old_method) { |
880 assert(new_method != NULL, "method_with_idnum() should not be NULL"); |
881 put_method_at(new_method, index); |
881 assert(old_method != new_method, "sanity check"); |
882 // For default methods, need to update the _default_methods array |
882 |
883 // which can only have one method entry for a given signature |
883 put_method_at(new_method, index); |
884 bool updated_default = false; |
884 // For default methods, need to update the _default_methods array |
885 if (old_method->is_default_method()) { |
885 // which can only have one method entry for a given signature |
886 updated_default = adjust_default_method(index, old_method, new_method); |
886 bool updated_default = false; |
887 } |
887 if (old_method->is_default_method()) { |
888 |
888 updated_default = adjust_default_method(index, old_method, new_method); |
889 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { |
889 } |
890 if (!(*trace_name_printed)) { |
890 |
891 // RC_TRACE_MESG macro has an embedded ResourceMark |
891 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { |
892 RC_TRACE_MESG(("adjust: klassname=%s for methods from name=%s", |
892 if (!(*trace_name_printed)) { |
893 klass()->external_name(), |
893 // RC_TRACE_MESG macro has an embedded ResourceMark |
894 old_method->method_holder()->external_name())); |
894 RC_TRACE_MESG(("adjust: klassname=%s for methods from name=%s", |
895 *trace_name_printed = true; |
895 klass()->external_name(), |
896 } |
896 old_method->method_holder()->external_name())); |
897 // RC_TRACE macro has an embedded ResourceMark |
897 *trace_name_printed = true; |
898 RC_TRACE(0x00100000, ("vtable method update: %s(%s), updated default = %s", |
898 } |
899 new_method->name()->as_C_string(), |
899 // RC_TRACE macro has an embedded ResourceMark |
900 new_method->signature()->as_C_string(), |
900 RC_TRACE(0x00100000, ("vtable method update: %s(%s), updated default = %s", |
901 updated_default ? "true" : "false")); |
901 new_method->name()->as_C_string(), |
902 } |
902 new_method->signature()->as_C_string(), |
903 // cannot 'break' here; see for-loop comment above. |
903 updated_default ? "true" : "false")); |
904 } |
|
905 } |
904 } |
906 } |
905 } |
907 } |
906 } |
908 |
907 |
909 // a vtable should never contain old or obsolete methods |
908 // a vtable should never contain old or obsolete methods |
1192 ime++; |
1191 ime++; |
1193 } |
1192 } |
1194 } |
1193 } |
1195 |
1194 |
1196 #if INCLUDE_JVMTI |
1195 #if INCLUDE_JVMTI |
1197 void klassItable::adjust_method_entries(Method** old_methods, Method** new_methods, |
1196 // search the itable for uses of either obsolete or EMCP methods |
1198 int methods_length, bool * trace_name_printed) { |
1197 void klassItable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) { |
1199 // search the itable for uses of either obsolete or EMCP methods |
1198 |
1200 for (int j = 0; j < methods_length; j++) { |
1199 itableMethodEntry* ime = method_entry(0); |
1201 Method* old_method = old_methods[j]; |
1200 for (int i = 0; i < _size_method_table; i++, ime++) { |
1202 Method* new_method = new_methods[j]; |
1201 Method* old_method = ime->method(); |
1203 itableMethodEntry* ime = method_entry(0); |
1202 if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) { |
1204 |
1203 continue; // skip uninteresting entries |
1205 // The itable can describe more than one interface and the same |
1204 } |
1206 // method signature can be specified by more than one interface. |
1205 assert(!old_method->is_deleted(), "itable methods may not be deleted"); |
1207 // This means we have to do an exhaustive search to find all the |
1206 |
1208 // old_method references. |
1207 Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum()); |
1209 for (int i = 0; i < _size_method_table; i++) { |
1208 |
1210 if (ime->method() == old_method) { |
1209 assert(new_method != NULL, "method_with_idnum() should not be NULL"); |
1211 ime->initialize(new_method); |
1210 assert(old_method != new_method, "sanity check"); |
1212 |
1211 |
1213 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { |
1212 ime->initialize(new_method); |
1214 if (!(*trace_name_printed)) { |
1213 |
1215 // RC_TRACE_MESG macro has an embedded ResourceMark |
1214 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { |
1216 RC_TRACE_MESG(("adjust: name=%s", |
1215 if (!(*trace_name_printed)) { |
1217 old_method->method_holder()->external_name())); |
1216 // RC_TRACE_MESG macro has an embedded ResourceMark |
1218 *trace_name_printed = true; |
1217 RC_TRACE_MESG(("adjust: name=%s", |
1219 } |
1218 old_method->method_holder()->external_name())); |
1220 // RC_TRACE macro has an embedded ResourceMark |
1219 *trace_name_printed = true; |
1221 RC_TRACE(0x00200000, ("itable method update: %s(%s)", |
1220 } |
1222 new_method->name()->as_C_string(), |
1221 // RC_TRACE macro has an embedded ResourceMark |
1223 new_method->signature()->as_C_string())); |
1222 RC_TRACE(0x00200000, ("itable method update: %s(%s)", |
1224 } |
1223 new_method->name()->as_C_string(), |
1225 // cannot 'break' here; see for-loop comment above. |
1224 new_method->signature()->as_C_string())); |
1226 } |
|
1227 ime++; |
|
1228 } |
1225 } |
1229 } |
1226 } |
1230 } |
1227 } |
1231 |
1228 |
1232 // an itable should never contain old or obsolete methods |
1229 // an itable should never contain old or obsolete methods |