< prev index next >
src/share/vm/classfile/systemDictionary.cpp
Print this page
*** 118,131 ****
oop SystemDictionary::java_system_loader() {
return _java_system_loader;
}
void SystemDictionary::compute_java_system_loader(TRAPS) {
! KlassHandle system_klass(THREAD, WK_KLASS(ClassLoader_klass));
JavaValue result(T_OBJECT);
JavaCalls::call_static(&result,
! KlassHandle(THREAD, WK_KLASS(ClassLoader_klass)),
vmSymbols::getSystemClassLoader_name(),
vmSymbols::void_classloader_signature(),
CHECK);
_java_system_loader = (oop)result.get_jobject();
--- 118,131 ----
oop SystemDictionary::java_system_loader() {
return _java_system_loader;
}
void SystemDictionary::compute_java_system_loader(TRAPS) {
! Klass* system_klass = WK_KLASS(ClassLoader_klass);
JavaValue result(T_OBJECT);
JavaCalls::call_static(&result,
! WK_KLASS(ClassLoader_klass),
vmSymbols::getSystemClassLoader_name(),
vmSymbols::void_classloader_signature(),
CHECK);
_java_system_loader = (oop)result.get_jobject();
*** 182,226 ****
// Forwards to resolve_or_null
Klass* SystemDictionary::resolve_or_fail(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, TRAPS) {
Klass* klass = resolve_or_null(class_name, class_loader, protection_domain, THREAD);
if (HAS_PENDING_EXCEPTION || klass == NULL) {
- KlassHandle k_h(THREAD, klass);
// can return a null klass
! klass = handle_resolution_exception(class_name, throw_error, k_h, THREAD);
}
return klass;
}
Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name,
bool throw_error,
! KlassHandle klass_h, TRAPS) {
if (HAS_PENDING_EXCEPTION) {
// If we have a pending exception we forward it to the caller, unless throw_error is true,
// in which case we have to check whether the pending exception is a ClassNotFoundException,
// and if so convert it to a NoClassDefFoundError
// And chain the original ClassNotFoundException
if (throw_error && PENDING_EXCEPTION->is_a(SystemDictionary::ClassNotFoundException_klass())) {
ResourceMark rm(THREAD);
! assert(klass_h() == NULL, "Should not have result with exception pending");
Handle e(THREAD, PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string(), e);
} else {
return NULL;
}
}
// Class not found, throw appropriate error or exception depending on value of throw_error
! if (klass_h() == NULL) {
ResourceMark rm(THREAD);
if (throw_error) {
THROW_MSG_NULL(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string());
} else {
THROW_MSG_NULL(vmSymbols::java_lang_ClassNotFoundException(), class_name->as_C_string());
}
}
! return (Klass*)klass_h();
}
Klass* SystemDictionary::resolve_or_fail(Symbol* class_name,
bool throw_error, TRAPS)
--- 182,225 ----
// Forwards to resolve_or_null
Klass* SystemDictionary::resolve_or_fail(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, TRAPS) {
Klass* klass = resolve_or_null(class_name, class_loader, protection_domain, THREAD);
if (HAS_PENDING_EXCEPTION || klass == NULL) {
// can return a null klass
! klass = handle_resolution_exception(class_name, throw_error, klass, THREAD);
}
return klass;
}
Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name,
bool throw_error,
! Klass* klass, TRAPS) {
if (HAS_PENDING_EXCEPTION) {
// If we have a pending exception we forward it to the caller, unless throw_error is true,
// in which case we have to check whether the pending exception is a ClassNotFoundException,
// and if so convert it to a NoClassDefFoundError
// And chain the original ClassNotFoundException
if (throw_error && PENDING_EXCEPTION->is_a(SystemDictionary::ClassNotFoundException_klass())) {
ResourceMark rm(THREAD);
! assert(klass == NULL, "Should not have result with exception pending");
Handle e(THREAD, PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string(), e);
} else {
return NULL;
}
}
// Class not found, throw appropriate error or exception depending on value of throw_error
! if (klass == NULL) {
ResourceMark rm(THREAD);
if (throw_error) {
THROW_MSG_NULL(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string());
} else {
THROW_MSG_NULL(vmSymbols::java_lang_ClassNotFoundException(), class_name->as_C_string());
}
}
! return klass;
}
Klass* SystemDictionary::resolve_or_fail(Symbol* class_name,
bool throw_error, TRAPS)
*** 400,411 ****
Klass* superk = SystemDictionary::resolve_or_null(class_name,
class_loader,
protection_domain,
THREAD);
- KlassHandle superk_h(THREAD, superk);
-
// Clean up of placeholders moved so that each classloadAction registrar self-cleans up
// It is no longer necessary to keep the placeholder table alive until update_dictionary
// or error. GC used to walk the placeholder table as strong roots.
// The instanceKlass is kept alive because the class loader is on the stack,
// which keeps the loader_data alive, as well as all instanceKlasses in
--- 399,408 ----
*** 413,431 ****
{
MutexLocker mu(SystemDictionary_lock, THREAD);
placeholders()->find_and_remove(p_index, p_hash, child_name, loader_data, PlaceholderTable::LOAD_SUPER, THREAD);
SystemDictionary_lock->notify_all();
}
! if (HAS_PENDING_EXCEPTION || superk_h() == NULL) {
// can null superk
! superk_h = KlassHandle(THREAD, handle_resolution_exception(class_name, true, superk_h, THREAD));
}
! return superk_h();
}
! void SystemDictionary::validate_protection_domain(instanceKlassHandle klass,
Handle class_loader,
Handle protection_domain,
TRAPS) {
if(!has_checkPackageAccess()) return;
--- 410,428 ----
{
MutexLocker mu(SystemDictionary_lock, THREAD);
placeholders()->find_and_remove(p_index, p_hash, child_name, loader_data, PlaceholderTable::LOAD_SUPER, THREAD);
SystemDictionary_lock->notify_all();
}
! if (HAS_PENDING_EXCEPTION || superk == NULL) {
// can null superk
! superk = handle_resolution_exception(class_name, true, superk, THREAD);
}
! return superk;
}
! void SystemDictionary::validate_protection_domain(InstanceKlass* klass,
Handle class_loader,
Handle protection_domain,
TRAPS) {
if(!has_checkPackageAccess()) return;
*** 436,450 ****
// Print out trace information
outputStream* log = Log(protectiondomain)::debug_stream();
log->print_cr("Checking package access");
log->print("class loader: "); class_loader()->print_value_on(log);
log->print(" protection domain: "); protection_domain()->print_value_on(log);
! log->print(" loading: "); klass()->print_value_on(log);
log->cr();
}
! KlassHandle system_loader(THREAD, SystemDictionary::ClassLoader_klass());
JavaCalls::call_special(&result,
class_loader,
system_loader,
vmSymbols::checkPackageAccess_name(),
vmSymbols::class_protectiondomain_signature(),
--- 433,447 ----
// Print out trace information
outputStream* log = Log(protectiondomain)::debug_stream();
log->print_cr("Checking package access");
log->print("class loader: "); class_loader()->print_value_on(log);
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(),
*** 538,552 ****
// to force placeholder entry creation for this class for circularity detection
// Caller must check for pending exception
// Returns non-null Klass* if other thread has completed load
// and we are done,
// If return null Klass* and no pending exception, the caller must load the class
! instanceKlassHandle SystemDictionary::handle_parallel_super_load(
Symbol* name, Symbol* superclassname, Handle class_loader,
Handle protection_domain, Handle lockObject, TRAPS) {
- instanceKlassHandle nh = instanceKlassHandle(); // null Handle
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);
--- 535,548 ----
// to force placeholder entry creation for this class for circularity detection
// Caller must check for pending exception
// Returns non-null Klass* if other thread has completed load
// and we are done,
// If return null Klass* and no pending exception, the caller must load the class
! 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);
*** 562,598 ****
Klass* superk = SystemDictionary::resolve_super_or_fail(name,
superclassname,
class_loader,
protection_domain,
true,
! CHECK_(nh));
// 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
! Klass* check = find_class(d_index, d_hash, name, loader_data);
! if (check != NULL) {
! // Klass is already loaded, so just return it
! return(instanceKlassHandle(THREAD, check));
! } else {
! return nh;
! }
}
// 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
! Klass* check = find_class(d_index, d_hash, name, loader_data);
if (check != NULL) {
// Klass is already loaded, so just return it
! return(instanceKlassHandle(THREAD, check));
} else {
placeholder = placeholders()->get_entry(p_index, p_hash, name, loader_data);
if (placeholder && placeholder->super_load_in_progress() ){
// Before UnsyncloadClass:
// We only get here if the application has released the
--- 558,588 ----
Klass* superk = SystemDictionary::resolve_super_or_fail(name,
superclassname,
class_loader,
protection_domain,
true,
! CHECK_NULL);
// 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);
if (placeholder && placeholder->super_load_in_progress() ){
// Before UnsyncloadClass:
// We only get here if the application has released the
*** 617,650 ****
// If not in SD and not in PH, other thread's load must have failed
super_load_in_progress = false;
}
}
}
! return (nh);
}
static void post_class_load_event(const Ticks& start_time,
! instanceKlassHandle k,
const ClassLoaderData* init_cld) {
#if INCLUDE_TRACE
EventClassLoad event(UNTIMED);
if (event.should_commit()) {
event.set_starttime(start_time);
! event.set_loadedClass(k());
event.set_definingClassLoader(k->class_loader_data());
event.set_initiatingClassLoader(init_cld);
event.commit();
}
#endif // INCLUDE_TRACE
}
! static void class_define_event(instanceKlassHandle k,
const ClassLoaderData* def_cld) {
#if INCLUDE_TRACE
EventClassDefine event;
if (event.should_commit()) {
! event.set_definedClass(k());
event.set_definingClassLoader(def_cld);
event.commit();
}
#endif // INCLUDE_TRACE
}
--- 607,640 ----
// If not in SD and not in PH, other thread's load must have failed
super_load_in_progress = false;
}
}
}
! return NULL;
}
static void post_class_load_event(const Ticks& start_time,
! InstanceKlass* k,
const ClassLoaderData* init_cld) {
#if INCLUDE_TRACE
EventClassLoad event(UNTIMED);
if (event.should_commit()) {
event.set_starttime(start_time);
! event.set_loadedClass(k);
event.set_definingClassLoader(k->class_loader_data());
event.set_initiatingClassLoader(init_cld);
event.commit();
}
#endif // INCLUDE_TRACE
}
! static void class_define_event(InstanceKlass* k,
const ClassLoaderData* def_cld) {
#if INCLUDE_TRACE
EventClassDefine event;
if (event.should_commit()) {
! event.set_definedClass(k);
event.set_definingClassLoader(def_cld);
event.commit();
}
#endif // INCLUDE_TRACE
}
*** 706,726 ****
// Check again (after locking) if class already exist in SystemDictionary
bool class_has_been_loaded = false;
bool super_load_in_progress = false;
bool havesupername = false;
! instanceKlassHandle k;
PlaceholderEntry* placeholder;
Symbol* superclassname = NULL;
{
MutexLocker mu(SystemDictionary_lock, THREAD);
! Klass* 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 = instanceKlassHandle(THREAD, check);
} else {
placeholder = placeholders()->get_entry(p_index, p_hash, name, loader_data);
if (placeholder && placeholder->super_load_in_progress()) {
super_load_in_progress = true;
if (placeholder->havesupername() == true) {
--- 696,716 ----
// Check again (after locking) if class already exist in SystemDictionary
bool class_has_been_loaded = false;
bool super_load_in_progress = false;
bool havesupername = false;
! InstanceKlass* k = NULL;
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 {
placeholder = placeholders()->get_entry(p_index, p_hash, name, loader_data);
if (placeholder && placeholder->super_load_in_progress()) {
super_load_in_progress = true;
if (placeholder->havesupername() == true) {
*** 731,746 ****
}
}
// If the class is in the placeholder table, class loading is in progress
if (super_load_in_progress && havesupername==true) {
! k = SystemDictionary::handle_parallel_super_load(name, superclassname,
! class_loader, protection_domain, lockObject, THREAD);
if (HAS_PENDING_EXCEPTION) {
return NULL;
}
! if (!k.is_null()) {
class_has_been_loaded = true;
}
}
bool throw_circularity_error = false;
--- 721,739 ----
}
}
// If the class is in the placeholder table, class loading is in progress
if (super_load_in_progress && havesupername==true) {
! k = handle_parallel_super_load(name,
! superclassname,
! class_loader,
! protection_domain,
! lockObject, THREAD);
if (HAS_PENDING_EXCEPTION) {
return NULL;
}
! if (k != NULL) {
class_has_been_loaded = true;
}
}
bool throw_circularity_error = false;
*** 793,806 ****
// case 2: traditional with broken classloader lock. wait on first
// requestor.
double_lock_wait(lockObject, THREAD);
}
// Check if classloading completed while we were waiting
! Klass* check = find_class(d_index, d_hash, name, loader_data);
if (check != NULL) {
// Klass is already loaded, so just return it
! k = instanceKlassHandle(THREAD, check);
class_has_been_loaded = true;
}
// check if other thread failed to load and cleaned up
oldprobe = placeholders()->get_entry(p_index, p_hash, name, loader_data);
}
--- 786,799 ----
// 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;
}
// check if other thread failed to load and cleaned up
oldprobe = placeholders()->get_entry(p_index, p_hash, name, loader_data);
}
*** 818,831 ****
// 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
! Klass* 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 = instanceKlassHandle(THREAD, check);
class_has_been_loaded = true;
}
}
}
--- 811,824 ----
// 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;
}
}
}
*** 848,873 ****
// successfully loaded InstanceKlass
// Should not get here for classloaders that support parallelism
// with the new cleaner mechanism, even with AllowParallelDefineClass
// Bootstrap goes through here to allow for an extra guarantee check
if (UnsyncloadClass || (class_loader.is_null())) {
! if (k.is_null() && HAS_PENDING_EXCEPTION
&& PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
MutexLocker mu(SystemDictionary_lock, THREAD);
! Klass* check = find_class(d_index, d_hash, name, loader_data);
if (check != NULL) {
// Klass is already loaded, so just use it
! k = instanceKlassHandle(THREAD, check);
CLEAR_PENDING_EXCEPTION;
guarantee((!class_loader.is_null()), "dup definition for bootstrap loader?");
}
}
}
// If everything was OK (no exceptions, no null return value), and
// class_loader is NOT the defining loader, do a little more bookkeeping.
! if (!HAS_PENDING_EXCEPTION && !k.is_null() &&
k->class_loader() != class_loader()) {
check_constraints(d_index, d_hash, k, class_loader, false, THREAD);
// Need to check for a PENDING_EXCEPTION again; check_constraints
--- 841,866 ----
// successfully loaded InstanceKlass
// Should not get here for classloaders that support parallelism
// with the new cleaner mechanism, even with AllowParallelDefineClass
// 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?");
}
}
}
// If everything was OK (no exceptions, no null return value), and
// class_loader is NOT the defining loader, do a little more bookkeeping.
! if (!HAS_PENDING_EXCEPTION && k != NULL &&
k->class_loader() != class_loader()) {
check_constraints(d_index, d_hash, k, class_loader, false, THREAD);
// Need to check for a PENDING_EXCEPTION again; check_constraints
*** 881,891 ****
}
if (JvmtiExport::should_post_class_load()) {
Thread *thread = THREAD;
assert(thread->is_Java_thread(), "thread->is_Java_thread()");
! JvmtiExport::post_class_load((JavaThread *) thread, k());
}
}
}
} // load_instance_class loop
--- 874,884 ----
}
if (JvmtiExport::should_post_class_load()) {
Thread *thread = THREAD;
assert(thread->is_Java_thread(), "thread->is_Java_thread()");
! JvmtiExport::post_class_load((JavaThread *) thread, k);
}
}
}
} // load_instance_class loop
*** 897,923 ****
placeholders()->find_and_remove(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, THREAD);
SystemDictionary_lock->notify_all();
}
}
! if (HAS_PENDING_EXCEPTION || k.is_null()) {
return NULL;
}
post_class_load_event(class_load_start_time, k, loader_data);
#ifdef ASSERT
{
ClassLoaderData* loader_data = k->class_loader_data();
MutexLocker mu(SystemDictionary_lock, THREAD);
Klass* kk = find_class(name, loader_data);
! assert(kk == k(), "should be present in dictionary");
}
#endif
// return if the protection domain in NULL
! 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,
--- 890,916 ----
placeholders()->find_and_remove(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, THREAD);
SystemDictionary_lock->notify_all();
}
}
! if (HAS_PENDING_EXCEPTION || k == NULL) {
return NULL;
}
post_class_load_event(class_load_start_time, k, loader_data);
#ifdef ASSERT
{
ClassLoaderData* loader_data = k->class_loader_data();
MutexLocker mu(SystemDictionary_lock, THREAD);
Klass* kk = find_class(name, loader_data);
! assert(kk == k, "should be present in dictionary");
}
#endif
// return if the protection domain in NULL
! 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,
*** 928,945 ****
// 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();
}
}
// Verify protection domain. If it fails an exception is thrown
validate_protection_domain(k, class_loader, protection_domain, CHECK_NULL);
! return k();
}
// This routine does not lock the system dictionary.
//
--- 921,938 ----
// 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;
}
}
// Verify protection domain. If it fails an exception is thrown
validate_protection_domain(k, class_loader, protection_domain, CHECK_NULL);
! return k;
}
// This routine does not lock the system dictionary.
//
*** 1017,1027 ****
// Note: this method is much like resolve_from_stream, but
// does not publish the classes via the SystemDictionary.
// Handles unsafe_DefineAnonymousClass and redefineclasses
// RedefinedClasses do not add to the class hierarchy
! Klass* SystemDictionary::parse_stream(Symbol* class_name,
Handle class_loader,
Handle protection_domain,
ClassFileStream* st,
const InstanceKlass* host_klass,
GrowableArray<Handle>* cp_patches,
--- 1010,1020 ----
// Note: this method is much like resolve_from_stream, but
// does not publish the classes via the SystemDictionary.
// Handles unsafe_DefineAnonymousClass and redefineclasses
// RedefinedClasses do not add to the class hierarchy
! InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
Handle class_loader,
Handle protection_domain,
ClassFileStream* st,
const InstanceKlass* host_klass,
GrowableArray<Handle>* cp_patches,
*** 1047,1065 ****
// Parse stream and create a klass.
// Note that we do this even though this klass might
// already be present in the SystemDictionary, otherwise we would not
// throw potential ClassFormatErrors.
! instanceKlassHandle k = KlassFactory::create_from_stream(st,
class_name,
loader_data,
protection_domain,
host_klass,
cp_patches,
CHECK_NULL);
! if (host_klass != NULL && k.not_null()) {
// If it's anonymous, initialize it now, since nobody else will.
{
MutexLocker mu_r(Compile_lock, THREAD);
--- 1040,1058 ----
// Parse stream and create a klass.
// Note that we do this even though this klass might
// already be present in the SystemDictionary, otherwise we would not
// throw potential ClassFormatErrors.
! InstanceKlass* k = KlassFactory::create_from_stream(st,
class_name,
loader_data,
protection_domain,
host_klass,
cp_patches,
CHECK_NULL);
! if (host_klass != NULL && k != NULL) {
// If it's anonymous, initialize it now, since nobody else will.
{
MutexLocker mu_r(Compile_lock, THREAD);
*** 1081,1107 ****
k->eager_initialize(CHECK_NULL);
// notify jvmti
if (JvmtiExport::should_post_class_load()) {
assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
! JvmtiExport::post_class_load((JavaThread *) THREAD, k());
}
post_class_load_event(class_load_start_time, k, loader_data);
}
assert(host_klass != NULL || NULL == cp_patches,
"cp_patches only found with host_klass");
! return k();
}
// Add a klass to the system from a stream (called by jni_DefineClass and
// JVM_DefineClass).
// Note: class_name can be NULL. In that case we do not know the name of
// the class until we have parsed the stream.
! Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
Handle class_loader,
Handle protection_domain,
ClassFileStream* st,
TRAPS) {
--- 1074,1100 ----
k->eager_initialize(CHECK_NULL);
// notify jvmti
if (JvmtiExport::should_post_class_load()) {
assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
! JvmtiExport::post_class_load((JavaThread *) THREAD, k);
}
post_class_load_event(class_load_start_time, k, loader_data);
}
assert(host_klass != NULL || NULL == cp_patches,
"cp_patches only found with host_klass");
! return k;
}
// Add a klass to the system from a stream (called by jni_DefineClass and
// JVM_DefineClass).
// Note: class_name can be NULL. In that case we do not know the name of
// the class until we have parsed the stream.
! InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* class_name,
Handle class_loader,
Handle protection_domain,
ClassFileStream* st,
TRAPS) {
*** 1125,1147 ****
// Parse the stream and create a klass.
// Note that we do this even though this klass might
// already be present in the SystemDictionary, otherwise we would not
// throw potential ClassFormatErrors.
- //
! instanceKlassHandle k;
#if INCLUDE_CDS
k = SystemDictionaryShared::lookup_from_stream(class_name,
class_loader,
protection_domain,
st,
CHECK_NULL);
#endif
! if (k.is_null()) {
if (st->buffer() == NULL) {
return NULL;
}
k = KlassFactory::create_from_stream(st,
class_name,
--- 1118,1139 ----
// Parse the stream and create a klass.
// Note that we do this even though this klass might
// already be present in the SystemDictionary, otherwise we would not
// throw potential ClassFormatErrors.
! InstanceKlass* k = NULL;
#if INCLUDE_CDS
k = SystemDictionaryShared::lookup_from_stream(class_name,
class_loader,
protection_domain,
st,
CHECK_NULL);
#endif
! if (k == NULL) {
if (st->buffer() == NULL) {
return NULL;
}
k = KlassFactory::create_from_stream(st,
class_name,
*** 1150,1170 ****
NULL, // host_klass
NULL, // cp_patches
CHECK_NULL);
}
! assert(k.not_null(), "no klass created");
Symbol* h_name = k->name();
assert(class_name == NULL || class_name == h_name, "name mismatch");
bool define_succeeded = false;
// Add class just loaded
// If a class loader supports parallel classloading handle parallel define requests
// find_or_define_instance_class may return a different InstanceKlass
if (is_parallelCapable(class_loader)) {
! instanceKlassHandle defined_k = find_or_define_instance_class(h_name, class_loader, k, CHECK_NULL);
! if (k() == defined_k()) {
// we have won over other concurrent threads (if any) that are
// competing to define the same class.
define_succeeded = true;
}
k = defined_k;
--- 1142,1162 ----
NULL, // host_klass
NULL, // cp_patches
CHECK_NULL);
}
! assert(k != NULL, "no klass created");
Symbol* h_name = k->name();
assert(class_name == NULL || class_name == h_name, "name mismatch");
bool define_succeeded = false;
// Add class just loaded
// If a class loader supports parallel classloading handle parallel define requests
// find_or_define_instance_class may return a different InstanceKlass
if (is_parallelCapable(class_loader)) {
! InstanceKlass* defined_k = find_or_define_instance_class(h_name, class_loader, k, CHECK_NULL);
! if (k == defined_k) {
// we have won over other concurrent threads (if any) that are
// competing to define the same class.
define_succeeded = true;
}
k = defined_k;
*** 1176,1189 ****
// Make sure we have an entry in the SystemDictionary on success
debug_only( {
MutexLocker mu(SystemDictionary_lock, THREAD);
Klass* check = find_class(h_name, k->class_loader_data());
! assert(check == k(), "should be present in the dictionary");
} );
! return k();
}
#if INCLUDE_CDS
void SystemDictionary::set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
int number_of_entries) {
--- 1168,1181 ----
// Make sure we have an entry in the SystemDictionary on success
debug_only( {
MutexLocker mu(SystemDictionary_lock, THREAD);
Klass* check = find_class(h_name, k->class_loader_data());
! assert(check == k, "should be present in the dictionary");
} );
! return k;
}
#if INCLUDE_CDS
void SystemDictionary::set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
int number_of_entries) {
*** 1194,1204 ****
// If there is a shared dictionary, then find the entry for the
// given shared system class, if any.
! Klass* 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);
--- 1186,1196 ----
// 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);
*** 1212,1241 ****
// dictionary). Force the superclass and all interfaces to be loaded.
// Update the class definition to include sibling classes and no
// subclasses (yet). [Classes in the shared space are not part of the
// object hierarchy until loaded.]
! instanceKlassHandle SystemDictionary::load_shared_class(
Symbol* class_name, Handle class_loader, TRAPS) {
! instanceKlassHandle ik (THREAD, find_shared_class(class_name));
// Make sure we only return the boot class for the NULL classloader.
! if (ik.not_null() &&
ik->is_shared_boot_class() && class_loader.is_null()) {
Handle protection_domain;
return load_shared_class(ik, class_loader, protection_domain, THREAD);
}
! return instanceKlassHandle();
}
// Check if a shared class can be loaded by the specific classloader:
//
// NULL classloader:
// - Module class from "modules" jimage. ModuleEntry must be defined in the classloader.
// - Class from -Xbootclasspath/a. The class has no defined PackageEntry, or must
// be defined in an unnamed module.
bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
! instanceKlassHandle ik,
Handle class_loader, TRAPS) {
assert(!ModuleEntryTable::javabase_moduleEntry()->is_patched(),
"Cannot use sharing if java.base is patched");
ResourceMark rm;
int path_index = ik->shared_classpath_index();
--- 1204,1233 ----
// dictionary). Force the superclass and all interfaces to be loaded.
// Update the class definition to include sibling classes and no
// subclasses (yet). [Classes in the shared space are not part of the
// object hierarchy until loaded.]
! InstanceKlass* SystemDictionary::load_shared_class(
Symbol* class_name, Handle class_loader, TRAPS) {
! InstanceKlass* ik = find_shared_class(class_name);
// Make sure we only return the boot class for the NULL classloader.
! if (ik != NULL &&
ik->is_shared_boot_class() && class_loader.is_null()) {
Handle protection_domain;
return load_shared_class(ik, class_loader, protection_domain, THREAD);
}
! return NULL;
}
// Check if a shared class can be loaded by the specific classloader:
//
// NULL classloader:
// - Module class from "modules" jimage. ModuleEntry must be defined in the classloader.
// - Class from -Xbootclasspath/a. The class has no defined PackageEntry, or must
// be defined in an unnamed module.
bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
! InstanceKlass* ik,
Handle class_loader, TRAPS) {
assert(!ModuleEntryTable::javabase_moduleEntry()->is_patched(),
"Cannot use sharing if java.base is patched");
ResourceMark rm;
int path_index = ik->shared_classpath_index();
*** 1308,1329 ****
pkg_entry, mod_entry, CHECK_(false));
return res;
}
}
! instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik,
Handle class_loader,
Handle protection_domain, TRAPS) {
- instanceKlassHandle nh = instanceKlassHandle(); // null Handle
! if (ik.not_null()) {
Symbol* class_name = ik->name();
bool visible = is_shared_class_visible(
! class_name, ik, class_loader, CHECK_(nh));
if (!visible) {
! return nh;
}
// Resolve the superclass and interfaces. They must be the same
// as in dump time, because the layout of <ik> depends on
// the specific layout of ik->super() and ik->local_interfaces().
--- 1300,1320 ----
pkg_entry, mod_entry, CHECK_(false));
return res;
}
}
! InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik,
Handle class_loader,
Handle protection_domain, TRAPS) {
! if (ik != NULL) {
Symbol* class_name = ik->name();
bool visible = is_shared_class_visible(
! class_name, ik, class_loader, CHECK_NULL);
if (!visible) {
! return NULL;
}
// Resolve the superclass and interfaces. They must be the same
// as in dump time, because the layout of <ik> depends on
// the specific layout of ik->super() and ik->local_interfaces().
*** 1332,1346 ****
// load <ik> from the shared archive.
if (ik->super() != NULL) {
Symbol* cn = ik->super()->name();
Klass *s = resolve_super_or_fail(class_name, cn,
! class_loader, protection_domain, true, CHECK_(nh));
if (s != ik->super()) {
// The dynamically resolved super class is not the same as the one we used during dump time,
// so we cannot use ik.
! return nh;
} else {
assert(s->is_shared(), "must be");
}
}
--- 1323,1337 ----
// load <ik> from the shared archive.
if (ik->super() != NULL) {
Symbol* cn = ik->super()->name();
Klass *s = resolve_super_or_fail(class_name, cn,
! class_loader, protection_domain, true, CHECK_NULL);
if (s != ik->super()) {
// The dynamically resolved super class is not the same as the one we used during dump time,
// so we cannot use ik.
! return NULL;
} else {
assert(s->is_shared(), "must be");
}
}
*** 1352,1374 ****
// Note: can not use InstanceKlass::cast here because
// interfaces' InstanceKlass's C++ vtbls haven't been
// reinitialized yet (they will be once the interface classes
// are loaded)
Symbol* name = k->name();
! Klass* i = resolve_super_or_fail(class_name, name, class_loader, protection_domain, false, CHECK_(nh));
if (k != i) {
// The dynamically resolved interface class is not the same as the one we used during dump time,
// so we cannot use ik.
! return nh;
} else {
assert(i->is_shared(), "must be");
}
}
! instanceKlassHandle new_ik = KlassFactory::check_shared_class_file_load_hook(
! ik, class_name, class_loader, protection_domain, CHECK_(nh));
! if (new_ik.not_null()) {
// The class is changed by CFLH. Return the new class. The shared class is
// not used.
return new_ik;
}
--- 1343,1365 ----
// Note: can not use InstanceKlass::cast here because
// interfaces' InstanceKlass's C++ vtbls haven't been
// reinitialized yet (they will be once the interface classes
// are loaded)
Symbol* name = k->name();
! Klass* i = resolve_super_or_fail(class_name, name, class_loader, protection_domain, false, CHECK_NULL);
if (k != i) {
// The dynamically resolved interface class is not the same as the one we used during dump time,
// so we cannot use ik.
! return NULL;
} else {
assert(i->is_shared(), "must be");
}
}
! InstanceKlass* new_ik = KlassFactory::check_shared_class_file_load_hook(
! ik, class_name, class_loader, protection_domain, CHECK_NULL);
! if (new_ik != NULL) {
// The class is changed by CFLH. Return the new class. The shared class is
// not used.
return new_ik;
}
*** 1389,1408 ****
Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
check_loader_lock_contention(lockObject, THREAD);
ObjectLocker ol(lockObject, THREAD, true);
// prohibited package check assumes all classes loaded from archive call
// restore_unshareable_info which calls ik->set_package()
! ik->restore_unshareable_info(loader_data, protection_domain, CHECK_(nh));
}
if (log_is_enabled(Info, class, load)) {
! ik()->print_loading_log(LogLevel::Info, loader_data, NULL, NULL);
}
// No 'else' here as logging levels are not mutually exclusive
if (log_is_enabled(Debug, class, load)) {
! ik()->print_loading_log(LogLevel::Debug, loader_data, NULL, NULL);
}
// For boot loader, ensure that GetSystemPackage knows that a class in this
// package was loaded.
if (class_loader.is_null()) {
--- 1380,1399 ----
Handle lockObject = compute_loader_lock_object(class_loader, THREAD);
check_loader_lock_contention(lockObject, THREAD);
ObjectLocker ol(lockObject, THREAD, true);
// prohibited package check assumes all classes loaded from archive call
// restore_unshareable_info which calls ik->set_package()
! ik->restore_unshareable_info(loader_data, protection_domain, CHECK_NULL);
}
if (log_is_enabled(Info, class, load)) {
! ik->print_loading_log(LogLevel::Info, loader_data, NULL, NULL);
}
// No 'else' here as logging levels are not mutually exclusive
if (log_is_enabled(Debug, class, load)) {
! ik->print_loading_log(LogLevel::Debug, loader_data, NULL, NULL);
}
// For boot loader, ensure that GetSystemPackage knows that a class in this
// package was loaded.
if (class_loader.is_null()) {
*** 1419,1434 ****
classlist_file->flush();
}
}
// notify a class loaded from shared object
! ClassLoadingService::notify_class_loaded(ik(), true /* shared class */);
}
ik->set_has_passed_fingerprint_check(false);
if (UseAOT && ik->supers_have_passed_fingerprint_checks()) {
! uint64_t aot_fp = AOTLoader::get_saved_fingerprint(ik());
uint64_t cds_fp = ik->get_stored_fingerprint();
if (aot_fp != 0 && aot_fp == cds_fp) {
// This class matches with a class saved in an AOT library
ik->set_has_passed_fingerprint_check(true);
} else {
--- 1410,1425 ----
classlist_file->flush();
}
}
// notify a class loaded from shared object
! ClassLoadingService::notify_class_loaded(ik, true /* shared class */);
}
ik->set_has_passed_fingerprint_check(false);
if (UseAOT && ik->supers_have_passed_fingerprint_checks()) {
! uint64_t aot_fp = AOTLoader::get_saved_fingerprint(ik);
uint64_t cds_fp = ik->get_stored_fingerprint();
if (aot_fp != 0 && aot_fp == cds_fp) {
// This class matches with a class saved in an AOT library
ik->set_has_passed_fingerprint_check(true);
} else {
*** 1438,1449 ****
}
return ik;
}
#endif // INCLUDE_CDS
! instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
! instanceKlassHandle nh = instanceKlassHandle(); // null Handle
if (class_loader.is_null()) {
ResourceMark rm;
PackageEntry* pkg_entry = NULL;
bool search_only_bootloader_append = false;
--- 1429,1439 ----
}
return ik;
}
#endif // INCLUDE_CDS
! InstanceKlass* SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
if (class_loader.is_null()) {
ResourceMark rm;
PackageEntry* pkg_entry = NULL;
bool search_only_bootloader_append = false;
*** 1471,1488 ****
// load the class post java.base definition. If
// java.base has not been defined, let the class load
// and its package will be checked later by
// ModuleEntryTable::verify_javabase_packages.
if (ModuleEntryTable::javabase_defined()) {
! return nh;
}
} else {
// Check that the class' package is defined within java.base.
ModuleEntry* mod_entry = pkg_entry->module();
Symbol* mod_entry_name = mod_entry->name();
if (mod_entry_name->fast_compare(vmSymbols::java_base()) != 0) {
! return nh;
}
}
}
} else {
assert(!DumpSharedSpaces, "Archive dumped after module system initialization");
--- 1461,1478 ----
// load the class post java.base definition. If
// java.base has not been defined, let the class load
// and its package will be checked later by
// ModuleEntryTable::verify_javabase_packages.
if (ModuleEntryTable::javabase_defined()) {
! return NULL;
}
} else {
// Check that the class' package is defined within java.base.
ModuleEntry* mod_entry = pkg_entry->module();
Symbol* mod_entry_name = mod_entry->name();
if (mod_entry_name->fast_compare(vmSymbols::java_base()) != 0) {
! return NULL;
}
}
}
} else {
assert(!DumpSharedSpaces, "Archive dumped after module system initialization");
*** 1504,1532 ****
!search_only_bootloader_append,
"Attempt to load a class outside of boot loader's module path");
// Search the shared system dictionary for classes preloaded into the
// shared spaces.
! instanceKlassHandle k;
{
#if INCLUDE_CDS
PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
k = load_shared_class(class_name, class_loader, THREAD);
#endif
}
! if (k.is_null()) {
// Use VM class loader
PerfTraceTime vmtimer(ClassLoader::perf_sys_classload_time());
! k = ClassLoader::load_class(class_name, search_only_bootloader_append, CHECK_(nh));
}
// find_or_define_instance_class may return a different InstanceKlass
! if (!k.is_null()) {
! instanceKlassHandle defined_k =
! find_or_define_instance_class(class_name, class_loader, k, CHECK_(nh));
! k = defined_k;
}
return k;
} else {
// Use user specified class loader to load class. Call loadClass operation on class_loader.
ResourceMark rm(THREAD);
--- 1494,1520 ----
!search_only_bootloader_append,
"Attempt to load a class outside of boot loader's module path");
// Search the shared system dictionary for classes preloaded into the
// shared spaces.
! InstanceKlass* k = NULL;
{
#if INCLUDE_CDS
PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
k = load_shared_class(class_name, class_loader, THREAD);
#endif
}
! if (k == NULL) {
// Use VM class loader
PerfTraceTime vmtimer(ClassLoader::perf_sys_classload_time());
! k = ClassLoader::load_class(class_name, search_only_bootloader_append, CHECK_NULL);
}
// find_or_define_instance_class may return a different InstanceKlass
! if (k != NULL) {
! k = find_or_define_instance_class(class_name, class_loader, k, CHECK_NULL);
}
return k;
} else {
// Use user specified class loader to load class. Call loadClass operation on class_loader.
ResourceMark rm(THREAD);
*** 1539,1555 ****
ClassLoader::perf_app_classload_count(),
jt->get_thread_stat()->perf_recursion_counts_addr(),
jt->get_thread_stat()->perf_timers_addr(),
PerfClassTraceTime::CLASS_LOAD);
! Handle s = java_lang_String::create_from_symbol(class_name, CHECK_(nh));
// Translate to external class name format, i.e., convert '/' chars to '.'
! Handle string = java_lang_String::externalize_classname(s, CHECK_(nh));
JavaValue result(T_OBJECT);
! KlassHandle spec_klass (THREAD, SystemDictionary::ClassLoader_klass());
// Call public unsynchronized loadClass(String) directly for all class loaders
// for parallelCapable class loaders. JDK >=7, loadClass(String, boolean) will
// acquire a class-name based lock rather than the class loader object lock.
// JDK < 7 already acquire the class loader lock in loadClass(String, boolean),
--- 1527,1543 ----
ClassLoader::perf_app_classload_count(),
jt->get_thread_stat()->perf_recursion_counts_addr(),
jt->get_thread_stat()->perf_timers_addr(),
PerfClassTraceTime::CLASS_LOAD);
! Handle s = java_lang_String::create_from_symbol(class_name, CHECK_NULL);
// Translate to external class name format, i.e., convert '/' chars to '.'
! Handle string = java_lang_String::externalize_classname(s, CHECK_NULL);
JavaValue result(T_OBJECT);
! InstanceKlass* spec_klass = SystemDictionary::ClassLoader_klass();
// Call public unsynchronized loadClass(String) directly for all class loaders
// for parallelCapable class loaders. JDK >=7, loadClass(String, boolean) will
// acquire a class-name based lock rather than the class loader object lock.
// JDK < 7 already acquire the class loader lock in loadClass(String, boolean),
*** 1571,1612 ****
class_loader,
spec_klass,
vmSymbols::loadClassInternal_name(),
vmSymbols::string_class_signature(),
string,
! CHECK_(nh));
} else {
JavaCalls::call_virtual(&result,
class_loader,
spec_klass,
vmSymbols::loadClass_name(),
vmSymbols::string_class_signature(),
string,
! CHECK_(nh));
}
assert(result.get_type() == T_OBJECT, "just checking");
oop obj = (oop) result.get_jobject();
// Primitive classes return null since forName() can not be
// used to obtain any of the Class objects representing primitives or void
if ((obj != NULL) && !(java_lang_Class::is_primitive(obj))) {
! instanceKlassHandle k =
! instanceKlassHandle(THREAD, java_lang_Class::as_Klass(obj));
// For user defined Java class loaders, check that the name returned is
// the same as that requested. This check is done for the bootstrap
// loader when parsing the class file.
if (class_name == k->name()) {
return k;
}
}
// Class is not found or has the wrong name, return NULL
! return nh;
}
}
! void SystemDictionary::define_instance_class(instanceKlassHandle k, TRAPS) {
HandleMark hm(THREAD);
ClassLoaderData* loader_data = k->class_loader_data();
Handle class_loader_h(THREAD, loader_data->class_loader());
--- 1559,1599 ----
class_loader,
spec_klass,
vmSymbols::loadClassInternal_name(),
vmSymbols::string_class_signature(),
string,
! CHECK_NULL);
} else {
JavaCalls::call_virtual(&result,
class_loader,
spec_klass,
vmSymbols::loadClass_name(),
vmSymbols::string_class_signature(),
string,
! CHECK_NULL);
}
assert(result.get_type() == T_OBJECT, "just checking");
oop obj = (oop) result.get_jobject();
// Primitive classes return null since forName() can not be
// used to obtain any of the Class objects representing primitives or void
if ((obj != NULL) && !(java_lang_Class::is_primitive(obj))) {
! InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(obj));
// For user defined Java class loaders, check that the name returned is
// the same as that requested. This check is done for the bootstrap
// loader when parsing the class file.
if (class_name == k->name()) {
return k;
}
}
// Class is not found or has the wrong name, return NULL
! return NULL;
}
}
! void SystemDictionary::define_instance_class(InstanceKlass* k, TRAPS) {
HandleMark hm(THREAD);
ClassLoaderData* loader_data = k->class_loader_data();
Handle class_loader_h(THREAD, loader_data->class_loader());
*** 1667,1677 ****
k->eager_initialize(THREAD);
// notify jvmti
if (JvmtiExport::should_post_class_load()) {
assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
! JvmtiExport::post_class_load((JavaThread *) THREAD, k());
}
class_define_event(k, loader_data);
}
--- 1654,1664 ----
k->eager_initialize(THREAD);
// notify jvmti
if (JvmtiExport::should_post_class_load()) {
assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
! JvmtiExport::post_class_load((JavaThread *) THREAD, k);
}
class_define_event(k, loader_data);
}
*** 1693,1723 ****
// Note: VM callers should ensure consistency of k/class_name,class_loader
// Be careful when modifying this code: once you have run
// placeholders()->find_and_add(PlaceholderTable::DEFINE_CLASS),
// you need to find_and_remove it before returning.
// So be careful to not exit with a CHECK_ macro betweeen these calls.
! instanceKlassHandle SystemDictionary::find_or_define_instance_class(Symbol* class_name, Handle class_loader, instanceKlassHandle k, TRAPS) {
- instanceKlassHandle nh = instanceKlassHandle(); // null Handle
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))) {
! Klass* check = find_class(d_index, d_hash, name_h, loader_data);
if (check != NULL) {
! return(instanceKlassHandle(THREAD, check));
}
}
// Acquire define token for this class/classloader
probe = placeholders()->find_and_add(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, NULL, THREAD);
--- 1680,1710 ----
// Note: VM callers should ensure consistency of k/class_name,class_loader
// Be careful when modifying this code: once you have run
// placeholders()->find_and_add(PlaceholderTable::DEFINE_CLASS),
// you need to find_and_remove it before returning.
// So be careful to not exit with a CHECK_ macro betweeen these calls.
! 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;
}
}
// Acquire define token for this class/classloader
probe = placeholders()->find_and_add(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, NULL, THREAD);
*** 1733,1746 ****
// 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
! Klass* check = find_class(d_index, d_hash, name_h, loader_data);
assert(check != NULL, "definer missed recording success");
#endif
! return(instanceKlassHandle(THREAD, probe->instance_klass()));
} else {
// This thread will define the class (even if earlier thread tried and had an error)
probe->set_definer(THREAD);
}
}
--- 1720,1733 ----
// 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)
probe->set_definer(THREAD);
}
}
*** 1757,1777 ****
if (probe != NULL) {
if (HAS_PENDING_EXCEPTION) {
linkage_exception = Handle(THREAD,PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
} else {
! probe->set_instance_klass(k());
}
probe->set_definer(NULL);
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
SystemDictionary_lock->notify_all();
}
}
// Can't throw exception while holding lock due to rank ordering
if (linkage_exception() != NULL) {
! THROW_OOP_(linkage_exception(), nh); // throws exception and returns
}
return k;
}
Handle SystemDictionary::compute_loader_lock_object(Handle class_loader, TRAPS) {
--- 1744,1764 ----
if (probe != NULL) {
if (HAS_PENDING_EXCEPTION) {
linkage_exception = Handle(THREAD,PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
} else {
! probe->set_instance_klass(k);
}
probe->set_definer(NULL);
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
SystemDictionary_lock->notify_all();
}
}
// Can't throw exception while holding lock due to rank ordering
if (linkage_exception() != NULL) {
! THROW_OOP_(linkage_exception(), NULL); // throws exception and returns
}
return k;
}
Handle SystemDictionary::compute_loader_lock_object(Handle class_loader, TRAPS) {
*** 1807,1825 ****
}
// ----------------------------------------------------------------------------
// Lookup
! Klass* 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?");
! Klass* k = dictionary()->find_class(index, hash, class_name, loader_data);
! return k;
}
// Basic find on classes in the midst of being loaded
Symbol* SystemDictionary::find_placeholder(Symbol* class_name,
--- 1794,1811 ----
}
// ----------------------------------------------------------------------------
// 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,
*** 1830,1840 ****
return placeholders()->find_entry(p_index, p_hash, class_name, loader_data);
}
// Used for assertions and verification only
! Klass* SystemDictionary::find_class(Symbol* class_name, ClassLoaderData* loader_data) {
#ifndef ASSERT
guarantee(VerifyBeforeGC ||
VerifyDuringGC ||
VerifyBeforeExit ||
VerifyDuringStartup ||
--- 1816,1826 ----
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 ||
*** 1858,1869 ****
// ----------------------------------------------------------------------------
// Update hierachy. This is done before the new klass has been added to the SystemDictionary. The Recompile_lock
// is held, to ensure that the compiler is not using the class hierachy, and that deoptimization will kick in
// before a new class is used.
! void SystemDictionary::add_to_hierarchy(instanceKlassHandle k, TRAPS) {
! assert(k.not_null(), "just checking");
assert_locked_or_safepoint(Compile_lock);
// Link into hierachy. Make sure the vtables are initialized before linking into
k->append_to_sibling_list(); // add to superklass/sibling list
k->process_interfaces(THREAD); // handle all "implements" declarations
--- 1844,1855 ----
// ----------------------------------------------------------------------------
// Update hierachy. This is done before the new klass has been added to the SystemDictionary. The Recompile_lock
// is held, to ensure that the compiler is not using the class hierachy, and that deoptimization will kick in
// before a new class is used.
! void SystemDictionary::add_to_hierarchy(InstanceKlass* k, TRAPS) {
! assert(k != NULL, "just checking");
assert_locked_or_safepoint(Compile_lock);
// Link into hierachy. Make sure the vtables are initialized before linking into
k->append_to_sibling_list(); // add to superklass/sibling list
k->process_interfaces(THREAD); // handle all "implements" declarations
*** 2140,2151 ****
WKID scan = FIRST_WKID;
// first do Object, then String, Class
if (UseSharedSpaces) {
initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Object_klass), scan, CHECK);
// Initialize the constant pool for the Object_class
! InstanceKlass* ik = InstanceKlass::cast(Object_klass());
! ik->constants()->restore_unshareable_info(CHECK);
initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK);
} else {
initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK);
}
--- 2126,2136 ----
WKID scan = FIRST_WKID;
// first do Object, then String, Class
if (UseSharedSpaces) {
initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Object_klass), scan, CHECK);
// Initialize the constant pool for the Object_class
! Object_klass()->constants()->restore_unshareable_info(CHECK);
initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK);
} else {
initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK);
}
*** 2221,2251 ****
// must be satisfied by all classes in the dictionary.
// if defining is true, then LinkageError if already in systemDictionary
// if initiating loader, then ok if InstanceKlass matches existing entry
void SystemDictionary::check_constraints(int d_index, unsigned int d_hash,
! instanceKlassHandle k,
Handle class_loader, bool defining,
TRAPS) {
const char *linkage_error1 = NULL;
const char *linkage_error2 = NULL;
{
Symbol* name = k->name();
ClassLoaderData *loader_data = class_loader_data(class_loader);
MutexLocker mu(SystemDictionary_lock, THREAD);
! Klass* check = find_class(d_index, d_hash, name, loader_data);
! if (check != (Klass*)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
// also holds array classes
assert(check->is_instance_klass(), "noninstance in systemdictionary");
! if ((defining == true) || (k() != check)) {
linkage_error1 = "loader (instance of ";
linkage_error2 = "): attempted duplicate class definition for name: \"";
} else {
return;
}
--- 2206,2236 ----
// must be satisfied by all classes in the dictionary.
// if defining is true, then LinkageError if already in systemDictionary
// if initiating loader, then ok if InstanceKlass matches existing entry
void SystemDictionary::check_constraints(int d_index, unsigned int d_hash,
! InstanceKlass* k,
Handle class_loader, bool defining,
TRAPS) {
const char *linkage_error1 = NULL;
const char *linkage_error2 = NULL;
{
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
// also holds array classes
assert(check->is_instance_klass(), "noninstance in systemdictionary");
! if ((defining == true) || (k != check)) {
linkage_error1 = "loader (instance of ";
linkage_error2 = "): attempted duplicate class definition for name: \"";
} else {
return;
}
*** 2282,2292 ****
// Update system dictionary - done after check_constraint and add_to_hierachy
// have been called.
void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
int p_index, unsigned int p_hash,
! instanceKlassHandle k,
Handle class_loader,
TRAPS) {
// Compile_lock prevents systemDictionary updates during compilations
assert_locked_or_safepoint(Compile_lock);
Symbol* name = k->name();
--- 2267,2277 ----
// Update system dictionary - done after check_constraint and add_to_hierachy
// have been called.
void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
int p_index, unsigned int p_hash,
! InstanceKlass* k,
Handle class_loader,
TRAPS) {
// Compile_lock prevents systemDictionary updates during compilations
assert_locked_or_safepoint(Compile_lock);
Symbol* name = k->name();
*** 2314,2324 ****
k->set_prototype_header(markOopDesc::biased_locking_prototype());
}
}
// Make a new system dictionary entry.
! Klass* 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
--- 2299,2309 ----
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
*** 2405,2416 ****
MutexLocker mu_s(SystemDictionary_lock, THREAD);
// Better never do a GC while we're holding these oops
NoSafepointVerifier nosafepoint;
! Klass* klass1 = find_class(d_index1, d_hash1, constraint_name, loader_data1);
! Klass* klass2 = find_class(d_index2, d_hash2, constraint_name, loader_data2);
return constraints()->add_entry(constraint_name, klass1, class_loader1,
klass2, class_loader2);
}
}
--- 2390,2401 ----
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);
}
}
*** 2566,2576 ****
return spe->method();
}
// Helper for unpacking the return value from linkMethod and linkCallSite.
static methodHandle unpack_method_and_appendix(Handle mname,
! KlassHandle accessing_klass,
objArrayHandle appendix_box,
Handle* appendix_result,
TRAPS) {
methodHandle empty;
if (mname.not_null()) {
--- 2551,2561 ----
return spe->method();
}
// Helper for unpacking the return value from linkMethod and linkCallSite.
static methodHandle unpack_method_and_appendix(Handle mname,
! Klass* accessing_klass,
objArrayHandle appendix_box,
Handle* appendix_result,
TRAPS) {
methodHandle empty;
if (mname.not_null()) {
*** 2590,2612 ****
(*appendix_result) = Handle(THREAD, appendix);
// the target is stored in the cpCache and if a reference to this
// MethodName is dropped we need a way to make sure the
// class_loader containing this method is kept alive.
// FIXME: the appendix might also preserve this dependency.
! ClassLoaderData* this_key = InstanceKlass::cast(accessing_klass())->class_loader_data();
this_key->record_dependency(m->method_holder(), CHECK_NULL); // Can throw OOM
return methodHandle(THREAD, m);
}
}
THROW_MSG_(vmSymbols::java_lang_LinkageError(), "bad value from MethodHandleNatives", empty);
return empty;
}
! methodHandle SystemDictionary::find_method_handle_invoker(KlassHandle klass,
Symbol* name,
Symbol* signature,
! KlassHandle accessing_klass,
Handle *appendix_result,
Handle *method_type_result,
TRAPS) {
methodHandle empty;
assert(THREAD->can_call_java() ,"");
--- 2575,2597 ----
(*appendix_result) = Handle(THREAD, appendix);
// the target is stored in the cpCache and if a reference to this
// MethodName is dropped we need a way to make sure the
// class_loader containing this method is kept alive.
// FIXME: the appendix might also preserve this dependency.
! ClassLoaderData* this_key = accessing_klass->class_loader_data();
this_key->record_dependency(m->method_holder(), CHECK_NULL); // Can throw OOM
return methodHandle(THREAD, m);
}
}
THROW_MSG_(vmSymbols::java_lang_LinkageError(), "bad value from MethodHandleNatives", empty);
return empty;
}
! methodHandle SystemDictionary::find_method_handle_invoker(Klass* klass,
Symbol* name,
Symbol* signature,
! Klass* accessing_klass,
Handle *appendix_result,
Handle *method_type_result,
TRAPS) {
methodHandle empty;
assert(THREAD->can_call_java() ,"");
*** 2618,2636 ****
Handle name_str (THREAD, name_oop);
objArrayHandle appendix_box = oopFactory::new_objArray_handle(SystemDictionary::Object_klass(), 1, CHECK_(empty));
assert(appendix_box->obj_at(0) == NULL, "");
// This should not happen. JDK code should take care of that.
! if (accessing_klass.is_null() || method_type.is_null()) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad invokehandle", empty);
}
// call java.lang.invoke.MethodHandleNatives::linkMethod(... String, MethodType) -> MemberName
JavaCallArguments args;
! args.push_oop(Handle(THREAD, accessing_klass()->java_mirror()));
args.push_int(ref_kind);
! args.push_oop(Handle(THREAD, klass()->java_mirror()));
args.push_oop(name_str);
args.push_oop(method_type);
args.push_oop(appendix_box);
JavaValue result(T_OBJECT);
JavaCalls::call_static(&result,
--- 2603,2621 ----
Handle name_str (THREAD, name_oop);
objArrayHandle appendix_box = oopFactory::new_objArray_handle(SystemDictionary::Object_klass(), 1, CHECK_(empty));
assert(appendix_box->obj_at(0) == NULL, "");
// This should not happen. JDK code should take care of that.
! if (accessing_klass == NULL || method_type.is_null()) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad invokehandle", empty);
}
// call java.lang.invoke.MethodHandleNatives::linkMethod(... String, MethodType) -> MemberName
JavaCallArguments args;
! args.push_oop(Handle(THREAD, accessing_klass->java_mirror()));
args.push_int(ref_kind);
! args.push_oop(Handle(THREAD, klass->java_mirror()));
args.push_oop(name_str);
args.push_oop(method_type);
args.push_oop(appendix_box);
JavaValue result(T_OBJECT);
JavaCalls::call_static(&result,
*** 2665,2675 ****
// Ask Java code to find or construct a java.lang.invoke.MethodType for the given
// signature, as interpreted relative to the given class loader.
// Because of class loader constraints, all method handle usage must be
// consistent with this loader.
Handle SystemDictionary::find_method_handle_type(Symbol* signature,
! KlassHandle accessing_klass,
TRAPS) {
Handle empty;
vmIntrinsics::ID null_iid = vmIntrinsics::_none; // distinct from all method handle invoker intrinsics
unsigned int hash = invoke_method_table()->compute_hash(signature, null_iid);
int index = invoke_method_table()->hash_to_index(hash);
--- 2650,2660 ----
// Ask Java code to find or construct a java.lang.invoke.MethodType for the given
// signature, as interpreted relative to the given class loader.
// Because of class loader constraints, all method handle usage must be
// consistent with this loader.
Handle SystemDictionary::find_method_handle_type(Symbol* signature,
! Klass* accessing_klass,
TRAPS) {
Handle empty;
vmIntrinsics::ID null_iid = vmIntrinsics::_none; // distinct from all method handle invoker intrinsics
unsigned int hash = invoke_method_table()->compute_hash(signature, null_iid);
int index = invoke_method_table()->hash_to_index(hash);
*** 2681,2693 ****
warning("SystemDictionary::find_method_handle_type called from compiler thread"); // FIXME
return Handle(); // do not attempt from within compiler, unless it was cached
}
Handle class_loader, protection_domain;
! if (accessing_klass.not_null()) {
! class_loader = Handle(THREAD, InstanceKlass::cast(accessing_klass())->class_loader());
! protection_domain = Handle(THREAD, InstanceKlass::cast(accessing_klass())->protection_domain());
}
bool can_be_cached = true;
int npts = ArgumentCount(signature).size();
objArrayHandle pts = oopFactory::new_objArray_handle(SystemDictionary::Class_klass(), npts, CHECK_(empty));
int arg = 0;
--- 2666,2678 ----
warning("SystemDictionary::find_method_handle_type called from compiler thread"); // FIXME
return Handle(); // do not attempt from within compiler, unless it was cached
}
Handle class_loader, protection_domain;
! if (accessing_klass != NULL) {
! class_loader = Handle(THREAD, accessing_klass->class_loader());
! protection_domain = Handle(THREAD, accessing_klass->protection_domain());
}
bool can_be_cached = true;
int npts = ArgumentCount(signature).size();
objArrayHandle pts = oopFactory::new_objArray_handle(SystemDictionary::Class_klass(), npts, CHECK_(empty));
int arg = 0;
*** 2714,2732 ****
rt = Handle(THREAD, mirror);
else
pts->obj_at_put(arg++, mirror);
// Check accessibility.
! if (ss.is_object() && accessing_klass.not_null()) {
Klass* sel_klass = java_lang_Class::as_Klass(mirror);
mirror = NULL; // safety
// Emulate ConstantPool::verify_constant_pool_resolve.
if (sel_klass->is_objArray_klass())
sel_klass = ObjArrayKlass::cast(sel_klass)->bottom_klass();
if (sel_klass->is_instance_klass()) {
! KlassHandle sel_kh(THREAD, sel_klass);
! LinkResolver::check_klass_accessability(accessing_klass, sel_kh, CHECK_(empty));
}
}
}
assert(arg == npts, "");
--- 2699,2716 ----
rt = Handle(THREAD, mirror);
else
pts->obj_at_put(arg++, mirror);
// Check accessibility.
! if (ss.is_object() && accessing_klass != NULL) {
Klass* sel_klass = java_lang_Class::as_Klass(mirror);
mirror = NULL; // safety
// Emulate ConstantPool::verify_constant_pool_resolve.
if (sel_klass->is_objArray_klass())
sel_klass = ObjArrayKlass::cast(sel_klass)->bottom_klass();
if (sel_klass->is_instance_klass()) {
! LinkResolver::check_klass_accessability(accessing_klass, sel_klass, CHECK_(empty));
}
}
}
assert(arg == npts, "");
*** 2755,2776 ****
// report back to the caller with the MethodType
return method_type;
}
// Ask Java code to find or construct a method handle constant.
! Handle SystemDictionary::link_method_handle_constant(KlassHandle caller,
int ref_kind, //e.g., JVM_REF_invokeVirtual
! KlassHandle callee,
Symbol* name_sym,
Symbol* signature,
TRAPS) {
Handle empty;
Handle name = java_lang_String::create_from_symbol(name_sym, CHECK_(empty));
Handle type;
if (signature->utf8_length() > 0 && signature->byte_at(0) == '(') {
type = find_method_handle_type(signature, caller, CHECK_(empty));
! } else if (caller.is_null()) {
// This should not happen. JDK code should take care of that.
THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad MH constant", empty);
} else {
ResourceMark rm(THREAD);
SignatureStream ss(signature, false);
--- 2739,2760 ----
// report back to the caller with the MethodType
return method_type;
}
// Ask Java code to find or construct a method handle constant.
! Handle SystemDictionary::link_method_handle_constant(Klass* caller,
int ref_kind, //e.g., JVM_REF_invokeVirtual
! Klass* callee,
Symbol* name_sym,
Symbol* signature,
TRAPS) {
Handle empty;
Handle name = java_lang_String::create_from_symbol(name_sym, CHECK_(empty));
Handle type;
if (signature->utf8_length() > 0 && signature->byte_at(0) == '(') {
type = find_method_handle_type(signature, caller, CHECK_(empty));
! } else if (caller == NULL) {
// This should not happen. JDK code should take care of that.
THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad MH constant", empty);
} else {
ResourceMark rm(THREAD);
SignatureStream ss(signature, false);
*** 2803,2813 ****
return Handle(THREAD, (oop) result.get_jobject());
}
// Ask Java code to find or construct a java.lang.invoke.CallSite for the given
// name and signature, as interpreted relative to the given class loader.
! methodHandle SystemDictionary::find_dynamic_call_site_invoker(KlassHandle caller,
Handle bootstrap_specifier,
Symbol* name,
Symbol* type,
Handle *appendix_result,
Handle *method_type_result,
--- 2787,2797 ----
return Handle(THREAD, (oop) result.get_jobject());
}
// Ask Java code to find or construct a java.lang.invoke.CallSite for the given
// name and signature, as interpreted relative to the given class loader.
! methodHandle SystemDictionary::find_dynamic_call_site_invoker(Klass* caller,
Handle bootstrap_specifier,
Symbol* name,
Symbol* type,
Handle *appendix_result,
Handle *method_type_result,
*** 2834,2844 ****
Handle method_name = java_lang_String::create_from_symbol(name, CHECK_(empty));
Handle method_type = find_method_handle_type(type, caller, CHECK_(empty));
// This should not happen. JDK code should take care of that.
! if (caller.is_null() || method_type.is_null()) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad invokedynamic", empty);
}
objArrayHandle appendix_box = oopFactory::new_objArray_handle(SystemDictionary::Object_klass(), 1, CHECK_(empty));
assert(appendix_box->obj_at(0) == NULL, "");
--- 2818,2828 ----
Handle method_name = java_lang_String::create_from_symbol(name, CHECK_(empty));
Handle method_type = find_method_handle_type(type, caller, CHECK_(empty));
// This should not happen. JDK code should take care of that.
! if (caller == NULL || method_type.is_null()) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad invokedynamic", empty);
}
objArrayHandle appendix_box = oopFactory::new_objArray_handle(SystemDictionary::Object_klass(), 1, CHECK_(empty));
assert(appendix_box->obj_at(0) == NULL, "");
< prev index next >