src/share/vm/oops/klassVtable.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8141564.03 Cdiff src/share/vm/oops/klassVtable.cpp

src/share/vm/oops/klassVtable.cpp

Print this page

        

*** 24,33 **** --- 24,34 ---- #include "precompiled.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "gc/shared/gcLocker.hpp" + #include "logging/log.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.inline.hpp" #include "oops/instanceKlass.hpp" #include "oops/klassVtable.hpp" #include "oops/method.hpp"
*** 132,147 **** assert(superVtable->length() <= _length, "vtable too short"); #ifdef ASSERT superVtable->verify(tty, true); #endif superVtable->copy_vtable_to(table()); - #ifndef PRODUCT - if (PrintVtables && Verbose) { ResourceMark rm; ! tty->print_cr("copy vtable from %s to %s size %d", super->internal_name(), klass()->internal_name(), _length); ! } ! #endif return superVtable->length(); } } // --- 133,146 ---- assert(superVtable->length() <= _length, "vtable too short"); #ifdef ASSERT superVtable->verify(tty, true); #endif superVtable->copy_vtable_to(table()); ResourceMark rm; ! log_develop_trace(vtables)("copy vtable from %s to %s size %d", ! super->internal_name(), klass()->internal_name(), ! _length); return superVtable->length(); } } //
*** 150,162 **** // Note: Arrays can have intermediate array supers. Use java_super to skip them. KlassHandle super (THREAD, klass()->java_super()); int nofNewEntries = 0; ! if (PrintVtables && !klass()->is_array_klass()) { ResourceMark rm(THREAD); ! tty->print_cr("Initializing: %s", _klass->name()->as_C_string()); } #ifdef ASSERT oop* end_of_obj = (oop*)_klass() + _klass()->size(); oop* end_of_vtable = (oop*)&table()[_length]; --- 149,161 ---- // Note: Arrays can have intermediate array supers. Use java_super to skip them. KlassHandle super (THREAD, klass()->java_super()); int nofNewEntries = 0; ! if (!klass()->is_array_klass()) { ResourceMark rm(THREAD); ! log_develop_debug(vtables)("Initializing: %s", _klass->name()->as_C_string()); } #ifdef ASSERT oop* end_of_obj = (oop*)_klass() + _klass()->size(); oop* end_of_vtable = (oop*)&table()[_length];
*** 269,296 **** Symbol* name= target_method()->name(); Symbol* signature = target_method()->signature(); assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch"); #endif if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { ! #ifndef PRODUCT ! if (PrintVtables && Verbose) { ResourceMark rm(THREAD); char* sig = target_method()->name_and_sig_as_C_string(); ! tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ", supersuperklass->internal_name(), _klass->internal_name(), sig, vtable_index); ! super_method->access_flags().print_on(tty); ! if (super_method->is_default_method()) { ! tty->print("default "); } ! tty->print("overriders flags: "); ! target_method->access_flags().print_on(tty); ! if (target_method->is_default_method()) { ! tty->print("default "); ! } ! } ! #endif /*PRODUCT*/ break; // return found superk } } else { // super class has no vtable entry here, stop transitive search superk = (InstanceKlass*)NULL; --- 268,290 ---- Symbol* name= target_method()->name(); Symbol* signature = target_method()->signature(); assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch"); #endif if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { ! if (develop_log_is_enabled(Trace, vtables)) { ResourceMark rm(THREAD); + outputStream* logst = LogHandle(vtables)::trace_stream(); char* sig = target_method()->name_and_sig_as_C_string(); ! logst->print("transitive overriding superclass %s with %s::%s index %d, original flags: ", supersuperklass->internal_name(), _klass->internal_name(), sig, vtable_index); ! super_method->print_linkage_flags(logst); ! logst->print("overriders flags: "); ! target_method->print_linkage_flags(logst); ! logst->cr(); } ! break; // return found superk } } else { // super class has no vtable entry here, stop transitive search superk = (InstanceKlass*)NULL;
*** 301,310 **** --- 295,327 ---- } return superk; } + static void log_vtables(int i, bool overrides, methodHandle target_method, + KlassHandle target_klass, Method* super_method, + Thread* thread) { + #ifndef PRODUCT + if (develop_log_is_enabled(Trace, vtables)) { + ResourceMark rm(thread); + outputStream* logst = LogHandle(vtables)::trace_stream(); + char* sig = target_method()->name_and_sig_as_C_string(); + if (overrides) { + logst->print("overriding with %s::%s index %d, original flags: ", + target_klass->internal_name(), sig, i); + } else { + logst->print("NOT overriding with %s::%s index %d, original flags: ", + target_klass->internal_name(), sig, i); + } + super_method->print_linkage_flags(logst); + logst->print("overriders flags: "); + target_method->print_linkage_flags(logst); + logst->cr(); + } + #endif + } + // Update child's copy of super vtable for overrides // OR return true if a new vtable entry is required. // Only called for InstanceKlass's, i.e. not for arrays // If that changed, could not use _klass as handle for klass bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle target_method,
*** 394,403 **** --- 411,423 ---- if (super_method->name() == name && super_method->signature() == signature) { // get super_klass for method_holder for the found method InstanceKlass* super_klass = super_method->method_holder(); + // Whether the method is being overridden + bool overrides = false; + // private methods are also never overridden if (!super_method->is_private() && (is_default || ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) || ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION)
*** 447,542 **** } } } put_method_at(target_method(), i); if (!is_default) { target_method()->set_vtable_index(i); } else { if (def_vtable_indices != NULL) { def_vtable_indices->at_put(default_index, i); } assert(super_method->is_default_method() || super_method->is_overpass() || super_method->is_abstract(), "default override error"); } - - - #ifndef PRODUCT - if (PrintVtables && Verbose) { - ResourceMark rm(THREAD); - char* sig = target_method()->name_and_sig_as_C_string(); - tty->print("overriding with %s::%s index %d, original flags: ", - target_klass->internal_name(), sig, i); - super_method->access_flags().print_on(tty); - if (super_method->is_default_method()) { - tty->print("default "); - } - if (super_method->is_overpass()) { - tty->print("overpass"); - } - tty->print("overriders flags: "); - target_method->access_flags().print_on(tty); - if (target_method->is_default_method()) { - tty->print("default "); - } - if (target_method->is_overpass()) { - tty->print("overpass"); - } - tty->cr(); - } - #endif /*PRODUCT*/ } else { ! // allocate_new = true; default. We might override one entry, ! // but not override another. Once we override one, not need new ! #ifndef PRODUCT ! if (PrintVtables && Verbose) { ! ResourceMark rm(THREAD); ! char* sig = target_method()->name_and_sig_as_C_string(); ! tty->print("NOT overriding with %s::%s index %d, original flags: ", ! target_klass->internal_name(), sig,i); ! super_method->access_flags().print_on(tty); ! if (super_method->is_default_method()) { ! tty->print("default "); ! } ! if (super_method->is_overpass()) { ! tty->print("overpass"); ! } ! tty->print("overriders flags: "); ! target_method->access_flags().print_on(tty); ! if (target_method->is_default_method()) { ! tty->print("default "); ! } ! if (target_method->is_overpass()) { ! tty->print("overpass"); ! } ! tty->cr(); ! } ! #endif /*PRODUCT*/ } } } return allocate_new; } void klassVtable::put_method_at(Method* m, int index) { ! #ifndef PRODUCT ! if (PrintVtables && Verbose) { ResourceMark rm; const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>"; ! tty->print("adding %s at index %d, flags: ", sig, index); if (m != NULL) { ! m->access_flags().print_on(tty); ! if (m->is_default_method()) { ! tty->print("default "); ! } ! if (m->is_overpass()) { ! tty->print("overpass"); ! } } ! tty->cr(); } - #endif table()[index].set(m); } // Find out if a method "m" with superclass "super", loader "classloader" and // name "classname" needs a new vtable entry. Let P be a class package defined --- 467,506 ---- } } } put_method_at(target_method(), i); + overrides = true; if (!is_default) { target_method()->set_vtable_index(i); } else { if (def_vtable_indices != NULL) { def_vtable_indices->at_put(default_index, i); } assert(super_method->is_default_method() || super_method->is_overpass() || super_method->is_abstract(), "default override error"); } } else { ! overrides = false; } + log_vtables(i, overrides, target_method, target_klass, super_method, THREAD); } } return allocate_new; } void klassVtable::put_method_at(Method* m, int index) { ! if (develop_log_is_enabled(Trace, vtables)) { ResourceMark rm; + outputStream* logst = LogHandle(vtables)::trace_stream(); const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>"; ! logst->print("adding %s at index %d, flags: ", sig, index); if (m != NULL) { ! m->print_linkage_flags(logst); } ! logst->cr(); } table()[index].set(m); } // Find out if a method "m" with superclass "super", loader "classloader" and // name "classname" needs a new vtable entry. Let P be a class package defined
*** 850,871 **** int klassVtable::fill_in_mirandas(int initialized) { GrowableArray<Method*> mirandas(20); get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(), ik()->default_methods(), ik()->local_interfaces()); for (int i = 0; i < mirandas.length(); i++) { ! if (PrintVtables && Verbose) { Method* meth = mirandas.at(i); ResourceMark rm(Thread::current()); if (meth != NULL) { char* sig = meth->name_and_sig_as_C_string(); ! tty->print("fill in mirandas with %s index %d, flags: ", sig, initialized); ! meth->access_flags().print_on(tty); ! if (meth->is_default_method()) { ! tty->print("default "); ! } ! tty->cr(); } } put_method_at(mirandas.at(i), initialized); ++initialized; } --- 814,833 ---- int klassVtable::fill_in_mirandas(int initialized) { GrowableArray<Method*> mirandas(20); get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(), ik()->default_methods(), ik()->local_interfaces()); for (int i = 0; i < mirandas.length(); i++) { ! if (develop_log_is_enabled(Trace, vtables)) { Method* meth = mirandas.at(i); ResourceMark rm(Thread::current()); + outputStream* logst = LogHandle(vtables)::trace_stream(); if (meth != NULL) { char* sig = meth->name_and_sig_as_C_string(); ! logst->print("fill in mirandas with %s index %d, flags: ", sig, initialized); ! meth->print_linkage_flags(logst); ! logst->cr(); } } put_method_at(mirandas.at(i), initialized); ++initialized; }
*** 1034,1044 **** // There's alway an extra itable entry so we can null-terminate it. guarantee(size_offset_table() >= 1, "too small"); int num_interfaces = size_offset_table() - 1; if (num_interfaces > 0) { ! if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count, _klass->name()->as_C_string()); // Iterate through all interfaces int i; --- 996,1006 ---- // There's alway an extra itable entry so we can null-terminate it. guarantee(size_offset_table() >= 1, "too small"); int num_interfaces = size_offset_table() - 1; if (num_interfaces > 0) { ! log_develop_debug(itables)("%3d: Initializing itables for %s", ++initialize_count, _klass->name()->as_C_string()); // Iterate through all interfaces int i;
*** 1067,1104 **** return true; } int klassItable::assign_itable_indices_for_interface(Klass* klass) { // an interface does not have an itable, but its methods need to be numbered ! if (TraceItables) tty->print_cr("%3d: Initializing itable indices for interface %s", ++initialize_count, ! klass->name()->as_C_string()); Array<Method*>* methods = InstanceKlass::cast(klass)->methods(); int nof_methods = methods->length(); int ime_num = 0; for (int i = 0; i < nof_methods; i++) { Method* m = methods->at(i); if (interface_method_needs_itable_index(m)) { assert(!m->is_final_method(), "no final interface methods"); // If m is already assigned a vtable index, do not disturb it. ! if (TraceItables && Verbose) { ResourceMark rm; ! const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>"; if (m->has_vtable_index()) { ! tty->print("vtable index %d for method: %s, flags: ", m->vtable_index(), sig); } else { ! tty->print("itable index %d for method: %s, flags: ", ime_num, sig); } ! if (m != NULL) { ! m->access_flags().print_on(tty); ! if (m->is_default_method()) { ! tty->print("default "); ! } ! if (m->is_overpass()) { ! tty->print("overpass"); ! } ! } ! tty->cr(); } if (!m->has_vtable_index()) { assert(m->vtable_index() == Method::pending_itable_index, "set by initialize_vtable"); m->set_itable_index(ime_num); // Progress to next itable entry --- 1029,1060 ---- return true; } int klassItable::assign_itable_indices_for_interface(Klass* klass) { // an interface does not have an itable, but its methods need to be numbered ! log_develop_debug(itables)("%3d: Initializing itable indices for interface %s", ! ++initialize_count, klass->name()->as_C_string()); Array<Method*>* methods = InstanceKlass::cast(klass)->methods(); int nof_methods = methods->length(); int ime_num = 0; for (int i = 0; i < nof_methods; i++) { Method* m = methods->at(i); if (interface_method_needs_itable_index(m)) { assert(!m->is_final_method(), "no final interface methods"); // If m is already assigned a vtable index, do not disturb it. ! if (develop_log_is_enabled(Trace, itables)) { ResourceMark rm; ! outputStream* logst = LogHandle(itables)::trace_stream(); ! assert(m != NULL, "methods can never be null"); ! const char* sig = m->name_and_sig_as_C_string(); if (m->has_vtable_index()) { ! logst->print("vtable index %d for method: %s, flags: ", m->vtable_index(), sig); } else { ! logst->print("itable index %d for method: %s, flags: ", ime_num, sig); } ! m->print_linkage_flags(logst); ! logst->cr(); } if (!m->has_vtable_index()) { assert(m->vtable_index() == Method::pending_itable_index, "set by initialize_vtable"); m->set_itable_index(ime_num); // Progress to next itable entry
*** 1198,1220 **** // ime may have moved during GC so recalculate address int ime_num = m->itable_index(); assert(ime_num < ime_count, "oob"); itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target()); ! if (TraceItables && Verbose) { ResourceMark rm(THREAD); if (target() != NULL) { char* sig = target()->name_and_sig_as_C_string(); ! tty->print("interface: %s, ime_num: %d, target: %s, method_holder: %s ", interf_h()->internal_name(), ime_num, sig, target()->method_holder()->internal_name()); ! tty->print("target_method flags: "); ! target()->access_flags().print_on(tty); ! if (target()->is_default_method()) { ! tty->print("default "); ! } ! tty->cr(); } } } } } --- 1154,1174 ---- // ime may have moved during GC so recalculate address int ime_num = m->itable_index(); assert(ime_num < ime_count, "oob"); itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target()); ! if (develop_log_is_enabled(Trace, itables)) { ResourceMark rm(THREAD); if (target() != NULL) { + outputStream* logst = LogHandle(itables)::trace_stream(); char* sig = target()->name_and_sig_as_C_string(); ! logst->print("interface: %s, ime_num: %d, target: %s, method_holder: %s ", interf_h()->internal_name(), ime_num, sig, target()->method_holder()->internal_name()); ! logst->print("target_method flags: "); ! target()->print_linkage_flags(logst); ! logst->cr(); } } } } }
src/share/vm/oops/klassVtable.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File