# HG changeset patch # User coleenp # Date 1347893219 14400 # Node ID 1df4fd11c5b8c1dca6efb5e17dda9398b7795691 # Parent 92f03fcf979a8ca4a7dd29b1a9f3aa614e44dc2a 7197269: NPG: FollowReferences has no ClassLoader -> Class link to follow Summary: restore java/lang/ClassLoader.addClass() upcall Reviewed-by: sspitsyn, dcubed, jmasa diff -r 92f03fcf979a -r 1df4fd11c5b8 hotspot/src/share/vm/classfile/systemDictionary.cpp --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Sep 13 21:20:26 2012 +0200 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Mon Sep 17 10:46:59 2012 -0400 @@ -1496,6 +1496,19 @@ int d_index = dictionary()->hash_to_index(d_hash); check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK); + // Register class just loaded with class loader (placed in Vector) + // Note we do this before updating the dictionary, as this can + // fail with an OutOfMemoryError (if it does, we will *not* put this + // class in the dictionary and will not update the class hierarchy). + // JVMTI FollowReferences needs to find the classes this way. + if (k->class_loader() != NULL) { + methodHandle m(THREAD, Universe::loader_addClass_method()); + JavaValue result(T_VOID); + JavaCallArguments args(class_loader_h); + args.push_oop(Handle(THREAD, k->java_mirror())); + JavaCalls::call(&result, m, &args, CHECK); + } + // Add the new class. We need recompile lock during update of CHA. { unsigned int p_hash = placeholders()->compute_hash(name_h, loader_data); diff -r 92f03fcf979a -r 1df4fd11c5b8 hotspot/src/share/vm/classfile/vmSymbols.hpp --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Sep 13 21:20:26 2012 +0200 +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Mon Sep 17 10:46:59 2012 -0400 @@ -314,6 +314,7 @@ template(type_name, "type") \ template(findNative_name, "findNative") \ template(deadChild_name, "deadChild") \ + template(addClass_name, "addClass") \ template(getFromClass_name, "getFromClass") \ template(dispatch_name, "dispatch") \ template(getSystemClassLoader_name, "getSystemClassLoader") \ diff -r 92f03fcf979a -r 1df4fd11c5b8 hotspot/src/share/vm/memory/universe.cpp --- a/hotspot/src/share/vm/memory/universe.cpp Thu Sep 13 21:20:26 2012 +0200 +++ b/hotspot/src/share/vm/memory/universe.cpp Mon Sep 17 10:46:59 2012 -0400 @@ -117,6 +117,7 @@ oop Universe::_the_null_string = NULL; oop Universe::_the_min_jint_string = NULL; LatestMethodOopCache* Universe::_finalizer_register_cache = NULL; +LatestMethodOopCache* Universe::_loader_addClass_cache = NULL; ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL; oop Universe::_out_of_memory_error_java_heap = NULL; oop Universe::_out_of_memory_error_perm_gen = NULL; @@ -228,6 +229,7 @@ f->do_ptr((void**)&_the_empty_method_array); f->do_ptr((void**)&_the_empty_klass_array); _finalizer_register_cache->serialize(f); + _loader_addClass_cache->serialize(f); _reflect_invoke_cache->serialize(f); } @@ -652,6 +654,7 @@ // We have a heap so create the Method* caches before // Metaspace::initialize_shared_spaces() tries to populate them. Universe::_finalizer_register_cache = new LatestMethodOopCache(); + Universe::_loader_addClass_cache = new LatestMethodOopCache(); Universe::_reflect_invoke_cache = new ActiveMethodOopsCache(); if (UseSharedSpaces) { @@ -1041,6 +1044,16 @@ } Universe::_reflect_invoke_cache->init(k_h(), m, CHECK_false); + // Setup method for registering loaded classes in class loader vector + InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false); + m = InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature()); + if (m == NULL || m->is_static()) { + THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(), + "java.lang.ClassLoader.addClass", false); + } + Universe::_loader_addClass_cache->init( + SystemDictionary::ClassLoader_klass(), m, CHECK_false); + // The folowing is initializing converter functions for serialization in // JVM.cpp. If we clean up the StrictMath code above we may want to find // a better solution for this as well. diff -r 92f03fcf979a -r 1df4fd11c5b8 hotspot/src/share/vm/memory/universe.hpp --- a/hotspot/src/share/vm/memory/universe.hpp Thu Sep 13 21:20:26 2012 +0200 +++ b/hotspot/src/share/vm/memory/universe.hpp Mon Sep 17 10:46:59 2012 -0400 @@ -175,6 +175,7 @@ static oop _the_null_string; // A cache of "null" as a Java string static oop _the_min_jint_string; // A cache of "-2147483648" as a Java string static LatestMethodOopCache* _finalizer_register_cache; // static method for registering finalizable objects + static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks static oop _out_of_memory_error_java_heap; // preallocated error object (no backtrace) static oop _out_of_memory_error_perm_gen; // preallocated error object (no backtrace) @@ -318,6 +319,7 @@ static oop the_null_string() { return _the_null_string; } static oop the_min_jint_string() { return _the_min_jint_string; } static Method* finalizer_register_method() { return _finalizer_register_cache->get_Method(); } + static Method* loader_addClass_method() { return _loader_addClass_cache->get_Method(); } static ActiveMethodOopsCache* reflect_invoke_cache() { return _reflect_invoke_cache; } static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; } static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; }