src/hotspot/share/classfile/dictionary.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/hotspot/share/classfile/dictionary.cpp	Wed Nov  1 11:21:36 2017
--- new/src/hotspot/share/classfile/dictionary.cpp	Wed Nov  1 11:21:36 2017

*** 27,63 **** --- 27,71 ---- #include "classfile/sharedClassUtil.hpp" #include "classfile/dictionary.hpp" #include "classfile/protectionDomainCache.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/systemDictionaryShared.hpp" + #include "gc/shared/gcLocker.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/iterator.hpp" #include "memory/metaspaceClosure.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" #include "utilities/hashtable.inline.hpp" + // Optimization: if any dictionary needs resizing, we set this flag, + // so that we dont't have to walk all dictionaries to check if any actually + // needs resizing, which is costly to do at Safepoint. + bool Dictionary::_some_dictionary_needs_resizing = false; + size_t Dictionary::entry_size() { if (DumpSharedSpaces) { return SystemDictionaryShared::dictionary_entry_size(); } else { return sizeof(DictionaryEntry); } } ! Dictionary::Dictionary(ClassLoaderData* loader_data, int table_size, bool resizable) ! : _loader_data(loader_data), Hashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size()) { ! : _loader_data(loader_data), _resizable(resizable), _needs_resizing(false), + Hashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size()) { }; Dictionary::Dictionary(ClassLoaderData* loader_data, int table_size, HashtableBucket<mtClass>* t, ! int number_of_entries, bool resizable) ! : _loader_data(loader_data), Hashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size(), t, number_of_entries) { ! : _loader_data(loader_data), _resizable(resizable), _needs_resizing(false), + Hashtable<InstanceKlass*, mtClass>(table_size, (int)entry_size(), t, number_of_entries) { }; Dictionary::~Dictionary() { DictionaryEntry* probe = NULL; for (int index = 0; index < table_size(); index++) {
*** 94,103 **** --- 102,165 ---- // Unlink from the Hashtable prior to freeing unlink_entry(entry); FREE_C_HEAP_ARRAY(char, entry); } + const int _resize_load_trigger = 5; // load factor that will trigger the resize + const double _resize_factor = 2.0; // by how much we will resize using current number of entries + const int _resize_max_size = 40423; // the max dictionary size allowed + const int _primelist[] = {107, 1009, 2017, 4049, 5051, 10103, 20201, _resize_max_size}; + const int _prime_array_size = sizeof(_primelist)/sizeof(int); + + // Calculate next "good" dictionary size based on requested count + static int calculate_dictionary_size(int requested) { + int newsize = _primelist[0]; + int index = 0; + for (newsize = _primelist[index]; index < (_prime_array_size - 1); + newsize = _primelist[++index]) { + if (requested <= newsize) { + break; + } + } + return newsize; + } + + bool Dictionary::does_any_dictionary_needs_resizing() { + return Dictionary::_some_dictionary_needs_resizing; + } + + void Dictionary::check_if_needs_resize() { + if (_resizable == true) { + if (number_of_entries() > (_resize_load_trigger*table_size())) { + _needs_resizing = true; + Dictionary::_some_dictionary_needs_resizing = true; + } + } + } + + bool Dictionary::resize_if_needed() { + int desired_size = 0; + if (_needs_resizing == true) { + desired_size = calculate_dictionary_size((int)(_resize_factor*number_of_entries())); + if (desired_size >= _resize_max_size) { + desired_size = _resize_max_size; + // We have reached the limit, turn resizing off + _resizable = false; + } + if ((desired_size != 0) && (desired_size != table_size())) { + if (!resize(desired_size)) { + // Something went wrong, turn resizing off + _resizable = false; + } + } + } + + _needs_resizing = false; + Dictionary::_some_dictionary_needs_resizing = false; + + return (desired_size != 0); + } bool DictionaryEntry::contains_protection_domain(oop protection_domain) const { #ifdef ASSERT if (protection_domain == instance_klass()->protection_domain()) { // Ensure this doesn't show up in the pd_set (invariant)
*** 262,279 **** --- 324,343 ---- // Readers of the SystemDictionary aren't always locked, so _buckets // is volatile. The store of the next field in the constructor is // also cast to volatile; we do this to ensure store order is maintained // by the compilers. - void Dictionary::add_klass(int index, unsigned int hash, Symbol* class_name, InstanceKlass* obj) { assert_locked_or_safepoint(SystemDictionary_lock); assert(obj != NULL, "adding NULL obj"); assert(obj->name() == class_name, "sanity check on name"); DictionaryEntry* entry = new_entry(hash, obj); + int index = hash_to_index(hash); add_entry(index, entry); + check_if_needs_resize(); } // This routine does not lock the dictionary. //
*** 297,308 **** --- 361,375 ---- } return NULL; } - InstanceKlass* Dictionary::find(int index, unsigned int hash, Symbol* name, Handle protection_domain) { + NoSafepointVerifier nsv; + + int index = hash_to_index(hash); DictionaryEntry* entry = get_entry(index, hash, name); if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) { return entry->instance_klass(); } else { return NULL;
*** 348,360 **** --- 415,428 ---- assert(entry->contains_protection_domain(protection_domain()), "now protection domain should be present"); } - bool Dictionary::is_valid_protection_domain(int index, unsigned int hash, Symbol* name, Handle protection_domain) { + int index = hash_to_index(hash); DictionaryEntry* entry = get_entry(index, hash, name); return entry->is_valid_protection_domain(protection_domain); }

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