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