--- old/src/hotspot/share/classfile/systemDictionary.cpp 2018-02-12 15:25:31.952390794 -0500 +++ new/src/hotspot/share/classfile/systemDictionary.cpp 2018-02-12 15:25:31.398400465 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -106,7 +106,6 @@ 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 @@ -159,7 +158,7 @@ // Parallel class loading check bool SystemDictionary::is_parallelCapable(Handle class_loader) { - if (UnsyncloadClass || class_loader.is_null()) return true; + if (class_loader.is_null()) return true; if (AlwaysLockClassLoader) return false; return java_lang_ClassLoader::parallelCapable(class_loader()); } @@ -503,8 +502,7 @@ // // 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 +// 2) custom classLoader has broken the class loader objectLock // so another thread got here in parallel // // lockObject must be held. @@ -594,7 +592,6 @@ } 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 @@ -687,9 +684,9 @@ // 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 + // the define. + // ParallelCapable Classloaders and the bootstrap classloader + // do not acquire lock here. bool DoObjectLock = true; if (is_parallelCapable(class_loader)) { DoObjectLock = false; @@ -765,14 +762,11 @@ // 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 + // 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 5. parallelCapable user level classloaders - without objectLocker + // case 4. parallelCapable user level classloaders - without objectLocker // Allow parallel classloading of a class/classloader pair { @@ -788,7 +782,7 @@ // 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, + // case 3: bootstrap classloader: prevent futile classloading, // wait on first requestor if (class_loader.is_null()) { SystemDictionary_lock->wait(); @@ -811,7 +805,7 @@ } } // All cases: add LOAD_INSTANCE holding SystemDictionary_lock - // case 3: UnsyncloadClass || case 5: parallelCapable: allow competing threads to try + // case 4: parallelCapable: allow competing threads to try // LOAD_INSTANCE in parallel if (!throw_circularity_error && !class_has_been_loaded) { @@ -844,28 +838,6 @@ // 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 && @@ -1097,7 +1069,7 @@ HandleMark hm(THREAD); // Classloaders that support parallelism, e.g. bootstrap classloader, - // or all classloaders with UnsyncloadClass do not acquire lock here + // do not acquire lock here bool DoObjectLock = true; if (is_parallelCapable(class_loader)) { DoObjectLock = false; @@ -1556,40 +1528,17 @@ 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 + // 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); - } + // 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(); @@ -1718,7 +1667,7 @@ { MutexLocker mu(SystemDictionary_lock, THREAD); // First check if class already defined - if (UnsyncloadClass || (is_parallelDefine(class_loader))) { + if (is_parallelDefine(class_loader)) { InstanceKlass* check = find_class(d_hash, name_h, dictionary); if (check != NULL) { return check; @@ -1737,7 +1686,7 @@ // 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)) { + 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 @@ -2174,10 +2123,6 @@ //_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);