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");