Wed, 25 Mar 2009 13:09:28 -0400
6603316: Improve instrumentation for classes loaded at startup
Reviewed-by: xlu, mchung
1.1 --- a/src/share/vm/classfile/classFileParser.cpp Mon Mar 23 10:42:20 2009 -0400 1.2 +++ b/src/share/vm/classfile/classFileParser.cpp Wed Mar 25 13:09:28 2009 -0400 1.3 @@ -3230,7 +3230,7 @@ 1.4 // print out the superclass. 1.5 const char * from = Klass::cast(this_klass())->external_name(); 1.6 if (this_klass->java_super() != NULL) { 1.7 - tty->print("RESOLVE %s %s\n", from, instanceKlass::cast(this_klass->java_super())->external_name()); 1.8 + tty->print("RESOLVE %s %s (super)\n", from, instanceKlass::cast(this_klass->java_super())->external_name()); 1.9 } 1.10 // print out each of the interface classes referred to by this class. 1.11 objArrayHandle local_interfaces(THREAD, this_klass->local_interfaces()); 1.12 @@ -3240,7 +3240,7 @@ 1.13 klassOop k = klassOop(local_interfaces->obj_at(i)); 1.14 instanceKlass* to_class = instanceKlass::cast(k); 1.15 const char * to = to_class->external_name(); 1.16 - tty->print("RESOLVE %s %s\n", from, to); 1.17 + tty->print("RESOLVE %s %s (interface)\n", from, to); 1.18 } 1.19 } 1.20 }
2.1 --- a/src/share/vm/prims/jni.cpp Mon Mar 23 10:42:20 2009 -0400 2.2 +++ b/src/share/vm/prims/jni.cpp Wed Mar 25 13:09:28 2009 -0400 2.3 @@ -301,6 +301,10 @@ 2.4 klassOop k = SystemDictionary::resolve_from_stream(class_name, class_loader, 2.5 Handle(), &st, CHECK_NULL); 2.6 2.7 + if (TraceClassResolution && k != NULL) { 2.8 + trace_class_resolution(k); 2.9 + } 2.10 + 2.11 cls = (jclass)JNIHandles::make_local( 2.12 env, Klass::cast(k)->java_mirror()); 2.13 return cls; 2.14 @@ -365,6 +369,10 @@ 2.15 result = find_class_from_class_loader(env, sym, true, loader, 2.16 protection_domain, true, thread); 2.17 2.18 + if (TraceClassResolution && result != NULL) { 2.19 + trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result))); 2.20 + } 2.21 + 2.22 // If we were the first invocation of jni_FindClass, we enable compilation again 2.23 // rather than just allowing invocation counter to overflow and decay. 2.24 // Controlled by flag DelayCompilationDuringStartup. 2.25 @@ -2646,7 +2654,12 @@ 2.26 Handle protection_domain; // null protection domain 2.27 2.28 symbolHandle sym = oopFactory::new_symbol_handle(name, CHECK_NULL); 2.29 - return find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL); 2.30 + jclass result = find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL); 2.31 + 2.32 + if (TraceClassResolution && result != NULL) { 2.33 + trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result))); 2.34 + } 2.35 + return result; 2.36 } 2.37 2.38 // These lookups are done with the NULL (bootstrap) ClassLoader to
3.1 --- a/src/share/vm/prims/jvm.cpp Mon Mar 23 10:42:20 2009 -0400 3.2 +++ b/src/share/vm/prims/jvm.cpp Wed Mar 25 13:09:28 2009 -0400 3.3 @@ -64,6 +64,7 @@ 3.4 ResourceMark rm; 3.5 int line_number = -1; 3.6 const char * source_file = NULL; 3.7 + const char * trace = "explicit"; 3.8 klassOop caller = NULL; 3.9 JavaThread* jthread = JavaThread::current(); 3.10 if (jthread->has_last_Java_frame()) { 3.11 @@ -107,12 +108,21 @@ 3.12 (last_caller->name() == vmSymbols::loadClassInternal_name() || 3.13 last_caller->name() == vmSymbols::loadClass_name())) { 3.14 found_it = true; 3.15 + } else if (!vfst.at_end()) { 3.16 + if (vfst.method()->is_native()) { 3.17 + // JNI call 3.18 + found_it = true; 3.19 + } 3.20 } 3.21 if (found_it && !vfst.at_end()) { 3.22 // found the caller 3.23 caller = vfst.method()->method_holder(); 3.24 line_number = vfst.method()->line_number_from_bci(vfst.bci()); 3.25 - symbolOop s = instanceKlass::cast(vfst.method()->method_holder())->source_file_name(); 3.26 + if (line_number == -1) { 3.27 + // show method name if it's a native method 3.28 + trace = vfst.method()->name_and_sig_as_C_string(); 3.29 + } 3.30 + symbolOop s = instanceKlass::cast(caller)->source_file_name(); 3.31 if (s != NULL) { 3.32 source_file = s->as_C_string(); 3.33 } 3.34 @@ -124,15 +134,15 @@ 3.35 const char * to = Klass::cast(to_class)->external_name(); 3.36 // print in a single call to reduce interleaving between threads 3.37 if (source_file != NULL) { 3.38 - tty->print("RESOLVE %s %s %s:%d (explicit)\n", from, to, source_file, line_number); 3.39 + tty->print("RESOLVE %s %s %s:%d (%s)\n", from, to, source_file, line_number, trace); 3.40 } else { 3.41 - tty->print("RESOLVE %s %s (explicit)\n", from, to); 3.42 + tty->print("RESOLVE %s %s (%s)\n", from, to, trace); 3.43 } 3.44 } 3.45 } 3.46 } 3.47 3.48 -static void trace_class_resolution(klassOop to_class) { 3.49 +void trace_class_resolution(klassOop to_class) { 3.50 EXCEPTION_MARK; 3.51 trace_class_resolution_impl(to_class, THREAD); 3.52 if (HAS_PENDING_EXCEPTION) { 3.53 @@ -3213,8 +3223,12 @@ 3.54 } 3.55 Handle h_loader(THREAD, loader); 3.56 Handle h_prot (THREAD, protection_domain); 3.57 - return find_class_from_class_loader(env, name, true, h_loader, h_prot, 3.58 - false, thread); 3.59 + jclass result = find_class_from_class_loader(env, name, true, h_loader, h_prot, 3.60 + false, thread); 3.61 + if (TraceClassResolution && result != NULL) { 3.62 + trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result))); 3.63 + } 3.64 + return result; 3.65 JVM_END 3.66 3.67
4.1 --- a/src/share/vm/prims/jvm_misc.hpp Mon Mar 23 10:42:20 2009 -0400 4.2 +++ b/src/share/vm/prims/jvm_misc.hpp Wed Mar 25 13:09:28 2009 -0400 4.3 @@ -27,6 +27,7 @@ 4.4 4.5 jclass find_class_from_class_loader(JNIEnv* env, symbolHandle name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS); 4.6 4.7 +void trace_class_resolution(klassOop to_class); 4.8 4.9 /* 4.10 * Support for Serialization and RMI. Currently used by HotSpot only.