8008549: NPG: SystemDictionary::find(...) unnecessarily keeps class loaders alive
Summary: SystemDictionary::find(...) should not create and register ClassLoaderData objects for class loaders.
Reviewed-by: coleenp, acorn
Contributed-by: Stefan Karlsson <stefan.karlsson@oracle.com>, Erik Helin <erik.helin@oracle.com>
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp Tue Feb 26 14:09:52 2013 +0100
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp Thu Feb 21 17:22:15 2013 +0100
@@ -234,6 +234,7 @@
void add_to_deallocate_list(Metadata* m);
static ClassLoaderData* class_loader_data(oop loader);
+ static ClassLoaderData* class_loader_data_or_null(oop loader);
static ClassLoaderData* anonymous_class_loader_data(oop loader, TRAPS);
static void print_loader(ClassLoaderData *loader_data, outputStream *out);
--- a/hotspot/src/share/vm/classfile/classLoaderData.inline.hpp Tue Feb 26 14:09:52 2013 +0100
+++ b/hotspot/src/share/vm/classfile/classLoaderData.inline.hpp Thu Feb 21 17:22:15 2013 +0100
@@ -25,9 +25,15 @@
#include "classfile/classLoaderData.hpp"
#include "classfile/javaClasses.hpp"
+inline ClassLoaderData* ClassLoaderData::class_loader_data_or_null(oop loader) {
+ if (loader == NULL) {
+ return ClassLoaderData::the_null_class_loader_data();
+ }
+ return java_lang_ClassLoader::loader_data(loader);
+}
+
inline ClassLoaderData* ClassLoaderData::class_loader_data(oop loader) {
- if (loader == NULL) return ClassLoaderData::the_null_class_loader_data();
- ClassLoaderData* loader_data = java_lang_ClassLoader::loader_data(loader);
+ ClassLoaderData* loader_data = class_loader_data_or_null(loader);
assert(loader_data != NULL, "Must be");
return loader_data;
}
--- a/hotspot/src/share/vm/classfile/dictionary.cpp Tue Feb 26 14:09:52 2013 +0100
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp Thu Feb 21 17:22:15 2013 +0100
@@ -347,6 +347,7 @@
assert_locked_or_safepoint(SystemDictionary_lock);
assert(obj() != NULL, "adding NULL obj");
assert(obj()->name() == class_name, "sanity check on name");
+ assert(loader_data != NULL, "Must be non-NULL");
unsigned int hash = compute_hash(class_name, loader_data);
int index = hash_to_index(hash);
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Tue Feb 26 14:09:52 2013 +0100
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Feb 21 17:22:15 2013 +0100
@@ -866,16 +866,22 @@
// the new entry.
Klass* SystemDictionary::find(Symbol* class_name,
- Handle class_loader,
- Handle protection_domain,
- TRAPS) {
+ Handle class_loader,
+ Handle protection_domain,
+ TRAPS) {
// UseNewReflection
// The result of this call should be consistent with the result
// of the call to resolve_instance_class_or_null().
// See evaluation 6790209 and 4474172 for more details.
class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
- ClassLoaderData* loader_data = register_loader(class_loader, CHECK_NULL);
+ ClassLoaderData* loader_data = ClassLoaderData::class_loader_data_or_null(class_loader());
+
+ if (loader_data == NULL) {
+ // If the ClassLoaderData has not been setup,
+ // then the class loader has no entries in the dictionary.
+ return NULL;
+ }
unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data);
int d_index = dictionary()->hash_to_index(d_hash);