< 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 >