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