--- /dev/null 2015-11-23 10:40:07.746434391 -0500 +++ new/test/runtime/logging/p1/A.java 2015-12-03 14:13:14.646105270 -0500 @@ -0,0 +1,28 @@ +/* + * 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"); } +} --- /dev/null 2015-11-23 10:40:07.746434391 -0500 +++ new/test/runtime/logging/ClassB.java 2015-12-03 14:13:14.646838287 -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. + */ + +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(); + } +} --- /dev/null 2015-11-23 10:40:07.746434391 -0500 +++ new/test/runtime/logging/VtablesTest.java 2015-12-03 14:13:14.645100112 -0500 @@ -0,0 +1,62 @@ +/* + * 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 + * @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 "); + output.shouldHaveExitValue(0); + + pb = ProcessTools.createJavaProcessBuilder("-Xlog:vtables=trace", "p1/C"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("transitive overriding superclass "); + output.shouldHaveExitValue(0); + } + } +} + --- old/src/share/vm/logging/logTag.hpp 2015-12-03 14:13:14.841296835 -0500 +++ new/src/share/vm/logging/logTag.hpp 2015-12-03 14:13:14.669198950 -0500 @@ -32,9 +32,11 @@ // not be used in log calls, and should not be listed below.) #define LOG_TAG_LIST \ LOG_TAG(defaultmethods) \ + LOG_TAG(itables) \ LOG_TAG(logging) \ LOG_TAG(safepoint) \ - LOG_TAG(vmoperation) + LOG_TAG(vmoperation) \ + LOG_TAG(vtables) #define PREFIX_LOG_TAG(T) (LogTag::T) --- /dev/null 2015-11-23 10:40:07.746434391 -0500 +++ new/test/runtime/logging/ItablesTest.java 2015-12-03 14:13:14.642638115 -0500 @@ -0,0 +1,57 @@ +/* + * 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 + * @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); + } + } +} --- old/src/share/vm/interpreter/linkResolver.cpp 2015-12-03 14:13:14.860721931 -0500 +++ new/src/share/vm/interpreter/linkResolver.cpp 2015-12-03 14:13:14.693521544 -0500 @@ -31,9 +31,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" @@ -727,6 +729,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() ? "" : klass->internal_name()), + (resolved_klass.is_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) { @@ -783,10 +815,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; @@ -1031,10 +1063,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; @@ -1103,10 +1134,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 @@ -1157,10 +1187,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; @@ -1238,10 +1267,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); @@ -1337,10 +1366,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()) { @@ -1587,28 +1615,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() ? "" : klass->internal_name()), - (resolved_klass.is_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 --- old/src/share/vm/interpreter/linkResolver.hpp 2015-12-03 14:13:14.872108788 -0500 +++ new/src/share/vm/interpreter/linkResolver.hpp 2015-12-03 14:13:14.678812962 -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 --- old/src/share/vm/oops/klassVtable.cpp 2015-12-03 14:13:14.872123433 -0500 +++ new/src/share/vm/oops/klassVtable.cpp 2015-12-03 14:13:14.662197742 -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,10 @@ 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 + ResourceMark rm; + log_develop_trace(vtables)("copy vtable from %s to %s size %d", + super->internal_name(), klass()->internal_name(), + _length); return superVtable->length(); } } @@ -152,9 +151,9 @@ KlassHandle super (THREAD, klass()->java_super()); int nofNewEntries = 0; - if (PrintVtables && !klass()->is_array_klass()) { + if (develop_log_is_enabled(Debug, vtables) && !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 +270,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 +297,30 @@ return superk; } +static void log_vtables(int i, bool allocate_new, 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 (allocate_new) { + // allocate_new = true; default. We might override one entry, + logst->print("NOT overriding with %s::%s index %d, original flags: ", + target_klass->internal_name(), sig, i); + } else { + logst->print("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 @@ -446,95 +464,36 @@ 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*/ - } 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(); + + 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"); } -#endif /*PRODUCT*/ } + log_vtables(i, allocate_new, 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() : ""; - 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); } @@ -851,18 +810,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); @@ -1035,8 +992,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 @@ -1068,8 +1025,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* methods = InstanceKlass::cast(klass)->methods(); int nof_methods = methods->length(); int ime_num = 0; @@ -1078,24 +1035,17 @@ 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; + outputStream* logst = LogHandle(itables)::trace_stream(); const char* sig = (m != NULL) ? 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"); @@ -1199,19 +1149,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(); } } } --- old/src/share/vm/interpreter/interpreterRuntime.cpp 2015-12-03 14:13:14.872102702 -0500 +++ new/src/share/vm/interpreter/interpreterRuntime.cpp 2015-12-03 14:13:14.685010264 -0500 @@ -35,6 +35,7 @@ #include "interpreter/interpreterRuntime.hpp" #include "interpreter/linkResolver.hpp" #include "interpreter/templateTable.hpp" +#include "logging/log.hpp" #include "memory/oopFactory.hpp" #include "memory/universe.inline.hpp" #include "oops/constantPool.hpp" @@ -749,10 +750,10 @@ if (cp_cache_entry->is_resolved(bytecode)) return; if (bytecode == Bytecodes::_invokeinterface) { - if (TraceItables && Verbose) { - 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()); - } + ResourceMark rm(thread); + 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 if (bytecode == Bytecodes::_invokeinterface) { --- old/src/share/vm/oops/method.hpp 2015-12-03 14:13:14.872658323 -0500 +++ new/src/share/vm/oops/method.hpp 2015-12-03 14:13:14.667116054 -0500 @@ -459,7 +459,7 @@ int itable_index() const { assert(valid_itable_index(), ""); return itable_index_max - _vtable_index; } void set_itable_index(int index) { _vtable_index = itable_index_max - index; assert(valid_itable_index(), ""); } - + // interpreter entry address interpreter_entry() const { return _i2i_entry; } // Only used when first initialize so we can set _i2i_entry and _from_interpreted_entry @@ -924,6 +924,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}"; } --- old/src/share/vm/oops/method.cpp 2015-12-03 14:13:14.861030454 -0500 +++ new/src/share/vm/oops/method.cpp 2015-12-03 14:13:14.676528415 -0500 @@ -2174,6 +2174,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 { --- old/src/share/vm/runtime/globals.hpp 2015-12-03 14:13:14.931685305 -0500 +++ new/src/share/vm/runtime/globals.hpp 2015-12-03 14:13:14.732324933 -0500 @@ -740,9 +740,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") \ \ @@ -2808,9 +2805,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 2015-11-23 10:40:07.746434391 -0500 +++ new/test/runtime/logging/p1/C.java 2015-12-03 14:13:15.124943177 -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 2015-11-23 10:40:07.746434391 -0500 +++ new/test/runtime/logging/p2/B.jcod 2015-12-03 14:13:16.562887366 -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 ""; // #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