Mon, 17 Sep 2012 10:46:59 -0400
7197269: NPG: FollowReferences has no ClassLoader -> Class link to follow
Summary: restore java/lang/ClassLoader.addClass() upcall
Reviewed-by: sspitsyn, dcubed, jmasa
1.1 --- a/src/share/vm/classfile/systemDictionary.cpp Thu Sep 13 21:20:26 2012 +0200 1.2 +++ b/src/share/vm/classfile/systemDictionary.cpp Mon Sep 17 10:46:59 2012 -0400 1.3 @@ -1496,6 +1496,19 @@ 1.4 int d_index = dictionary()->hash_to_index(d_hash); 1.5 check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK); 1.6 1.7 + // Register class just loaded with class loader (placed in Vector) 1.8 + // Note we do this before updating the dictionary, as this can 1.9 + // fail with an OutOfMemoryError (if it does, we will *not* put this 1.10 + // class in the dictionary and will not update the class hierarchy). 1.11 + // JVMTI FollowReferences needs to find the classes this way. 1.12 + if (k->class_loader() != NULL) { 1.13 + methodHandle m(THREAD, Universe::loader_addClass_method()); 1.14 + JavaValue result(T_VOID); 1.15 + JavaCallArguments args(class_loader_h); 1.16 + args.push_oop(Handle(THREAD, k->java_mirror())); 1.17 + JavaCalls::call(&result, m, &args, CHECK); 1.18 + } 1.19 + 1.20 // Add the new class. We need recompile lock during update of CHA. 1.21 { 1.22 unsigned int p_hash = placeholders()->compute_hash(name_h, loader_data);
2.1 --- a/src/share/vm/classfile/vmSymbols.hpp Thu Sep 13 21:20:26 2012 +0200 2.2 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Sep 17 10:46:59 2012 -0400 2.3 @@ -314,6 +314,7 @@ 2.4 template(type_name, "type") \ 2.5 template(findNative_name, "findNative") \ 2.6 template(deadChild_name, "deadChild") \ 2.7 + template(addClass_name, "addClass") \ 2.8 template(getFromClass_name, "getFromClass") \ 2.9 template(dispatch_name, "dispatch") \ 2.10 template(getSystemClassLoader_name, "getSystemClassLoader") \
3.1 --- a/src/share/vm/memory/universe.cpp Thu Sep 13 21:20:26 2012 +0200 3.2 +++ b/src/share/vm/memory/universe.cpp Mon Sep 17 10:46:59 2012 -0400 3.3 @@ -117,6 +117,7 @@ 3.4 oop Universe::_the_null_string = NULL; 3.5 oop Universe::_the_min_jint_string = NULL; 3.6 LatestMethodOopCache* Universe::_finalizer_register_cache = NULL; 3.7 +LatestMethodOopCache* Universe::_loader_addClass_cache = NULL; 3.8 ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL; 3.9 oop Universe::_out_of_memory_error_java_heap = NULL; 3.10 oop Universe::_out_of_memory_error_perm_gen = NULL; 3.11 @@ -228,6 +229,7 @@ 3.12 f->do_ptr((void**)&_the_empty_method_array); 3.13 f->do_ptr((void**)&_the_empty_klass_array); 3.14 _finalizer_register_cache->serialize(f); 3.15 + _loader_addClass_cache->serialize(f); 3.16 _reflect_invoke_cache->serialize(f); 3.17 } 3.18 3.19 @@ -652,6 +654,7 @@ 3.20 // We have a heap so create the Method* caches before 3.21 // Metaspace::initialize_shared_spaces() tries to populate them. 3.22 Universe::_finalizer_register_cache = new LatestMethodOopCache(); 3.23 + Universe::_loader_addClass_cache = new LatestMethodOopCache(); 3.24 Universe::_reflect_invoke_cache = new ActiveMethodOopsCache(); 3.25 3.26 if (UseSharedSpaces) { 3.27 @@ -1041,6 +1044,16 @@ 3.28 } 3.29 Universe::_reflect_invoke_cache->init(k_h(), m, CHECK_false); 3.30 3.31 + // Setup method for registering loaded classes in class loader vector 3.32 + InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false); 3.33 + m = InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature()); 3.34 + if (m == NULL || m->is_static()) { 3.35 + THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(), 3.36 + "java.lang.ClassLoader.addClass", false); 3.37 + } 3.38 + Universe::_loader_addClass_cache->init( 3.39 + SystemDictionary::ClassLoader_klass(), m, CHECK_false); 3.40 + 3.41 // The folowing is initializing converter functions for serialization in 3.42 // JVM.cpp. If we clean up the StrictMath code above we may want to find 3.43 // a better solution for this as well.
4.1 --- a/src/share/vm/memory/universe.hpp Thu Sep 13 21:20:26 2012 +0200 4.2 +++ b/src/share/vm/memory/universe.hpp Mon Sep 17 10:46:59 2012 -0400 4.3 @@ -175,6 +175,7 @@ 4.4 static oop _the_null_string; // A cache of "null" as a Java string 4.5 static oop _the_min_jint_string; // A cache of "-2147483648" as a Java string 4.6 static LatestMethodOopCache* _finalizer_register_cache; // static method for registering finalizable objects 4.7 + static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector 4.8 static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks 4.9 static oop _out_of_memory_error_java_heap; // preallocated error object (no backtrace) 4.10 static oop _out_of_memory_error_perm_gen; // preallocated error object (no backtrace) 4.11 @@ -318,6 +319,7 @@ 4.12 static oop the_null_string() { return _the_null_string; } 4.13 static oop the_min_jint_string() { return _the_min_jint_string; } 4.14 static Method* finalizer_register_method() { return _finalizer_register_cache->get_Method(); } 4.15 + static Method* loader_addClass_method() { return _loader_addClass_cache->get_Method(); } 4.16 static ActiveMethodOopsCache* reflect_invoke_cache() { return _reflect_invoke_cache; } 4.17 static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; } 4.18 static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; }