mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-07 04:05:17 +00:00
8141564: Convert TraceItables and PrintVtables to Unified Logging
The former -XX:+TraceItables and +PrintVtables flags have been converted to UL options -Xlog:itables=trace and vtables=trace Reviewed-by: acorn, coleenp, dholmes
This commit is contained in:
parent
98193d202b
commit
6dac872d4d
@ -773,9 +773,11 @@ void InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code byte
|
||||
if (cp_cache_entry->is_resolved(bytecode)) return;
|
||||
|
||||
if (bytecode == Bytecodes::_invokeinterface) {
|
||||
if (TraceItables && Verbose) {
|
||||
if (develop_log_is_enabled(Trace, itables)) {
|
||||
ResourceMark rm(thread);
|
||||
tty->print_cr("Resolving: klass: %s to method: %s", info.resolved_klass()->name()->as_C_string(), info.resolved_method()->name()->as_C_string());
|
||||
log_develop_trace(itables)("Resolving: klass: %s to method: %s",
|
||||
info.resolved_klass()->name()->as_C_string(),
|
||||
info.resolved_method()->name()->as_C_string());
|
||||
}
|
||||
}
|
||||
#ifdef ASSERT
|
||||
|
||||
@ -32,9 +32,11 @@
|
||||
#include "interpreter/bytecode.hpp"
|
||||
#include "interpreter/interpreterRuntime.hpp"
|
||||
#include "interpreter/linkResolver.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "memory/universe.inline.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/method.hpp"
|
||||
#include "oops/objArrayOop.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
@ -728,6 +730,36 @@ methodHandle LinkResolver::resolve_method(const LinkInfo& link_info,
|
||||
return resolved_method;
|
||||
}
|
||||
|
||||
static void trace_method_resolution(const char* prefix,
|
||||
KlassHandle klass,
|
||||
KlassHandle resolved_klass,
|
||||
const methodHandle& method,
|
||||
bool logitables,
|
||||
int index = -1) {
|
||||
#ifndef PRODUCT
|
||||
ResourceMark rm;
|
||||
outputStream* st;
|
||||
if (logitables) {
|
||||
st = LogHandle(itables)::trace_stream();
|
||||
} else {
|
||||
st = LogHandle(vtables)::trace_stream();
|
||||
}
|
||||
st->print("%s%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
|
||||
prefix,
|
||||
(klass.is_null() ? "<NULL>" : klass->internal_name()),
|
||||
(resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
|
||||
Method::name_and_sig_as_C_string(resolved_klass(),
|
||||
method->name(),
|
||||
method->signature()),
|
||||
method->method_holder()->internal_name());
|
||||
method->print_linkage_flags(st);
|
||||
if (index != -1) {
|
||||
st->print("vtable_index:%d", index);
|
||||
}
|
||||
st->cr();
|
||||
#endif // PRODUCT
|
||||
}
|
||||
|
||||
methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
|
||||
bool nostatics, TRAPS) {
|
||||
|
||||
@ -784,10 +816,10 @@ methodHandle LinkResolver::resolve_interface_method(const LinkInfo& link_info,
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||
}
|
||||
|
||||
if (TraceItables && Verbose) {
|
||||
if (develop_log_is_enabled(Trace, itables)) {
|
||||
trace_method_resolution("invokeinterface resolved method: caller-class",
|
||||
link_info.current_klass(), resolved_klass, resolved_method);
|
||||
tty->cr();
|
||||
link_info.current_klass(), resolved_klass,
|
||||
resolved_method, true);
|
||||
}
|
||||
|
||||
return resolved_method;
|
||||
@ -1032,10 +1064,9 @@ methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||
}
|
||||
|
||||
if (TraceItables && Verbose) {
|
||||
if (develop_log_is_enabled(Trace, itables)) {
|
||||
trace_method_resolution("invokespecial resolved method: caller-class:",
|
||||
current_klass, resolved_klass, resolved_method);
|
||||
tty->cr();
|
||||
current_klass, resolved_klass, resolved_method, true);
|
||||
}
|
||||
|
||||
return resolved_method;
|
||||
@ -1104,10 +1135,9 @@ void LinkResolver::runtime_resolve_special_method(CallInfo& result,
|
||||
sel_method->signature()));
|
||||
}
|
||||
|
||||
if (TraceItables && Verbose) {
|
||||
if (develop_log_is_enabled(Trace, itables)) {
|
||||
trace_method_resolution("invokespecial selected method: resolved-class:",
|
||||
resolved_klass, resolved_klass, sel_method);
|
||||
tty->cr();
|
||||
resolved_klass, resolved_klass, sel_method, true);
|
||||
}
|
||||
|
||||
// setup result
|
||||
@ -1158,10 +1188,9 @@ methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
|
||||
}
|
||||
|
||||
if (PrintVtables && Verbose) {
|
||||
if (develop_log_is_enabled(Trace, vtables)) {
|
||||
trace_method_resolution("invokevirtual resolved method: caller-class:",
|
||||
current_klass, resolved_klass, resolved_method);
|
||||
tty->cr();
|
||||
current_klass, resolved_klass, resolved_method, false);
|
||||
}
|
||||
|
||||
return resolved_method;
|
||||
@ -1239,10 +1268,10 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
|
||||
selected_method->signature()));
|
||||
}
|
||||
|
||||
if (PrintVtables && Verbose) {
|
||||
if (develop_log_is_enabled(Trace, vtables)) {
|
||||
trace_method_resolution("invokevirtual selected method: receiver-class:",
|
||||
recv_klass, resolved_klass, selected_method);
|
||||
tty->print_cr("vtable_index:%d", vtable_index);
|
||||
recv_klass, resolved_klass, selected_method,
|
||||
false, vtable_index);
|
||||
}
|
||||
// setup result
|
||||
result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
|
||||
@ -1338,10 +1367,9 @@ void LinkResolver::runtime_resolve_interface_method(CallInfo& result,
|
||||
sel_method->signature()));
|
||||
}
|
||||
|
||||
if (TraceItables && Verbose) {
|
||||
if (develop_log_is_enabled(Trace, itables)) {
|
||||
trace_method_resolution("invokeinterface selected method: receiver-class",
|
||||
recv_klass, resolved_klass, sel_method);
|
||||
tty->cr();
|
||||
recv_klass, resolved_klass, sel_method, true);
|
||||
}
|
||||
// setup result
|
||||
if (!resolved_method->has_itable_index()) {
|
||||
@ -1588,28 +1616,3 @@ void LinkResolver::resolve_dynamic_call(CallInfo& result,
|
||||
result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD);
|
||||
wrap_invokedynamic_exception(CHECK);
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void LinkResolver::trace_method_resolution(const char* prefix,
|
||||
KlassHandle klass,
|
||||
KlassHandle resolved_klass,
|
||||
const methodHandle& method) {
|
||||
ResourceMark rm;
|
||||
tty->print("%s%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
|
||||
prefix,
|
||||
(klass.is_null() ? "<NULL>" : klass->internal_name()),
|
||||
(resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
|
||||
Method::name_and_sig_as_C_string(resolved_klass(),
|
||||
method->name(),
|
||||
method->signature()),
|
||||
method->method_holder()->internal_name()
|
||||
);
|
||||
method->access_flags().print_on(tty);
|
||||
if (method->is_default_method()) {
|
||||
tty->print("default ");
|
||||
}
|
||||
if (method->is_overpass()) {
|
||||
tty->print("overpass ");
|
||||
}
|
||||
}
|
||||
#endif // PRODUCT
|
||||
|
||||
@ -295,9 +295,5 @@ class LinkResolver: AllStatic {
|
||||
static void resolve_invoke(CallInfo& result, Handle recv,
|
||||
const constantPoolHandle& pool, int index,
|
||||
Bytecodes::Code byte, TRAPS);
|
||||
private:
|
||||
static void trace_method_resolution(const char* prefix, KlassHandle klass,
|
||||
KlassHandle resolved_klass,
|
||||
const methodHandle& method) PRODUCT_RETURN;
|
||||
};
|
||||
#endif // SHARE_VM_INTERPRETER_LINKRESOLVER_HPP
|
||||
|
||||
@ -52,6 +52,7 @@
|
||||
LOG_TAG(heap) \
|
||||
LOG_TAG(humongous) \
|
||||
LOG_TAG(ihop) \
|
||||
LOG_TAG(itables) \
|
||||
LOG_TAG(jni) \
|
||||
LOG_TAG(liveness) \
|
||||
LOG_TAG(logging) \
|
||||
@ -80,7 +81,8 @@
|
||||
LOG_TAG(tlab) \
|
||||
LOG_TAG(time) \
|
||||
LOG_TAG(verify) \
|
||||
LOG_TAG(vmoperation)
|
||||
LOG_TAG(vmoperation) \
|
||||
LOG_TAG(vtables)
|
||||
|
||||
#define PREFIX_LOG_TAG(T) (LogTag::_##T)
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#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"
|
||||
@ -134,12 +135,12 @@ int klassVtable::initialize_from_super(KlassHandle super) {
|
||||
superVtable->verify(tty, true);
|
||||
#endif
|
||||
superVtable->copy_vtable_to(table());
|
||||
#ifndef PRODUCT
|
||||
if (PrintVtables && Verbose) {
|
||||
if (develop_log_is_enabled(Trace, vtables)) {
|
||||
ResourceMark rm;
|
||||
tty->print_cr("copy vtable from %s to %s size %d", super->internal_name(), klass()->internal_name(), _length);
|
||||
log_develop_trace(vtables)("copy vtable from %s to %s size %d",
|
||||
super->internal_name(), klass()->internal_name(),
|
||||
_length);
|
||||
}
|
||||
#endif
|
||||
return superVtable->length();
|
||||
}
|
||||
}
|
||||
@ -152,9 +153,9 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
|
||||
KlassHandle super (THREAD, klass()->java_super());
|
||||
int nofNewEntries = 0;
|
||||
|
||||
if (PrintVtables && !klass()->is_array_klass()) {
|
||||
if (!klass()->is_array_klass()) {
|
||||
ResourceMark rm(THREAD);
|
||||
tty->print_cr("Initializing: %s", _klass->name()->as_C_string());
|
||||
log_develop_debug(vtables)("Initializing: %s", _klass->name()->as_C_string());
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
@ -271,24 +272,19 @@ InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper
|
||||
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) {
|
||||
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();
|
||||
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 ");
|
||||
}
|
||||
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();
|
||||
}
|
||||
#endif /*PRODUCT*/
|
||||
|
||||
break; // return found superk
|
||||
}
|
||||
} else {
|
||||
@ -303,6 +299,29 @@ InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper
|
||||
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
|
||||
@ -396,6 +415,9 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar
|
||||
// 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
|
||||
@ -446,95 +468,39 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar
|
||||
THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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*/
|
||||
|
||||
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 {
|
||||
// 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*/
|
||||
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) {
|
||||
#ifndef PRODUCT
|
||||
if (PrintVtables && Verbose) {
|
||||
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>";
|
||||
tty->print("adding %s at index %d, flags: ", sig, index);
|
||||
logst->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");
|
||||
}
|
||||
m->print_linkage_flags(logst);
|
||||
}
|
||||
tty->cr();
|
||||
logst->cr();
|
||||
}
|
||||
#endif
|
||||
table()[index].set(m);
|
||||
}
|
||||
|
||||
@ -852,18 +818,16 @@ int klassVtable::fill_in_mirandas(int initialized) {
|
||||
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) {
|
||||
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();
|
||||
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();
|
||||
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);
|
||||
@ -1036,8 +1000,8 @@ void klassItable::initialize_itable(bool checkconstraints, TRAPS) {
|
||||
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());
|
||||
log_develop_debug(itables)("%3d: Initializing itables for %s", ++initialize_count,
|
||||
_klass->name()->as_C_string());
|
||||
|
||||
|
||||
// Iterate through all interfaces
|
||||
@ -1069,8 +1033,8 @@ inline bool interface_method_needs_itable_index(Method* m) {
|
||||
|
||||
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());
|
||||
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;
|
||||
@ -1079,24 +1043,18 @@ int klassItable::assign_itable_indices_for_interface(Klass* klass) {
|
||||
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) {
|
||||
if (develop_log_is_enabled(Trace, itables)) {
|
||||
ResourceMark rm;
|
||||
const char* sig = (m != NULL) ? m->name_and_sig_as_C_string() : "<NULL>";
|
||||
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()) {
|
||||
tty->print("vtable index %d for method: %s, flags: ", m->vtable_index(), sig);
|
||||
logst->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);
|
||||
logst->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();
|
||||
m->print_linkage_flags(logst);
|
||||
logst->cr();
|
||||
}
|
||||
if (!m->has_vtable_index()) {
|
||||
assert(m->vtable_index() == Method::pending_itable_index, "set by initialize_vtable");
|
||||
@ -1200,19 +1158,17 @@ void klassItable::initialize_itable_for_interface(int method_table_offset, Klass
|
||||
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) {
|
||||
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();
|
||||
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();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2207,6 +2207,15 @@ void Method::print_on(outputStream* st) const {
|
||||
}
|
||||
}
|
||||
|
||||
void Method::print_linkage_flags(outputStream* st) {
|
||||
access_flags().print_on(st);
|
||||
if (is_default_method()) {
|
||||
st->print("default ");
|
||||
}
|
||||
if (is_overpass()) {
|
||||
st->print("overpass ");
|
||||
}
|
||||
}
|
||||
#endif //PRODUCT
|
||||
|
||||
void Method::print_value_on(outputStream* st) const {
|
||||
|
||||
@ -939,6 +939,7 @@ class Method : public Metadata {
|
||||
void print_on(outputStream* st) const;
|
||||
#endif
|
||||
void print_value_on(outputStream* st) const;
|
||||
void print_linkage_flags(outputStream* st) PRODUCT_RETURN;
|
||||
|
||||
const char* internal_name() const { return "{method}"; }
|
||||
|
||||
|
||||
@ -741,9 +741,6 @@ public:
|
||||
product(bool, ForceTimeHighResolution, false, \
|
||||
"Using high time resolution (for Win32 only)") \
|
||||
\
|
||||
develop(bool, TraceItables, false, \
|
||||
"Trace initialization and use of itables") \
|
||||
\
|
||||
develop(bool, TracePcPatching, false, \
|
||||
"Trace usage of frame::patch_pc") \
|
||||
\
|
||||
@ -2699,9 +2696,6 @@ public:
|
||||
develop(bool, DebugVtables, false, \
|
||||
"add debugging code to vtable dispatch") \
|
||||
\
|
||||
develop(bool, PrintVtables, false, \
|
||||
"print vtables when printing klass") \
|
||||
\
|
||||
notproduct(bool, PrintVtableStats, false, \
|
||||
"print vtables stats at end of run") \
|
||||
\
|
||||
|
||||
67
hotspot/test/runtime/logging/ClassB.java
Normal file
67
hotspot/test/runtime/logging/ClassB.java
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import p2.D;
|
||||
|
||||
interface InterfaceA {
|
||||
public void Method1();
|
||||
public void Method2();
|
||||
}
|
||||
|
||||
class ClassA implements InterfaceA {
|
||||
public void Method1() {
|
||||
System.out.println("ClassA's Method1");
|
||||
}
|
||||
public void Method2() {
|
||||
System.out.println("ClassA's Method2");
|
||||
}
|
||||
public void Method3() {
|
||||
System.out.println("ClassA's Method3");
|
||||
}
|
||||
public void Method4() {
|
||||
System.out.println("ClassA's Method4");
|
||||
}
|
||||
}
|
||||
|
||||
public class ClassB extends ClassA {
|
||||
public void Method1() {
|
||||
System.out.println("ClassB's Method1");
|
||||
}
|
||||
public void Method3() {
|
||||
System.out.println("ClassB's Method3");
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
ClassB classBObj = new ClassB();
|
||||
classBObj.Method1();
|
||||
classBObj.Method2();
|
||||
classBObj.Method3();
|
||||
classBObj.Method4();
|
||||
ClassA classAObj = new ClassA();
|
||||
classAObj.Method1();
|
||||
classAObj.Method2();
|
||||
classAObj.Method3();
|
||||
classAObj.Method4();
|
||||
D classD = new D();
|
||||
D.loadD();
|
||||
}
|
||||
}
|
||||
58
hotspot/test/runtime/logging/ItablesTest.java
Normal file
58
hotspot/test/runtime/logging/ItablesTest.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8141564
|
||||
* @summary itables=trace should have logging from each of the statements
|
||||
* in the code
|
||||
* @library /testlibrary
|
||||
* @ignore 8146435
|
||||
* @compile ClassB.java
|
||||
* @modules java.base/sun.misc
|
||||
* java.management
|
||||
* @run driver ItablesTest
|
||||
*/
|
||||
|
||||
import jdk.test.lib.*;
|
||||
|
||||
public class ItablesTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (Platform.isDebugBuild()) {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||
"-Xlog:itables=trace", "ClassB");
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
output.shouldContain(": Initializing itables for ClassB");
|
||||
output.shouldContain(": Initializing itable indices for interface ");
|
||||
output.shouldContain("vtable index ");
|
||||
output.shouldContain("itable index ");
|
||||
output.shouldContain("target: ClassB.Method1()V, method_holder: ClassB target_method flags: public");
|
||||
output.shouldContain("invokeinterface resolved method: caller-class");
|
||||
output.shouldContain("invokespecial resolved method: caller-class:ClassB");
|
||||
output.shouldContain("invokespecial selected method: resolved-class:ClassB");
|
||||
output.shouldContain("invokeinterface selected method: receiver-class");
|
||||
output.shouldContain("Resolving: klass: ");
|
||||
output.shouldHaveExitValue(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
63
hotspot/test/runtime/logging/VtablesTest.java
Normal file
63
hotspot/test/runtime/logging/VtablesTest.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8141564
|
||||
* @summary vtables=trace should have logging from each of the statements in the code
|
||||
* @library /testlibrary
|
||||
* @compile ClassB.java
|
||||
* p1/A.java
|
||||
* p2/B.jcod
|
||||
* p1/C.java
|
||||
* p2/D.java
|
||||
* @modules java.base/sun.misc
|
||||
* java.management
|
||||
* @run driver VtablesTest
|
||||
*/
|
||||
|
||||
import jdk.test.lib.*;
|
||||
|
||||
public class VtablesTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (Platform.isDebugBuild()) {
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||
"-Xlog:vtables=trace", "ClassB");
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
output.shouldContain("copy vtable from ClassA to ClassB");
|
||||
output.shouldContain("Initializing: ClassB");
|
||||
output.shouldContain("adding ClassB.Method1()V");
|
||||
output.shouldContain("] overriding with ClassB::ClassB.Method2()V");
|
||||
output.shouldContain("invokevirtual resolved method: caller-class:ClassB");
|
||||
output.shouldContain("invokevirtual selected method: receiver-class:ClassB");
|
||||
output.shouldContain("NOT overriding with p2.D::p2.D.nooverride()V");
|
||||
output.shouldHaveExitValue(0);
|
||||
|
||||
pb = ProcessTools.createJavaProcessBuilder("-Xlog:vtables=trace", "p1/C");
|
||||
output = new OutputAnalyzer(pb.start());
|
||||
output.shouldContain("transitive overriding superclass ");
|
||||
output.shouldHaveExitValue(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
29
hotspot/test/runtime/logging/p1/A.java
Normal file
29
hotspot/test/runtime/logging/p1/A.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p1;
|
||||
|
||||
public class A {
|
||||
public void test() { System.out.println("In A's test method"); }
|
||||
void nooverride() {}
|
||||
}
|
||||
34
hotspot/test/runtime/logging/p1/C.java
Normal file
34
hotspot/test/runtime/logging/p1/C.java
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p1;
|
||||
|
||||
import p2.B;
|
||||
|
||||
public class C extends B {
|
||||
public void test() { System.out.println("In C's test method"); }
|
||||
public static void main(String args[]) {
|
||||
C c = new C();
|
||||
c.test();
|
||||
}
|
||||
}
|
||||
125
hotspot/test/runtime/logging/p2/B.jcod
Normal file
125
hotspot/test/runtime/logging/p2/B.jcod
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
class p2/B {
|
||||
0xCAFEBABE;
|
||||
0; // minor version
|
||||
52; // version
|
||||
[28] { // Constant Pool
|
||||
; // first element is empty
|
||||
Method #6 #14; // #1 at 0x0A
|
||||
Field #15 #16; // #2 at 0x0F
|
||||
String #17; // #3 at 0x14
|
||||
Method #18 #19; // #4 at 0x17
|
||||
class #20; // #5 at 0x1C
|
||||
class #21; // #6 at 0x1F
|
||||
Utf8 "<init>"; // #7 at 0x22
|
||||
Utf8 "()V"; // #8 at 0x2B
|
||||
Utf8 "Code"; // #9 at 0x31
|
||||
Utf8 "LineNumberTable"; // #10 at 0x38
|
||||
Utf8 "test"; // #11 at 0x4A
|
||||
Utf8 "SourceFile"; // #12 at 0x52
|
||||
Utf8 "B.java"; // #13 at 0x5F
|
||||
NameAndType #7 #8; // #14 at 0x68
|
||||
class #22; // #15 at 0x6D
|
||||
NameAndType #23 #24; // #16 at 0x70
|
||||
Utf8 "In B's test method"; // #17 at 0x75
|
||||
class #25; // #18 at 0x8A
|
||||
NameAndType #26 #27; // #19 at 0x8D
|
||||
Utf8 "p2/B"; // #20 at 0x92
|
||||
Utf8 "p1/A"; // #21 at 0x99
|
||||
Utf8 "java/lang/System"; // #22 at 0xA0
|
||||
Utf8 "out"; // #23 at 0xB3
|
||||
Utf8 "Ljava/io/PrintStream;"; // #24 at 0xB9
|
||||
Utf8 "java/io/PrintStream"; // #25 at 0xD1
|
||||
Utf8 "println"; // #26 at 0xE7
|
||||
Utf8 "(Ljava/lang/String;)V"; // #27 at 0xF1
|
||||
} // Constant Pool
|
||||
|
||||
0x0021; // access
|
||||
#5;// this_cpx
|
||||
#6;// super_cpx
|
||||
|
||||
[0] { // Interfaces
|
||||
} // Interfaces
|
||||
|
||||
[0] { // fields
|
||||
} // fields
|
||||
|
||||
[2] { // methods
|
||||
{ // Member at 0x0115
|
||||
0x0001; // access
|
||||
#7; // name_cpx
|
||||
#8; // sig_cpx
|
||||
[1] { // Attributes
|
||||
Attr(#9, 29) { // Code at 0x011D
|
||||
1; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[5]{
|
||||
0x2AB70001B1;
|
||||
};
|
||||
[0] { // Traps
|
||||
} // end Traps
|
||||
[1] { // Attributes
|
||||
Attr(#10, 6) { // LineNumberTable at 0x0134
|
||||
[1] { // LineNumberTable
|
||||
0 5; // at 0x0140
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
;
|
||||
{ // Member at 0x0140
|
||||
0x0000; // access
|
||||
#11; // name_cpx
|
||||
#8; // sig_cpx
|
||||
[1] { // Attributes
|
||||
Attr(#9, 33) { // Code at 0x0148
|
||||
2; // max_stack
|
||||
1; // max_locals
|
||||
Bytes[9]{
|
||||
0xB200021203B60004;
|
||||
0xB1;
|
||||
};
|
||||
[0] { // Traps
|
||||
} // end Traps
|
||||
[1] { // Attributes
|
||||
Attr(#10, 6) { // LineNumberTable at 0x0163
|
||||
[1] { // LineNumberTable
|
||||
0 6; // at 0x016F
|
||||
}
|
||||
} // end LineNumberTable
|
||||
} // Attributes
|
||||
} // end Code
|
||||
} // Attributes
|
||||
} // Member
|
||||
} // methods
|
||||
|
||||
[1] { // Attributes
|
||||
Attr(#12, 2) { // SourceFile at 0x0171
|
||||
#13;
|
||||
} // end SourceFile
|
||||
} // Attributes
|
||||
} // end class p2/B
|
||||
29
hotspot/test/runtime/logging/p2/D.java
Normal file
29
hotspot/test/runtime/logging/p2/D.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p2;
|
||||
|
||||
public class D extends p1.A {
|
||||
void nooverride() {}
|
||||
public static void loadD() {}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user