# HG changeset patch # User acorn # Date 1238000968 14400 # Node ID ee9da33d43ab44f7d24efac8ee9fa799994a3f64 # Parent 2e18a3d0155bed922ed543ee79853334030e29fb 6603316: Improve instrumentation for classes loaded at startup Reviewed-by: xlu, mchung diff -r 2e18a3d0155b -r ee9da33d43ab hotspot/src/share/vm/classfile/classFileParser.cpp --- a/hotspot/src/share/vm/classfile/classFileParser.cpp Mon Mar 23 10:42:20 2009 -0400 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Mar 25 13:09:28 2009 -0400 @@ -3230,7 +3230,7 @@ // print out the superclass. const char * from = Klass::cast(this_klass())->external_name(); if (this_klass->java_super() != NULL) { - tty->print("RESOLVE %s %s\n", from, instanceKlass::cast(this_klass->java_super())->external_name()); + tty->print("RESOLVE %s %s (super)\n", from, instanceKlass::cast(this_klass->java_super())->external_name()); } // print out each of the interface classes referred to by this class. objArrayHandle local_interfaces(THREAD, this_klass->local_interfaces()); @@ -3240,7 +3240,7 @@ klassOop k = klassOop(local_interfaces->obj_at(i)); instanceKlass* to_class = instanceKlass::cast(k); const char * to = to_class->external_name(); - tty->print("RESOLVE %s %s\n", from, to); + tty->print("RESOLVE %s %s (interface)\n", from, to); } } } diff -r 2e18a3d0155b -r ee9da33d43ab hotspot/src/share/vm/prims/jni.cpp --- a/hotspot/src/share/vm/prims/jni.cpp Mon Mar 23 10:42:20 2009 -0400 +++ b/hotspot/src/share/vm/prims/jni.cpp Wed Mar 25 13:09:28 2009 -0400 @@ -301,6 +301,10 @@ klassOop k = SystemDictionary::resolve_from_stream(class_name, class_loader, Handle(), &st, CHECK_NULL); + if (TraceClassResolution && k != NULL) { + trace_class_resolution(k); + } + cls = (jclass)JNIHandles::make_local( env, Klass::cast(k)->java_mirror()); return cls; @@ -365,6 +369,10 @@ result = find_class_from_class_loader(env, sym, true, loader, protection_domain, true, thread); + if (TraceClassResolution && result != NULL) { + trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result))); + } + // If we were the first invocation of jni_FindClass, we enable compilation again // rather than just allowing invocation counter to overflow and decay. // Controlled by flag DelayCompilationDuringStartup. @@ -2646,7 +2654,12 @@ Handle protection_domain; // null protection domain symbolHandle sym = oopFactory::new_symbol_handle(name, CHECK_NULL); - return find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL); + jclass result = find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL); + + if (TraceClassResolution && result != NULL) { + trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result))); + } + return result; } // These lookups are done with the NULL (bootstrap) ClassLoader to diff -r 2e18a3d0155b -r ee9da33d43ab hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Mon Mar 23 10:42:20 2009 -0400 +++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Mar 25 13:09:28 2009 -0400 @@ -64,6 +64,7 @@ ResourceMark rm; int line_number = -1; const char * source_file = NULL; + const char * trace = "explicit"; klassOop caller = NULL; JavaThread* jthread = JavaThread::current(); if (jthread->has_last_Java_frame()) { @@ -107,12 +108,21 @@ (last_caller->name() == vmSymbols::loadClassInternal_name() || last_caller->name() == vmSymbols::loadClass_name())) { found_it = true; + } else if (!vfst.at_end()) { + if (vfst.method()->is_native()) { + // JNI call + found_it = true; + } } if (found_it && !vfst.at_end()) { // found the caller caller = vfst.method()->method_holder(); line_number = vfst.method()->line_number_from_bci(vfst.bci()); - symbolOop s = instanceKlass::cast(vfst.method()->method_holder())->source_file_name(); + if (line_number == -1) { + // show method name if it's a native method + trace = vfst.method()->name_and_sig_as_C_string(); + } + symbolOop s = instanceKlass::cast(caller)->source_file_name(); if (s != NULL) { source_file = s->as_C_string(); } @@ -124,15 +134,15 @@ const char * to = Klass::cast(to_class)->external_name(); // print in a single call to reduce interleaving between threads if (source_file != NULL) { - tty->print("RESOLVE %s %s %s:%d (explicit)\n", from, to, source_file, line_number); + tty->print("RESOLVE %s %s %s:%d (%s)\n", from, to, source_file, line_number, trace); } else { - tty->print("RESOLVE %s %s (explicit)\n", from, to); + tty->print("RESOLVE %s %s (%s)\n", from, to, trace); } } } } -static void trace_class_resolution(klassOop to_class) { +void trace_class_resolution(klassOop to_class) { EXCEPTION_MARK; trace_class_resolution_impl(to_class, THREAD); if (HAS_PENDING_EXCEPTION) { @@ -3213,8 +3223,12 @@ } Handle h_loader(THREAD, loader); Handle h_prot (THREAD, protection_domain); - return find_class_from_class_loader(env, name, true, h_loader, h_prot, - false, thread); + jclass result = find_class_from_class_loader(env, name, true, h_loader, h_prot, + false, thread); + if (TraceClassResolution && result != NULL) { + trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result))); + } + return result; JVM_END diff -r 2e18a3d0155b -r ee9da33d43ab hotspot/src/share/vm/prims/jvm_misc.hpp --- a/hotspot/src/share/vm/prims/jvm_misc.hpp Mon Mar 23 10:42:20 2009 -0400 +++ b/hotspot/src/share/vm/prims/jvm_misc.hpp Wed Mar 25 13:09:28 2009 -0400 @@ -27,6 +27,7 @@ jclass find_class_from_class_loader(JNIEnv* env, symbolHandle name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS); +void trace_class_resolution(klassOop to_class); /* * Support for Serialization and RMI. Currently used by HotSpot only.