src/share/vm/classfile/systemDictionary.cpp
Print this page
rev 6853 : 8046070: Class Data Sharing clean up and refactoring
Summary: Cleaned up CDS to be more configurable, maintainable and extensible
Reviewed-by: dholmes, coleenp, acorn, mchung
*** 29,42 ****
--- 29,47 ----
#include "classfile/loaderConstraints.hpp"
#include "classfile/placeholders.hpp"
#include "classfile/resolutionErrors.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/systemDictionary.hpp"
+ #if INCLUDE_CDS
+ #include "classfile/sharedClassUtil.hpp"
+ #include "classfile/systemDictionaryShared.hpp"
+ #endif
#include "classfile/vmSymbols.hpp"
#include "compiler/compileBroker.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "interpreter/interpreter.hpp"
+ #include "memory/filemap.hpp"
#include "memory/gcLocker.hpp"
#include "memory/oopFactory.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceRefKlass.hpp"
#include "oops/klass.inline.hpp"
*** 108,117 ****
--- 113,124 ----
vmSymbols::getSystemClassLoader_name(),
vmSymbols::void_classloader_signature(),
CHECK);
_java_system_loader = (oop)result.get_jobject();
+
+ CDS_ONLY(SystemDictionaryShared::initialize(CHECK);)
}
ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, TRAPS) {
if (class_loader() == NULL) return ClassLoaderData::the_null_class_loader_data();
*** 972,981 ****
--- 979,989 ----
ClassLoaderData* loader_data;
if (host_klass.not_null()) {
// Create a new CLD for anonymous class, that uses the same class loader
// as the host_klass
guarantee(host_klass->class_loader() == class_loader(), "should be the same");
+ guarantee(!DumpSharedSpaces, "must not create anonymous classes when dumping");
loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader(), CHECK_NULL);
loader_data->record_dependency(host_klass(), CHECK_NULL);
} else {
loader_data = ClassLoaderData::class_loader_data(class_loader());
}
*** 1132,1142 ****
} );
return k();
}
!
void SystemDictionary::set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
int number_of_entries) {
assert(length == _nof_buckets * sizeof(HashtableBucket<mtClass>),
"bad shared dictionary size.");
_shared_dictionary = new Dictionary(_nof_buckets, t, number_of_entries);
--- 1140,1150 ----
} );
return k();
}
! #if INCLUDE_CDS
void SystemDictionary::set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
int number_of_entries) {
assert(length == _nof_buckets * sizeof(HashtableBucket<mtClass>),
"bad shared dictionary size.");
_shared_dictionary = new Dictionary(_nof_buckets, t, number_of_entries);
*** 1165,1180 ****
// object hierarchy until loaded.]
instanceKlassHandle SystemDictionary::load_shared_class(
Symbol* class_name, Handle class_loader, TRAPS) {
instanceKlassHandle ik (THREAD, find_shared_class(class_name));
! return load_shared_class(ik, class_loader, THREAD);
}
! instanceKlassHandle SystemDictionary::load_shared_class(
! instanceKlassHandle ik, Handle class_loader, TRAPS) {
! assert(class_loader.is_null(), "non-null classloader for shared class?");
if (ik.not_null()) {
instanceKlassHandle nh = instanceKlassHandle(); // null Handle
Symbol* class_name = ik->name();
// Found the class, now load the superclass and interfaces. If they
--- 1173,1194 ----
// object hierarchy until loaded.]
instanceKlassHandle SystemDictionary::load_shared_class(
Symbol* class_name, Handle class_loader, TRAPS) {
instanceKlassHandle ik (THREAD, find_shared_class(class_name));
! // Make sure we only return the boot class for the NULL classloader.
! if (ik.not_null() &&
! SharedClassUtil::is_shared_boot_class(ik()) && class_loader.is_null()) {
! Handle protection_domain;
! return load_shared_class(ik, class_loader, protection_domain, THREAD);
! }
! return instanceKlassHandle();
}
! instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik,
! Handle class_loader,
! Handle protection_domain, TRAPS) {
if (ik.not_null()) {
instanceKlassHandle nh = instanceKlassHandle(); // null Handle
Symbol* class_name = ik->name();
// Found the class, now load the superclass and interfaces. If they
*** 1182,1192 ****
// their hierarchy references (supers, subs, and interfaces).
if (ik->super() != NULL) {
Symbol* cn = ik->super()->name();
resolve_super_or_fail(class_name, cn,
! class_loader, Handle(), true, CHECK_(nh));
}
Array<Klass*>* interfaces = ik->local_interfaces();
int num_interfaces = interfaces->length();
for (int index = 0; index < num_interfaces; index++) {
--- 1196,1206 ----
// their hierarchy references (supers, subs, and interfaces).
if (ik->super() != NULL) {
Symbol* cn = ik->super()->name();
resolve_super_or_fail(class_name, cn,
! class_loader, protection_domain, true, CHECK_(nh));
}
Array<Klass*>* interfaces = ik->local_interfaces();
int num_interfaces = interfaces->length();
for (int index = 0; index < num_interfaces; index++) {
*** 1195,1248 ****
// Note: can not use InstanceKlass::cast here because
// interfaces' InstanceKlass's C++ vtbls haven't been
// reinitialized yet (they will be once the interface classes
// are loaded)
Symbol* name = k->name();
! resolve_super_or_fail(class_name, name, class_loader, Handle(), false, CHECK_(nh));
}
// Adjust methods to recover missing data. They need addresses for
// interpreter entry points and their default native method address
// must be reset.
// Updating methods must be done under a lock so multiple
// threads don't update these in parallel
! // Shared classes are all currently loaded by the bootstrap
! // classloader, so this will never cause a deadlock on
! // a custom class loader lock.
{
Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
check_loader_lock_contention(lockObject, THREAD);
ObjectLocker ol(lockObject, THREAD, true);
! ik->restore_unshareable_info(CHECK_(nh));
}
if (TraceClassLoading) {
ResourceMark rm;
tty->print("[Loaded %s", ik->external_name());
tty->print(" from shared objects file");
tty->print_cr("]");
}
// notify a class loaded from shared object
ClassLoadingService::notify_class_loaded(InstanceKlass::cast(ik()),
true /* shared class */);
}
return ik;
}
!
instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
instanceKlassHandle nh = instanceKlassHandle(); // null Handle
if (class_loader.is_null()) {
// Search the shared system dictionary for classes preloaded into the
// shared spaces.
instanceKlassHandle k;
{
PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
k = load_shared_class(class_name, class_loader, THREAD);
}
if (k.is_null()) {
// Use VM class loader
PerfTraceTime vmtimer(ClassLoader::perf_sys_classload_time());
--- 1209,1281 ----
// Note: can not use InstanceKlass::cast here because
// interfaces' InstanceKlass's C++ vtbls haven't been
// reinitialized yet (they will be once the interface classes
// are loaded)
Symbol* name = k->name();
! resolve_super_or_fail(class_name, name, class_loader, protection_domain, false, CHECK_(nh));
}
// Adjust methods to recover missing data. They need addresses for
// interpreter entry points and their default native method address
// must be reset.
// Updating methods must be done under a lock so multiple
// threads don't update these in parallel
! //
! // Shared classes are all currently loaded by either the bootstrap or
! // internal parallel class loaders, so this will never cause a deadlock
! // on a custom class loader lock.
+ ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
{
Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
check_loader_lock_contention(lockObject, THREAD);
ObjectLocker ol(lockObject, THREAD, true);
! ik->restore_unshareable_info(loader_data, protection_domain, CHECK_(nh));
}
if (TraceClassLoading) {
ResourceMark rm;
tty->print("[Loaded %s", ik->external_name());
tty->print(" from shared objects file");
+ if (class_loader.not_null()) {
+ tty->print(" by %s", loader_data->loader_name());
+ }
tty->print_cr("]");
}
+
+ #if INCLUDE_CDS
+ if (DumpLoadedClassList != NULL && classlist_file->is_open()) {
+ // Only dump the classes that can be stored into CDS archive
+ if (SystemDictionaryShared::is_sharing_possible(loader_data)) {
+ ResourceMark rm(THREAD);
+ classlist_file->print_cr("%s", ik->name()->as_C_string());
+ classlist_file->flush();
+ }
+ }
+ #endif
+
// notify a class loaded from shared object
ClassLoadingService::notify_class_loaded(InstanceKlass::cast(ik()),
true /* shared class */);
}
return ik;
}
! #endif
instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
instanceKlassHandle nh = instanceKlassHandle(); // null Handle
if (class_loader.is_null()) {
// Search the shared system dictionary for classes preloaded into the
// shared spaces.
instanceKlassHandle k;
{
+ #if INCLUDE_CDS
PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
k = load_shared_class(class_name, class_loader, THREAD);
+ #endif
}
if (k.is_null()) {
// Use VM class loader
PerfTraceTime vmtimer(ClassLoader::perf_sys_classload_time());
*** 1597,1607 ****
// Also, first reinitialize vtable because it may have gotten out of synch
// while the new class wasn't connected to the class hierarchy.
Universe::flush_dependents_on(k);
}
-
// ----------------------------------------------------------------------------
// GC support
// Following roots during mark-sweep is separated in two phases.
//
--- 1630,1639 ----
*** 1680,1689 ****
--- 1712,1722 ----
}
void SystemDictionary::roots_oops_do(OopClosure* strong, OopClosure* weak) {
strong->do_oop(&_java_system_loader);
strong->do_oop(&_system_loader_lock_obj);
+ CDS_ONLY(SystemDictionaryShared::roots_oops_do(strong);)
// Adjust dictionary
dictionary()->roots_oops_do(strong, weak);
// Visit extra methods
*** 1691,1700 ****
--- 1724,1734 ----
}
void SystemDictionary::oops_do(OopClosure* f) {
f->do_oop(&_java_system_loader);
f->do_oop(&_system_loader_lock_obj);
+ CDS_ONLY(SystemDictionaryShared::oops_do(f);)
// Adjust dictionary
dictionary()->oops_do(f);
// Visit extra methods
*** 1752,1761 ****
--- 1786,1799 ----
void SystemDictionary::methods_do(void f(Method*)) {
dictionary()->methods_do(f);
invoke_method_table()->methods_do(f);
}
+ void SystemDictionary::remove_classes_in_error_state() {
+ dictionary()->remove_classes_in_error_state();
+ }
+
// ----------------------------------------------------------------------------
// Lazily load klasses
void SystemDictionary::load_abstract_ownable_synchronizer_klass(TRAPS) {
// if multiple threads calling this function, only one thread will load
*** 2561,2584 ****
return dictionary()->number_of_entries();
}
// ----------------------------------------------------------------------------
! #ifndef PRODUCT
! void SystemDictionary::print() {
! dictionary()->print();
// Placeholders
GCMutexLocker mu(SystemDictionary_lock);
placeholders()->print();
// loader constraints - print under SD_lock
constraints()->print();
}
- #endif
void SystemDictionary::verify() {
guarantee(dictionary() != NULL, "Verify of system dictionary failed");
guarantee(constraints() != NULL,
"Verify of loader constraints failed");
--- 2599,2623 ----
return dictionary()->number_of_entries();
}
// ----------------------------------------------------------------------------
! void SystemDictionary::print_shared(bool details) {
! shared_dictionary()->print(details);
! }
! void SystemDictionary::print(bool details) {
! dictionary()->print(details);
// Placeholders
GCMutexLocker mu(SystemDictionary_lock);
placeholders()->print();
// loader constraints - print under SD_lock
constraints()->print();
}
void SystemDictionary::verify() {
guarantee(dictionary() != NULL, "Verify of system dictionary failed");
guarantee(constraints() != NULL,
"Verify of loader constraints failed");