7197269: NPG: FollowReferences has no ClassLoader -> Class link to follow
Summary: restore java/lang/ClassLoader.addClass() upcall
Reviewed-by: sspitsyn, dcubed, jmasa
--- 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);
--- 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") \
--- 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.
--- 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; }