< prev index next >
src/share/vm/classfile/systemDictionary.cpp
Print this page
*** 33,42 ****
--- 33,43 ----
#include "classfile/javaClasses.inline.hpp"
#include "classfile/klassFactory.hpp"
#include "classfile/loaderConstraints.hpp"
#include "classfile/packageEntry.hpp"
#include "classfile/placeholders.hpp"
+ #include "classfile/protectionDomainCache.hpp"
#include "classfile/resolutionErrors.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
*** 85,107 ****
#endif
#if INCLUDE_TRACE
#include "trace/tracing.hpp"
#endif
- Dictionary* SystemDictionary::_dictionary = NULL;
PlaceholderTable* SystemDictionary::_placeholders = NULL;
Dictionary* SystemDictionary::_shared_dictionary = NULL;
LoaderConstraintTable* SystemDictionary::_loader_constraints = NULL;
ResolutionErrorTable* SystemDictionary::_resolution_errors = NULL;
SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL;
!
int SystemDictionary::_number_of_modifications = 0;
- int SystemDictionary::_sdgeneration = 0;
- const int SystemDictionary::_primelist[_prime_array_size] = {1009,2017,4049,5051,10103,
- 20201,40423,99991};
-
oop SystemDictionary::_system_loader_lock_obj = NULL;
InstanceKlass* SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT]
= { NULL /*, NULL...*/ };
--- 86,103 ----
#endif
#if INCLUDE_TRACE
#include "trace/tracing.hpp"
#endif
PlaceholderTable* SystemDictionary::_placeholders = NULL;
Dictionary* SystemDictionary::_shared_dictionary = NULL;
LoaderConstraintTable* SystemDictionary::_loader_constraints = NULL;
ResolutionErrorTable* SystemDictionary::_resolution_errors = NULL;
SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL;
! ProtectionDomainCacheTable* SystemDictionary::_pd_cache_table = NULL;
int SystemDictionary::_number_of_modifications = 0;
oop SystemDictionary::_system_loader_lock_obj = NULL;
InstanceKlass* SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT]
= { NULL /*, NULL...*/ };
*** 113,122 ****
--- 109,122 ----
bool SystemDictionary::_has_checkPackageAccess = false;
// lazily initialized klass variables
InstanceKlass* volatile SystemDictionary::_abstract_ownable_synchronizer_klass = NULL;
+ // Default ProtectionDomainCacheSize value
+
+ const int defaultProtectionDomainCacheSize = 1009;
+
// ----------------------------------------------------------------------------
// Java-level SystemLoader
oop SystemDictionary::java_system_loader() {
*** 353,375 ****
// We might not already have a placeholder if this child_name was
// first seen via resolve_from_stream (jni_DefineClass or JVM_DefineClass);
// the name of the class might not be known until the stream is actually
// parsed.
// Bugs 4643874, 4715493
- // compute_hash can have a safepoint
ClassLoaderData* loader_data = class_loader_data(class_loader);
! unsigned int d_hash = dictionary()->compute_hash(child_name, loader_data);
! int d_index = dictionary()->hash_to_index(d_hash);
! unsigned int p_hash = placeholders()->compute_hash(child_name, loader_data);
int p_index = placeholders()->hash_to_index(p_hash);
// can't throw error holding a lock
bool child_already_loaded = false;
bool throw_circularity_error = false;
{
MutexLocker mu(SystemDictionary_lock, THREAD);
! Klass* childk = find_class(d_index, d_hash, child_name, loader_data);
Klass* quicksuperk;
// to support // loading: if child done loading, just return superclass
// if class_name, & class_loader don't match:
// if initial define, SD update will give LinkageError
// if redefine: compare_class_versions will give HIERARCHY_CHANGED
--- 353,375 ----
// We might not already have a placeholder if this child_name was
// first seen via resolve_from_stream (jni_DefineClass or JVM_DefineClass);
// the name of the class might not be known until the stream is actually
// parsed.
// Bugs 4643874, 4715493
ClassLoaderData* loader_data = class_loader_data(class_loader);
! Dictionary* dictionary = loader_data->dictionary();
! unsigned int d_hash = dictionary->compute_hash(child_name);
! int d_index = dictionary->hash_to_index(d_hash);
! unsigned int p_hash = placeholders()->compute_hash(child_name);
int p_index = placeholders()->hash_to_index(p_hash);
// can't throw error holding a lock
bool child_already_loaded = false;
bool throw_circularity_error = false;
{
MutexLocker mu(SystemDictionary_lock, THREAD);
! Klass* childk = find_class(d_index, d_hash, child_name, dictionary);
Klass* quicksuperk;
// to support // loading: if child done loading, just return superclass
// if class_name, & class_loader don't match:
// if initial define, SD update will give LinkageError
// if redefine: compare_class_versions will give HIERARCHY_CHANGED
*** 441,457 ****
log->print(" protection domain: "); protection_domain()->print_value_on(log);
log->print(" loading: "); klass->print_value_on(log);
log->cr();
}
InstanceKlass* system_loader = SystemDictionary::ClassLoader_klass();
JavaCalls::call_special(&result,
class_loader,
system_loader,
vmSymbols::checkPackageAccess_name(),
vmSymbols::class_protectiondomain_signature(),
! Handle(THREAD, klass->java_mirror()),
protection_domain,
THREAD);
if (HAS_PENDING_EXCEPTION) {
log_debug(protectiondomain)("DENIED !!!!!!!!!!!!!!!!!!!!!");
--- 441,461 ----
log->print(" protection domain: "); protection_domain()->print_value_on(log);
log->print(" loading: "); klass->print_value_on(log);
log->cr();
}
+ // This handle and the class_loader handle passed in keeps this class from
+ // being unloaded through several GC points.
+ Handle mirror(THREAD, klass->java_mirror());
+
InstanceKlass* system_loader = SystemDictionary::ClassLoader_klass();
JavaCalls::call_special(&result,
class_loader,
system_loader,
vmSymbols::checkPackageAccess_name(),
vmSymbols::class_protectiondomain_signature(),
! mirror,
protection_domain,
THREAD);
if (HAS_PENDING_EXCEPTION) {
log_debug(protectiondomain)("DENIED !!!!!!!!!!!!!!!!!!!!!");
*** 462,493 ****
if (HAS_PENDING_EXCEPTION) return;
// If no exception has been thrown, we have validated the protection domain
// Insert the protection domain of the initiating class into the set.
{
- // We recalculate the entry here -- we've called out to java since
- // the last time it was calculated.
ClassLoaderData* loader_data = class_loader_data(class_loader);
Symbol* kn = klass->name();
! unsigned int d_hash = dictionary()->compute_hash(kn, loader_data);
! int d_index = dictionary()->hash_to_index(d_hash);
MutexLocker mu(SystemDictionary_lock, THREAD);
! {
! // Note that we have an entry, and entries can be deleted only during GC,
! // so we cannot allow GC to occur while we're holding this entry.
!
! // We're using a NoSafepointVerifier to catch any place where we
! // might potentially do a GC at all.
! // Dictionary::do_unloading() asserts that classes in SD are only
! // unloaded at a safepoint. Anonymous classes are not in SD.
! NoSafepointVerifier nosafepoint;
! dictionary()->add_protection_domain(d_index, d_hash, klass, loader_data,
protection_domain, THREAD);
}
- }
}
// We only get here if this thread finds that another thread
// has already claimed the placeholder token for the current operation,
// but that other thread either never owned or gave up the
--- 466,486 ----
if (HAS_PENDING_EXCEPTION) return;
// If no exception has been thrown, we have validated the protection domain
// Insert the protection domain of the initiating class into the set.
{
ClassLoaderData* loader_data = class_loader_data(class_loader);
+ Dictionary* dictionary = loader_data->dictionary();
Symbol* kn = klass->name();
! unsigned int d_hash = dictionary->compute_hash(kn);
! int d_index = dictionary->hash_to_index(d_hash);
MutexLocker mu(SystemDictionary_lock, THREAD);
! dictionary->add_protection_domain(d_index, d_hash, klass,
protection_domain, THREAD);
}
}
// We only get here if this thread finds that another thread
// has already claimed the placeholder token for the current operation,
// but that other thread either never owned or gave up the
*** 544,556 ****
InstanceKlass* SystemDictionary::handle_parallel_super_load(
Symbol* name, Symbol* superclassname, Handle class_loader,
Handle protection_domain, Handle lockObject, TRAPS) {
ClassLoaderData* loader_data = class_loader_data(class_loader);
! unsigned int d_hash = dictionary()->compute_hash(name, loader_data);
! int d_index = dictionary()->hash_to_index(d_hash);
! unsigned int p_hash = placeholders()->compute_hash(name, loader_data);
int p_index = placeholders()->hash_to_index(p_hash);
// superk is not used, resolve_super called for circularity check only
// This code is reached in two situations. One if this thread
// is loading the same class twice (e.g. ClassCircularity, or
--- 537,550 ----
InstanceKlass* SystemDictionary::handle_parallel_super_load(
Symbol* name, Symbol* superclassname, Handle class_loader,
Handle protection_domain, Handle lockObject, TRAPS) {
ClassLoaderData* loader_data = class_loader_data(class_loader);
! Dictionary* dictionary = loader_data->dictionary();
! unsigned int d_hash = dictionary->compute_hash(name);
! int d_index = dictionary->hash_to_index(d_hash);
! unsigned int p_hash = placeholders()->compute_hash(name);
int p_index = placeholders()->hash_to_index(p_hash);
// superk is not used, resolve_super called for circularity check only
// This code is reached in two situations. One if this thread
// is loading the same class twice (e.g. ClassCircularity, or
*** 569,589 ****
// parallelCapable class loaders do NOT wait for parallel superclass loads to complete
// Serial class loaders and bootstrap classloader do wait for superclass loads
if (!class_loader.is_null() && is_parallelCapable(class_loader)) {
MutexLocker mu(SystemDictionary_lock, THREAD);
// Check if classloading completed while we were loading superclass or waiting
! return find_class(d_index, d_hash, name, loader_data);
}
// must loop to both handle other placeholder updates
// and spurious notifications
bool super_load_in_progress = true;
PlaceholderEntry* placeholder;
while (super_load_in_progress) {
MutexLocker mu(SystemDictionary_lock, THREAD);
// Check if classloading completed while we were loading superclass or waiting
! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data);
if (check != NULL) {
// Klass is already loaded, so just return it
return check;
} else {
placeholder = placeholders()->get_entry(p_index, p_hash, name, loader_data);
--- 563,583 ----
// parallelCapable class loaders do NOT wait for parallel superclass loads to complete
// Serial class loaders and bootstrap classloader do wait for superclass loads
if (!class_loader.is_null() && is_parallelCapable(class_loader)) {
MutexLocker mu(SystemDictionary_lock, THREAD);
// Check if classloading completed while we were loading superclass or waiting
! return find_class(d_index, d_hash, name, dictionary);
}
// must loop to both handle other placeholder updates
// and spurious notifications
bool super_load_in_progress = true;
PlaceholderEntry* placeholder;
while (super_load_in_progress) {
MutexLocker mu(SystemDictionary_lock, THREAD);
// Check if classloading completed while we were loading superclass or waiting
! InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
if (check != NULL) {
// Klass is already loaded, so just return it
return check;
} else {
placeholder = placeholders()->get_entry(p_index, p_hash, name, loader_data);
*** 659,679 ****
HandleMark hm(THREAD);
// Fix for 4474172; see evaluation for more details
class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL);
// Do lookup to see if class already exist and the protection domain
// has the right access
// This call uses find which checks protection domain already matches
// All subsequent calls use find_class, and set has_loaded_class so that
// before we return a result we call out to java to check for valid protection domain
// to allow returning the Klass* and add it to the pd_set if it is valid
! unsigned int d_hash = dictionary()->compute_hash(name, loader_data);
! int d_index = dictionary()->hash_to_index(d_hash);
! Klass* probe = dictionary()->find(d_index, d_hash, name, loader_data,
! protection_domain, THREAD);
if (probe != NULL) return probe;
// Non-bootstrap class loaders will call out to class loader and
// define via jvm/jni_DefineClass which will acquire the
--- 653,673 ----
HandleMark hm(THREAD);
// Fix for 4474172; see evaluation for more details
class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL);
+ Dictionary* dictionary = loader_data->dictionary();
// Do lookup to see if class already exist and the protection domain
// has the right access
// This call uses find which checks protection domain already matches
// All subsequent calls use find_class, and set has_loaded_class so that
// before we return a result we call out to java to check for valid protection domain
// to allow returning the Klass* and add it to the pd_set if it is valid
! unsigned int d_hash = dictionary->compute_hash(name);
! int d_index = dictionary->hash_to_index(d_hash);
! Klass* probe = dictionary->find(d_index, d_hash, name, protection_domain);
if (probe != NULL) return probe;
// Non-bootstrap class loaders will call out to class loader and
// define via jvm/jni_DefineClass which will acquire the
*** 687,697 ****
bool DoObjectLock = true;
if (is_parallelCapable(class_loader)) {
DoObjectLock = false;
}
! unsigned int p_hash = placeholders()->compute_hash(name, loader_data);
int p_index = placeholders()->hash_to_index(p_hash);
// Class is not in SystemDictionary so we have to do loading.
// Make sure we are synchronized on the class loader before we proceed
Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
--- 681,691 ----
bool DoObjectLock = true;
if (is_parallelCapable(class_loader)) {
DoObjectLock = false;
}
! unsigned int p_hash = placeholders()->compute_hash(name);
int p_index = placeholders()->hash_to_index(p_hash);
// Class is not in SystemDictionary so we have to do loading.
// Make sure we are synchronized on the class loader before we proceed
Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
*** 706,716 ****
PlaceholderEntry* placeholder;
Symbol* superclassname = NULL;
{
MutexLocker mu(SystemDictionary_lock, THREAD);
! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data);
if (check != NULL) {
// Klass is already loaded, so just return it
class_has_been_loaded = true;
k = check;
} else {
--- 700,710 ----
PlaceholderEntry* placeholder;
Symbol* superclassname = NULL;
{
MutexLocker mu(SystemDictionary_lock, THREAD);
! InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
if (check != NULL) {
// Klass is already loaded, so just return it
class_has_been_loaded = true;
k = check;
} else {
*** 790,800 ****
// case 2: traditional with broken classloader lock. wait on first
// requestor.
double_lock_wait(lockObject, THREAD);
}
// Check if classloading completed while we were waiting
! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data);
if (check != NULL) {
// Klass is already loaded, so just return it
k = check;
class_has_been_loaded = true;
}
--- 784,794 ----
// case 2: traditional with broken classloader lock. wait on first
// requestor.
double_lock_wait(lockObject, THREAD);
}
// Check if classloading completed while we were waiting
! InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
if (check != NULL) {
// Klass is already loaded, so just return it
k = check;
class_has_been_loaded = true;
}
*** 815,825 ****
// if they did not catch another thread holding LOAD_INSTANCE,
// need a check analogous to the acquire ObjectLocker/find_class
// i.e. now that we hold the LOAD_INSTANCE token on loading this class/CL
// one final check if the load has already completed
// class loaders holding the ObjectLock shouldn't find the class here
! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data);
if (check != NULL) {
// Klass is already loaded, so return it after checking/adding protection domain
k = check;
class_has_been_loaded = true;
}
--- 809,819 ----
// if they did not catch another thread holding LOAD_INSTANCE,
// need a check analogous to the acquire ObjectLocker/find_class
// i.e. now that we hold the LOAD_INSTANCE token on loading this class/CL
// one final check if the load has already completed
// class loaders holding the ObjectLock shouldn't find the class here
! InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
if (check != NULL) {
// Klass is already loaded, so return it after checking/adding protection domain
k = check;
class_has_been_loaded = true;
}
*** 848,858 ****
// Bootstrap goes through here to allow for an extra guarantee check
if (UnsyncloadClass || (class_loader.is_null())) {
if (k == NULL && HAS_PENDING_EXCEPTION
&& PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
MutexLocker mu(SystemDictionary_lock, THREAD);
! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data);
if (check != NULL) {
// Klass is already loaded, so just use it
k = check;
CLEAR_PENDING_EXCEPTION;
guarantee((!class_loader.is_null()), "dup definition for bootstrap loader?");
--- 842,852 ----
// Bootstrap goes through here to allow for an extra guarantee check
if (UnsyncloadClass || (class_loader.is_null())) {
if (k == NULL && HAS_PENDING_EXCEPTION
&& PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
MutexLocker mu(SystemDictionary_lock, THREAD);
! InstanceKlass* check = find_class(d_index, d_hash, name, dictionary);
if (check != NULL) {
// Klass is already loaded, so just use it
k = check;
CLEAR_PENDING_EXCEPTION;
guarantee((!class_loader.is_null()), "dup definition for bootstrap loader?");
*** 882,892 ****
assert(thread->is_Java_thread(), "thread->is_Java_thread()");
JvmtiExport::post_class_load((JavaThread *) thread, k);
}
}
}
! } // load_instance_class loop
if (load_instance_added == true) {
// clean up placeholder entries for LOAD_INSTANCE success or error
// This brackets the SystemDictionary updates for both defining
// and initiating loaders
--- 876,886 ----
assert(thread->is_Java_thread(), "thread->is_Java_thread()");
JvmtiExport::post_class_load((JavaThread *) thread, k);
}
}
}
! } // load_instance_class
if (load_instance_added == true) {
// clean up placeholder entries for LOAD_INSTANCE success or error
// This brackets the SystemDictionary updates for both defining
// and initiating loaders
*** 915,933 ****
if (protection_domain() == NULL) return k;
// Check the protection domain has the right access
{
MutexLocker mu(SystemDictionary_lock, THREAD);
! // Note that we have an entry, and entries can be deleted only during GC,
! // so we cannot allow GC to occur while we're holding this entry.
! // We're using a NoSafepointVerifier to catch any place where we
! // might potentially do a GC at all.
! // Dictionary::do_unloading() asserts that classes in SD are only
! // unloaded at a safepoint. Anonymous classes are not in SD.
! NoSafepointVerifier nosafepoint;
! if (dictionary()->is_valid_protection_domain(d_index, d_hash, name,
! loader_data,
protection_domain)) {
return k;
}
}
--- 909,919 ----
if (protection_domain() == NULL) return k;
// Check the protection domain has the right access
{
MutexLocker mu(SystemDictionary_lock, THREAD);
! if (dictionary->is_valid_protection_domain(d_index, d_hash, name,
protection_domain)) {
return k;
}
}
*** 964,987 ****
// If the ClassLoaderData has not been setup,
// then the class loader has no entries in the dictionary.
return NULL;
}
! unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data);
! int d_index = dictionary()->hash_to_index(d_hash);
!
! {
! // Note that we have an entry, and entries can be deleted only during GC,
! // so we cannot allow GC to occur while we're holding this entry.
! // We're using a NoSafepointVerifier to catch any place where we
! // might potentially do a GC at all.
! // Dictionary::do_unloading() asserts that classes in SD are only
! // unloaded at a safepoint. Anonymous classes are not in SD.
! NoSafepointVerifier nosafepoint;
! return dictionary()->find(d_index, d_hash, class_name, loader_data,
! protection_domain, THREAD);
}
}
// Look for a loaded instance or array klass by name. Do not do any loading.
// return NULL in case of error.
--- 950,969 ----
// If the ClassLoaderData has not been setup,
// then the class loader has no entries in the dictionary.
return NULL;
}
! Dictionary* dictionary = loader_data->dictionary_or_null();
! // If ClassLoaderData has no dictionary, the class won't be found in it
! if (dictionary == NULL) {
! return NULL;
}
+
+ unsigned int d_hash = dictionary->compute_hash(class_name);
+ int d_index = dictionary->hash_to_index(d_hash);
+ return dictionary->find(d_index, d_hash, class_name,
+ protection_domain);
}
// Look for a loaded instance or array klass by name. Do not do any loading.
// return NULL in case of error.
*** 1031,1041 ****
// Create a new CLD for anonymous class, that uses the same class loader
// as the host_klass
guarantee(host_klass->class_loader() == class_loader(), "should be the same");
guarantee(!DumpSharedSpaces, "must not create anonymous classes when dumping");
loader_data = ClassLoaderData::anonymous_class_loader_data(class_loader(), CHECK_NULL);
- loader_data->record_dependency(host_klass, CHECK_NULL);
} else {
loader_data = ClassLoaderData::class_loader_data(class_loader());
}
assert(st != NULL, "invariant");
--- 1013,1022 ----
*** 1185,1206 ****
}
#if INCLUDE_CDS
void SystemDictionary::set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
int number_of_entries) {
! assert(length == _nof_buckets * sizeof(HashtableBucket<mtClass>),
"bad shared dictionary size.");
! _shared_dictionary = new Dictionary(_nof_buckets, t, number_of_entries);
}
// If there is a shared dictionary, then find the entry for the
// given shared system class, if any.
InstanceKlass* SystemDictionary::find_shared_class(Symbol* class_name) {
if (shared_dictionary() != NULL) {
! unsigned int d_hash = shared_dictionary()->compute_hash(class_name, NULL);
int d_index = shared_dictionary()->hash_to_index(d_hash);
return shared_dictionary()->find_shared_class(d_index, d_hash, class_name);
} else {
return NULL;
--- 1166,1188 ----
}
#if INCLUDE_CDS
void SystemDictionary::set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
int number_of_entries) {
! assert(length == _shared_dictionary_size * sizeof(HashtableBucket<mtClass>),
"bad shared dictionary size.");
! _shared_dictionary = new Dictionary(ClassLoaderData::the_null_class_loader_data(),
! _shared_dictionary_size, t, number_of_entries);
}
// If there is a shared dictionary, then find the entry for the
// given shared system class, if any.
InstanceKlass* SystemDictionary::find_shared_class(Symbol* class_name) {
if (shared_dictionary() != NULL) {
! unsigned int d_hash = shared_dictionary()->compute_hash(class_name);
int d_index = shared_dictionary()->hash_to_index(d_hash);
return shared_dictionary()->find_shared_class(d_index, d_hash, class_name);
} else {
return NULL;
*** 1622,1633 ****
// Existing classloaders will call define_instance_class with the
// classloader lock held
// Parallel classloaders will call find_or_define_instance_class
// which will require a token to perform the define class
Symbol* name_h = k->name();
! unsigned int d_hash = dictionary()->compute_hash(name_h, loader_data);
! int d_index = dictionary()->hash_to_index(d_hash);
check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK);
// Register class just loaded with class loader (placed in Vector)
// Note we do this before updating the dictionary, as this can
// fail with an OutOfMemoryError (if it does, we will *not* put this
--- 1604,1616 ----
// Existing classloaders will call define_instance_class with the
// classloader lock held
// Parallel classloaders will call find_or_define_instance_class
// which will require a token to perform the define class
Symbol* name_h = k->name();
! Dictionary* dictionary = loader_data->dictionary();
! unsigned int d_hash = dictionary->compute_hash(name_h);
! int d_index = dictionary->hash_to_index(d_hash);
check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK);
// Register class just loaded with class loader (placed in Vector)
// Note we do this before updating the dictionary, as this can
// fail with an OutOfMemoryError (if it does, we will *not* put this
*** 1641,1651 ****
JavaCalls::call(&result, m, &args, CHECK);
}
// Add the new class. We need recompile lock during update of CHA.
{
! unsigned int p_hash = placeholders()->compute_hash(name_h, loader_data);
int p_index = placeholders()->hash_to_index(p_hash);
MutexLocker mu_r(Compile_lock, THREAD);
// Add to class hierarchy, initialize vtables, and do possible
--- 1624,1634 ----
JavaCalls::call(&result, m, &args, CHECK);
}
// Add the new class. We need recompile lock during update of CHA.
{
! unsigned int p_hash = placeholders()->compute_hash(name_h);
int p_index = placeholders()->hash_to_index(p_hash);
MutexLocker mu_r(Compile_lock, THREAD);
// Add to class hierarchy, initialize vtables, and do possible
*** 1691,1714 ****
InstanceKlass* SystemDictionary::find_or_define_instance_class(Symbol* class_name, Handle class_loader,
InstanceKlass* k, TRAPS) {
Symbol* name_h = k->name(); // passed in class_name may be null
ClassLoaderData* loader_data = class_loader_data(class_loader);
! unsigned int d_hash = dictionary()->compute_hash(name_h, loader_data);
! int d_index = dictionary()->hash_to_index(d_hash);
// Hold SD lock around find_class and placeholder creation for DEFINE_CLASS
! unsigned int p_hash = placeholders()->compute_hash(name_h, loader_data);
int p_index = placeholders()->hash_to_index(p_hash);
PlaceholderEntry* probe;
{
MutexLocker mu(SystemDictionary_lock, THREAD);
// First check if class already defined
if (UnsyncloadClass || (is_parallelDefine(class_loader))) {
! InstanceKlass* check = find_class(d_index, d_hash, name_h, loader_data);
if (check != NULL) {
return check;
}
}
--- 1674,1698 ----
InstanceKlass* SystemDictionary::find_or_define_instance_class(Symbol* class_name, Handle class_loader,
InstanceKlass* k, TRAPS) {
Symbol* name_h = k->name(); // passed in class_name may be null
ClassLoaderData* loader_data = class_loader_data(class_loader);
+ Dictionary* dictionary = loader_data->dictionary();
! unsigned int d_hash = dictionary->compute_hash(name_h);
! int d_index = dictionary->hash_to_index(d_hash);
// Hold SD lock around find_class and placeholder creation for DEFINE_CLASS
! unsigned int p_hash = placeholders()->compute_hash(name_h);
int p_index = placeholders()->hash_to_index(p_hash);
PlaceholderEntry* probe;
{
MutexLocker mu(SystemDictionary_lock, THREAD);
// First check if class already defined
if (UnsyncloadClass || (is_parallelDefine(class_loader))) {
! InstanceKlass* check = find_class(d_index, d_hash, name_h, dictionary);
if (check != NULL) {
return check;
}
}
*** 1726,1736 ****
// caught by finding an entry in the SystemDictionary
if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) {
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
SystemDictionary_lock->notify_all();
#ifdef ASSERT
! InstanceKlass* check = find_class(d_index, d_hash, name_h, loader_data);
assert(check != NULL, "definer missed recording success");
#endif
return probe->instance_klass();
} else {
// This thread will define the class (even if earlier thread tried and had an error)
--- 1710,1720 ----
// caught by finding an entry in the SystemDictionary
if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) {
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
SystemDictionary_lock->notify_all();
#ifdef ASSERT
! InstanceKlass* check = find_class(d_index, d_hash, name_h, dictionary);
assert(check != NULL, "definer missed recording success");
#endif
return probe->instance_klass();
} else {
// This thread will define the class (even if earlier thread tried and had an error)
*** 1765,1774 ****
--- 1749,1759 ----
THROW_OOP_(linkage_exception(), NULL); // throws exception and returns
}
return k;
}
+
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);
} else {
*** 1802,1851 ****
// ----------------------------------------------------------------------------
// Lookup
InstanceKlass* SystemDictionary::find_class(int index, unsigned int hash,
Symbol* class_name,
! ClassLoaderData* loader_data) {
assert_locked_or_safepoint(SystemDictionary_lock);
! assert (index == dictionary()->index_for(class_name, loader_data),
! "incorrect index?");
!
! return dictionary()->find_class(index, hash, class_name, loader_data);
}
// Basic find on classes in the midst of being loaded
Symbol* SystemDictionary::find_placeholder(Symbol* class_name,
ClassLoaderData* loader_data) {
assert_locked_or_safepoint(SystemDictionary_lock);
! unsigned int p_hash = placeholders()->compute_hash(class_name, loader_data);
int p_index = placeholders()->hash_to_index(p_hash);
return placeholders()->find_entry(p_index, p_hash, class_name, loader_data);
}
// Used for assertions and verification only
InstanceKlass* SystemDictionary::find_class(Symbol* class_name, ClassLoaderData* loader_data) {
#ifndef ASSERT
guarantee(VerifyBeforeGC ||
VerifyDuringGC ||
VerifyBeforeExit ||
VerifyDuringStartup ||
VerifyAfterGC, "too expensive");
#endif
- assert_locked_or_safepoint(SystemDictionary_lock);
! // First look in the loaded class array
! unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data);
! int d_index = dictionary()->hash_to_index(d_hash);
! return find_class(d_index, d_hash, class_name, loader_data);
! }
!
!
! // Get the next class in the dictionary.
! Klass* SystemDictionary::try_get_next_class() {
! return dictionary()->try_get_next_class();
}
// ----------------------------------------------------------------------------
// Update hierachy. This is done before the new klass has been added to the SystemDictionary. The Recompile_lock
--- 1787,1832 ----
// ----------------------------------------------------------------------------
// Lookup
InstanceKlass* SystemDictionary::find_class(int index, unsigned int hash,
Symbol* class_name,
! Dictionary* dictionary) {
assert_locked_or_safepoint(SystemDictionary_lock);
! return dictionary->find_class(index, hash, class_name);
}
// Basic find on classes in the midst of being loaded
Symbol* SystemDictionary::find_placeholder(Symbol* class_name,
ClassLoaderData* loader_data) {
assert_locked_or_safepoint(SystemDictionary_lock);
! unsigned int p_hash = placeholders()->compute_hash(class_name);
int p_index = placeholders()->hash_to_index(p_hash);
return placeholders()->find_entry(p_index, p_hash, class_name, loader_data);
}
// Used for assertions and verification only
+ // Precalculating the hash and index is an optimization because there are many lookups
+ // before adding the class.
InstanceKlass* SystemDictionary::find_class(Symbol* class_name, ClassLoaderData* loader_data) {
+ assert_locked_or_safepoint(SystemDictionary_lock);
#ifndef ASSERT
guarantee(VerifyBeforeGC ||
VerifyDuringGC ||
VerifyBeforeExit ||
VerifyDuringStartup ||
VerifyAfterGC, "too expensive");
#endif
! Dictionary* dictionary = loader_data->dictionary_or_null();
! if (dictionary == NULL) {
! return NULL;
! }
! unsigned int d_hash = dictionary->compute_hash(class_name);
! int d_index = dictionary->hash_to_index(d_hash);
! return find_class(d_index, d_hash, class_name, dictionary);
}
// ----------------------------------------------------------------------------
// Update hierachy. This is done before the new klass has been added to the SystemDictionary. The Recompile_lock
*** 1880,1904 ****
void SystemDictionary::always_strong_oops_do(OopClosure* blk) {
roots_oops_do(blk, NULL);
}
- // Calculate a "good" systemdictionary size based
- // on predicted or current loaded classes count
- int SystemDictionary::calculate_systemdictionary_size(int classcount) {
- int newsize = _old_default_sdsize;
- if ((classcount > 0) && !DumpSharedSpaces) {
- int desiredsize = classcount/_average_depth_goal;
- for (newsize = _primelist[_sdgeneration]; _sdgeneration < _prime_array_size -1;
- newsize = _primelist[++_sdgeneration]) {
- if (desiredsize <= newsize) {
- break;
- }
- }
- }
- return newsize;
- }
#ifdef ASSERT
class VerifySDReachableAndLiveClosure : public OopClosure {
private:
BoolObjectClosure* _is_alive;
--- 1861,1870 ----
*** 1932,1955 ****
do_cleaning);
}
if (unloading_occurred) {
GCTraceTime(Debug, gc, phases) t("Dictionary", gc_timer);
- dictionary()->do_unloading();
constraints()->purge_loader_constraints();
resolution_errors()->purge_resolution_errors();
}
{
GCTraceTime(Debug, gc, phases) t("ProtectionDomainCacheTable", gc_timer);
// Oops referenced by the system dictionary may get unreachable independently
// of the class loader (eg. cached protection domain oops). So we need to
! // explicitly unlink them here instead of in Dictionary::do_unloading.
! dictionary()->unlink(is_alive);
#ifdef ASSERT
VerifySDReachableAndLiveClosure cl(is_alive);
! dictionary()->oops_do(&cl);
#endif
}
if (do_cleaning) {
GCTraceTime(Debug, gc, phases) t("ResolvedMethodTable", gc_timer);
--- 1898,1921 ----
do_cleaning);
}
if (unloading_occurred) {
GCTraceTime(Debug, gc, phases) t("Dictionary", gc_timer);
constraints()->purge_loader_constraints();
resolution_errors()->purge_resolution_errors();
}
{
GCTraceTime(Debug, gc, phases) t("ProtectionDomainCacheTable", gc_timer);
// Oops referenced by the system dictionary may get unreachable independently
// of the class loader (eg. cached protection domain oops). So we need to
! // explicitly unlink them here.
! _pd_cache_table->unlink(is_alive);
!
#ifdef ASSERT
VerifySDReachableAndLiveClosure cl(is_alive);
! _pd_cache_table->oops_do(&cl);
#endif
}
if (do_cleaning) {
GCTraceTime(Debug, gc, phases) t("ResolvedMethodTable", gc_timer);
*** 1963,1973 ****
strong->do_oop(&_java_system_loader);
strong->do_oop(&_system_loader_lock_obj);
CDS_ONLY(SystemDictionaryShared::roots_oops_do(strong);)
// Adjust dictionary
! dictionary()->roots_oops_do(strong, weak);
// Visit extra methods
invoke_method_table()->oops_do(strong);
if (weak != NULL) {
--- 1929,1948 ----
strong->do_oop(&_java_system_loader);
strong->do_oop(&_system_loader_lock_obj);
CDS_ONLY(SystemDictionaryShared::roots_oops_do(strong);)
// Adjust dictionary
! // Do strong roots marking if the closures are the same.
! if (strong == weak || !ClassUnloading) {
! // Only the protection domain oops contain references into the heap. Iterate
! // over all of them.
! _pd_cache_table->oops_do(strong);
! } else {
! if (weak != NULL) {
! _pd_cache_table->oops_do(weak);
! }
! }
// Visit extra methods
invoke_method_table()->oops_do(strong);
if (weak != NULL) {
*** 1978,2024 ****
void SystemDictionary::oops_do(OopClosure* f) {
f->do_oop(&_java_system_loader);
f->do_oop(&_system_loader_lock_obj);
CDS_ONLY(SystemDictionaryShared::oops_do(f);)
! // Adjust dictionary
! dictionary()->oops_do(f);
// Visit extra methods
invoke_method_table()->oops_do(f);
ResolvedMethodTable::oops_do(f);
}
- // Just the classes from defining class loaders
- // Don't iterate over placeholders
- void SystemDictionary::classes_do(void f(Klass*)) {
- dictionary()->classes_do(f);
- }
-
- // Added for initialize_itable_for_klass
- // Just the classes from defining class loaders
- // Don't iterate over placeholders
- void SystemDictionary::classes_do(void f(Klass*, TRAPS), TRAPS) {
- dictionary()->classes_do(f, CHECK);
- }
-
- // All classes, and their class loaders
- // Don't iterate over placeholders
- void SystemDictionary::classes_do(void f(Klass*, ClassLoaderData*)) {
- dictionary()->classes_do(f);
- }
-
void SystemDictionary::methods_do(void f(Method*)) {
// Walk methods in loaded classes
ClassLoaderDataGraph::methods_do(f);
// Walk method handle intrinsics
invoke_method_table()->methods_do(f);
}
void SystemDictionary::remove_classes_in_error_state() {
! dictionary()->remove_classes_in_error_state();
}
// ----------------------------------------------------------------------------
// Lazily load klasses
--- 1953,1981 ----
void SystemDictionary::oops_do(OopClosure* f) {
f->do_oop(&_java_system_loader);
f->do_oop(&_system_loader_lock_obj);
CDS_ONLY(SystemDictionaryShared::oops_do(f);)
! // Only the protection domain oops contain references into the heap. Iterate
! // over all of them.
! _pd_cache_table->oops_do(f);
// Visit extra methods
invoke_method_table()->oops_do(f);
ResolvedMethodTable::oops_do(f);
}
void SystemDictionary::methods_do(void f(Method*)) {
// Walk methods in loaded classes
ClassLoaderDataGraph::methods_do(f);
// Walk method handle intrinsics
invoke_method_table()->methods_do(f);
}
void SystemDictionary::remove_classes_in_error_state() {
! ClassLoaderData::the_null_class_loader_data()->dictionary()->remove_classes_in_error_state();
}
// ----------------------------------------------------------------------------
// Lazily load klasses
*** 2038,2056 ****
// ----------------------------------------------------------------------------
// Initialization
void SystemDictionary::initialize(TRAPS) {
// Allocate arrays
! assert(dictionary() == NULL,
! "SystemDictionary should only be initialized once");
! _sdgeneration = 0;
! _dictionary = new Dictionary(calculate_systemdictionary_size(PredictedLoadedClassCount));
! _placeholders = new PlaceholderTable(_nof_buckets);
_number_of_modifications = 0;
_loader_constraints = new LoaderConstraintTable(_loader_constraint_size);
_resolution_errors = new ResolutionErrorTable(_resolution_error_size);
_invoke_method_table = new SymbolPropertyTable(_invoke_method_size);
// Allocate private object used as system class loader lock
_system_loader_lock_obj = oopFactory::new_intArray(0, CHECK);
// Initialize basic classes
initialize_preloaded_classes(CHECK);
--- 1995,2010 ----
// ----------------------------------------------------------------------------
// Initialization
void SystemDictionary::initialize(TRAPS) {
// Allocate arrays
! _placeholders = new PlaceholderTable(_placeholder_table_size);
_number_of_modifications = 0;
_loader_constraints = new LoaderConstraintTable(_loader_constraint_size);
_resolution_errors = new ResolutionErrorTable(_resolution_error_size);
_invoke_method_table = new SymbolPropertyTable(_invoke_method_size);
+ _pd_cache_table = new ProtectionDomainCacheTable(defaultProtectionDomainCacheSize);
// Allocate private object used as system class loader lock
_system_loader_lock_obj = oopFactory::new_intArray(0, CHECK);
// Initialize basic classes
initialize_preloaded_classes(CHECK);
*** 2214,2224 ****
Symbol* name = k->name();
ClassLoaderData *loader_data = class_loader_data(class_loader);
MutexLocker mu(SystemDictionary_lock, THREAD);
! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data);
if (check != NULL) {
// if different InstanceKlass - duplicate class definition,
// else - ok, class loaded by a different thread in parallel,
// we should only have found it if it was done loading and ok to use
// system dictionary only holds instance classes, placeholders
--- 2168,2178 ----
Symbol* name = k->name();
ClassLoaderData *loader_data = class_loader_data(class_loader);
MutexLocker mu(SystemDictionary_lock, THREAD);
! InstanceKlass* check = find_class(d_index, d_hash, name, loader_data->dictionary());
if (check != NULL) {
// if different InstanceKlass - duplicate class definition,
// else - ok, class loaded by a different thread in parallel,
// we should only have found it if it was done loading and ok to use
// system dictionary only holds instance classes, placeholders
*** 2296,2316 ****
k->set_prototype_header(markOopDesc::biased_locking_prototype());
}
}
// Make a new system dictionary entry.
! InstanceKlass* sd_check = find_class(d_index, d_hash, name, loader_data);
if (sd_check == NULL) {
! dictionary()->add_klass(name, loader_data, k);
notice_modification();
}
! #ifdef ASSERT
! sd_check = find_class(d_index, d_hash, name, loader_data);
assert (sd_check != NULL, "should have entry in system dictionary");
// Note: there may be a placeholder entry: for circularity testing
// or for parallel defines
! #endif
SystemDictionary_lock->notify_all();
}
}
--- 2250,2271 ----
k->set_prototype_header(markOopDesc::biased_locking_prototype());
}
}
// Make a new system dictionary entry.
! Dictionary* dictionary = loader_data->dictionary();
! InstanceKlass* sd_check = find_class(d_index, d_hash, name, dictionary);
if (sd_check == NULL) {
! dictionary->add_klass(d_index, d_hash, name, k);
notice_modification();
}
! #ifdef ASSERT
! sd_check = find_class(d_index, d_hash, name, dictionary);
assert (sd_check != NULL, "should have entry in system dictionary");
// Note: there may be a placeholder entry: for circularity testing
// or for parallel defines
! #endif
SystemDictionary_lock->notify_all();
}
}
*** 2376,2398 ****
return true;
} else {
constraint_name = fd.object_key();
}
}
- unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, loader_data1);
- int d_index1 = dictionary()->hash_to_index(d_hash1);
! unsigned int d_hash2 = dictionary()->compute_hash(constraint_name, loader_data2);
! int d_index2 = dictionary()->hash_to_index(d_hash2);
{
MutexLocker mu_s(SystemDictionary_lock, THREAD);
!
! // Better never do a GC while we're holding these oops
! NoSafepointVerifier nosafepoint;
!
! InstanceKlass* klass1 = find_class(d_index1, d_hash1, constraint_name, loader_data1);
! InstanceKlass* klass2 = find_class(d_index2, d_hash2, constraint_name, loader_data2);
return constraints()->add_entry(constraint_name, klass1, class_loader1,
klass2, class_loader2);
}
}
--- 2331,2353 ----
return true;
} else {
constraint_name = fd.object_key();
}
}
! Dictionary* dictionary1 = loader_data1->dictionary();
! unsigned int d_hash1 = dictionary1->compute_hash(constraint_name);
! int d_index1 = dictionary1->hash_to_index(d_hash1);
!
! Dictionary* dictionary2 = loader_data2->dictionary();
! unsigned int d_hash2 = dictionary2->compute_hash(constraint_name);
! int d_index2 = dictionary2->hash_to_index(d_hash2);
!
{
MutexLocker mu_s(SystemDictionary_lock, THREAD);
! InstanceKlass* klass1 = find_class(d_index1, d_hash1, constraint_name, dictionary1);
! InstanceKlass* klass2 = find_class(d_index2, d_hash2, constraint_name, dictionary2);
return constraints()->add_entry(constraint_name, klass1, class_loader1,
klass2, class_loader2);
}
}
*** 2840,2907 ****
Handle mname(THREAD, (oop) result.get_jobject());
(*method_type_result) = method_type;
return unpack_method_and_appendix(mname, caller, appendix_box, appendix_result, THREAD);
}
! // Since the identity hash code for symbols changes when the symbols are
! // moved from the regular perm gen (hash in the mark word) to the shared
! // spaces (hash is the address), the classes loaded into the dictionary
! // may be in the wrong buckets.
void SystemDictionary::reorder_dictionary() {
! dictionary()->reorder_dictionary();
}
void SystemDictionary::copy_buckets(char** top, char* end) {
! dictionary()->copy_buckets(top, end);
}
void SystemDictionary::copy_table(char** top, char* end) {
! dictionary()->copy_table(top, end);
}
- int SystemDictionary::number_of_classes() {
- return dictionary()->number_of_entries();
- }
-
-
// ----------------------------------------------------------------------------
void SystemDictionary::print_shared(bool details) {
shared_dictionary()->print(details);
}
void SystemDictionary::print(bool details) {
! dictionary()->print(details);
- // Placeholders
GCMutexLocker mu(SystemDictionary_lock);
placeholders()->print();
// loader constraints - print under SD_lock
constraints()->print();
}
void SystemDictionary::verify() {
- guarantee(dictionary() != NULL, "Verify of system dictionary failed");
guarantee(constraints() != NULL,
"Verify of loader constraints failed");
! guarantee(dictionary()->number_of_entries() >= 0 &&
! placeholders()->number_of_entries() >= 0,
"Verify of system dictionary failed");
// Verify dictionary
! dictionary()->verify();
GCMutexLocker mu(SystemDictionary_lock);
placeholders()->verify();
// Verify constraint table
guarantee(constraints() != NULL, "Verify of loader constraints failed");
! constraints()->verify(dictionary(), placeholders());
}
// caller needs ResourceMark
const char* SystemDictionary::loader_name(const oop loader) {
return ((loader) == NULL ? "<bootloader>" :
--- 2795,2870 ----
Handle mname(THREAD, (oop) result.get_jobject());
(*method_type_result) = method_type;
return unpack_method_and_appendix(mname, caller, appendix_box, appendix_result, THREAD);
}
! // Protection domain cache table handling
!
! ProtectionDomainCacheEntry* SystemDictionary::cache_get(Handle protection_domain) {
! return _pd_cache_table->get(protection_domain);
! }
!
void SystemDictionary::reorder_dictionary() {
! ClassLoaderData::the_null_class_loader_data()->dictionary()->reorder_dictionary();
}
void SystemDictionary::copy_buckets(char** top, char* end) {
! ClassLoaderData::the_null_class_loader_data()->dictionary()->copy_buckets(top, end);
}
void SystemDictionary::copy_table(char** top, char* end) {
! ClassLoaderData::the_null_class_loader_data()->dictionary()->copy_table(top, end);
}
// ----------------------------------------------------------------------------
void SystemDictionary::print_shared(bool details) {
shared_dictionary()->print(details);
}
void SystemDictionary::print(bool details) {
! if (shared_dictionary() != NULL) {
! tty->print_cr("Shared Dictionary");
! shared_dictionary()->print(details);
! }
GCMutexLocker mu(SystemDictionary_lock);
+
+ ClassLoaderDataGraph::print_dictionary(details);
+
+ // Placeholders
placeholders()->print();
+ tty->cr();
// loader constraints - print under SD_lock
constraints()->print();
+ tty->cr();
+
+ _pd_cache_table->print();
+ tty->cr();
}
void SystemDictionary::verify() {
guarantee(constraints() != NULL,
"Verify of loader constraints failed");
! guarantee(placeholders()->number_of_entries() >= 0,
"Verify of system dictionary failed");
// Verify dictionary
! ClassLoaderDataGraph::verify_dictionary();
GCMutexLocker mu(SystemDictionary_lock);
placeholders()->verify();
// Verify constraint table
guarantee(constraints() != NULL, "Verify of loader constraints failed");
! constraints()->verify(placeholders());
!
! _pd_cache_table->verify();
}
// caller needs ResourceMark
const char* SystemDictionary::loader_name(const oop loader) {
return ((loader) == NULL ? "<bootloader>" :
< prev index next >