8141564: Convert TraceItables and PrintVtables to Unified Logging
Summary: The former -XX:+TraceItables and +PrintVtables flags have been converted to UL options -Xlog:itables=trace and vtables=trace
Reviewed-by: acorn, coleenp, dholmes
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Jan 07 16:25:53 2016 +0100
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Jan 07 13:53:20 2016 -0500
@@ -773,9 +773,11 @@
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
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Jan 07 16:25:53 2016 +0100
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Jan 07 13:53:20 2016 -0500
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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
--- a/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Jan 07 16:25:53 2016 +0100
+++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Jan 07 13:53:20 2016 -0500
@@ -295,9 +295,5 @@
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
--- a/hotspot/src/share/vm/logging/logTag.hpp Thu Jan 07 16:25:53 2016 +0100
+++ b/hotspot/src/share/vm/logging/logTag.hpp Thu Jan 07 13:53:20 2016 -0500
@@ -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)
--- a/hotspot/src/share/vm/oops/klassVtable.cpp Thu Jan 07 16:25:53 2016 +0100
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp Thu Jan 07 13:53:20 2016 -0500
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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();
+ 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");
}
-#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*/
+ 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 @@
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 @@
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 @@
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 @@
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 @@
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();
}
}
}
--- a/hotspot/src/share/vm/oops/method.cpp Thu Jan 07 16:25:53 2016 +0100
+++ b/hotspot/src/share/vm/oops/method.cpp Thu Jan 07 13:53:20 2016 -0500
@@ -2207,6 +2207,15 @@
}
}
+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 {
--- a/hotspot/src/share/vm/oops/method.hpp Thu Jan 07 16:25:53 2016 +0100
+++ b/hotspot/src/share/vm/oops/method.hpp Thu Jan 07 13:53:20 2016 -0500
@@ -939,6 +939,7 @@
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}"; }
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Jan 07 16:25:53 2016 +0100
+++ b/hotspot/src/share/vm/runtime/globals.hpp Thu Jan 07 13:53:20 2016 -0500
@@ -741,9 +741,6 @@
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 @@
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") \
\
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/ClassB.java Thu Jan 07 13:53:20 2016 -0500
@@ -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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/ItablesTest.java Thu Jan 07 13:53:20 2016 -0500
@@ -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);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/VtablesTest.java Thu Jan 07 13:53:20 2016 -0500
@@ -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);
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/p1/A.java Thu Jan 07 13:53:20 2016 -0500
@@ -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() {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/p1/C.java Thu Jan 07 13:53:20 2016 -0500
@@ -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();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/p2/B.jcod Thu Jan 07 13:53:20 2016 -0500
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/logging/p2/D.java Thu Jan 07 13:53:20 2016 -0500
@@ -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() {}
+}