24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" |
26 #include "classfile/systemDictionary.hpp" |
27 #include "classfile/vmSymbols.hpp" |
27 #include "classfile/vmSymbols.hpp" |
28 #include "gc/shared/gcLocker.hpp" |
28 #include "gc/shared/gcLocker.hpp" |
|
29 #include "logging/log.hpp" |
29 #include "memory/resourceArea.hpp" |
30 #include "memory/resourceArea.hpp" |
30 #include "memory/universe.inline.hpp" |
31 #include "memory/universe.inline.hpp" |
31 #include "oops/instanceKlass.hpp" |
32 #include "oops/instanceKlass.hpp" |
32 #include "oops/klassVtable.hpp" |
33 #include "oops/klassVtable.hpp" |
33 #include "oops/method.hpp" |
34 #include "oops/method.hpp" |
269 Symbol* name= target_method()->name(); |
270 Symbol* name= target_method()->name(); |
270 Symbol* signature = target_method()->signature(); |
271 Symbol* signature = target_method()->signature(); |
271 assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch"); |
272 assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch"); |
272 #endif |
273 #endif |
273 if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { |
274 if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { |
274 #ifndef PRODUCT |
275 if (develop_log_is_enabled(Trace, vtables)) { |
275 if (PrintVtables && Verbose) { |
|
276 ResourceMark rm(THREAD); |
276 ResourceMark rm(THREAD); |
|
277 outputStream* logst = LogHandle(vtables)::trace_stream(); |
277 char* sig = target_method()->name_and_sig_as_C_string(); |
278 char* sig = target_method()->name_and_sig_as_C_string(); |
278 tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ", |
279 logst->print("transitive overriding superclass %s with %s::%s index %d, original flags: ", |
279 supersuperklass->internal_name(), |
280 supersuperklass->internal_name(), |
280 _klass->internal_name(), sig, vtable_index); |
281 _klass->internal_name(), sig, vtable_index); |
281 super_method->access_flags().print_on(tty); |
282 super_method->print_linkage_flags(logst); |
282 if (super_method->is_default_method()) { |
283 logst->print("overriders flags: "); |
283 tty->print("default "); |
284 target_method->print_linkage_flags(logst); |
284 } |
285 logst->cr(); |
285 tty->print("overriders flags: "); |
|
286 target_method->access_flags().print_on(tty); |
|
287 if (target_method->is_default_method()) { |
|
288 tty->print("default "); |
|
289 } |
|
290 } |
286 } |
291 #endif /*PRODUCT*/ |
287 |
292 break; // return found superk |
288 break; // return found superk |
293 } |
289 } |
294 } else { |
290 } else { |
295 // super class has no vtable entry here, stop transitive search |
291 // super class has no vtable entry here, stop transitive search |
296 superk = (InstanceKlass*)NULL; |
292 superk = (InstanceKlass*)NULL; |
299 // if no override found yet, continue to search up |
295 // if no override found yet, continue to search up |
300 superk = superk->super() == NULL ? NULL : InstanceKlass::cast(superk->super()); |
296 superk = superk->super() == NULL ? NULL : InstanceKlass::cast(superk->super()); |
301 } |
297 } |
302 |
298 |
303 return superk; |
299 return superk; |
|
300 } |
|
301 |
|
302 static void log_vtables(int i, bool overrides, methodHandle target_method, |
|
303 KlassHandle target_klass, Method* super_method, |
|
304 Thread* thread) { |
|
305 #ifndef PRODUCT |
|
306 if (develop_log_is_enabled(Trace, vtables)) { |
|
307 ResourceMark rm(thread); |
|
308 outputStream* logst = LogHandle(vtables)::trace_stream(); |
|
309 char* sig = target_method()->name_and_sig_as_C_string(); |
|
310 if (overrides) { |
|
311 logst->print("overriding with %s::%s index %d, original flags: ", |
|
312 target_klass->internal_name(), sig, i); |
|
313 } else { |
|
314 logst->print("NOT overriding with %s::%s index %d, original flags: ", |
|
315 target_klass->internal_name(), sig, i); |
|
316 } |
|
317 super_method->print_linkage_flags(logst); |
|
318 logst->print("overriders flags: "); |
|
319 target_method->print_linkage_flags(logst); |
|
320 logst->cr(); |
|
321 } |
|
322 #endif |
304 } |
323 } |
305 |
324 |
306 // Update child's copy of super vtable for overrides |
325 // Update child's copy of super vtable for overrides |
307 // OR return true if a new vtable entry is required. |
326 // OR return true if a new vtable entry is required. |
308 // Only called for InstanceKlass's, i.e. not for arrays |
327 // Only called for InstanceKlass's, i.e. not for arrays |
393 // Check if method name matches |
412 // Check if method name matches |
394 if (super_method->name() == name && super_method->signature() == signature) { |
413 if (super_method->name() == name && super_method->signature() == signature) { |
395 |
414 |
396 // get super_klass for method_holder for the found method |
415 // get super_klass for method_holder for the found method |
397 InstanceKlass* super_klass = super_method->method_holder(); |
416 InstanceKlass* super_klass = super_method->method_holder(); |
|
417 |
|
418 // Whether the method is being overridden |
|
419 bool overrides = false; |
398 |
420 |
399 // private methods are also never overridden |
421 // private methods are also never overridden |
400 if (!super_method->is_private() && |
422 if (!super_method->is_private() && |
401 (is_default |
423 (is_default |
402 || ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) |
424 || ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) |
444 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, |
466 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, |
445 failed_type_name); |
467 failed_type_name); |
446 THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false); |
468 THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false); |
447 } |
469 } |
448 } |
470 } |
449 } |
|
450 |
|
451 put_method_at(target_method(), i); |
|
452 if (!is_default) { |
|
453 target_method()->set_vtable_index(i); |
|
454 } else { |
|
455 if (def_vtable_indices != NULL) { |
|
456 def_vtable_indices->at_put(default_index, i); |
|
457 } |
|
458 assert(super_method->is_default_method() || super_method->is_overpass() |
|
459 || super_method->is_abstract(), "default override error"); |
|
460 } |
|
461 |
|
462 |
|
463 #ifndef PRODUCT |
|
464 if (PrintVtables && Verbose) { |
|
465 ResourceMark rm(THREAD); |
|
466 char* sig = target_method()->name_and_sig_as_C_string(); |
|
467 tty->print("overriding with %s::%s index %d, original flags: ", |
|
468 target_klass->internal_name(), sig, i); |
|
469 super_method->access_flags().print_on(tty); |
|
470 if (super_method->is_default_method()) { |
|
471 tty->print("default "); |
|
472 } |
|
473 if (super_method->is_overpass()) { |
|
474 tty->print("overpass"); |
|
475 } |
|
476 tty->print("overriders flags: "); |
|
477 target_method->access_flags().print_on(tty); |
|
478 if (target_method->is_default_method()) { |
|
479 tty->print("default "); |
|
480 } |
|
481 if (target_method->is_overpass()) { |
|
482 tty->print("overpass"); |
|
483 } |
|
484 tty->cr(); |
|
485 } |
471 } |
486 #endif /*PRODUCT*/ |
472 |
|
473 put_method_at(target_method(), i); |
|
474 overrides = true; |
|
475 if (!is_default) { |
|
476 target_method()->set_vtable_index(i); |
|
477 } else { |
|
478 if (def_vtable_indices != NULL) { |
|
479 def_vtable_indices->at_put(default_index, i); |
|
480 } |
|
481 assert(super_method->is_default_method() || super_method->is_overpass() |
|
482 || super_method->is_abstract(), "default override error"); |
|
483 } |
487 } else { |
484 } else { |
488 // allocate_new = true; default. We might override one entry, |
485 overrides = false; |
489 // but not override another. Once we override one, not need new |
486 } |
490 #ifndef PRODUCT |
487 log_vtables(i, overrides, target_method, target_klass, super_method, THREAD); |
491 if (PrintVtables && Verbose) { |
|
492 ResourceMark rm(THREAD); |
|
493 char* sig = target_method()->name_and_sig_as_C_string(); |
|
494 tty->print("NOT overriding with %s::%s index %d, original flags: ", |
|
495 target_klass->internal_name(), sig,i); |
|
496 super_method->access_flags().print_on(tty); |
|
497 if (super_method->is_default_method()) { |
|
498 tty->print("default "); |
|
499 } |
|
500 if (super_method->is_overpass()) { |
|
501 tty->print("overpass"); |
|
502 } |
|
503 tty->print("overriders flags: "); |
|
504 target_method->access_flags().print_on(tty); |
|
505 if (target_method->is_default_method()) { |
|
506 tty->print("default "); |
|
507 } |
|
508 if (target_method->is_overpass()) { |
|
509 tty->print("overpass"); |
|
510 } |
|
511 tty->cr(); |
|
512 } |
|
513 #endif /*PRODUCT*/ |
|
514 } |
|
515 } |
488 } |
516 } |
489 } |
517 return allocate_new; |
490 return allocate_new; |
518 } |
491 } |
519 |
492 |
520 void klassVtable::put_method_at(Method* m, int index) { |
493 void klassVtable::put_method_at(Method* m, int index) { |
521 #ifndef PRODUCT |
494 if (develop_log_is_enabled(Trace, vtables)) { |
522 if (PrintVtables && Verbose) { |
|
523 ResourceMark rm; |
495 ResourceMark rm; |
|
496 outputStream* logst = LogHandle(vtables)::trace_stream(); |
524 const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>"; |
497 const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>"; |
525 tty->print("adding %s at index %d, flags: ", sig, index); |
498 logst->print("adding %s at index %d, flags: ", sig, index); |
526 if (m != NULL) { |
499 if (m != NULL) { |
527 m->access_flags().print_on(tty); |
500 m->print_linkage_flags(logst); |
528 if (m->is_default_method()) { |
501 } |
529 tty->print("default "); |
502 logst->cr(); |
530 } |
503 } |
531 if (m->is_overpass()) { |
|
532 tty->print("overpass"); |
|
533 } |
|
534 } |
|
535 tty->cr(); |
|
536 } |
|
537 #endif |
|
538 table()[index].set(m); |
504 table()[index].set(m); |
539 } |
505 } |
540 |
506 |
541 // Find out if a method "m" with superclass "super", loader "classloader" and |
507 // Find out if a method "m" with superclass "super", loader "classloader" and |
542 // name "classname" needs a new vtable entry. Let P be a class package defined |
508 // name "classname" needs a new vtable entry. Let P be a class package defined |
850 int klassVtable::fill_in_mirandas(int initialized) { |
816 int klassVtable::fill_in_mirandas(int initialized) { |
851 GrowableArray<Method*> mirandas(20); |
817 GrowableArray<Method*> mirandas(20); |
852 get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(), |
818 get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(), |
853 ik()->default_methods(), ik()->local_interfaces()); |
819 ik()->default_methods(), ik()->local_interfaces()); |
854 for (int i = 0; i < mirandas.length(); i++) { |
820 for (int i = 0; i < mirandas.length(); i++) { |
855 if (PrintVtables && Verbose) { |
821 if (develop_log_is_enabled(Trace, vtables)) { |
856 Method* meth = mirandas.at(i); |
822 Method* meth = mirandas.at(i); |
857 ResourceMark rm(Thread::current()); |
823 ResourceMark rm(Thread::current()); |
|
824 outputStream* logst = LogHandle(vtables)::trace_stream(); |
858 if (meth != NULL) { |
825 if (meth != NULL) { |
859 char* sig = meth->name_and_sig_as_C_string(); |
826 char* sig = meth->name_and_sig_as_C_string(); |
860 tty->print("fill in mirandas with %s index %d, flags: ", |
827 logst->print("fill in mirandas with %s index %d, flags: ", |
861 sig, initialized); |
828 sig, initialized); |
862 meth->access_flags().print_on(tty); |
829 meth->print_linkage_flags(logst); |
863 if (meth->is_default_method()) { |
830 logst->cr(); |
864 tty->print("default "); |
|
865 } |
|
866 tty->cr(); |
|
867 } |
831 } |
868 } |
832 } |
869 put_method_at(mirandas.at(i), initialized); |
833 put_method_at(mirandas.at(i), initialized); |
870 ++initialized; |
834 ++initialized; |
871 } |
835 } |
1034 |
998 |
1035 // There's alway an extra itable entry so we can null-terminate it. |
999 // There's alway an extra itable entry so we can null-terminate it. |
1036 guarantee(size_offset_table() >= 1, "too small"); |
1000 guarantee(size_offset_table() >= 1, "too small"); |
1037 int num_interfaces = size_offset_table() - 1; |
1001 int num_interfaces = size_offset_table() - 1; |
1038 if (num_interfaces > 0) { |
1002 if (num_interfaces > 0) { |
1039 if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count, |
1003 log_develop_debug(itables)("%3d: Initializing itables for %s", ++initialize_count, |
1040 _klass->name()->as_C_string()); |
1004 _klass->name()->as_C_string()); |
1041 |
1005 |
1042 |
1006 |
1043 // Iterate through all interfaces |
1007 // Iterate through all interfaces |
1044 int i; |
1008 int i; |
1045 for(i = 0; i < num_interfaces; i++) { |
1009 for(i = 0; i < num_interfaces; i++) { |
1067 return true; |
1031 return true; |
1068 } |
1032 } |
1069 |
1033 |
1070 int klassItable::assign_itable_indices_for_interface(Klass* klass) { |
1034 int klassItable::assign_itable_indices_for_interface(Klass* klass) { |
1071 // an interface does not have an itable, but its methods need to be numbered |
1035 // an interface does not have an itable, but its methods need to be numbered |
1072 if (TraceItables) tty->print_cr("%3d: Initializing itable indices for interface %s", ++initialize_count, |
1036 log_develop_debug(itables)("%3d: Initializing itable indices for interface %s", |
1073 klass->name()->as_C_string()); |
1037 ++initialize_count, klass->name()->as_C_string()); |
1074 Array<Method*>* methods = InstanceKlass::cast(klass)->methods(); |
1038 Array<Method*>* methods = InstanceKlass::cast(klass)->methods(); |
1075 int nof_methods = methods->length(); |
1039 int nof_methods = methods->length(); |
1076 int ime_num = 0; |
1040 int ime_num = 0; |
1077 for (int i = 0; i < nof_methods; i++) { |
1041 for (int i = 0; i < nof_methods; i++) { |
1078 Method* m = methods->at(i); |
1042 Method* m = methods->at(i); |
1079 if (interface_method_needs_itable_index(m)) { |
1043 if (interface_method_needs_itable_index(m)) { |
1080 assert(!m->is_final_method(), "no final interface methods"); |
1044 assert(!m->is_final_method(), "no final interface methods"); |
1081 // If m is already assigned a vtable index, do not disturb it. |
1045 // If m is already assigned a vtable index, do not disturb it. |
1082 if (TraceItables && Verbose) { |
1046 if (develop_log_is_enabled(Trace, itables)) { |
1083 ResourceMark rm; |
1047 ResourceMark rm; |
1084 const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>"; |
1048 outputStream* logst = LogHandle(itables)::trace_stream(); |
|
1049 assert(m != NULL, "methods can never be null"); |
|
1050 const char* sig = m->name_and_sig_as_C_string(); |
1085 if (m->has_vtable_index()) { |
1051 if (m->has_vtable_index()) { |
1086 tty->print("vtable index %d for method: %s, flags: ", m->vtable_index(), sig); |
1052 logst->print("vtable index %d for method: %s, flags: ", m->vtable_index(), sig); |
1087 } else { |
1053 } else { |
1088 tty->print("itable index %d for method: %s, flags: ", ime_num, sig); |
1054 logst->print("itable index %d for method: %s, flags: ", ime_num, sig); |
1089 } |
1055 } |
1090 if (m != NULL) { |
1056 m->print_linkage_flags(logst); |
1091 m->access_flags().print_on(tty); |
1057 logst->cr(); |
1092 if (m->is_default_method()) { |
|
1093 tty->print("default "); |
|
1094 } |
|
1095 if (m->is_overpass()) { |
|
1096 tty->print("overpass"); |
|
1097 } |
|
1098 } |
|
1099 tty->cr(); |
|
1100 } |
1058 } |
1101 if (!m->has_vtable_index()) { |
1059 if (!m->has_vtable_index()) { |
1102 assert(m->vtable_index() == Method::pending_itable_index, "set by initialize_vtable"); |
1060 assert(m->vtable_index() == Method::pending_itable_index, "set by initialize_vtable"); |
1103 m->set_itable_index(ime_num); |
1061 m->set_itable_index(ime_num); |
1104 // Progress to next itable entry |
1062 // Progress to next itable entry |
1198 |
1156 |
1199 // ime may have moved during GC so recalculate address |
1157 // ime may have moved during GC so recalculate address |
1200 int ime_num = m->itable_index(); |
1158 int ime_num = m->itable_index(); |
1201 assert(ime_num < ime_count, "oob"); |
1159 assert(ime_num < ime_count, "oob"); |
1202 itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target()); |
1160 itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target()); |
1203 if (TraceItables && Verbose) { |
1161 if (develop_log_is_enabled(Trace, itables)) { |
1204 ResourceMark rm(THREAD); |
1162 ResourceMark rm(THREAD); |
1205 if (target() != NULL) { |
1163 if (target() != NULL) { |
|
1164 outputStream* logst = LogHandle(itables)::trace_stream(); |
1206 char* sig = target()->name_and_sig_as_C_string(); |
1165 char* sig = target()->name_and_sig_as_C_string(); |
1207 tty->print("interface: %s, ime_num: %d, target: %s, method_holder: %s ", |
1166 logst->print("interface: %s, ime_num: %d, target: %s, method_holder: %s ", |
1208 interf_h()->internal_name(), ime_num, sig, |
1167 interf_h()->internal_name(), ime_num, sig, |
1209 target()->method_holder()->internal_name()); |
1168 target()->method_holder()->internal_name()); |
1210 tty->print("target_method flags: "); |
1169 logst->print("target_method flags: "); |
1211 target()->access_flags().print_on(tty); |
1170 target()->print_linkage_flags(logst); |
1212 if (target()->is_default_method()) { |
1171 logst->cr(); |
1213 tty->print("default "); |
|
1214 } |
|
1215 tty->cr(); |
|
1216 } |
1172 } |
1217 } |
1173 } |
1218 } |
1174 } |
1219 } |
1175 } |
1220 } |
1176 } |