src/hotspot/share/classfile/systemDictionary.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File webrev Cdiff src/hotspot/share/classfile/systemDictionary.cpp

src/hotspot/share/classfile/systemDictionary.cpp

Print this page

        

*** 369,387 **** // 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 --- 369,386 ---- // 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); 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_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
*** 485,497 **** 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); } } --- 484,496 ---- 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); MutexLocker mu(SystemDictionary_lock, THREAD); + int d_index = dictionary->hash_to_index(d_hash); dictionary->add_protection_domain(d_index, d_hash, klass, protection_domain, THREAD); } }
*** 553,563 **** 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 --- 552,561 ----
*** 577,597 **** // 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); --- 575,595 ---- // 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_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_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);
*** 668,689 **** // 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 // class loader object lock to protect against multiple threads // defining the class in parallel by accident. --- 666,687 ---- // 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(); + unsigned int d_hash = dictionary->compute_hash(name); // 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 ! { ! Klass* probe = dictionary->find(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 // class loader object lock to protect against multiple threads // defining the class in parallel by accident.
*** 714,724 **** 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 { --- 712,722 ---- PlaceholderEntry* placeholder; Symbol* superclassname = NULL; { MutexLocker mu(SystemDictionary_lock, THREAD); ! InstanceKlass* check = find_class(d_hash, name, dictionary); if (check != NULL) { // Klass is already loaded, so just return it class_has_been_loaded = true; k = check; } else {
*** 798,808 **** // 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; } --- 796,806 ---- // 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_hash, name, dictionary); if (check != NULL) { // Klass is already loaded, so just return it k = check; class_has_been_loaded = true; }
*** 823,833 **** // 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; } --- 821,831 ---- // 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_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; }
*** 856,866 **** // 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?"); --- 854,864 ---- // 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_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?");
*** 871,889 **** // If everything was OK (no exceptions, no null return value), and // class_loader is NOT the defining loader, do a little more bookkeeping. if (!HAS_PENDING_EXCEPTION && k != NULL && k->class_loader() != class_loader()) { ! check_constraints(d_index, d_hash, k, class_loader, false, THREAD); // Need to check for a PENDING_EXCEPTION again; check_constraints // can throw and doesn't use the CHECK macro. if (!HAS_PENDING_EXCEPTION) { { // Grabbing the Compile_lock prevents systemDictionary updates // during compilations. MutexLocker mu(Compile_lock, THREAD); ! update_dictionary(d_index, d_hash, p_index, p_hash, k, class_loader, THREAD); } if (JvmtiExport::should_post_class_load()) { Thread *thread = THREAD; --- 869,887 ---- // If everything was OK (no exceptions, no null return value), and // class_loader is NOT the defining loader, do a little more bookkeeping. if (!HAS_PENDING_EXCEPTION && k != NULL && k->class_loader() != class_loader()) { ! check_constraints(d_hash, k, class_loader, false, THREAD); // Need to check for a PENDING_EXCEPTION again; check_constraints // can throw and doesn't use the CHECK macro. if (!HAS_PENDING_EXCEPTION) { { // Grabbing the Compile_lock prevents systemDictionary updates // during compilations. MutexLocker mu(Compile_lock, THREAD); ! update_dictionary(d_hash, p_index, p_hash, k, class_loader, THREAD); } if (JvmtiExport::should_post_class_load()) { Thread *thread = THREAD;
*** 921,931 **** // return if the protection domain in NULL if (protection_domain() == NULL) return k; // Check the protection domain has the right access ! if (dictionary->is_valid_protection_domain(d_index, d_hash, name, protection_domain)) { return k; } // Verify protection domain. If it fails an exception is thrown --- 919,929 ---- // return if the protection domain in NULL if (protection_domain() == NULL) return k; // Check the protection domain has the right access ! if (dictionary->is_valid_protection_domain(d_hash, name, protection_domain)) { return k; } // Verify protection domain. If it fails an exception is thrown
*** 963,974 **** return NULL; } Dictionary* dictionary = loader_data->dictionary(); 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. --- 961,971 ---- return NULL; } Dictionary* dictionary = loader_data->dictionary(); unsigned int d_hash = dictionary->compute_hash(class_name); ! return dictionary->find(d_hash, class_name, protection_domain); } // Look for a loaded instance or array klass by name. Do not do any loading.
*** 1642,1653 **** // 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 // class in the dictionary and will not update the class hierarchy). --- 1639,1649 ---- // 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); ! check_constraints(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).
*** 1671,1681 **** // deoptimizations. add_to_hierarchy(k, CHECK); // No exception, but can block // Add to systemDictionary - so other classes can see it. // Grabs and releases SystemDictionary_lock ! update_dictionary(d_index, d_hash, p_index, p_hash, k, class_loader_h, THREAD); } k->eager_initialize(THREAD); // notify jvmti --- 1667,1677 ---- // deoptimizations. add_to_hierarchy(k, CHECK); // No exception, but can block // Add to systemDictionary - so other classes can see it. // Grabs and releases SystemDictionary_lock ! update_dictionary(d_hash, p_index, p_hash, k, class_loader_h, THREAD); } k->eager_initialize(THREAD); // notify jvmti
*** 1713,1734 **** 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; } } --- 1709,1729 ---- 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); // 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_hash, name_h, dictionary); if (check != NULL) { return check; } }
*** 1746,1756 **** // 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) --- 1741,1751 ---- // 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_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)
*** 1821,1834 **** } // ---------------------------------------------------------------------------- // 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 --- 1816,1830 ---- } // ---------------------------------------------------------------------------- // Lookup ! InstanceKlass* SystemDictionary::find_class(unsigned int hash, Symbol* class_name, Dictionary* dictionary) { assert_locked_or_safepoint(SystemDictionary_lock); + int index = dictionary->hash_to_index(hash); return dictionary->find_class(index, hash, class_name); } // Basic find on classes in the midst of being loaded
*** 1854,1865 **** VerifyAfterGC, "too expensive"); #endif Dictionary* dictionary = loader_data->dictionary(); 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 --- 1850,1860 ---- VerifyAfterGC, "too expensive"); #endif Dictionary* dictionary = loader_data->dictionary(); unsigned int d_hash = dictionary->compute_hash(class_name); ! return find_class(d_hash, class_name, dictionary); } // ---------------------------------------------------------------------------- // Update hierachy. This is done before the new klass has been added to the SystemDictionary. The Recompile_lock
*** 2208,2218 **** // that the dictionary needs to maintain a set of contraints that // must be satisfied by all classes in the dictionary. // if defining is true, then LinkageError if already in dictionary // if initiating loader, then ok if InstanceKlass matches existing entry ! void SystemDictionary::check_constraints(int d_index, unsigned int d_hash, InstanceKlass* k, Handle class_loader, bool defining, TRAPS) { const char *linkage_error1 = NULL; const char *linkage_error2 = NULL; --- 2203,2213 ---- // that the dictionary needs to maintain a set of contraints that // must be satisfied by all classes in the dictionary. // if defining is true, then LinkageError if already in dictionary // if initiating loader, then ok if InstanceKlass matches existing entry ! void SystemDictionary::check_constraints(unsigned int d_hash, InstanceKlass* k, Handle class_loader, bool defining, TRAPS) { const char *linkage_error1 = NULL; const char *linkage_error2 = NULL;
*** 2220,2230 **** 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 // dictionary only holds instance classes, placeholders --- 2215,2225 ---- Symbol* name = k->name(); ClassLoaderData *loader_data = class_loader_data(class_loader); MutexLocker mu(SystemDictionary_lock, THREAD); ! InstanceKlass* check = find_class(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 // dictionary only holds instance classes, placeholders
*** 2268,2278 **** } // Update class loader data dictionary - done after check_constraint and add_to_hierachy // have been called. ! void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash, int p_index, unsigned int p_hash, InstanceKlass* k, Handle class_loader, TRAPS) { // Compile_lock prevents systemDictionary updates during compilations --- 2263,2273 ---- } // Update class loader data dictionary - done after check_constraint and add_to_hierachy // have been called. ! void SystemDictionary::update_dictionary(unsigned int d_hash, int p_index, unsigned int p_hash, InstanceKlass* k, Handle class_loader, TRAPS) { // Compile_lock prevents systemDictionary updates during compilations
*** 2303,2319 **** } } // Make a new 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 dictionary"); // Note: there may be a placeholder entry: for circularity testing // or for parallel defines #endif SystemDictionary_lock->notify_all(); --- 2298,2314 ---- } } // Make a new dictionary entry. Dictionary* dictionary = loader_data->dictionary(); ! InstanceKlass* sd_check = find_class(d_hash, name, dictionary); if (sd_check == NULL) { ! dictionary->add_klass(d_hash, name, k); notice_modification(); } #ifdef ASSERT ! sd_check = find_class(d_hash, name, dictionary); assert (sd_check != NULL, "should have entry in dictionary"); // Note: there may be a placeholder entry: for circularity testing // or for parallel defines #endif SystemDictionary_lock->notify_all();
*** 2386,2405 **** } } 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); } } --- 2381,2398 ---- } } Dictionary* dictionary1 = loader_data1->dictionary(); unsigned int d_hash1 = dictionary1->compute_hash(constraint_name); Dictionary* dictionary2 = loader_data2->dictionary(); unsigned int d_hash2 = dictionary2->compute_hash(constraint_name); { MutexLocker mu_s(SystemDictionary_lock, THREAD); ! InstanceKlass* klass1 = find_class(d_hash1, constraint_name, dictionary1); ! InstanceKlass* klass2 = find_class(d_hash2, constraint_name, dictionary2); return constraints()->add_entry(constraint_name, klass1, class_loader1, klass2, class_loader2); } }
src/hotspot/share/classfile/systemDictionary.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File