< prev index next >

src/hotspot/share/classfile/systemDictionary.cpp

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 104,114 **** InstanceKlass* SystemDictionary::_box_klasses[T_VOID+1] = { NULL /*, NULL...*/ }; oop SystemDictionary::_java_system_loader = NULL; oop SystemDictionary::_java_platform_loader = NULL; - bool SystemDictionary::_has_loadClassInternal = false; bool SystemDictionary::_has_checkPackageAccess = false; // lazily initialized klass variables InstanceKlass* volatile SystemDictionary::_abstract_ownable_synchronizer_klass = NULL; --- 104,113 ----
*** 157,167 **** // ---------------------------------------------------------------------------- // Parallel class loading check bool SystemDictionary::is_parallelCapable(Handle class_loader) { ! if (UnsyncloadClass || class_loader.is_null()) return true; if (AlwaysLockClassLoader) return false; return java_lang_ClassLoader::parallelCapable(class_loader()); } // ---------------------------------------------------------------------------- // ParallelDefineClass flag does not apply to bootclass loader --- 156,166 ---- // ---------------------------------------------------------------------------- // Parallel class loading check bool SystemDictionary::is_parallelCapable(Handle class_loader) { ! if (class_loader.is_null()) return true; if (AlwaysLockClassLoader) return false; return java_lang_ClassLoader::parallelCapable(class_loader()); } // ---------------------------------------------------------------------------- // ParallelDefineClass flag does not apply to bootclass loader
*** 501,512 **** // Waits on SystemDictionary_lock to indicate placeholder table updated // On return, caller must recheck placeholder table state // // We only get here if // 1) custom classLoader, i.e. not bootstrap classloader ! // 2) UnsyncloadClass not set ! // 3) custom classLoader has broken the class loader objectLock // so another thread got here in parallel // // lockObject must be held. // Complicated dance due to lock ordering: // Must first release the classloader object lock to --- 500,510 ---- // Waits on SystemDictionary_lock to indicate placeholder table updated // On return, caller must recheck placeholder table state // // We only get here if // 1) custom classLoader, i.e. not bootstrap classloader ! // 2) custom classLoader has broken the class loader objectLock // so another thread got here in parallel // // lockObject must be held. // Complicated dance due to lock ordering: // Must first release the classloader object lock to
*** 592,602 **** // 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 // classloader lock when another thread was in the middle of loading a // superclass/superinterface for this class, and now // this thread is also trying to load this class. // To minimize surprises, the first thread that started to --- 590,599 ----
*** 685,697 **** // define via jvm/jni_DefineClass which will acquire the // class loader object lock to protect against multiple threads // defining the class in parallel by accident. // This lock must be acquired here so the waiter will find // any successful result in the SystemDictionary and not attempt ! // the define ! // ParallelCapable Classloaders and the bootstrap classloader, ! // or all classloaders with UnsyncloadClass do not acquire lock here bool DoObjectLock = true; if (is_parallelCapable(class_loader)) { DoObjectLock = false; } --- 682,694 ---- // define via jvm/jni_DefineClass which will acquire the // class loader object lock to protect against multiple threads // defining the class in parallel by accident. // This lock must be acquired here so the waiter will find // any successful result in the SystemDictionary and not attempt ! // the define. ! // ParallelCapable Classloaders and the bootstrap classloader ! // do not acquire lock here. bool DoObjectLock = true; if (is_parallelCapable(class_loader)) { DoObjectLock = false; }
*** 763,780 **** // as a deadlock workaround. Detection of this case requires that // this check is done while holding the classloader object lock, // and that lock is still held when calling classloader's loadClass. // For these classloaders, we ensure that the first requestor // completes the load and other requestors wait for completion. ! // case 3. UnsyncloadClass - don't use objectLocker ! // With this flag, we allow parallel classloading of a ! // class/classloader pair ! // case4. Bootstrap classloader - don't own objectLocker // This classloader supports parallelism at the classloader level, // but only allows a single load of a class/classloader pair. // No performance benefit and no deadlock issues. ! // case 5. parallelCapable user level classloaders - without objectLocker // Allow parallel classloading of a class/classloader pair { MutexLocker mu(SystemDictionary_lock, THREAD); if (class_loader.is_null() || !is_parallelCapable(class_loader)) { --- 760,774 ---- // as a deadlock workaround. Detection of this case requires that // this check is done while holding the classloader object lock, // and that lock is still held when calling classloader's loadClass. // For these classloaders, we ensure that the first requestor // completes the load and other requestors wait for completion. ! // case 3. Bootstrap classloader - don't own objectLocker // This classloader supports parallelism at the classloader level, // but only allows a single load of a class/classloader pair. // No performance benefit and no deadlock issues. ! // case 4. parallelCapable user level classloaders - without objectLocker // Allow parallel classloading of a class/classloader pair { MutexLocker mu(SystemDictionary_lock, THREAD); if (class_loader.is_null() || !is_parallelCapable(class_loader)) {
*** 786,796 **** throw_circularity_error = true; } else { // case 1: traditional: should never see load_in_progress. while (!class_has_been_loaded && oldprobe && oldprobe->instance_load_in_progress()) { ! // case 4: bootstrap classloader: prevent futile classloading, // wait on first requestor if (class_loader.is_null()) { SystemDictionary_lock->wait(); } else { // case 2: traditional with broken classloader lock. wait on first --- 780,790 ---- throw_circularity_error = true; } else { // case 1: traditional: should never see load_in_progress. while (!class_has_been_loaded && oldprobe && oldprobe->instance_load_in_progress()) { ! // case 3: bootstrap classloader: prevent futile classloading, // wait on first requestor if (class_loader.is_null()) { SystemDictionary_lock->wait(); } else { // case 2: traditional with broken classloader lock. wait on first
*** 809,819 **** } } } } // All cases: add LOAD_INSTANCE holding SystemDictionary_lock ! // case 3: UnsyncloadClass || case 5: parallelCapable: allow competing threads to try // LOAD_INSTANCE in parallel if (!throw_circularity_error && !class_has_been_loaded) { PlaceholderEntry* newprobe = placeholders()->find_and_add(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, NULL, THREAD); load_instance_added = true; --- 803,813 ---- } } } } // All cases: add LOAD_INSTANCE holding SystemDictionary_lock ! // case 4: parallelCapable: allow competing threads to try // LOAD_INSTANCE in parallel if (!throw_circularity_error && !class_has_been_loaded) { PlaceholderEntry* newprobe = placeholders()->find_and_add(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, NULL, THREAD); load_instance_added = true;
*** 842,873 **** if (!class_has_been_loaded) { // Do actual loading k = load_instance_class(name, class_loader, THREAD); - // For UnsyncloadClass only - // If they got a linkageError, check if a parallel class load succeeded. - // If it did, then for bytecode resolution the specification requires - // that we return the same result we did for the other thread, i.e. the - // 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_hash, name, dictionary); - if (check != NULL) { - // Klass is already loaded, so just use it - k = check; - CLEAR_PENDING_EXCEPTION; - guarantee((!class_loader.is_null()), "dup definition for bootstrap loader?"); - } - } - } - // 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()) { --- 836,845 ----
*** 1095,1105 **** #endif HandleMark hm(THREAD); // Classloaders that support parallelism, e.g. bootstrap classloader, ! // or all classloaders with UnsyncloadClass do not acquire lock here bool DoObjectLock = true; if (is_parallelCapable(class_loader)) { DoObjectLock = false; } --- 1067,1077 ---- #endif HandleMark hm(THREAD); // Classloaders that support parallelism, e.g. bootstrap classloader, ! // do not acquire lock here bool DoObjectLock = true; if (is_parallelCapable(class_loader)) { DoObjectLock = false; }
*** 1554,1597 **** 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), ! // so the call to loadClassInternal() was not required. ! // ! // UnsyncloadClass flag means both call loadClass(String) and do ! // not acquire the class loader lock even for class loaders that are ! // not parallelCapable. This was a risky transitional ! // flag for diagnostic purposes only. It is risky to call ! // custom class loaders without synchronization. ! // WARNING If a custom class loader does NOT synchronizer findClass, or callers of ! // findClass, the UnsyncloadClass flag risks unexpected timing bugs in the field. ! // Do NOT assume this will be supported in future releases. ! // ! // Added MustCallLoadClassInternal in case we discover in the field ! // a customer that counts on this call ! if (MustCallLoadClassInternal && has_loadClassInternal()) { ! JavaCalls::call_special(&result, ! 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 --- 1526,1546 ---- 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). 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
*** 1716,1726 **** PlaceholderEntry* probe; { MutexLocker mu(SystemDictionary_lock, THREAD); // First check if class already defined ! if (UnsyncloadClass || (is_parallelDefine(class_loader))) { InstanceKlass* check = find_class(d_hash, name_h, dictionary); if (check != NULL) { return check; } } --- 1665,1675 ---- PlaceholderEntry* probe; { MutexLocker mu(SystemDictionary_lock, THREAD); // First check if class already defined ! if (is_parallelDefine(class_loader)) { InstanceKlass* check = find_class(d_hash, name_h, dictionary); if (check != NULL) { return check; } }
*** 1735,1745 **** SystemDictionary_lock->wait(); } // Only special cases allow parallel defines and can use other thread's results // Other cases fall through, and may run into duplicate defines // 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_hash, name_h, dictionary); assert(check != NULL, "definer missed recording success"); --- 1684,1694 ---- SystemDictionary_lock->wait(); } // Only special cases allow parallel defines and can use other thread's results // Other cases fall through, and may run into duplicate defines // caught by finding an entry in the SystemDictionary ! if (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_hash, name_h, dictionary); assert(check != NULL, "definer missed recording success");
*** 2172,2185 **** _box_klasses[T_INT] = WK_KLASS(Integer_klass); _box_klasses[T_LONG] = WK_KLASS(Long_klass); //_box_klasses[T_OBJECT] = WK_KLASS(object_klass); //_box_klasses[T_ARRAY] = WK_KLASS(object_klass); - { // Compute whether we should use loadClass or loadClassInternal when loading classes. - Method* method = InstanceKlass::cast(ClassLoader_klass())->find_method(vmSymbols::loadClassInternal_name(), vmSymbols::string_class_signature()); - _has_loadClassInternal = (method != NULL); - } { // Compute whether we should use checkPackageAccess or NOT Method* method = InstanceKlass::cast(ClassLoader_klass())->find_method(vmSymbols::checkPackageAccess_name(), vmSymbols::class_protectiondomain_signature()); _has_checkPackageAccess = (method != NULL); } } --- 2121,2130 ----
< prev index next >