8292375: Convert ProtectionDomainCacheTable to ResourceHashtable
Reviewed-by: dholmes, iklam
This commit is contained in:
parent
6fc58b8324
commit
fcc0cf9677
src/hotspot/share
classfile
dictionary.cppprotectionDomainCache.cppprotectionDomainCache.hppsystemDictionary.cppsystemDictionary.hpp
prims
runtime
utilities
test/hotspot/jtreg/serviceability/dcmd/vm
@ -166,9 +166,9 @@ bool DictionaryEntry::contains_protection_domain(oop protection_domain) const {
|
||||
void DictionaryEntry::add_protection_domain(ClassLoaderData* loader_data, Handle protection_domain) {
|
||||
assert_lock_strong(SystemDictionary_lock);
|
||||
if (!contains_protection_domain(protection_domain())) {
|
||||
ProtectionDomainCacheEntry* entry = SystemDictionary::pd_cache_table()->get(protection_domain);
|
||||
WeakHandle obj = ProtectionDomainCacheTable::add_if_absent(protection_domain);
|
||||
// Additions and deletions hold the SystemDictionary_lock, readers are lock-free
|
||||
ProtectionDomainEntry* new_head = new ProtectionDomainEntry(entry, _pd_set);
|
||||
ProtectionDomainEntry* new_head = new ProtectionDomainEntry(obj, _pd_set);
|
||||
release_set_pd_set(new_head);
|
||||
}
|
||||
LogTarget(Trace, protectiondomain) lt;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,23 +35,28 @@
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/weakHandle.inline.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
#include "utilities/hashtable.inline.hpp"
|
||||
#include "utilities/resourceHash.hpp"
|
||||
|
||||
unsigned int ProtectionDomainCacheTable::compute_hash(Handle protection_domain) {
|
||||
// Identity hash can safepoint, so keep protection domain in a Handle.
|
||||
return (unsigned int)(protection_domain->identity_hash());
|
||||
unsigned int ProtectionDomainCacheTable::compute_hash(const WeakHandle& protection_domain) {
|
||||
// The protection domain in the hash computation is passed from a Handle so cannot resolve to null.
|
||||
assert(protection_domain.peek() != nullptr, "Must be live");
|
||||
return (unsigned int)(protection_domain.resolve()->identity_hash());
|
||||
}
|
||||
|
||||
int ProtectionDomainCacheTable::index_for(Handle protection_domain) {
|
||||
return hash_to_index(compute_hash(protection_domain));
|
||||
bool ProtectionDomainCacheTable::equals(const WeakHandle& protection_domain1, const WeakHandle& protection_domain2) {
|
||||
return protection_domain1.peek() == protection_domain2.peek();
|
||||
}
|
||||
|
||||
ProtectionDomainCacheTable::ProtectionDomainCacheTable(int table_size)
|
||||
: Hashtable<WeakHandle, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry))
|
||||
{ _dead_entries = false;
|
||||
_total_oops_removed = 0;
|
||||
}
|
||||
// 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, ResourceObj::C_HEAP, mtClass,
|
||||
ProtectionDomainCacheTable::compute_hash,
|
||||
ProtectionDomainCacheTable::equals> _pd_cache_table;
|
||||
|
||||
bool ProtectionDomainCacheTable::_dead_entries = false;
|
||||
int ProtectionDomainCacheTable::_total_oops_removed = 0;
|
||||
|
||||
void ProtectionDomainCacheTable::trigger_cleanup() {
|
||||
MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
|
||||
@ -129,107 +134,91 @@ void ProtectionDomainCacheTable::unlink() {
|
||||
// Purge any deleted entries outside of the SystemDictionary_lock.
|
||||
purge_deleted_entries();
|
||||
|
||||
// Reacquire the lock to remove entries from the hashtable.
|
||||
MutexLocker ml(SystemDictionary_lock);
|
||||
int oops_removed = 0;
|
||||
for (int i = 0; i < table_size(); ++i) {
|
||||
ProtectionDomainCacheEntry** p = bucket_addr(i);
|
||||
ProtectionDomainCacheEntry* entry = bucket(i);
|
||||
while (entry != NULL) {
|
||||
oop pd = entry->object_no_keepalive();
|
||||
if (pd != NULL) {
|
||||
p = entry->next_addr();
|
||||
} else {
|
||||
oops_removed++;
|
||||
|
||||
struct Deleter {
|
||||
int _oops_removed;
|
||||
Deleter() : _oops_removed(0) {}
|
||||
|
||||
bool do_entry(WeakHandle& key, WeakHandle& value) {
|
||||
oop pd = value.peek();
|
||||
if (value.peek() == nullptr) {
|
||||
_oops_removed++;
|
||||
LogTarget(Debug, protectiondomain, table) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
ls.print_cr("protection domain unlinked at %d", i);
|
||||
ls.print_cr("protection domain unlinked %d", _oops_removed);
|
||||
}
|
||||
entry->literal().release(Universe::vm_weak());
|
||||
*p = entry->next();
|
||||
free_entry(entry);
|
||||
value.release(Universe::vm_weak());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
entry = *p;
|
||||
}
|
||||
}
|
||||
_total_oops_removed += oops_removed;
|
||||
};
|
||||
|
||||
Deleter deleter;
|
||||
_pd_cache_table.unlink(&deleter);
|
||||
|
||||
_total_oops_removed += deleter._oops_removed;
|
||||
_dead_entries = false;
|
||||
}
|
||||
|
||||
void ProtectionDomainCacheTable::print_on(outputStream* st) const {
|
||||
void ProtectionDomainCacheTable::print_on(outputStream* st) {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
st->print_cr("Protection domain cache table (table_size=%d, classes=%d)",
|
||||
table_size(), number_of_entries());
|
||||
for (int index = 0; index < table_size(); index++) {
|
||||
for (ProtectionDomainCacheEntry* probe = bucket(index);
|
||||
probe != NULL;
|
||||
probe = probe->next()) {
|
||||
st->print_cr("%4d: protection_domain: " PTR_FORMAT, index, p2i(probe->object_no_keepalive()));
|
||||
}
|
||||
}
|
||||
auto printer = [&] (WeakHandle& key, WeakHandle& value) {
|
||||
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);
|
||||
}
|
||||
|
||||
void ProtectionDomainCacheTable::verify() {
|
||||
verify_table<ProtectionDomainCacheEntry>("Protection Domain Table");
|
||||
}
|
||||
|
||||
oop ProtectionDomainCacheEntry::object() {
|
||||
return literal().resolve();
|
||||
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);
|
||||
}
|
||||
|
||||
// The object_no_keepalive() call peeks at the phantomly reachable oop without
|
||||
// keeping it alive. This is okay to do in the VM thread state if it is not
|
||||
// leaked out to become strongly reachable.
|
||||
oop ProtectionDomainCacheEntry::object_no_keepalive() {
|
||||
return literal().peek();
|
||||
}
|
||||
|
||||
// keeping it alive. This is used for traversing DictionaryEntry pd_set.
|
||||
oop ProtectionDomainEntry::object_no_keepalive() {
|
||||
return _pd_cache->object_no_keepalive();
|
||||
return _object.peek();
|
||||
}
|
||||
|
||||
void ProtectionDomainCacheEntry::verify() {
|
||||
guarantee(object_no_keepalive() == NULL || oopDesc::is_oop(object_no_keepalive()), "must be an oop");
|
||||
}
|
||||
|
||||
ProtectionDomainCacheEntry* ProtectionDomainCacheTable::get(Handle protection_domain) {
|
||||
unsigned int hash = compute_hash(protection_domain);
|
||||
int index = hash_to_index(hash);
|
||||
|
||||
ProtectionDomainCacheEntry* entry = find_entry(index, protection_domain);
|
||||
if (entry == NULL) {
|
||||
entry = add_entry(index, hash, protection_domain);
|
||||
}
|
||||
// keep entry alive
|
||||
(void)entry->object();
|
||||
return entry;
|
||||
}
|
||||
|
||||
ProtectionDomainCacheEntry* ProtectionDomainCacheTable::find_entry(int index, Handle protection_domain) {
|
||||
WeakHandle ProtectionDomainCacheTable::add_if_absent(Handle protection_domain) {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
for (ProtectionDomainCacheEntry* e = bucket(index); e != NULL; e = e->next()) {
|
||||
if (e->object_no_keepalive() == protection_domain()) {
|
||||
return e;
|
||||
WeakHandle w(Universe::vm_weak(), protection_domain);
|
||||
bool 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());
|
||||
} else {
|
||||
LogTarget(Debug, protectiondomain, table) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
ls.print("protection domain added ");
|
||||
protection_domain->print_value_on(&ls);
|
||||
ls.cr();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
// Keep entry alive
|
||||
(void)wk->resolve();
|
||||
return *wk;
|
||||
}
|
||||
|
||||
ProtectionDomainCacheEntry* ProtectionDomainCacheTable::add_entry(int index, unsigned int hash, Handle protection_domain) {
|
||||
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||
assert(index == index_for(protection_domain), "incorrect index?");
|
||||
assert(find_entry(index, protection_domain) == NULL, "no double entry");
|
||||
|
||||
LogTarget(Debug, protectiondomain, table) lt;
|
||||
if (lt.is_enabled()) {
|
||||
LogStream ls(lt);
|
||||
ls.print("protection domain added ");
|
||||
protection_domain->print_value_on(&ls);
|
||||
ls.cr();
|
||||
}
|
||||
WeakHandle w(Universe::vm_weak(), protection_domain);
|
||||
ProtectionDomainCacheEntry* p = new_entry(hash, w);
|
||||
Hashtable<WeakHandle, mtClass>::add_entry(index, p);
|
||||
return p;
|
||||
void ProtectionDomainCacheTable::print_table_statistics(outputStream* st) {
|
||||
auto size = [&] (WeakHandle& key, WeakHandle& value) {
|
||||
// The only storage is in OopStorage for an oop
|
||||
return sizeof(oop);
|
||||
};
|
||||
TableStatistics ts = _pd_cache_table.statistics_calculate(size);
|
||||
ts.print(st, "ProtectionDomainCacheTable");
|
||||
}
|
||||
|
||||
int ProtectionDomainCacheTable::number_of_entries() {
|
||||
return _pd_cache_table.number_of_entries();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,88 +28,43 @@
|
||||
#include "oops/oop.hpp"
|
||||
#include "oops/weakHandle.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "utilities/hashtable.hpp"
|
||||
|
||||
// This class caches the approved protection domains that can access loaded classes.
|
||||
// Dictionary entry pd_set point to entries in this hashtable. Please refer
|
||||
// to dictionary.hpp pd_set for more information about how protection domain entries
|
||||
// are used.
|
||||
// This table is walked during GC, rather than the class loader data graph dictionaries.
|
||||
class ProtectionDomainCacheEntry : public HashtableEntry<WeakHandle, mtClass> {
|
||||
friend class VMStructs;
|
||||
public:
|
||||
oop object();
|
||||
oop object_no_keepalive();
|
||||
|
||||
ProtectionDomainCacheEntry* next() {
|
||||
return (ProtectionDomainCacheEntry*)HashtableEntry<WeakHandle, mtClass>::next();
|
||||
}
|
||||
|
||||
ProtectionDomainCacheEntry** next_addr() {
|
||||
return (ProtectionDomainCacheEntry**)HashtableEntry<WeakHandle, mtClass>::next_addr();
|
||||
}
|
||||
|
||||
void verify();
|
||||
};
|
||||
|
||||
// The ProtectionDomainCacheTable contains all protection domain oops. The
|
||||
// dictionary entries reference its entries instead of having references to oops
|
||||
// directly.
|
||||
// This is used to speed up system dictionary iteration: the oops in the
|
||||
// protection domain are the only ones referring the Java heap. So when there is
|
||||
// need to update these, instead of going over every entry of the system dictionary,
|
||||
// we only need to iterate over this set.
|
||||
// The ProtectionDomainCacheTable maps all java.security.ProtectionDomain objects that are
|
||||
// registered by DictionaryEntry::add_protection_domain() to a unique WeakHandle.
|
||||
// The amount of different protection domains used is typically magnitudes smaller
|
||||
// than the number of system dictionary entries (loaded classes).
|
||||
class ProtectionDomainCacheTable : public Hashtable<WeakHandle, mtClass> {
|
||||
ProtectionDomainCacheEntry* bucket(int i) const {
|
||||
return (ProtectionDomainCacheEntry*) Hashtable<WeakHandle, mtClass>::bucket(i);
|
||||
}
|
||||
class ProtectionDomainCacheTable : public AllStatic {
|
||||
|
||||
// The following method is not MT-safe and must be done under lock.
|
||||
ProtectionDomainCacheEntry** bucket_addr(int i) {
|
||||
return (ProtectionDomainCacheEntry**) Hashtable<WeakHandle, mtClass>::bucket_addr(i);
|
||||
}
|
||||
|
||||
ProtectionDomainCacheEntry* new_entry(unsigned int hash, WeakHandle protection_domain) {
|
||||
ProtectionDomainCacheEntry* entry = (ProtectionDomainCacheEntry*)
|
||||
Hashtable<WeakHandle, mtClass>::new_entry(hash, protection_domain);
|
||||
return entry;
|
||||
}
|
||||
|
||||
static unsigned int compute_hash(Handle protection_domain);
|
||||
|
||||
int index_for(Handle protection_domain);
|
||||
ProtectionDomainCacheEntry* add_entry(int index, unsigned int hash, Handle protection_domain);
|
||||
ProtectionDomainCacheEntry* find_entry(int index, Handle protection_domain);
|
||||
|
||||
bool _dead_entries;
|
||||
int _total_oops_removed;
|
||||
static bool _dead_entries;
|
||||
static int _total_oops_removed;
|
||||
|
||||
public:
|
||||
ProtectionDomainCacheTable(int table_size);
|
||||
ProtectionDomainCacheEntry* get(Handle protection_domain);
|
||||
static unsigned int compute_hash(const WeakHandle& protection_domain);
|
||||
static bool equals(const WeakHandle& protection_domain1, const WeakHandle& protection_domain2);
|
||||
|
||||
void unlink();
|
||||
static WeakHandle add_if_absent(Handle protection_domain);
|
||||
static void unlink();
|
||||
|
||||
void print_on(outputStream* st) const;
|
||||
void verify();
|
||||
static void print_on(outputStream* st);
|
||||
static void verify();
|
||||
|
||||
bool has_work() { return _dead_entries; }
|
||||
void trigger_cleanup();
|
||||
static bool has_work() { return _dead_entries; }
|
||||
static void trigger_cleanup();
|
||||
|
||||
int removed_entries_count() { return _total_oops_removed; };
|
||||
static int removed_entries_count() { return _total_oops_removed; };
|
||||
static int number_of_entries();
|
||||
static void print_table_statistics(outputStream* st);
|
||||
};
|
||||
|
||||
|
||||
// This describes the linked list protection domain for each DictionaryEntry in pd_set.
|
||||
class ProtectionDomainEntry :public CHeapObj<mtClass> {
|
||||
ProtectionDomainCacheEntry* _pd_cache;
|
||||
WeakHandle _object;
|
||||
ProtectionDomainEntry* volatile _next;
|
||||
public:
|
||||
|
||||
ProtectionDomainEntry(ProtectionDomainCacheEntry* pd_cache,
|
||||
ProtectionDomainEntry* head) : _pd_cache(pd_cache), _next(head) {}
|
||||
ProtectionDomainEntry(WeakHandle obj,
|
||||
ProtectionDomainEntry* head) : _object(obj), _next(head) {}
|
||||
|
||||
ProtectionDomainEntry* next_acquire() { return Atomic::load_acquire(&_next); }
|
||||
void release_set_next(ProtectionDomainEntry* entry) { Atomic::release_store(&_next, entry); }
|
||||
|
@ -116,17 +116,10 @@ class InvokeMethodKey : public StackObj {
|
||||
ResourceHashtable<InvokeMethodKey, Method*, 139, ResourceObj::C_HEAP, mtClass,
|
||||
InvokeMethodKey::compute_hash, InvokeMethodKey::key_comparison> _invoke_method_intrinsic_table;
|
||||
ResourceHashtable<Symbol*, OopHandle, 139, ResourceObj::C_HEAP, mtClass> _invoke_method_type_table;
|
||||
ProtectionDomainCacheTable* SystemDictionary::_pd_cache_table = NULL;
|
||||
|
||||
OopHandle SystemDictionary::_java_system_loader;
|
||||
OopHandle SystemDictionary::_java_platform_loader;
|
||||
|
||||
// Default ProtectionDomainCacheSize value
|
||||
const int defaultProtectionDomainCacheSize = 1009;
|
||||
|
||||
const int _resolution_error_size = 107; // number of entries in resolution error table
|
||||
const int _invoke_method_size = 139; // number of entries in invoke method table
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Java-level SystemLoader and PlatformLoader
|
||||
oop SystemDictionary::java_system_loader() {
|
||||
@ -1665,9 +1658,9 @@ bool SystemDictionary::do_unloading(GCTimer* gc_timer) {
|
||||
// explicitly unlink them here.
|
||||
// All protection domain oops are linked to the caller class, so if nothing
|
||||
// unloads, this is not needed.
|
||||
_pd_cache_table->trigger_cleanup();
|
||||
ProtectionDomainCacheTable::trigger_cleanup();
|
||||
} else {
|
||||
assert(_pd_cache_table->number_of_entries() == 0, "should be empty");
|
||||
assert(ProtectionDomainCacheTable::number_of_entries() == 0, "should be empty");
|
||||
}
|
||||
|
||||
MutexLocker ml(is_concurrent ? ClassInitError_lock : NULL);
|
||||
@ -1700,9 +1693,6 @@ void SystemDictionary::methods_do(void f(Method*)) {
|
||||
// Initialization
|
||||
|
||||
void SystemDictionary::initialize(TRAPS) {
|
||||
// Allocate arrays
|
||||
_pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);
|
||||
|
||||
#if INCLUDE_CDS
|
||||
SystemDictionaryShared::initialize();
|
||||
#endif
|
||||
@ -2468,7 +2458,7 @@ void SystemDictionary::print_on(outputStream *st) {
|
||||
LoaderConstraintTable::print_on(st);
|
||||
st->cr();
|
||||
|
||||
_pd_cache_table->print_on(st);
|
||||
ProtectionDomainCacheTable::print_on(st);
|
||||
st->cr();
|
||||
}
|
||||
|
||||
@ -2484,7 +2474,8 @@ void SystemDictionary::verify() {
|
||||
// Verify constraint table
|
||||
LoaderConstraintTable::verify();
|
||||
|
||||
_pd_cache_table->verify();
|
||||
// Verify protection domain table
|
||||
ProtectionDomainCacheTable::verify();
|
||||
}
|
||||
|
||||
void SystemDictionary::dump(outputStream *st, bool verbose) {
|
||||
@ -2495,7 +2486,7 @@ void SystemDictionary::dump(outputStream *st, bool verbose) {
|
||||
CDS_ONLY(SystemDictionaryShared::print_table_statistics(st));
|
||||
ClassLoaderDataGraph::print_table_statistics(st);
|
||||
LoaderConstraintTable::print_table_statistics(st);
|
||||
pd_cache_table()->print_table_statistics(st, "ProtectionDomainCache Table");
|
||||
ProtectionDomainCacheTable::print_table_statistics(st);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,11 +70,7 @@ class BootstrapInfo;
|
||||
class ClassFileStream;
|
||||
class ClassLoadInfo;
|
||||
class Dictionary;
|
||||
template <MEMFLAGS F> class HashtableBucket;
|
||||
class SymbolPropertyTable;
|
||||
class PackageEntry;
|
||||
class ProtectionDomainCacheTable;
|
||||
class ProtectionDomainCacheEntry;
|
||||
class GCTimer;
|
||||
class EventClassLoad;
|
||||
class Symbol;
|
||||
@ -190,9 +186,6 @@ class SystemDictionary : AllStatic {
|
||||
// loaders. Returns "true" iff something was unloaded.
|
||||
static bool do_unloading(GCTimer* gc_timer);
|
||||
|
||||
// Protection Domain Table
|
||||
static ProtectionDomainCacheTable* pd_cache_table() { return _pd_cache_table; }
|
||||
|
||||
// Printing
|
||||
static void print();
|
||||
static void print_on(outputStream* st);
|
||||
@ -295,15 +288,6 @@ public:
|
||||
const char* message);
|
||||
static const char* find_nest_host_error(const constantPoolHandle& pool, int which);
|
||||
|
||||
private:
|
||||
// Static tables owned by the SystemDictionary
|
||||
|
||||
// Invoke methods (JSR 292)
|
||||
static SymbolPropertyTable* _invoke_method_table;
|
||||
|
||||
// ProtectionDomain cache
|
||||
static ProtectionDomainCacheTable* _pd_cache_table;
|
||||
|
||||
protected:
|
||||
static InstanceKlass* _well_known_klasses[];
|
||||
|
||||
@ -314,8 +298,6 @@ private:
|
||||
static OopHandle _java_system_loader;
|
||||
static OopHandle _java_platform_loader;
|
||||
|
||||
static SymbolPropertyTable* invoke_method_table() { return _invoke_method_table; }
|
||||
|
||||
private:
|
||||
// Basic loading operations
|
||||
static InstanceKlass* resolve_instance_class_or_null(Symbol* class_name,
|
||||
|
@ -2387,7 +2387,7 @@ WB_ENTRY(jlong, WB_ResolvedMethodItemsCount(JNIEnv* env, jobject o))
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jint, WB_ProtectionDomainRemovedCount(JNIEnv* env, jobject o))
|
||||
return (jint) SystemDictionary::pd_cache_table()->removed_entries_count();
|
||||
return (jint) ProtectionDomainCacheTable::removed_entries_count();
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jint, WB_GetKlassMetadataSize(JNIEnv* env, jobject wb, jclass mirror))
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -150,7 +150,7 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
|
||||
(finalizerservice_work = FinalizerService::has_work()) |
|
||||
(resolved_method_table_work = ResolvedMethodTable::has_work()) |
|
||||
(thread_id_table_work = ThreadIdTable::has_work()) |
|
||||
(protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()) |
|
||||
(protection_domain_table_work = ProtectionDomainCacheTable::has_work()) |
|
||||
(oopstorage_work = OopStorage::has_cleanup_work_and_reset()) |
|
||||
(oop_handles_to_release = (_oop_handle_list != NULL)) |
|
||||
(cldg_cleanup_work = ClassLoaderDataGraph::should_clean_metaspaces_and_reset()) |
|
||||
@ -207,7 +207,7 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
|
||||
}
|
||||
|
||||
if (protection_domain_table_work) {
|
||||
SystemDictionary::pd_cache_table()->unlink();
|
||||
ProtectionDomainCacheTable::unlink();
|
||||
}
|
||||
|
||||
if (oopstorage_work) {
|
||||
|
@ -25,10 +25,6 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/dictionary.hpp"
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "classfile/moduleEntry.hpp"
|
||||
#include "classfile/packageEntry.hpp"
|
||||
#include "classfile/placeholders.hpp"
|
||||
#include "classfile/protectionDomainCache.hpp"
|
||||
#include "classfile/vmClasses.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "logging/log.hpp"
|
||||
@ -255,12 +251,7 @@ template <class T> void BasicHashtable<F>::verify_table(const char* table_name)
|
||||
|
||||
// Explicitly instantiate these types
|
||||
template class BasicHashtable<mtGC>;
|
||||
template class BasicHashtable<mtClass>;
|
||||
template class BasicHashtable<mtServiceability>;
|
||||
|
||||
template class Hashtable<nmethod*, mtGC>;
|
||||
template class Hashtable<InstanceKlass*, mtClass>;
|
||||
template class Hashtable<WeakHandle, mtClass>;
|
||||
template class Hashtable<WeakHandle, mtServiceability>;
|
||||
|
||||
template void BasicHashtable<mtClass>::verify_table<ProtectionDomainCacheEntry>(char const*);
|
||||
|
@ -58,6 +58,24 @@ public class DictionaryStatsTest {
|
||||
// Variance of bucket size : 0.045
|
||||
// Std. dev. of bucket size: 0.211
|
||||
// Maximum bucket size : 1
|
||||
// LoaderConstraintTable statistics:
|
||||
// Number of buckets : 107 = 856 bytes, each 8
|
||||
// Number of entries : 31 = 1736 bytes, each 56
|
||||
// Number of literals : 31 = 1120 bytes, avg 36.000
|
||||
// Total footprint : = 3712 bytes
|
||||
// Average bucket size : 0.290
|
||||
// Variance of bucket size : 0.281
|
||||
// Std. dev. of bucket size: 0.530
|
||||
// Maximum bucket size : 2
|
||||
// ProtectionDomainCacheTable statistics:
|
||||
// Number of buckets : 1009 = 8072 bytes, each 8
|
||||
// Number of entries : 0 = 0 bytes, each 0
|
||||
// Total footprint : = 8072 bytes
|
||||
// Average bucket size : 0.000
|
||||
// Variance of bucket size : 0.000
|
||||
// Std. dev. of bucket size: 0.000
|
||||
// Maximum bucket size : 0
|
||||
|
||||
|
||||
public void run(CommandExecutor executor) throws ClassNotFoundException {
|
||||
|
||||
@ -80,6 +98,11 @@ public class DictionaryStatsTest {
|
||||
output.shouldContain("Variance of bucket size");
|
||||
output.shouldContain("Std. dev. of bucket size");
|
||||
output.shouldContain("Maximum bucket size");
|
||||
output.shouldMatch("LoaderConstraintTable statistics:");
|
||||
// Would be nice to run this with "-Djava.security.manager=allow"
|
||||
// so the numbers aren't 0 (running make with VM_OPTIONS allowing
|
||||
// security manager does get 12 entries in this table.)
|
||||
output.shouldMatch("ProtectionDomainCacheTable statistics:");
|
||||
|
||||
// what is this?
|
||||
Reference.reachabilityFence(named_cl);
|
||||
|
Loading…
x
Reference in New Issue
Block a user