< prev index next >

src/share/vm/classfile/systemDictionary.cpp

Print this page

        

*** 33,42 **** --- 33,43 ---- #include "classfile/javaClasses.inline.hpp" #include "classfile/klassFactory.hpp" #include "classfile/loaderConstraints.hpp" #include "classfile/packageEntry.hpp" #include "classfile/placeholders.hpp" + #include "classfile/protectionDomainCache.hpp" #include "classfile/resolutionErrors.hpp" #include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp"
*** 84,106 **** #endif #if INCLUDE_TRACE #include "trace/tracing.hpp" #endif - Dictionary* SystemDictionary::_dictionary = NULL; PlaceholderTable* SystemDictionary::_placeholders = NULL; Dictionary* SystemDictionary::_shared_dictionary = NULL; LoaderConstraintTable* SystemDictionary::_loader_constraints = NULL; ResolutionErrorTable* SystemDictionary::_resolution_errors = NULL; SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL; ! int SystemDictionary::_number_of_modifications = 0; - int SystemDictionary::_sdgeneration = 0; - const int SystemDictionary::_primelist[_prime_array_size] = {1009,2017,4049,5051,10103, - 20201,40423,99991}; - oop SystemDictionary::_system_loader_lock_obj = NULL; InstanceKlass* SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT] = { NULL /*, NULL...*/ }; --- 85,102 ---- #endif #if INCLUDE_TRACE #include "trace/tracing.hpp" #endif PlaceholderTable* SystemDictionary::_placeholders = NULL; Dictionary* SystemDictionary::_shared_dictionary = NULL; LoaderConstraintTable* SystemDictionary::_loader_constraints = NULL; ResolutionErrorTable* SystemDictionary::_resolution_errors = NULL; SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL; ! ProtectionDomainCacheTable* SystemDictionary::_pd_cache_table = NULL; int SystemDictionary::_number_of_modifications = 0; oop SystemDictionary::_system_loader_lock_obj = NULL; InstanceKlass* SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT] = { NULL /*, NULL...*/ };
*** 112,121 **** --- 108,121 ---- bool SystemDictionary::_has_checkPackageAccess = false; // lazily initialized klass variables InstanceKlass* volatile SystemDictionary::_abstract_ownable_synchronizer_klass = NULL; + // Default ProtectionDomainCacheSize value + + const int defaultProtectionDomainCacheSize = 1009; + // ---------------------------------------------------------------------------- // Java-level SystemLoader oop SystemDictionary::java_system_loader() {
*** 352,374 **** // We might not already have a placeholder if this child_name was // first seen via resolve_from_stream (jni_DefineClass or JVM_DefineClass); // the name of the class might not be known until the stream is actually // parsed. // Bugs 4643874, 4715493 - // compute_hash can have a safepoint ClassLoaderData* loader_data = class_loader_data(class_loader); ! unsigned int d_hash = dictionary()->compute_hash(child_name, loader_data); ! int d_index = dictionary()->hash_to_index(d_hash); ! unsigned int p_hash = placeholders()->compute_hash(child_name, loader_data); int p_index = placeholders()->hash_to_index(p_hash); // can't throw error holding a lock bool child_already_loaded = false; bool throw_circularity_error = false; { MutexLocker mu(SystemDictionary_lock, THREAD); ! Klass* childk = find_class(d_index, d_hash, child_name, loader_data); Klass* quicksuperk; // to support // loading: if child done loading, just return superclass // if class_name, & class_loader don't match: // if initial define, SD update will give LinkageError // if redefine: compare_class_versions will give HIERARCHY_CHANGED --- 352,374 ---- // We might not already have a placeholder if this child_name was // first seen via resolve_from_stream (jni_DefineClass or JVM_DefineClass); // the name of the class might not be known until the stream is actually // parsed. // Bugs 4643874, 4715493 ClassLoaderData* loader_data = class_loader_data(class_loader); ! Dictionary* dictionary = loader_data->dictionary(); ! unsigned int d_hash = dictionary->compute_hash(child_name); ! int d_index = dictionary->hash_to_index(d_hash); ! unsigned int p_hash = placeholders()->compute_hash(child_name); int p_index = placeholders()->hash_to_index(p_hash); // can't throw error holding a lock bool child_already_loaded = false; bool throw_circularity_error = false; { MutexLocker mu(SystemDictionary_lock, THREAD); ! Klass* childk = find_class(d_index, d_hash, child_name, dictionary); Klass* quicksuperk; // to support // loading: if child done loading, just return superclass // if class_name, & class_loader don't match: // if initial define, SD update will give LinkageError // if redefine: compare_class_versions will give HIERARCHY_CHANGED
*** 440,456 **** log->print(" protection domain: "); protection_domain()->print_value_on(log); log->print(" loading: "); klass->print_value_on(log); log->cr(); } InstanceKlass* system_loader = SystemDictionary::ClassLoader_klass(); JavaCalls::call_special(&result, class_loader, system_loader, vmSymbols::checkPackageAccess_name(), vmSymbols::class_protectiondomain_signature(), ! Handle(THREAD, klass->java_mirror()), protection_domain, THREAD); if (HAS_PENDING_EXCEPTION) { log_debug(protectiondomain)("DENIED !!!!!!!!!!!!!!!!!!!!!"); --- 440,460 ---- log->print(" protection domain: "); protection_domain()->print_value_on(log); log->print(" loading: "); klass->print_value_on(log); log->cr(); } + // This handle and the class_loader handle passed in keeps this class from + // being unloaded through several GC points. + Handle mirror(THREAD, klass->java_mirror()); + InstanceKlass* system_loader = SystemDictionary::ClassLoader_klass(); JavaCalls::call_special(&result, class_loader, system_loader, vmSymbols::checkPackageAccess_name(), vmSymbols::class_protectiondomain_signature(), ! mirror, protection_domain, THREAD); if (HAS_PENDING_EXCEPTION) { log_debug(protectiondomain)("DENIED !!!!!!!!!!!!!!!!!!!!!");
*** 461,492 **** if (HAS_PENDING_EXCEPTION) return; // If no exception has been thrown, we have validated the protection domain // Insert the protection domain of the initiating class into the set. { - // We recalculate the entry here -- we've called out to java since - // the last time it was calculated. ClassLoaderData* loader_data = class_loader_data(class_loader); Symbol* kn = klass->name(); ! unsigned int d_hash = dictionary()->compute_hash(kn, loader_data); ! int d_index = dictionary()->hash_to_index(d_hash); MutexLocker mu(SystemDictionary_lock, THREAD); ! { ! // Note that we have an entry, and entries can be deleted only during GC, ! // so we cannot allow GC to occur while we're holding this entry. ! ! // We're using a NoSafepointVerifier to catch any place where we ! // might potentially do a GC at all. ! // Dictionary::do_unloading() asserts that classes in SD are only ! // unloaded at a safepoint. Anonymous classes are not in SD. ! NoSafepointVerifier nosafepoint; ! dictionary()->add_protection_domain(d_index, d_hash, klass, loader_data, protection_domain, THREAD); } - } } // We only get here if this thread finds that another thread // has already claimed the placeholder token for the current operation, // but that other thread either never owned or gave up the --- 465,485 ---- if (HAS_PENDING_EXCEPTION) return; // If no exception has been thrown, we have validated the protection domain // Insert the protection domain of the initiating class into the set. { ClassLoaderData* loader_data = class_loader_data(class_loader); + Dictionary* dictionary = loader_data->dictionary(); Symbol* kn = klass->name(); ! unsigned int d_hash = dictionary->compute_hash(kn); ! int d_index = dictionary->hash_to_index(d_hash); MutexLocker mu(SystemDictionary_lock, THREAD); ! dictionary->add_protection_domain(d_index, d_hash, klass, protection_domain, THREAD); } } // We only get here if this thread finds that another thread // has already claimed the placeholder token for the current operation, // but that other thread either never owned or gave up the
*** 543,555 **** InstanceKlass* SystemDictionary::handle_parallel_super_load( Symbol* name, Symbol* superclassname, Handle class_loader, Handle protection_domain, Handle lockObject, TRAPS) { ClassLoaderData* loader_data = class_loader_data(class_loader); ! unsigned int d_hash = dictionary()->compute_hash(name, loader_data); ! int d_index = dictionary()->hash_to_index(d_hash); ! unsigned int p_hash = placeholders()->compute_hash(name, loader_data); int p_index = placeholders()->hash_to_index(p_hash); // superk is not used, resolve_super called for circularity check only // This code is reached in two situations. One if this thread // is loading the same class twice (e.g. ClassCircularity, or --- 536,549 ---- InstanceKlass* SystemDictionary::handle_parallel_super_load( Symbol* name, Symbol* superclassname, Handle class_loader, Handle protection_domain, Handle lockObject, TRAPS) { ClassLoaderData* loader_data = class_loader_data(class_loader); ! Dictionary* dictionary = loader_data->dictionary(); ! unsigned int d_hash = dictionary->compute_hash(name); ! int d_index = dictionary->hash_to_index(d_hash); ! unsigned int p_hash = placeholders()->compute_hash(name); int p_index = placeholders()->hash_to_index(p_hash); // superk is not used, resolve_super called for circularity check only // This code is reached in two situations. One if this thread // is loading the same class twice (e.g. ClassCircularity, or
*** 568,588 **** // parallelCapable class loaders do NOT wait for parallel superclass loads to complete // Serial class loaders and bootstrap classloader do wait for superclass loads if (!class_loader.is_null() && is_parallelCapable(class_loader)) { MutexLocker mu(SystemDictionary_lock, THREAD); // Check if classloading completed while we were loading superclass or waiting ! return find_class(d_index, d_hash, name, loader_data); } // must loop to both handle other placeholder updates // and spurious notifications bool super_load_in_progress = true; PlaceholderEntry* placeholder; while (super_load_in_progress) { MutexLocker mu(SystemDictionary_lock, THREAD); // Check if classloading completed while we were loading superclass or waiting ! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data); if (check != NULL) { // Klass is already loaded, so just return it return check; } else { placeholder = placeholders()->get_entry(p_index, p_hash, name, loader_data); --- 562,582 ---- // parallelCapable class loaders do NOT wait for parallel superclass loads to complete // Serial class loaders and bootstrap classloader do wait for superclass loads if (!class_loader.is_null() && is_parallelCapable(class_loader)) { MutexLocker mu(SystemDictionary_lock, THREAD); // Check if classloading completed while we were loading superclass or waiting ! return find_class(d_index, d_hash, name, dictionary); } // must loop to both handle other placeholder updates // and spurious notifications bool super_load_in_progress = true; PlaceholderEntry* placeholder; while (super_load_in_progress) { MutexLocker mu(SystemDictionary_lock, THREAD); // Check if classloading completed while we were loading superclass or waiting ! InstanceKlass* check = find_class(d_index, d_hash, name, dictionary); if (check != NULL) { // Klass is already loaded, so just return it return check; } else { placeholder = placeholders()->get_entry(p_index, p_hash, name, loader_data);
*** 658,678 **** HandleMark hm(THREAD); // Fix for 4474172; see evaluation 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); // Do lookup to see if class already exist and the protection domain // has the right access // This call uses find which checks protection domain already matches // All subsequent calls use find_class, and set has_loaded_class so that // before we return a result we call out to java to check for valid protection domain // to allow returning the Klass* and add it to the pd_set if it is valid ! unsigned int d_hash = dictionary()->compute_hash(name, loader_data); ! int d_index = dictionary()->hash_to_index(d_hash); ! Klass* probe = dictionary()->find(d_index, d_hash, name, loader_data, ! protection_domain, THREAD); if (probe != NULL) return probe; // Non-bootstrap class loaders will call out to class loader and // define via jvm/jni_DefineClass which will acquire the --- 652,672 ---- HandleMark hm(THREAD); // Fix for 4474172; see evaluation 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); + Dictionary* dictionary = loader_data->dictionary(); // Do lookup to see if class already exist and the protection domain // has the right access // This call uses find which checks protection domain already matches // All subsequent calls use find_class, and set has_loaded_class so that // before we return a result we call out to java to check for valid protection domain // to allow returning the Klass* and add it to the pd_set if it is valid ! unsigned int d_hash = dictionary->compute_hash(name); ! int d_index = dictionary->hash_to_index(d_hash); ! Klass* probe = dictionary->find(d_index, d_hash, name, protection_domain); if (probe != NULL) return probe; // Non-bootstrap class loaders will call out to class loader and // define via jvm/jni_DefineClass which will acquire the
*** 686,696 **** bool DoObjectLock = true; if (is_parallelCapable(class_loader)) { DoObjectLock = false; } ! unsigned int p_hash = placeholders()->compute_hash(name, loader_data); int p_index = placeholders()->hash_to_index(p_hash); // Class is not in SystemDictionary so we have to do loading. // Make sure we are synchronized on the class loader before we proceed Handle lockObject = compute_loader_lock_object(class_loader, THREAD); --- 680,690 ---- bool DoObjectLock = true; if (is_parallelCapable(class_loader)) { DoObjectLock = false; } ! unsigned int p_hash = placeholders()->compute_hash(name); int p_index = placeholders()->hash_to_index(p_hash); // Class is not in SystemDictionary so we have to do loading. // Make sure we are synchronized on the class loader before we proceed Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
*** 705,715 **** PlaceholderEntry* placeholder; Symbol* superclassname = NULL; { MutexLocker mu(SystemDictionary_lock, THREAD); ! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data); if (check != NULL) { // Klass is already loaded, so just return it class_has_been_loaded = true; k = check; } else { --- 699,709 ---- PlaceholderEntry* placeholder; Symbol* superclassname = NULL; { MutexLocker mu(SystemDictionary_lock, THREAD); ! InstanceKlass* check = find_class(d_index, d_hash, name, dictionary); if (check != NULL) { // Klass is already loaded, so just return it class_has_been_loaded = true; k = check; } else {
*** 789,799 **** // case 2: traditional with broken classloader lock. wait on first // requestor. double_lock_wait(lockObject, THREAD); } // Check if classloading completed while we were waiting ! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data); if (check != NULL) { // Klass is already loaded, so just return it k = check; class_has_been_loaded = true; } --- 783,793 ---- // case 2: traditional with broken classloader lock. wait on first // requestor. double_lock_wait(lockObject, THREAD); } // Check if classloading completed while we were waiting ! InstanceKlass* check = find_class(d_index, d_hash, name, dictionary); if (check != NULL) { // Klass is already loaded, so just return it k = check; class_has_been_loaded = true; }
*** 814,824 **** // if they did not catch another thread holding LOAD_INSTANCE, // need a check analogous to the acquire ObjectLocker/find_class // i.e. now that we hold the LOAD_INSTANCE token on loading this class/CL // one final check if the load has already completed // class loaders holding the ObjectLock shouldn't find the class here ! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data); if (check != NULL) { // Klass is already loaded, so return it after checking/adding protection domain k = check; class_has_been_loaded = true; } --- 808,818 ---- // if they did not catch another thread holding LOAD_INSTANCE, // need a check analogous to the acquire ObjectLocker/find_class // i.e. now that we hold the LOAD_INSTANCE token on loading this class/CL // one final check if the load has already completed // class loaders holding the ObjectLock shouldn't find the class here ! InstanceKlass* check = find_class(d_index, d_hash, name, dictionary); if (check != NULL) { // Klass is already loaded, so return it after checking/adding protection domain k = check; class_has_been_loaded = true; }
*** 847,857 **** // Bootstrap goes through here to allow for an extra guarantee check if (UnsyncloadClass || (class_loader.is_null())) { if (k == NULL && HAS_PENDING_EXCEPTION && PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) { MutexLocker mu(SystemDictionary_lock, THREAD); ! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data); if (check != NULL) { // Klass is already loaded, so just use it k = check; CLEAR_PENDING_EXCEPTION; guarantee((!class_loader.is_null()), "dup definition for bootstrap loader?"); --- 841,851 ---- // Bootstrap goes through here to allow for an extra guarantee check if (UnsyncloadClass || (class_loader.is_null())) { if (k == NULL && HAS_PENDING_EXCEPTION && PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) { MutexLocker mu(SystemDictionary_lock, THREAD); ! InstanceKlass* check = find_class(d_index, d_hash, name, dictionary); if (check != NULL) { // Klass is already loaded, so just use it k = check; CLEAR_PENDING_EXCEPTION; guarantee((!class_loader.is_null()), "dup definition for bootstrap loader?");
*** 881,891 **** assert(thread->is_Java_thread(), "thread->is_Java_thread()"); JvmtiExport::post_class_load((JavaThread *) thread, k); } } } ! } // load_instance_class loop if (load_instance_added == true) { // clean up placeholder entries for LOAD_INSTANCE success or error // This brackets the SystemDictionary updates for both defining // and initiating loaders --- 875,885 ---- assert(thread->is_Java_thread(), "thread->is_Java_thread()"); JvmtiExport::post_class_load((JavaThread *) thread, k); } } } ! } // load_instance_class if (load_instance_added == true) { // clean up placeholder entries for LOAD_INSTANCE success or error // This brackets the SystemDictionary updates for both defining // and initiating loaders
*** 914,932 **** if (protection_domain() == NULL) return k; // Check the protection domain has the right access { MutexLocker mu(SystemDictionary_lock, THREAD); ! // Note that we have an entry, and entries can be deleted only during GC, ! // so we cannot allow GC to occur while we're holding this entry. ! // We're using a NoSafepointVerifier to catch any place where we ! // might potentially do a GC at all. ! // Dictionary::do_unloading() asserts that classes in SD are only ! // unloaded at a safepoint. Anonymous classes are not in SD. ! NoSafepointVerifier nosafepoint; ! if (dictionary()->is_valid_protection_domain(d_index, d_hash, name, ! loader_data, protection_domain)) { return k; } } --- 908,918 ---- if (protection_domain() == NULL) return k; // Check the protection domain has the right access { MutexLocker mu(SystemDictionary_lock, THREAD); ! if (dictionary->is_valid_protection_domain(d_index, d_hash, name, protection_domain)) { return k; } }
*** 963,986 **** // 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); ! ! { ! // Note that we have an entry, and entries can be deleted only during GC, ! // so we cannot allow GC to occur while we're holding this entry. ! // We're using a NoSafepointVerifier to catch any place where we ! // might potentially do a GC at all. ! // Dictionary::do_unloading() asserts that classes in SD are only ! // unloaded at a safepoint. Anonymous classes are not in SD. ! NoSafepointVerifier nosafepoint; ! return dictionary()->find(d_index, d_hash, class_name, loader_data, ! protection_domain, THREAD); } } // Look for a loaded instance or array klass by name. Do not do any loading. // return NULL in case of error. --- 949,968 ---- // If the ClassLoaderData has not been setup, // then the class loader has no entries in the dictionary. return NULL; } ! Dictionary* dictionary = loader_data->dictionary_or_null(); ! // If ClassLoaderData has no dictionary, the class won't be found in it ! if (dictionary == NULL) { ! return NULL; } + + unsigned int d_hash = dictionary->compute_hash(class_name); + int d_index = dictionary->hash_to_index(d_hash); + return dictionary->find(d_index, d_hash, class_name, + protection_domain); } // Look for a loaded instance or array klass by name. Do not do any loading. // return NULL in case of error.
*** 1030,1040 **** // 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()); } assert(st != NULL, "invariant"); --- 1012,1021 ----
*** 1186,1205 **** #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); } // If there is a shared dictionary, then find the entry for the // given shared system class, if any. InstanceKlass* SystemDictionary::find_shared_class(Symbol* class_name) { if (shared_dictionary() != NULL) { ! unsigned int d_hash = shared_dictionary()->compute_hash(class_name, NULL); int d_index = shared_dictionary()->hash_to_index(d_hash); return shared_dictionary()->find_shared_class(d_index, d_hash, class_name); } else { return NULL; --- 1167,1187 ---- #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(ClassLoaderData::the_null_class_loader_data(), ! _nof_buckets, t, number_of_entries); } // If there is a shared dictionary, then find the entry for the // given shared system class, if any. InstanceKlass* SystemDictionary::find_shared_class(Symbol* class_name) { if (shared_dictionary() != NULL) { ! unsigned int d_hash = shared_dictionary()->compute_hash(class_name); int d_index = shared_dictionary()->hash_to_index(d_hash); return shared_dictionary()->find_shared_class(d_index, d_hash, class_name); } else { return NULL;
*** 1621,1632 **** // Existing classloaders will call define_instance_class with the // classloader lock held // Parallel classloaders will call find_or_define_instance_class // which will require a token to perform the define class Symbol* name_h = k->name(); ! unsigned int d_hash = dictionary()->compute_hash(name_h, loader_data); ! 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 --- 1603,1615 ---- // Existing classloaders will call define_instance_class with the // classloader lock held // Parallel classloaders will call find_or_define_instance_class // which will require a token to perform the define class Symbol* name_h = k->name(); ! Dictionary* dictionary = loader_data->dictionary(); ! unsigned int d_hash = dictionary->compute_hash(name_h); ! 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
*** 1640,1650 **** 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); int p_index = placeholders()->hash_to_index(p_hash); MutexLocker mu_r(Compile_lock, THREAD); // Add to class hierarchy, initialize vtables, and do possible --- 1623,1633 ---- 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); int p_index = placeholders()->hash_to_index(p_hash); MutexLocker mu_r(Compile_lock, THREAD); // Add to class hierarchy, initialize vtables, and do possible
*** 1690,1713 **** InstanceKlass* SystemDictionary::find_or_define_instance_class(Symbol* class_name, Handle class_loader, InstanceKlass* k, TRAPS) { Symbol* name_h = k->name(); // passed in class_name may be null ClassLoaderData* loader_data = class_loader_data(class_loader); ! unsigned int d_hash = dictionary()->compute_hash(name_h, loader_data); ! int d_index = dictionary()->hash_to_index(d_hash); // Hold SD lock around find_class and placeholder creation for DEFINE_CLASS ! unsigned int p_hash = placeholders()->compute_hash(name_h, loader_data); int p_index = placeholders()->hash_to_index(p_hash); PlaceholderEntry* probe; { MutexLocker mu(SystemDictionary_lock, THREAD); // First check if class already defined if (UnsyncloadClass || (is_parallelDefine(class_loader))) { ! InstanceKlass* check = find_class(d_index, d_hash, name_h, loader_data); if (check != NULL) { return check; } } --- 1673,1697 ---- InstanceKlass* SystemDictionary::find_or_define_instance_class(Symbol* class_name, Handle class_loader, InstanceKlass* k, TRAPS) { Symbol* name_h = k->name(); // passed in class_name may be null ClassLoaderData* loader_data = class_loader_data(class_loader); + Dictionary* dictionary = loader_data->dictionary(); ! unsigned int d_hash = dictionary->compute_hash(name_h); ! int d_index = dictionary->hash_to_index(d_hash); // Hold SD lock around find_class and placeholder creation for DEFINE_CLASS ! unsigned int p_hash = placeholders()->compute_hash(name_h); int p_index = placeholders()->hash_to_index(p_hash); PlaceholderEntry* probe; { MutexLocker mu(SystemDictionary_lock, THREAD); // First check if class already defined if (UnsyncloadClass || (is_parallelDefine(class_loader))) { ! InstanceKlass* check = find_class(d_index, d_hash, name_h, dictionary); if (check != NULL) { return check; } }
*** 1725,1735 **** // caught by finding an entry in the SystemDictionary if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) { placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD); SystemDictionary_lock->notify_all(); #ifdef ASSERT ! InstanceKlass* check = find_class(d_index, d_hash, name_h, loader_data); assert(check != NULL, "definer missed recording success"); #endif return probe->instance_klass(); } else { // This thread will define the class (even if earlier thread tried and had an error) --- 1709,1719 ---- // caught by finding an entry in the SystemDictionary if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) { placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD); SystemDictionary_lock->notify_all(); #ifdef ASSERT ! InstanceKlass* check = find_class(d_index, d_hash, name_h, dictionary); assert(check != NULL, "definer missed recording success"); #endif return probe->instance_klass(); } else { // This thread will define the class (even if earlier thread tried and had an error)
*** 1764,1773 **** --- 1748,1758 ---- THROW_OOP_(linkage_exception(), NULL); // throws exception and returns } return k; } + Handle SystemDictionary::compute_loader_lock_object(Handle class_loader, TRAPS) { // If class_loader is NULL we synchronize on _system_loader_lock_obj if (class_loader.is_null()) { return Handle(THREAD, _system_loader_lock_obj); } else {
*** 1801,1850 **** // ---------------------------------------------------------------------------- // Lookup InstanceKlass* SystemDictionary::find_class(int index, unsigned int hash, Symbol* class_name, ! ClassLoaderData* loader_data) { assert_locked_or_safepoint(SystemDictionary_lock); ! assert (index == dictionary()->index_for(class_name, loader_data), ! "incorrect index?"); ! ! return dictionary()->find_class(index, hash, class_name, loader_data); } // Basic find on classes in the midst of being loaded Symbol* SystemDictionary::find_placeholder(Symbol* class_name, ClassLoaderData* loader_data) { assert_locked_or_safepoint(SystemDictionary_lock); ! unsigned int p_hash = placeholders()->compute_hash(class_name, loader_data); int p_index = placeholders()->hash_to_index(p_hash); return placeholders()->find_entry(p_index, p_hash, class_name, loader_data); } // Used for assertions and verification only InstanceKlass* SystemDictionary::find_class(Symbol* class_name, ClassLoaderData* loader_data) { #ifndef ASSERT guarantee(VerifyBeforeGC || VerifyDuringGC || VerifyBeforeExit || VerifyDuringStartup || VerifyAfterGC, "too expensive"); #endif - assert_locked_or_safepoint(SystemDictionary_lock); ! // First look in the loaded class array ! unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data); ! int d_index = dictionary()->hash_to_index(d_hash); ! return find_class(d_index, d_hash, class_name, loader_data); ! } ! ! ! // Get the next class in the dictionary. ! Klass* SystemDictionary::try_get_next_class() { ! return dictionary()->try_get_next_class(); } // ---------------------------------------------------------------------------- // Update hierachy. This is done before the new klass has been added to the SystemDictionary. The Recompile_lock --- 1786,1831 ---- // ---------------------------------------------------------------------------- // Lookup InstanceKlass* SystemDictionary::find_class(int index, unsigned int hash, Symbol* class_name, ! Dictionary* dictionary) { assert_locked_or_safepoint(SystemDictionary_lock); ! return dictionary->find_class(index, hash, class_name); } // Basic find on classes in the midst of being loaded Symbol* SystemDictionary::find_placeholder(Symbol* class_name, ClassLoaderData* loader_data) { assert_locked_or_safepoint(SystemDictionary_lock); ! unsigned int p_hash = placeholders()->compute_hash(class_name); int p_index = placeholders()->hash_to_index(p_hash); return placeholders()->find_entry(p_index, p_hash, class_name, loader_data); } // Used for assertions and verification only + // Precalculating the hash and index is an optimization because there are many lookups + // before adding the class. InstanceKlass* SystemDictionary::find_class(Symbol* class_name, ClassLoaderData* loader_data) { + assert_locked_or_safepoint(SystemDictionary_lock); #ifndef ASSERT guarantee(VerifyBeforeGC || VerifyDuringGC || VerifyBeforeExit || VerifyDuringStartup || VerifyAfterGC, "too expensive"); #endif ! Dictionary* dictionary = loader_data->dictionary_or_null(); ! if (dictionary == NULL) { ! return NULL; ! } ! unsigned int d_hash = dictionary->compute_hash(class_name); ! int d_index = dictionary->hash_to_index(d_hash); ! return find_class(d_index, d_hash, class_name, dictionary); } // ---------------------------------------------------------------------------- // Update hierachy. This is done before the new klass has been added to the SystemDictionary. The Recompile_lock
*** 1879,1903 **** void SystemDictionary::always_strong_oops_do(OopClosure* blk) { roots_oops_do(blk, NULL); } - // Calculate a "good" systemdictionary size based - // on predicted or current loaded classes count - int SystemDictionary::calculate_systemdictionary_size(int classcount) { - int newsize = _old_default_sdsize; - if ((classcount > 0) && !DumpSharedSpaces) { - int desiredsize = classcount/_average_depth_goal; - for (newsize = _primelist[_sdgeneration]; _sdgeneration < _prime_array_size -1; - newsize = _primelist[++_sdgeneration]) { - if (desiredsize <= newsize) { - break; - } - } - } - return newsize; - } #ifdef ASSERT class VerifySDReachableAndLiveClosure : public OopClosure { private: BoolObjectClosure* _is_alive; --- 1860,1869 ----
*** 1931,1954 **** do_cleaning); } if (unloading_occurred) { GCTraceTime(Debug, gc, phases) t("Dictionary", gc_timer); - dictionary()->do_unloading(); constraints()->purge_loader_constraints(); resolution_errors()->purge_resolution_errors(); } { GCTraceTime(Debug, gc, phases) t("ProtectionDomainCacheTable", gc_timer); // Oops referenced by the system dictionary may get unreachable independently // of the class loader (eg. cached protection domain oops). So we need to ! // explicitly unlink them here instead of in Dictionary::do_unloading. ! dictionary()->unlink(is_alive); #ifdef ASSERT VerifySDReachableAndLiveClosure cl(is_alive); ! dictionary()->oops_do(&cl); #endif } if (do_cleaning) { GCTraceTime(Debug, gc, phases) t("ResolvedMethodTable", gc_timer); --- 1897,1920 ---- do_cleaning); } if (unloading_occurred) { GCTraceTime(Debug, gc, phases) t("Dictionary", gc_timer); constraints()->purge_loader_constraints(); resolution_errors()->purge_resolution_errors(); } { GCTraceTime(Debug, gc, phases) t("ProtectionDomainCacheTable", gc_timer); // Oops referenced by the system dictionary may get unreachable independently // of the class loader (eg. cached protection domain oops). So we need to ! // explicitly unlink them here. ! _pd_cache_table->unlink(is_alive); ! #ifdef ASSERT VerifySDReachableAndLiveClosure cl(is_alive); ! _pd_cache_table->oops_do(&cl); #endif } if (do_cleaning) { GCTraceTime(Debug, gc, phases) t("ResolvedMethodTable", gc_timer);
*** 1962,1972 **** 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 invoke_method_table()->oops_do(strong); if (weak != NULL) { --- 1928,1947 ---- strong->do_oop(&_java_system_loader); strong->do_oop(&_system_loader_lock_obj); CDS_ONLY(SystemDictionaryShared::roots_oops_do(strong);) // Adjust dictionary ! // Do strong roots marking if the closures are the same. ! if (strong == weak || !ClassUnloading) { ! // Only the protection domain oops contain references into the heap. Iterate ! // over all of them. ! _pd_cache_table->oops_do(strong); ! } else { ! if (weak != NULL) { ! _pd_cache_table->oops_do(weak); ! } ! } // Visit extra methods invoke_method_table()->oops_do(strong); if (weak != NULL) {
*** 1977,2023 **** 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 invoke_method_table()->oops_do(f); ResolvedMethodTable::oops_do(f); } - // Just the classes from defining class loaders - // Don't iterate over placeholders - void SystemDictionary::classes_do(void f(Klass*)) { - dictionary()->classes_do(f); - } - - // Added for initialize_itable_for_klass - // Just the classes from defining class loaders - // Don't iterate over placeholders - void SystemDictionary::classes_do(void f(Klass*, TRAPS), TRAPS) { - dictionary()->classes_do(f, CHECK); - } - - // All classes, and their class loaders - // Don't iterate over placeholders - void SystemDictionary::classes_do(void f(Klass*, ClassLoaderData*)) { - dictionary()->classes_do(f); - } - void SystemDictionary::methods_do(void f(Method*)) { // Walk methods in loaded classes ClassLoaderDataGraph::methods_do(f); // Walk method handle intrinsics invoke_method_table()->methods_do(f); } void SystemDictionary::remove_classes_in_error_state() { ! dictionary()->remove_classes_in_error_state(); } // ---------------------------------------------------------------------------- // Lazily load klasses --- 1952,1980 ---- 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);) ! // Only the protection domain oops contain references into the heap. Iterate ! // over all of them. ! _pd_cache_table->oops_do(f); // Visit extra methods invoke_method_table()->oops_do(f); ResolvedMethodTable::oops_do(f); } void SystemDictionary::methods_do(void f(Method*)) { // Walk methods in loaded classes ClassLoaderDataGraph::methods_do(f); // Walk method handle intrinsics invoke_method_table()->methods_do(f); } void SystemDictionary::remove_classes_in_error_state() { ! ClassLoaderData::the_null_class_loader_data()->dictionary()->remove_classes_in_error_state(); } // ---------------------------------------------------------------------------- // Lazily load klasses
*** 2037,2055 **** // ---------------------------------------------------------------------------- // Initialization void SystemDictionary::initialize(TRAPS) { // Allocate arrays - assert(dictionary() == NULL, - "SystemDictionary should only be initialized once"); - _sdgeneration = 0; - _dictionary = new Dictionary(calculate_systemdictionary_size(PredictedLoadedClassCount)); _placeholders = new PlaceholderTable(_nof_buckets); _number_of_modifications = 0; _loader_constraints = new LoaderConstraintTable(_loader_constraint_size); _resolution_errors = new ResolutionErrorTable(_resolution_error_size); _invoke_method_table = new SymbolPropertyTable(_invoke_method_size); // Allocate private object used as system class loader lock _system_loader_lock_obj = oopFactory::new_intArray(0, CHECK); // Initialize basic classes initialize_preloaded_classes(CHECK); --- 1994,2009 ---- // ---------------------------------------------------------------------------- // Initialization void SystemDictionary::initialize(TRAPS) { // Allocate arrays _placeholders = new PlaceholderTable(_nof_buckets); _number_of_modifications = 0; _loader_constraints = new LoaderConstraintTable(_loader_constraint_size); _resolution_errors = new ResolutionErrorTable(_resolution_error_size); _invoke_method_table = new SymbolPropertyTable(_invoke_method_size); + _pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize); // Allocate private object used as system class loader lock _system_loader_lock_obj = oopFactory::new_intArray(0, CHECK); // Initialize basic classes initialize_preloaded_classes(CHECK);
*** 2213,2223 **** Symbol* name = k->name(); ClassLoaderData *loader_data = class_loader_data(class_loader); MutexLocker mu(SystemDictionary_lock, THREAD); ! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data); if (check != NULL) { // if different InstanceKlass - duplicate class definition, // else - ok, class loaded by a different thread in parallel, // we should only have found it if it was done loading and ok to use // system dictionary only holds instance classes, placeholders --- 2167,2177 ---- Symbol* name = k->name(); ClassLoaderData *loader_data = class_loader_data(class_loader); MutexLocker mu(SystemDictionary_lock, THREAD); ! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data->dictionary()); if (check != NULL) { // if different InstanceKlass - duplicate class definition, // else - ok, class loaded by a different thread in parallel, // we should only have found it if it was done loading and ok to use // system dictionary only holds instance classes, placeholders
*** 2295,2315 **** k->set_prototype_header(markOopDesc::biased_locking_prototype()); } } // Make a new system dictionary entry. ! InstanceKlass* sd_check = find_class(d_index, d_hash, name, loader_data); if (sd_check == NULL) { ! dictionary()->add_klass(name, loader_data, k); notice_modification(); } ! #ifdef ASSERT ! sd_check = find_class(d_index, d_hash, name, loader_data); assert (sd_check != NULL, "should have entry in system dictionary"); // Note: there may be a placeholder entry: for circularity testing // or for parallel defines ! #endif SystemDictionary_lock->notify_all(); } } --- 2249,2270 ---- k->set_prototype_header(markOopDesc::biased_locking_prototype()); } } // Make a new system dictionary entry. ! Dictionary* dictionary = loader_data->dictionary(); ! InstanceKlass* sd_check = find_class(d_index, d_hash, name, dictionary); if (sd_check == NULL) { ! dictionary->add_klass(d_index, d_hash, name, k); notice_modification(); } ! #ifdef ASSERT ! sd_check = find_class(d_index, d_hash, name, dictionary); assert (sd_check != NULL, "should have entry in system dictionary"); // Note: there may be a placeholder entry: for circularity testing // or for parallel defines ! #endif SystemDictionary_lock->notify_all(); } }
*** 2375,2397 **** return true; } else { constraint_name = fd.object_key(); } } - unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, loader_data1); - int d_index1 = dictionary()->hash_to_index(d_hash1); ! unsigned int d_hash2 = dictionary()->compute_hash(constraint_name, loader_data2); ! int d_index2 = dictionary()->hash_to_index(d_hash2); { MutexLocker mu_s(SystemDictionary_lock, THREAD); ! ! // Better never do a GC while we're holding these oops ! NoSafepointVerifier nosafepoint; ! ! InstanceKlass* klass1 = find_class(d_index1, d_hash1, constraint_name, loader_data1); ! InstanceKlass* klass2 = find_class(d_index2, d_hash2, constraint_name, loader_data2); return constraints()->add_entry(constraint_name, klass1, class_loader1, klass2, class_loader2); } } --- 2330,2352 ---- return true; } else { constraint_name = fd.object_key(); } } ! Dictionary* dictionary1 = loader_data1->dictionary(); ! unsigned int d_hash1 = dictionary1->compute_hash(constraint_name); ! int d_index1 = dictionary1->hash_to_index(d_hash1); ! ! Dictionary* dictionary2 = loader_data2->dictionary(); ! unsigned int d_hash2 = dictionary2->compute_hash(constraint_name); ! int d_index2 = dictionary2->hash_to_index(d_hash2); ! { MutexLocker mu_s(SystemDictionary_lock, THREAD); ! InstanceKlass* klass1 = find_class(d_index1, d_hash1, constraint_name, dictionary1); ! InstanceKlass* klass2 = find_class(d_index2, d_hash2, constraint_name, dictionary2); return constraints()->add_entry(constraint_name, klass1, class_loader1, klass2, class_loader2); } }
*** 2839,2906 **** Handle mname(THREAD, (oop) result.get_jobject()); (*method_type_result) = method_type; return unpack_method_and_appendix(mname, caller, appendix_box, appendix_result, THREAD); } ! // Since the identity hash code for symbols changes when the symbols are ! // moved from the regular perm gen (hash in the mark word) to the shared ! // spaces (hash is the address), the classes loaded into the dictionary ! // may be in the wrong buckets. void SystemDictionary::reorder_dictionary() { ! dictionary()->reorder_dictionary(); } void SystemDictionary::copy_buckets(char** top, char* end) { ! dictionary()->copy_buckets(top, end); } void SystemDictionary::copy_table(char** top, char* end) { ! dictionary()->copy_table(top, end); } - int SystemDictionary::number_of_classes() { - 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"); ! guarantee(dictionary()->number_of_entries() >= 0 && ! placeholders()->number_of_entries() >= 0, "Verify of system dictionary failed"); // Verify dictionary ! dictionary()->verify(); GCMutexLocker mu(SystemDictionary_lock); placeholders()->verify(); // Verify constraint table guarantee(constraints() != NULL, "Verify of loader constraints failed"); ! constraints()->verify(dictionary(), placeholders()); } // caller needs ResourceMark const char* SystemDictionary::loader_name(const oop loader) { return ((loader) == NULL ? "<bootloader>" : --- 2794,2869 ---- Handle mname(THREAD, (oop) result.get_jobject()); (*method_type_result) = method_type; return unpack_method_and_appendix(mname, caller, appendix_box, appendix_result, THREAD); } ! // Protection domain cache table handling ! ! ProtectionDomainCacheEntry* SystemDictionary::cache_get(Handle protection_domain) { ! return _pd_cache_table->get(protection_domain); ! } ! void SystemDictionary::reorder_dictionary() { ! ClassLoaderData::the_null_class_loader_data()->dictionary()->reorder_dictionary(); } void SystemDictionary::copy_buckets(char** top, char* end) { ! ClassLoaderData::the_null_class_loader_data()->dictionary()->copy_buckets(top, end); } void SystemDictionary::copy_table(char** top, char* end) { ! ClassLoaderData::the_null_class_loader_data()->dictionary()->copy_table(top, end); } // ---------------------------------------------------------------------------- void SystemDictionary::print_shared(bool details) { shared_dictionary()->print(details); } void SystemDictionary::print(bool details) { ! if (shared_dictionary() != NULL) { ! tty->print_cr("Shared Dictionary"); ! shared_dictionary()->print(details); ! } GCMutexLocker mu(SystemDictionary_lock); + + ClassLoaderDataGraph::print_dictionary(details); + + // Placeholders placeholders()->print(); + tty->cr(); // loader constraints - print under SD_lock constraints()->print(); + tty->cr(); + + _pd_cache_table->print(); + tty->cr(); } void SystemDictionary::verify() { guarantee(constraints() != NULL, "Verify of loader constraints failed"); ! guarantee(placeholders()->number_of_entries() >= 0, "Verify of system dictionary failed"); // Verify dictionary ! ClassLoaderDataGraph::verify_dictionary(); GCMutexLocker mu(SystemDictionary_lock); placeholders()->verify(); // Verify constraint table guarantee(constraints() != NULL, "Verify of loader constraints failed"); ! constraints()->verify(placeholders()); ! ! _pd_cache_table->verify(); } // caller needs ResourceMark const char* SystemDictionary::loader_name(const oop loader) { return ((loader) == NULL ? "<bootloader>" :
< prev index next >