8309140: ResourceHashtable failed "assert(~(_allocation_t[0] | allocation_mask) == (uintptr_t)this) failed: lost resource object"
Reviewed-by: coleenp, matsaave, dholmes
This commit is contained in:
parent
9f98136c3a
commit
b6c789faad
@ -109,7 +109,8 @@ class ConstraintSet { // copied into hashtable as
|
||||
};
|
||||
|
||||
|
||||
ResourceHashtable<SymbolHandle, ConstraintSet, 107, AnyObj::C_HEAP, mtClass, SymbolHandle::compute_hash> _loader_constraint_table;
|
||||
using InternalLoaderConstraintTable = ResourceHashtable<SymbolHandle, ConstraintSet, 107, AnyObj::C_HEAP, mtClass, SymbolHandle::compute_hash>;
|
||||
static InternalLoaderConstraintTable* _loader_constraint_table;
|
||||
|
||||
void LoaderConstraint::extend_loader_constraint(Symbol* class_name,
|
||||
ClassLoaderData* loader,
|
||||
@ -134,11 +135,15 @@ void LoaderConstraint::extend_loader_constraint(Symbol* class_name,
|
||||
// SystemDictionary lock held. This is true even for readers as
|
||||
// entries in the table could be being dynamically resized.
|
||||
|
||||
void LoaderConstraintTable::initialize() {
|
||||
_loader_constraint_table = new (mtClass) InternalLoaderConstraintTable();
|
||||
}
|
||||
|
||||
LoaderConstraint* LoaderConstraintTable::find_loader_constraint(
|
||||
Symbol* name, ClassLoaderData* loader_data) {
|
||||
|
||||
assert_lock_strong(SystemDictionary_lock);
|
||||
ConstraintSet* set = _loader_constraint_table.get(name);
|
||||
ConstraintSet* set = _loader_constraint_table->get(name);
|
||||
if (set == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -167,7 +172,7 @@ void LoaderConstraintTable::add_loader_constraint(Symbol* name, InstanceKlass* k
|
||||
// a parameter name to a method call. We impose this constraint that the
|
||||
// class that is eventually loaded must match between these two loaders.
|
||||
bool created;
|
||||
ConstraintSet* set = _loader_constraint_table.put_if_absent(name, &created);
|
||||
ConstraintSet* set = _loader_constraint_table->put_if_absent(name, &created);
|
||||
if (created) {
|
||||
set->initialize(constraint);
|
||||
} else {
|
||||
@ -249,7 +254,7 @@ void LoaderConstraintTable::purge_loader_constraints() {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
// Remove unloaded entries from constraint table
|
||||
PurgeUnloadedConstraints purge;
|
||||
_loader_constraint_table.unlink(&purge);
|
||||
_loader_constraint_table->unlink(&purge);
|
||||
}
|
||||
|
||||
void log_ldr_constraint_msg(Symbol* class_name, const char* reason,
|
||||
@ -441,7 +446,7 @@ void LoaderConstraintTable::merge_loader_constraints(Symbol* class_name,
|
||||
}
|
||||
|
||||
// Remove src from set
|
||||
ConstraintSet* set = _loader_constraint_table.get(class_name);
|
||||
ConstraintSet* set = _loader_constraint_table->get(class_name);
|
||||
set->remove_constraint(src);
|
||||
}
|
||||
|
||||
@ -480,7 +485,7 @@ void LoaderConstraintTable::verify() {
|
||||
}
|
||||
};
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
_loader_constraint_table.iterate_all(check);
|
||||
_loader_constraint_table->iterate_all(check);
|
||||
}
|
||||
|
||||
void LoaderConstraintTable::print_table_statistics(outputStream* st) {
|
||||
@ -494,7 +499,7 @@ void LoaderConstraintTable::print_table_statistics(outputStream* st) {
|
||||
}
|
||||
return sum;
|
||||
};
|
||||
TableStatistics ts = _loader_constraint_table.statistics_calculate(size);
|
||||
TableStatistics ts = _loader_constraint_table->statistics_calculate(size);
|
||||
ts.print(st, "LoaderConstraintTable");
|
||||
}
|
||||
|
||||
@ -516,8 +521,8 @@ void LoaderConstraintTable::print_on(outputStream* st) {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
ResourceMark rm;
|
||||
st->print_cr("Java loader constraints (table_size=%d, constraints=%d)",
|
||||
_loader_constraint_table.table_size(), _loader_constraint_table.number_of_entries());
|
||||
_loader_constraint_table.iterate_all(printer);
|
||||
_loader_constraint_table->table_size(), _loader_constraint_table->number_of_entries());
|
||||
_loader_constraint_table->iterate_all(printer);
|
||||
}
|
||||
|
||||
void LoaderConstraintTable::print() { print_on(tty); }
|
||||
|
@ -43,7 +43,7 @@ private:
|
||||
static void merge_loader_constraints(Symbol* class_name, LoaderConstraint* pp1,
|
||||
LoaderConstraint* pp2, InstanceKlass* klass);
|
||||
public:
|
||||
|
||||
static void initialize();
|
||||
// Check class loader constraints
|
||||
static bool add_entry(Symbol* name, InstanceKlass* klass1, ClassLoaderData* loader1,
|
||||
InstanceKlass* klass2, ClassLoaderData* loader2);
|
||||
|
@ -50,8 +50,9 @@ class PlaceholderKey {
|
||||
};
|
||||
|
||||
const int _placeholder_table_size = 503; // Does this really have to be prime?
|
||||
ResourceHashtable<PlaceholderKey, PlaceholderEntry, _placeholder_table_size, AnyObj::C_HEAP, mtClass,
|
||||
PlaceholderKey::hash, PlaceholderKey::equals> _placeholders;
|
||||
using InternalPlaceholderTable = ResourceHashtable<PlaceholderKey, PlaceholderEntry, _placeholder_table_size, AnyObj::C_HEAP, mtClass,
|
||||
PlaceholderKey::hash, PlaceholderKey::equals>;
|
||||
static InternalPlaceholderTable* _placeholders;
|
||||
|
||||
// SeenThread objects represent list of threads that are
|
||||
// currently performing a load action on a class.
|
||||
@ -207,7 +208,7 @@ PlaceholderEntry* add_entry(Symbol* class_name, ClassLoaderData* loader_data,
|
||||
entry.set_supername(supername);
|
||||
PlaceholderKey key(class_name, loader_data);
|
||||
bool created;
|
||||
PlaceholderEntry* table_copy = _placeholders.put_if_absent(key, entry, &created);
|
||||
PlaceholderEntry* table_copy = _placeholders->put_if_absent(key, entry, &created);
|
||||
assert(created, "better be absent");
|
||||
return table_copy;
|
||||
}
|
||||
@ -217,14 +218,14 @@ void remove_entry(Symbol* class_name, ClassLoaderData* loader_data) {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
|
||||
PlaceholderKey key(class_name, loader_data);
|
||||
_placeholders.remove(key);
|
||||
_placeholders->remove(key);
|
||||
}
|
||||
|
||||
|
||||
PlaceholderEntry* PlaceholderTable::get_entry(Symbol* class_name, ClassLoaderData* loader_data) {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
PlaceholderKey key(class_name, loader_data);
|
||||
return _placeholders.get(key);
|
||||
return _placeholders->get(key);
|
||||
}
|
||||
|
||||
static const char* action_to_string(PlaceholderTable::classloadAction action) {
|
||||
@ -271,6 +272,10 @@ PlaceholderEntry* PlaceholderTable::find_and_add(Symbol* name,
|
||||
return probe;
|
||||
}
|
||||
|
||||
void PlaceholderTable::initialize(){
|
||||
_placeholders = new (mtClass) InternalPlaceholderTable();
|
||||
}
|
||||
|
||||
|
||||
// placeholder is used to track class loading internal states
|
||||
// superthreadQ tracks class circularity, while loading superclass/superinterface
|
||||
@ -340,8 +345,8 @@ void PlaceholderTable::print_on(outputStream* st) {
|
||||
return true;
|
||||
};
|
||||
st->print_cr("Placeholder table (table_size=%d, placeholders=%d)",
|
||||
_placeholders.table_size(), _placeholders.number_of_entries());
|
||||
_placeholders.iterate(printer);
|
||||
_placeholders->table_size(), _placeholders->number_of_entries());
|
||||
_placeholders->iterate(printer);
|
||||
}
|
||||
|
||||
void PlaceholderTable::print() { return print_on(tty); }
|
||||
|
@ -52,7 +52,7 @@ class PlaceholderTable : public AllStatic {
|
||||
LOAD_SUPER = 2, // loading superclass for this class
|
||||
DEFINE_CLASS = 3 // find_or_define class
|
||||
};
|
||||
|
||||
static void initialize();
|
||||
static PlaceholderEntry* get_entry(Symbol* name, ClassLoaderData* loader_data);
|
||||
|
||||
// find_and_add returns probe pointer - old or new
|
||||
|
@ -51,13 +51,17 @@ bool ProtectionDomainCacheTable::equals(const WeakHandle& protection_domain1, co
|
||||
|
||||
// WeakHandle is both the key and the value. We need it as the key to compare the oops that each point to
|
||||
// for equality. We need it as the value to return the one that already exists to link in the DictionaryEntry.
|
||||
ResourceHashtable<WeakHandle, WeakHandle, 1009, AnyObj::C_HEAP, mtClass,
|
||||
using InternalProtectionDomainCacheTable = ResourceHashtable<WeakHandle, WeakHandle, 1009, AnyObj::C_HEAP, mtClass,
|
||||
ProtectionDomainCacheTable::compute_hash,
|
||||
ProtectionDomainCacheTable::equals> _pd_cache_table;
|
||||
ProtectionDomainCacheTable::equals>;
|
||||
static InternalProtectionDomainCacheTable* _pd_cache_table;
|
||||
|
||||
bool ProtectionDomainCacheTable::_dead_entries = false;
|
||||
int ProtectionDomainCacheTable::_total_oops_removed = 0;
|
||||
|
||||
void ProtectionDomainCacheTable::initialize(){
|
||||
_pd_cache_table = new (mtClass) InternalProtectionDomainCacheTable();
|
||||
}
|
||||
void ProtectionDomainCacheTable::trigger_cleanup() {
|
||||
MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
|
||||
_dead_entries = true;
|
||||
@ -159,7 +163,7 @@ void ProtectionDomainCacheTable::unlink() {
|
||||
};
|
||||
|
||||
Deleter deleter;
|
||||
_pd_cache_table.unlink(&deleter);
|
||||
_pd_cache_table->unlink(&deleter);
|
||||
|
||||
_total_oops_removed += deleter._oops_removed;
|
||||
_dead_entries = false;
|
||||
@ -171,15 +175,15 @@ void ProtectionDomainCacheTable::print_on(outputStream* st) {
|
||||
st->print_cr(" protection_domain: " PTR_FORMAT, p2i(value.peek()));
|
||||
};
|
||||
st->print_cr("Protection domain cache table (table_size=%d, protection domains=%d)",
|
||||
_pd_cache_table.table_size(), _pd_cache_table.number_of_entries());
|
||||
_pd_cache_table.iterate_all(printer);
|
||||
_pd_cache_table->table_size(), _pd_cache_table->number_of_entries());
|
||||
_pd_cache_table->iterate_all(printer);
|
||||
}
|
||||
|
||||
void ProtectionDomainCacheTable::verify() {
|
||||
auto verifier = [&] (WeakHandle& key, WeakHandle& value) {
|
||||
guarantee(value.peek() == nullptr || oopDesc::is_oop(value.peek()), "must be an oop");
|
||||
};
|
||||
_pd_cache_table.iterate_all(verifier);
|
||||
_pd_cache_table->iterate_all(verifier);
|
||||
}
|
||||
|
||||
// The object_no_keepalive() call peeks at the phantomly reachable oop without
|
||||
@ -192,7 +196,7 @@ WeakHandle ProtectionDomainCacheTable::add_if_absent(Handle protection_domain) {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
WeakHandle w(Universe::vm_weak(), protection_domain);
|
||||
bool created;
|
||||
WeakHandle* wk = _pd_cache_table.put_if_absent(w, w, &created);
|
||||
WeakHandle* wk = _pd_cache_table->put_if_absent(w, w, &created);
|
||||
if (!created) {
|
||||
// delete the one created since we already had it in the table
|
||||
w.release(Universe::vm_weak());
|
||||
@ -215,10 +219,10 @@ void ProtectionDomainCacheTable::print_table_statistics(outputStream* st) {
|
||||
// The only storage is in OopStorage for an oop
|
||||
return sizeof(oop);
|
||||
};
|
||||
TableStatistics ts = _pd_cache_table.statistics_calculate(size);
|
||||
TableStatistics ts = _pd_cache_table->statistics_calculate(size);
|
||||
ts.print(st, "ProtectionDomainCacheTable");
|
||||
}
|
||||
|
||||
int ProtectionDomainCacheTable::number_of_entries() {
|
||||
return _pd_cache_table.number_of_entries();
|
||||
return _pd_cache_table->number_of_entries();
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ class ProtectionDomainCacheTable : public AllStatic {
|
||||
static int _total_oops_removed;
|
||||
|
||||
public:
|
||||
static void initialize();
|
||||
static unsigned int compute_hash(const WeakHandle& protection_domain);
|
||||
static bool equals(const WeakHandle& protection_domain1, const WeakHandle& protection_domain2);
|
||||
|
||||
|
@ -54,9 +54,15 @@ class ResolutionErrorKey {
|
||||
}
|
||||
};
|
||||
|
||||
ResourceHashtable<ResolutionErrorKey, ResolutionErrorEntry*, 107, AnyObj::C_HEAP, mtClass,
|
||||
using InternalResolutionErrorTable = ResourceHashtable<ResolutionErrorKey, ResolutionErrorEntry*, 107, AnyObj::C_HEAP, mtClass,
|
||||
ResolutionErrorKey::hash,
|
||||
ResolutionErrorKey::equals> _resolution_error_table;
|
||||
ResolutionErrorKey::equals>;
|
||||
|
||||
static InternalResolutionErrorTable* _resolution_error_table;
|
||||
|
||||
void ResolutionErrorTable::initialize() {
|
||||
_resolution_error_table = new (mtClass) InternalResolutionErrorTable();
|
||||
}
|
||||
|
||||
// create new error entry
|
||||
void ResolutionErrorTable::add_entry(const constantPoolHandle& pool, int cp_index,
|
||||
@ -68,7 +74,7 @@ void ResolutionErrorTable::add_entry(const constantPoolHandle& pool, int cp_inde
|
||||
|
||||
ResolutionErrorKey key(pool(), cp_index);
|
||||
ResolutionErrorEntry *entry = new ResolutionErrorEntry(error, message, cause, cause_msg);
|
||||
_resolution_error_table.put(key, entry);
|
||||
_resolution_error_table->put(key, entry);
|
||||
}
|
||||
|
||||
// create new nest host error entry
|
||||
@ -80,14 +86,14 @@ void ResolutionErrorTable::add_entry(const constantPoolHandle& pool, int cp_inde
|
||||
|
||||
ResolutionErrorKey key(pool(), cp_index);
|
||||
ResolutionErrorEntry *entry = new ResolutionErrorEntry(message);
|
||||
_resolution_error_table.put(key, entry);
|
||||
_resolution_error_table->put(key, entry);
|
||||
}
|
||||
|
||||
// find entry in the table
|
||||
ResolutionErrorEntry* ResolutionErrorTable::find_entry(const constantPoolHandle& pool, int cp_index) {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
ResolutionErrorKey key(pool(), cp_index);
|
||||
ResolutionErrorEntry** entry = _resolution_error_table.get(key);
|
||||
ResolutionErrorEntry** entry = _resolution_error_table->get(key);
|
||||
return entry == nullptr ? nullptr : *entry;
|
||||
}
|
||||
|
||||
@ -139,7 +145,7 @@ void ResolutionErrorTable::delete_entry(ConstantPool* c) {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
|
||||
ResolutionErrorDeleteIterate deleteIterator(c);
|
||||
_resolution_error_table.unlink(&deleteIterator);
|
||||
_resolution_error_table->unlink(&deleteIterator);
|
||||
}
|
||||
|
||||
class ResolutionIteratePurgeErrors : StackObj {
|
||||
@ -160,5 +166,5 @@ void ResolutionErrorTable::purge_resolution_errors() {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
|
||||
ResolutionIteratePurgeErrors purgeErrorsIterator;
|
||||
_resolution_error_table.unlink(&purgeErrorsIterator);
|
||||
_resolution_error_table->unlink(&purgeErrorsIterator);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ class ResolutionErrorEntry;
|
||||
class ResolutionErrorTable : AllStatic {
|
||||
|
||||
public:
|
||||
static void initialize();
|
||||
static void add_entry(const constantPoolHandle& pool, int which, Symbol* error, Symbol* message,
|
||||
Symbol* cause, Symbol* cause_msg);
|
||||
|
||||
|
@ -113,9 +113,11 @@ class InvokeMethodKey : public StackObj {
|
||||
|
||||
};
|
||||
|
||||
ResourceHashtable<InvokeMethodKey, Method*, 139, AnyObj::C_HEAP, mtClass,
|
||||
InvokeMethodKey::compute_hash, InvokeMethodKey::key_comparison> _invoke_method_intrinsic_table;
|
||||
ResourceHashtable<SymbolHandle, OopHandle, 139, AnyObj::C_HEAP, mtClass, SymbolHandle::compute_hash> _invoke_method_type_table;
|
||||
using InvokeMethodIntrinsicTable = ResourceHashtable<InvokeMethodKey, Method*, 139, AnyObj::C_HEAP, mtClass,
|
||||
InvokeMethodKey::compute_hash, InvokeMethodKey::key_comparison>;
|
||||
static InvokeMethodIntrinsicTable* _invoke_method_intrinsic_table;
|
||||
using InvokeMethodTypeTable = ResourceHashtable<SymbolHandle, OopHandle, 139, AnyObj::C_HEAP, mtClass, SymbolHandle::compute_hash>;
|
||||
static InvokeMethodTypeTable* _invoke_method_type_table;
|
||||
|
||||
OopHandle SystemDictionary::_java_system_loader;
|
||||
OopHandle SystemDictionary::_java_platform_loader;
|
||||
@ -1592,7 +1594,7 @@ void SystemDictionary::methods_do(void f(Method*)) {
|
||||
|
||||
{
|
||||
MutexLocker ml(InvokeMethodIntrinsicTable_lock);
|
||||
_invoke_method_intrinsic_table.iterate_all(doit);
|
||||
_invoke_method_intrinsic_table->iterate_all(doit);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1601,10 +1603,15 @@ void SystemDictionary::methods_do(void f(Method*)) {
|
||||
// Initialization
|
||||
|
||||
void SystemDictionary::initialize(TRAPS) {
|
||||
_invoke_method_intrinsic_table = new (mtClass) InvokeMethodIntrinsicTable();
|
||||
_invoke_method_type_table = new (mtClass) InvokeMethodTypeTable();
|
||||
ResolutionErrorTable::initialize();
|
||||
LoaderConstraintTable::initialize();
|
||||
PlaceholderTable::initialize();
|
||||
ProtectionDomainCacheTable::initialize();
|
||||
#if INCLUDE_CDS
|
||||
SystemDictionaryShared::initialize();
|
||||
#endif
|
||||
|
||||
// Resolve basic classes
|
||||
vmClasses::resolve_all(CHECK);
|
||||
// Resolve classes used by archived heap objects
|
||||
@ -1954,7 +1961,7 @@ Method* SystemDictionary::find_method_handle_intrinsic(vmIntrinsicID iid,
|
||||
MonitorLocker ml(THREAD, InvokeMethodIntrinsicTable_lock);
|
||||
while (true) {
|
||||
bool created;
|
||||
met = _invoke_method_intrinsic_table.put_if_absent(key, &created);
|
||||
met = _invoke_method_intrinsic_table->put_if_absent(key, &created);
|
||||
assert(met != nullptr, "either created or found");
|
||||
if (*met != nullptr) {
|
||||
return *met;
|
||||
@ -1985,7 +1992,7 @@ Method* SystemDictionary::find_method_handle_intrinsic(vmIntrinsicID iid,
|
||||
MonitorLocker ml(THREAD, InvokeMethodIntrinsicTable_lock);
|
||||
if (throw_error) {
|
||||
// Remove the entry and let another thread try, or get the same exception.
|
||||
bool removed = _invoke_method_intrinsic_table.remove(key);
|
||||
bool removed = _invoke_method_intrinsic_table->remove(key);
|
||||
assert(removed, "must be the owner");
|
||||
ml.notify_all();
|
||||
} else {
|
||||
@ -2148,7 +2155,7 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature,
|
||||
OopHandle* o;
|
||||
{
|
||||
MutexLocker ml(THREAD, InvokeMethodTypeTable_lock);
|
||||
o = _invoke_method_type_table.get(signature);
|
||||
o = _invoke_method_type_table->get(signature);
|
||||
}
|
||||
|
||||
if (o != nullptr) {
|
||||
@ -2219,11 +2226,11 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature,
|
||||
MutexLocker ml(THREAD, InvokeMethodTypeTable_lock);
|
||||
bool created = false;
|
||||
assert(method_type != nullptr, "unexpected null");
|
||||
OopHandle* h = _invoke_method_type_table.get(signature);
|
||||
OopHandle* h = _invoke_method_type_table->get(signature);
|
||||
if (h == nullptr) {
|
||||
signature->make_permanent(); // The signature is never unloaded.
|
||||
OopHandle elem = OopHandle(Universe::vm_global(), method_type());
|
||||
bool created = _invoke_method_type_table.put(signature, elem);
|
||||
bool created = _invoke_method_type_table->put(signature, elem);
|
||||
assert(created, "better be created");
|
||||
}
|
||||
}
|
||||
|
@ -978,8 +978,8 @@ void InstanceKlass::initialize_super_interfaces(TRAPS) {
|
||||
}
|
||||
}
|
||||
|
||||
ResourceHashtable<const InstanceKlass*, OopHandle, 107, AnyObj::C_HEAP, mtClass>
|
||||
_initialization_error_table;
|
||||
using InitializationErrorTable = ResourceHashtable<const InstanceKlass*, OopHandle, 107, AnyObj::C_HEAP, mtClass>;
|
||||
static InitializationErrorTable* _initialization_error_table;
|
||||
|
||||
void InstanceKlass::add_initialization_error(JavaThread* current, Handle exception) {
|
||||
// Create the same exception with a message indicating the thread name,
|
||||
@ -1006,14 +1006,20 @@ void InstanceKlass::add_initialization_error(JavaThread* current, Handle excepti
|
||||
MutexLocker ml(current, ClassInitError_lock);
|
||||
OopHandle elem = OopHandle(Universe::vm_global(), init_error());
|
||||
bool created;
|
||||
_initialization_error_table.put_if_absent(this, elem, &created);
|
||||
if (_initialization_error_table == nullptr) {
|
||||
_initialization_error_table = new (mtClass) InitializationErrorTable();
|
||||
}
|
||||
_initialization_error_table->put_if_absent(this, elem, &created);
|
||||
assert(created, "Initialization is single threaded");
|
||||
log_trace(class, init)("Initialization error added for class %s", external_name());
|
||||
}
|
||||
|
||||
oop InstanceKlass::get_initialization_error(JavaThread* current) {
|
||||
MutexLocker ml(current, ClassInitError_lock);
|
||||
OopHandle* h = _initialization_error_table.get(this);
|
||||
if (_initialization_error_table == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
OopHandle* h = _initialization_error_table->get(this);
|
||||
return (h != nullptr) ? h->resolve() : nullptr;
|
||||
}
|
||||
|
||||
@ -1032,7 +1038,9 @@ void InstanceKlass::clean_initialization_error_table() {
|
||||
|
||||
assert_locked_or_safepoint(ClassInitError_lock);
|
||||
InitErrorTableCleaner cleaner;
|
||||
_initialization_error_table.unlink(&cleaner);
|
||||
if (_initialization_error_table != nullptr) {
|
||||
_initialization_error_table->unlink(&cleaner);
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceKlass::initialize_impl(TRAPS) {
|
||||
@ -4352,3 +4360,4 @@ void ClassHierarchyIterator::next() {
|
||||
_current = _current->next_sibling();
|
||||
return; // visit next sibling subclass
|
||||
}
|
||||
|
||||
|
@ -2627,17 +2627,18 @@ class AdapterFingerPrint : public CHeapObj<mtCode> {
|
||||
};
|
||||
|
||||
// A hashtable mapping from AdapterFingerPrints to AdapterHandlerEntries
|
||||
ResourceHashtable<AdapterFingerPrint*, AdapterHandlerEntry*, 293,
|
||||
using AdapterHandlerTable = ResourceHashtable<AdapterFingerPrint*, AdapterHandlerEntry*, 293,
|
||||
AnyObj::C_HEAP, mtCode,
|
||||
AdapterFingerPrint::compute_hash,
|
||||
AdapterFingerPrint::equals> _adapter_handler_table;
|
||||
AdapterFingerPrint::equals>;
|
||||
static AdapterHandlerTable* _adapter_handler_table;
|
||||
|
||||
// Find a entry with the same fingerprint if it exists
|
||||
static AdapterHandlerEntry* lookup(int total_args_passed, BasicType* sig_bt) {
|
||||
NOT_PRODUCT(_lookups++);
|
||||
assert_lock_strong(AdapterHandlerLibrary_lock);
|
||||
AdapterFingerPrint fp(total_args_passed, sig_bt);
|
||||
AdapterHandlerEntry** entry = _adapter_handler_table.get(&fp);
|
||||
AdapterHandlerEntry** entry = _adapter_handler_table->get(&fp);
|
||||
if (entry != nullptr) {
|
||||
#ifndef PRODUCT
|
||||
if (fp.is_compact()) _compact++;
|
||||
@ -2653,10 +2654,10 @@ static void print_table_statistics() {
|
||||
auto size = [&] (AdapterFingerPrint* key, AdapterHandlerEntry* a) {
|
||||
return sizeof(*key) + sizeof(*a);
|
||||
};
|
||||
TableStatistics ts = _adapter_handler_table.statistics_calculate(size);
|
||||
TableStatistics ts = _adapter_handler_table->statistics_calculate(size);
|
||||
ts.print(tty, "AdapterHandlerTable");
|
||||
tty->print_cr("AdapterHandlerTable (table_size=%d, entries=%d)",
|
||||
_adapter_handler_table.table_size(), _adapter_handler_table.number_of_entries());
|
||||
_adapter_handler_table->table_size(), _adapter_handler_table->number_of_entries());
|
||||
tty->print_cr("AdapterHandlerTable: lookups %d equals %d hits %d compact %d",
|
||||
_lookups, _equals, _hits, _compact);
|
||||
}
|
||||
@ -2704,6 +2705,7 @@ void AdapterHandlerLibrary::initialize() {
|
||||
AdapterBlob* obj_int_arg_blob = nullptr;
|
||||
AdapterBlob* obj_obj_arg_blob = nullptr;
|
||||
{
|
||||
_adapter_handler_table = new (mtCode) AdapterHandlerTable();
|
||||
MutexLocker mu(AdapterHandlerLibrary_lock);
|
||||
|
||||
// Create a special handler for abstract methods. Abstract methods
|
||||
@ -2945,7 +2947,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::create_adapter(AdapterBlob*& new_ada
|
||||
ttyLocker ttyl;
|
||||
entry->print_adapter_on(tty);
|
||||
tty->print_cr("i2c argument handler #%d for: %s %s (%d bytes generated)",
|
||||
_adapter_handler_table.number_of_entries(), fingerprint->as_basic_args_string(),
|
||||
_adapter_handler_table->number_of_entries(), fingerprint->as_basic_args_string(),
|
||||
fingerprint->as_string(), insts_size);
|
||||
tty->print_cr("c2i argument handler starts at " INTPTR_FORMAT, p2i(entry->get_c2i_entry()));
|
||||
if (Verbose || PrintStubCode) {
|
||||
@ -2963,7 +2965,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::create_adapter(AdapterBlob*& new_ada
|
||||
// The checks are inserted only if -XX:+VerifyAdapterCalls is specified.
|
||||
if (contains_all_checks || !VerifyAdapterCalls) {
|
||||
assert_lock_strong(AdapterHandlerLibrary_lock);
|
||||
_adapter_handler_table.put(fingerprint, entry);
|
||||
_adapter_handler_table->put(fingerprint, entry);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
@ -3296,7 +3298,7 @@ bool AdapterHandlerLibrary::contains(const CodeBlob* b) {
|
||||
return (found = (b == CodeCache::find_blob(a->get_i2c_entry())));
|
||||
};
|
||||
assert_locked_or_safepoint(AdapterHandlerLibrary_lock);
|
||||
_adapter_handler_table.iterate(findblob);
|
||||
_adapter_handler_table->iterate(findblob);
|
||||
return found;
|
||||
}
|
||||
|
||||
@ -3313,7 +3315,7 @@ void AdapterHandlerLibrary::print_handler_on(outputStream* st, const CodeBlob* b
|
||||
}
|
||||
};
|
||||
assert_locked_or_safepoint(AdapterHandlerLibrary_lock);
|
||||
_adapter_handler_table.iterate(findblob);
|
||||
_adapter_handler_table->iterate(findblob);
|
||||
assert(found, "Should have found handler");
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user