Skip to content
Permalink
Browse files
8246340: Move SystemDictionary GC roots into OopStorage
Use vm_global() OopStorage for system dictionary roots

Reviewed-by: eosterlund, lfoltan
  • Loading branch information
coleenp committed Jun 5, 2020
1 parent 06e47d0 commit 498b0e61ed87df42bcc81eb38edec24ef2eeb040
Showing 31 changed files with 149 additions and 167 deletions.
@@ -33,6 +33,7 @@
#include "memory/metaspaceClosure.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oopHandle.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepointVerifiers.hpp"
#include "utilities/hashtable.inline.hpp"
@@ -400,6 +401,20 @@ void Dictionary::clean_cached_protection_domains() {
}
}

oop SymbolPropertyEntry::method_type() const {
return _method_type.resolve();
}

void SymbolPropertyEntry::set_method_type(oop p) {
_method_type = OopHandle::create(p);
}

void SymbolPropertyEntry::free_entry() {
// decrement Symbol refcount here because hashtable doesn't.
literal()->decrement_refcount();
// Free OopHandle
_method_type.release();
}

SymbolPropertyTable::SymbolPropertyTable(int table_size)
: Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry))
@@ -436,16 +451,6 @@ SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash
return p;
}

void SymbolPropertyTable::oops_do(OopClosure* f) {
for (int index = 0; index < table_size(); index++) {
for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {
if (p->method_type() != NULL) {
f->do_oop(p->method_type_addr());
}
}
}
}

void SymbolPropertyTable::methods_do(void f(Method*)) {
for (int index = 0; index < table_size(); index++) {
for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) {
@@ -457,6 +462,11 @@ void SymbolPropertyTable::methods_do(void f(Method*)) {
}
}

void SymbolPropertyTable::free_entry(SymbolPropertyEntry* entry) {
entry->free_entry();
Hashtable<Symbol*, mtSymbol>::free_entry(entry);
}

void DictionaryEntry::verify_protection_domain_set() {
MutexLocker ml(ProtectionDomainSet_lock, Mutex::_no_safepoint_check_flag);
for (ProtectionDomainEntry* current = pd_set(); // accessed at a safepoint
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2020, 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
@@ -29,6 +29,7 @@
#include "classfile/systemDictionary.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/oop.hpp"
#include "oops/oopHandle.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/ostream.hpp"

@@ -180,7 +181,7 @@ class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> {
private:
intptr_t _symbol_mode; // secondary key
Method* _method;
oop _method_type;
OopHandle _method_type;

public:
Symbol* symbol() const { return literal(); }
@@ -191,9 +192,10 @@ class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> {
Method* method() const { return _method; }
void set_method(Method* p) { _method = p; }

oop method_type() const { return _method_type; }
oop* method_type_addr() { return &_method_type; }
void set_method_type(oop p) { _method_type = p; }
oop method_type() const;
void set_method_type(oop p);

void free_entry();

SymbolPropertyEntry* next() const {
return (SymbolPropertyEntry*)HashtableEntry<Symbol*, mtSymbol>::next();
@@ -253,11 +255,7 @@ class SymbolPropertyTable : public Hashtable<Symbol*, mtSymbol> {
SymbolPropertyTable(int table_size);
SymbolPropertyTable(int table_size, HashtableBucket<mtSymbol>* t, int number_of_entries);

void free_entry(SymbolPropertyEntry* entry) {
// decrement Symbol refcount here because hashtable doesn't.
entry->literal()->decrement_refcount();
Hashtable<Symbol*, mtSymbol>::free_entry(entry);
}
void free_entry(SymbolPropertyEntry* entry);

unsigned int compute_hash(Symbol* sym, intptr_t symbol_mode) {
// Use the regular identity_hash.
@@ -274,9 +272,6 @@ class SymbolPropertyTable : public Hashtable<Symbol*, mtSymbol> {
// must be done under SystemDictionary_lock
SymbolPropertyEntry* add_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);

// GC support
void oops_do(OopClosure* f);

void methods_do(void f(Method*));

void verify();
@@ -46,8 +46,6 @@
#include "code/codeCache.hpp"
#include "compiler/compileBroker.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/oopStorage.inline.hpp"
#include "gc/shared/oopStorageSet.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "interpreter/interpreter.hpp"
#include "jfr/jfrEvents.hpp"
@@ -68,6 +66,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oopHandle.inline.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayKlass.hpp"
#include "prims/jvmtiExport.hpp"
@@ -98,15 +97,15 @@ ResolutionErrorTable* SystemDictionary::_resolution_errors = NULL;
SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL;
ProtectionDomainCacheTable* SystemDictionary::_pd_cache_table = NULL;

oop SystemDictionary::_system_loader_lock_obj = NULL;

InstanceKlass* SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT]
= { NULL /*, NULL...*/ };

InstanceKlass* SystemDictionary::_box_klasses[T_VOID+1] = { NULL /*, NULL...*/ };

oop SystemDictionary::_java_system_loader = NULL;
oop SystemDictionary::_java_platform_loader = NULL;

OopHandle SystemDictionary::_system_loader_lock_obj;
OopHandle SystemDictionary::_java_system_loader;
OopHandle SystemDictionary::_java_platform_loader;

// Default ProtectionDomainCacheSize value

@@ -155,12 +154,16 @@ ClassLoadInfo::ClassLoadInfo(Handle protection_domain,
// ----------------------------------------------------------------------------
// Java-level SystemLoader and PlatformLoader

oop SystemDictionary::system_loader_lock() {
return _system_loader_lock_obj.resolve();
}

oop SystemDictionary::java_system_loader() {
return _java_system_loader;
return _java_system_loader.resolve();
}

oop SystemDictionary::java_platform_loader() {
return _java_platform_loader;
return _java_platform_loader.resolve();
}

void SystemDictionary::compute_java_loaders(TRAPS) {
@@ -172,15 +175,15 @@ void SystemDictionary::compute_java_loaders(TRAPS) {
vmSymbols::void_classloader_signature(),
CHECK);

_java_system_loader = (oop)result.get_jobject();
_java_system_loader = OopHandle::create((oop)result.get_jobject());

JavaCalls::call_static(&result,
class_loader_klass,
vmSymbols::getPlatformClassLoader_name(),
vmSymbols::void_classloader_signature(),
CHECK);

_java_platform_loader = (oop)result.get_jobject();
_java_platform_loader = OopHandle::create((oop)result.get_jobject());
}

ClassLoaderData* SystemDictionary::register_loader(Handle class_loader, bool create_mirror_cld) {
@@ -219,7 +222,7 @@ bool SystemDictionary::is_system_class_loader(oop class_loader) {
return false;
}
return (class_loader->klass() == SystemDictionary::jdk_internal_loader_ClassLoaders_AppClassLoader_klass() ||
class_loader == _java_system_loader);
class_loader == _java_system_loader.peek());
}

// Returns true if the passed class loader is the platform class loader.
@@ -603,7 +606,8 @@ void SystemDictionary::double_lock_wait(Handle lockObject, TRAPS) {
bool calledholdinglock
= ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, lockObject);
assert(calledholdinglock,"must hold lock for notify");
assert((lockObject() != _system_loader_lock_obj && !is_parallelCapable(lockObject)), "unexpected double_lock_wait");
assert((lockObject() != _system_loader_lock_obj.resolve() &&
!is_parallelCapable(lockObject)), "unexpected double_lock_wait");
ObjectSynchronizer::notifyall(lockObject, THREAD);
intx recursions = ObjectSynchronizer::complete_exit(lockObject, THREAD);
SystemDictionary_lock->wait();
@@ -1820,7 +1824,7 @@ InstanceKlass* SystemDictionary::find_or_define_instance_class(Symbol* class_nam
Handle SystemDictionary::compute_loader_lock_object(Handle class_loader, TRAPS) {
// If class_loader is NULL we synchronize on _system_loader_lock_obj
if (class_loader.is_null()) {
return Handle(THREAD, _system_loader_lock_obj);
return Handle(THREAD, _system_loader_lock_obj.resolve());
} else {
return class_loader;
}
@@ -1841,7 +1845,7 @@ void SystemDictionary::check_loader_lock_contention(Handle loader_lock, TRAPS) {
== ObjectSynchronizer::owner_other) {
// contention will likely happen, so increment the corresponding
// contention counter.
if (loader_lock() == _system_loader_lock_obj) {
if (loader_lock() == _system_loader_lock_obj.resolve()) {
ClassLoader::sync_systemLoaderLockContentionRate()->inc();
} else {
ClassLoader::sync_nonSystemLoaderLockContentionRate()->inc();
@@ -1958,20 +1962,6 @@ bool SystemDictionary::do_unloading(GCTimer* gc_timer) {
return unloading_occurred;
}

void SystemDictionary::oops_do(OopClosure* f, bool include_handles) {
f->do_oop(&_java_system_loader);
f->do_oop(&_java_platform_loader);
f->do_oop(&_system_loader_lock_obj);
CDS_ONLY(SystemDictionaryShared::oops_do(f);)

// Visit extra methods
invoke_method_table()->oops_do(f);

if (include_handles) {
OopStorageSet::vm_global()->oops_do(f);
}
}

// CDS: scan and relocate all classes referenced by _well_known_klasses[].
void SystemDictionary::well_known_klasses_do(MetaspaceClosure* it) {
for (int id = FIRST_WKID; id < WKID_LIMIT; id++) {
@@ -1999,7 +1989,9 @@ void SystemDictionary::initialize(TRAPS) {
_pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);

// Allocate private object used as system class loader lock
_system_loader_lock_obj = oopFactory::new_intArray(0, CHECK);
oop lock_obj = oopFactory::new_intArray(0, CHECK);
_system_loader_lock_obj = OopHandle::create(lock_obj);

// Initialize basic classes
resolve_well_known_classes(CHECK);
}
@@ -27,6 +27,7 @@

#include "classfile/classLoaderData.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/oopHandle.hpp"
#include "oops/symbol.hpp"
#include "runtime/java.hpp"
#include "runtime/mutexLocker.hpp"
@@ -381,13 +382,8 @@ class SystemDictionary : AllStatic {
// loaders. Returns "true" iff something was unloaded.
static bool do_unloading(GCTimer* gc_timer);

// Applies "f->do_oop" to all root oops in the system dictionary.
// If include_handles is true (the default), then the handles in the
// vm_global OopStorage object are included.
static void oops_do(OopClosure* f, bool include_handles = true);

// System loader lock
static oop system_loader_lock() { return _system_loader_lock_obj; }
static oop system_loader_lock();

// Protection Domain Table
static ProtectionDomainCacheTable* pd_cache_table() { return _pd_cache_table; }
@@ -585,7 +581,7 @@ class SystemDictionary : AllStatic {
static PlaceholderTable* _placeholders;

// Lock object for system class loader
static oop _system_loader_lock_obj;
static OopHandle _system_loader_lock_obj;

// Constraints on class loaders
static LoaderConstraintTable* _loader_constraints;
@@ -703,8 +699,8 @@ class SystemDictionary : AllStatic {
static InstanceKlass* _box_klasses[T_VOID+1];

private:
static oop _java_system_loader;
static oop _java_platform_loader;
static OopHandle _java_system_loader;
static OopHandle _java_platform_loader;

public:
static TableStatistics placeholders_statistics();
@@ -61,9 +61,9 @@
#include "utilities/stringUtils.hpp"


objArrayOop SystemDictionaryShared::_shared_protection_domains = NULL;
objArrayOop SystemDictionaryShared::_shared_jar_urls = NULL;
objArrayOop SystemDictionaryShared::_shared_jar_manifests = NULL;
OopHandle SystemDictionaryShared::_shared_protection_domains = NULL;
OopHandle SystemDictionaryShared::_shared_jar_urls = NULL;
OopHandle SystemDictionaryShared::_shared_jar_manifests = NULL;
DEBUG_ONLY(bool SystemDictionaryShared::_no_class_loading_should_happen = false;)

class DumpTimeSharedClassInfo: public CHeapObj<mtClass> {
@@ -460,15 +460,15 @@ static RunTimeSharedDictionary _dynamic_builtin_dictionary;
static RunTimeSharedDictionary _dynamic_unregistered_dictionary;

oop SystemDictionaryShared::shared_protection_domain(int index) {
return _shared_protection_domains->obj_at(index);
return ((objArrayOop)_shared_protection_domains.resolve())->obj_at(index);
}

oop SystemDictionaryShared::shared_jar_url(int index) {
return _shared_jar_urls->obj_at(index);
return ((objArrayOop)_shared_jar_urls.resolve())->obj_at(index);
}

oop SystemDictionaryShared::shared_jar_manifest(int index) {
return _shared_jar_manifests->obj_at(index);
return ((objArrayOop)_shared_jar_manifests.resolve())->obj_at(index);
}

Handle SystemDictionaryShared::get_shared_jar_manifest(int shared_path_index, TRAPS) {
@@ -926,30 +926,27 @@ InstanceKlass* SystemDictionaryShared::load_shared_class_for_builtin_loader(
return NULL;
}

void SystemDictionaryShared::oops_do(OopClosure* f) {
f->do_oop((oop*)&_shared_protection_domains);
f->do_oop((oop*)&_shared_jar_urls);
f->do_oop((oop*)&_shared_jar_manifests);
}

void SystemDictionaryShared::allocate_shared_protection_domain_array(int size, TRAPS) {
if (_shared_protection_domains == NULL) {
_shared_protection_domains = oopFactory::new_objArray(
if (_shared_protection_domains.resolve() == NULL) {
oop spd = oopFactory::new_objArray(
SystemDictionary::ProtectionDomain_klass(), size, CHECK);
_shared_protection_domains = OopHandle::create(spd);
}
}

void SystemDictionaryShared::allocate_shared_jar_url_array(int size, TRAPS) {
if (_shared_jar_urls == NULL) {
_shared_jar_urls = oopFactory::new_objArray(
if (_shared_jar_urls.resolve() == NULL) {
oop sju = oopFactory::new_objArray(
SystemDictionary::URL_klass(), size, CHECK);
_shared_jar_urls = OopHandle::create(sju);
}
}

void SystemDictionaryShared::allocate_shared_jar_manifest_array(int size, TRAPS) {
if (_shared_jar_manifests == NULL) {
_shared_jar_manifests = oopFactory::new_objArray(
if (_shared_jar_manifests.resolve() == NULL) {
oop sjm = oopFactory::new_objArray(
SystemDictionary::Jar_Manifest_klass(), size, CHECK);
_shared_jar_manifests = OopHandle::create(sjm);
}
}

0 comments on commit 498b0e6

Please sign in to comment.