src/hotspot/share/classfile/systemDictionary.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/hotspot/share/classfile/systemDictionary.cpp	Tue Oct 10 13:48:52 2017
--- new/src/hotspot/share/classfile/systemDictionary.cpp	Tue Oct 10 13:48:52 2017

*** 357,375 **** --- 357,374 ---- // 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
*** 473,485 **** --- 472,484 ---- 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); + int d_index = dictionary->hash_to_index(d_hash); dictionary->add_protection_domain(d_index, d_hash, klass, protection_domain, THREAD); } }
*** 541,551 **** --- 540,549 ---- 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
*** 565,585 **** --- 563,583 ---- // 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);
*** 656,677 **** --- 654,676 ---- // 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 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); + { ! MutexLocker mu(SystemDictionary_lock, THREAD); ! 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.
*** 702,712 **** --- 701,711 ---- 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 {
*** 786,796 **** --- 785,795 ---- // 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; }
*** 811,821 **** --- 810,820 ---- // 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; }
*** 844,854 **** --- 843,853 ---- // 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?");
*** 859,877 **** --- 858,876 ---- // 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;
*** 909,919 **** --- 908,918 ---- // 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
*** 951,962 **** --- 950,960 ---- 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, + return dictionary->find(d_hash, class_name, protection_domain); } // Look for a loaded instance or array klass by name. Do not do any loading.
*** 1630,1641 **** --- 1628,1638 ---- // 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); ! 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).
*** 1659,1669 **** --- 1656,1666 ---- // 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
*** 1701,1722 **** --- 1698,1718 ---- 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; } }
*** 1734,1744 **** --- 1730,1740 ---- // 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)
*** 1809,1822 **** --- 1805,1819 ---- } // ---------------------------------------------------------------------------- // Lookup - InstanceKlass* SystemDictionary::find_class(int index, 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
*** 1842,1853 **** --- 1839,1849 ---- 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); ! 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
*** 2194,2204 **** --- 2190,2200 ---- // 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;
*** 2206,2216 **** --- 2202,2212 ---- 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
*** 2254,2264 **** --- 2250,2260 ---- } // 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
*** 2289,2305 **** --- 2285,2301 ---- } } // 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();
*** 2372,2391 **** --- 2368,2385 ---- } } 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); } }

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