From 699a3cde74eac74fb54b2ade94d437c010449f89 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Tue, 9 Feb 2021 22:20:43 +0000 Subject: [PATCH 001/367] 8223188: Removed unnecessary #ifdef __cplusplus from .cpp sources Reviewed-by: herrick, almatvee, iklam --- .../windows/native/libjpackage/WindowsRegistry.cpp | 8 +++----- src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp | 6 +----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/jdk.jpackage/windows/native/libjpackage/WindowsRegistry.cpp b/src/jdk.jpackage/windows/native/libjpackage/WindowsRegistry.cpp index 3ecefb1adca..931cec8f5c6 100644 --- a/src/jdk.jpackage/windows/native/libjpackage/WindowsRegistry.cpp +++ b/src/jdk.jpackage/windows/native/libjpackage/WindowsRegistry.cpp @@ -68,9 +68,9 @@ std::wstring GetLongPath(const std::wstring& path) { } // namespace -#ifdef __cplusplus + extern "C" { -#endif + #undef jdk_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE #define jdk_jpackage_internal_WindowsRegistry_HKEY_LOCAL_MACHINE 1L @@ -216,6 +216,4 @@ extern "C" { return JNI_FALSE; } -#ifdef __cplusplus -} -#endif +} // extern "C" diff --git a/src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp b/src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp index 69a8e098d8e..b6dcb53b525 100644 --- a/src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp +++ b/src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp @@ -30,9 +30,7 @@ #include "JniUtils.h" #include "MsiDb.h" -#ifdef __cplusplus extern "C" { -#endif /* * Class: jdk_jpackage_internal_ExecutableRebrander @@ -159,6 +157,4 @@ extern "C" { return 1; } -#ifdef __cplusplus -} -#endif +} // extern "C" \ No newline at end of file -- GitLab From 4619f372ae5934091b0d40621a1dbcd9e4b0f80c Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 10 Feb 2021 01:59:41 +0000 Subject: [PATCH 002/367] 8261472: BasicConstraintsExtension::toString shows "PathLen:2147483647" if there is no pathLenConstraint Reviewed-by: jnimeh --- .../security/x509/BasicConstraintsExtension.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/sun/security/x509/BasicConstraintsExtension.java b/src/java.base/share/classes/sun/security/x509/BasicConstraintsExtension.java index 65e62ec25c0..38abaf7cb39 100644 --- a/src/java.base/share/classes/sun/security/x509/BasicConstraintsExtension.java +++ b/src/java.base/share/classes/sun/security/x509/BasicConstraintsExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, 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 @@ -171,10 +171,17 @@ implements CertAttrSet { * Return user readable form of extension. */ public String toString() { + String pathLenAsString; + if (pathLen < 0) { + pathLenAsString = " undefined"; + } else if (pathLen == Integer.MAX_VALUE) { + pathLenAsString = " no limit"; + } else { + pathLenAsString = String.valueOf(pathLen); + } return super.toString() + "BasicConstraints:[\n CA:" + ca + - "\n PathLen:" + - ((pathLen >= 0) ? String.valueOf(pathLen) : " undefined") + + "\n PathLen:" + pathLenAsString + "\n]\n"; } -- GitLab From 3af334a5c7ef8528ae67aea01f79905ecd71e964 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Wed, 10 Feb 2021 07:22:44 +0000 Subject: [PATCH 003/367] 6211257: BasicStroke.createStrokedShape(Shape): NPE is not specified Reviewed-by: serb, prr, aivanov --- .../share/classes/java/awt/BasicStroke.java | 1 + .../java/awt/BasicStroke/TestNullShape.java | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 test/jdk/java/awt/BasicStroke/TestNullShape.java diff --git a/src/java.desktop/share/classes/java/awt/BasicStroke.java b/src/java.desktop/share/classes/java/awt/BasicStroke.java index e74753265e3..cd68105186e 100644 --- a/src/java.desktop/share/classes/java/awt/BasicStroke.java +++ b/src/java.desktop/share/classes/java/awt/BasicStroke.java @@ -294,6 +294,7 @@ public class BasicStroke implements Stroke { * stroked outline of a specified {@code Shape}. * @param s the {@code Shape} boundary be stroked * @return the {@code Shape} of the stroked outline. + * @throws NullPointerException if {@code s} is {@code null} */ public Shape createStrokedShape(Shape s) { sun.java2d.pipe.RenderingEngine re = diff --git a/test/jdk/java/awt/BasicStroke/TestNullShape.java b/test/jdk/java/awt/BasicStroke/TestNullShape.java new file mode 100644 index 00000000000..219282d137f --- /dev/null +++ b/test/jdk/java/awt/BasicStroke/TestNullShape.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/** + * @test + * @bug 6211257 + * @summary Verifies NPE is thrown for BasicStroke.createStrokedShape(null). + */ +import java.awt.BasicStroke; +import java.awt.Shape; + +public class TestNullShape { + + public static void main(String[] args) { + + BasicStroke bs = new BasicStroke(); + try { + Shape s = bs.createStrokedShape(null); + System.out.println("result: false"); + throw new RuntimeException("NPE is expected"); + } catch (NullPointerException ne) { + System.out.println("result (npe): true"); + } + } +} -- GitLab From 752f92bc101f191d61cee3ba463f4e75ada0e7c3 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Wed, 10 Feb 2021 07:24:29 +0000 Subject: [PATCH 004/367] 6211242: AreaAveragingScaleFilter(int, int): IAE is not specified Reviewed-by: azvegint, trebari, serb --- .../awt/image/AreaAveragingScaleFilter.java | 2 + test/jdk/java/awt/image/TestNullAASF.java | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 test/jdk/java/awt/image/TestNullAASF.java diff --git a/src/java.desktop/share/classes/java/awt/image/AreaAveragingScaleFilter.java b/src/java.desktop/share/classes/java/awt/image/AreaAveragingScaleFilter.java index a8e09a7435c..decfeb33622 100644 --- a/src/java.desktop/share/classes/java/awt/image/AreaAveragingScaleFilter.java +++ b/src/java.desktop/share/classes/java/awt/image/AreaAveragingScaleFilter.java @@ -72,6 +72,8 @@ public class AreaAveragingScaleFilter extends ReplicateScaleFilter { * its source Image as specified by the width and height parameters. * @param width the target width to scale the image * @param height the target height to scale the image + * @throws IllegalArgumentException if {@code width} equals + * zero or {@code height} equals zero */ public AreaAveragingScaleFilter(int width, int height) { super(width, height); diff --git a/test/jdk/java/awt/image/TestNullAASF.java b/test/jdk/java/awt/image/TestNullAASF.java new file mode 100644 index 00000000000..c93b799ca00 --- /dev/null +++ b/test/jdk/java/awt/image/TestNullAASF.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/** + * @test + * @bug 6211242 + * @summary Verifies IAE is thrown if 0 is passed to + * AreaAveragingScaleFilter(width,height) constructor. + */ +import java.awt.image.AreaAveragingScaleFilter; + +public class TestNullAASF { + public static void main(String[] args) { + AreaAveragingScaleFilter filter = null; + try { + filter = new AreaAveragingScaleFilter(0, Integer.MAX_VALUE); + System.out.println("result: false"); + throw new RuntimeException("IAE expected for width=0"); + } catch (IllegalArgumentException e) { + System.out.println("result (iae): true"); + } + try { + filter = new AreaAveragingScaleFilter(Integer.MAX_VALUE, 0); + System.out.println("result: false"); + throw new RuntimeException("IAE expected for height=0"); + } catch (IllegalArgumentException e) { + System.out.println("result (iae): true"); + } + } +} -- GitLab From ad54d8dd832b22485d7ac45958cc4c9bfd70fbd2 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 10 Feb 2021 07:32:53 +0000 Subject: [PATCH 005/367] 8260934: java/lang/StringBuilder/HugeCapacity.java fails without Compact Strings Reviewed-by: iklam --- .../java/lang/StringBuilder/HugeCapacity.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/test/jdk/java/lang/StringBuilder/HugeCapacity.java b/test/jdk/java/lang/StringBuilder/HugeCapacity.java index 7da3e368e23..9f1617a9dd2 100644 --- a/test/jdk/java/lang/StringBuilder/HugeCapacity.java +++ b/test/jdk/java/lang/StringBuilder/HugeCapacity.java @@ -27,14 +27,20 @@ * @summary Capacity should not get close to Integer.MAX_VALUE unless * necessary * @requires (sun.arch.data.model == "64" & os.maxMemory >= 6G) - * @run main/othervm -Xms5G -Xmx5G HugeCapacity + * @run main/othervm -Xms5G -Xmx5G -XX:+CompactStrings HugeCapacity true + * @run main/othervm -Xms5G -Xmx5G -XX:-CompactStrings HugeCapacity false */ public class HugeCapacity { private static int failures = 0; public static void main(String[] args) { - testLatin1(); + if (args.length == 0) { + throw new IllegalArgumentException("Need the argument"); + } + boolean isCompact = Boolean.parseBoolean(args[0]); + + testLatin1(isCompact); testUtf16(); testHugeInitialString(); testHugeInitialCharSequence(); @@ -43,11 +49,12 @@ public class HugeCapacity { } } - private static void testLatin1() { + private static void testLatin1(boolean isCompact) { try { + int divisor = isCompact ? 2 : 4; StringBuilder sb = new StringBuilder(); - sb.ensureCapacity(Integer.MAX_VALUE / 2); - sb.ensureCapacity(Integer.MAX_VALUE / 2 + 1); + sb.ensureCapacity(Integer.MAX_VALUE / divisor); + sb.ensureCapacity(Integer.MAX_VALUE / divisor + 1); } catch (OutOfMemoryError oom) { oom.printStackTrace(); failures++; -- GitLab From a3d6e37153d09b3198c983bd7b689dca570386dc Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Wed, 10 Feb 2021 07:46:17 +0000 Subject: [PATCH 006/367] 8261302: NMT: Improve malloc site table hashing Reviewed-by: zgu, lucy --- .../share/utilities/nativeCallStack.cpp | 28 ++++++++----------- .../share/utilities/nativeCallStack.hpp | 5 ++-- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/hotspot/share/utilities/nativeCallStack.cpp b/src/hotspot/share/utilities/nativeCallStack.cpp index 45a29424fd7..b03d3dfcf46 100644 --- a/src/hotspot/share/utilities/nativeCallStack.cpp +++ b/src/hotspot/share/utilities/nativeCallStack.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, 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 @@ -28,6 +28,14 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/nativeCallStack.hpp" +static unsigned int calculate_hash(address stack[NMT_TrackingStackDepth]) { + uintptr_t hash = 0; + for (int i = 0; i < NMT_TrackingStackDepth; i++) { + hash += (uintptr_t)stack[i]; + } + return hash; +} + NativeCallStack::NativeCallStack(int toSkip, bool fillStack) : _hash_value(0) { @@ -51,6 +59,7 @@ NativeCallStack::NativeCallStack(int toSkip, bool fillStack) : _stack[index] = NULL; } } + _hash_value = calculate_hash(_stack); } NativeCallStack::NativeCallStack(address* pc, int frameCount) { @@ -63,7 +72,7 @@ NativeCallStack::NativeCallStack(address* pc, int frameCount) { for (; index < NMT_TrackingStackDepth; index ++) { _stack[index] = NULL; } - _hash_value = 0; + _hash_value = calculate_hash(_stack); } // number of stack frames captured @@ -77,21 +86,6 @@ int NativeCallStack::frames() const { return index; } -// Hash code. Any better algorithm? -unsigned int NativeCallStack::hash() const { - uintptr_t hash_val = _hash_value; - if (hash_val == 0) { - for (int index = 0; index < NMT_TrackingStackDepth; index++) { - if (_stack[index] == NULL) break; - hash_val += (uintptr_t)_stack[index]; - } - - NativeCallStack* p = const_cast(this); - p->_hash_value = (unsigned int)(hash_val & 0xFFFFFFFF); - } - return _hash_value; -} - void NativeCallStack::print_on(outputStream* out) const { print_on(out, 0); } diff --git a/src/hotspot/share/utilities/nativeCallStack.hpp b/src/hotspot/share/utilities/nativeCallStack.hpp index 724bba8ed35..090b0530a56 100644 --- a/src/hotspot/share/utilities/nativeCallStack.hpp +++ b/src/hotspot/share/utilities/nativeCallStack.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, 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 @@ -91,8 +91,7 @@ public: return _stack[index]; } - // Hash code. Any better algorithm? - unsigned int hash() const; + unsigned int hash() const { return _hash_value; } void print_on(outputStream* out) const; void print_on(outputStream* out, int indent) const; -- GitLab From 52fc01b3ee4ddefd3be3e541a2c53c818d9292c7 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 10 Feb 2021 12:33:47 +0000 Subject: [PATCH 007/367] 8261268: LOAD_INSTANCE placeholders unneeded for parallelCapable class loaders Reviewed-by: dholmes, iklam --- src/hotspot/share/classfile/placeholders.cpp | 5 +- src/hotspot/share/classfile/placeholders.hpp | 4 +- .../share/classfile/systemDictionary.cpp | 113 +++++++----------- 3 files changed, 49 insertions(+), 73 deletions(-) diff --git a/src/hotspot/share/classfile/placeholders.cpp b/src/hotspot/share/classfile/placeholders.cpp index 4f2b8d60b60..551b26e3099 100644 --- a/src/hotspot/share/classfile/placeholders.cpp +++ b/src/hotspot/share/classfile/placeholders.cpp @@ -104,7 +104,7 @@ void PlaceholderEntry::set_threadQ(SeenThread* seenthread, PlaceholderTable::cla // Doubly-linked list of Threads per action for class/classloader pair // Class circularity support: links in thread before loading superclass -// bootstrapsearchpath support: links in a thread before load_instance_class +// bootstrap loader support: links in a thread before load_instance_class // definers: use as queue of define requestors, including owner of // define token. Appends for debugging of requestor order void PlaceholderEntry::add_seen_thread(Thread* thread, PlaceholderTable::classloadAction action) { @@ -112,6 +112,9 @@ void PlaceholderEntry::add_seen_thread(Thread* thread, PlaceholderTable::classlo SeenThread* threadEntry = new SeenThread(thread); SeenThread* seen = actionToQueue(action); + assert(action != PlaceholderTable::LOAD_INSTANCE || seen == NULL, + "Only one LOAD_INSTANCE allowed at a time"); + if (seen == NULL) { set_threadQ(threadEntry, action); return; diff --git a/src/hotspot/share/classfile/placeholders.hpp b/src/hotspot/share/classfile/placeholders.hpp index abb0dc18ffa..d85ac9adfdc 100644 --- a/src/hotspot/share/classfile/placeholders.hpp +++ b/src/hotspot/share/classfile/placeholders.hpp @@ -120,8 +120,8 @@ class PlaceholderEntry : public HashtableEntry { InstanceKlass* _instanceKlass; // InstanceKlass from successful define SeenThread* _superThreadQ; // doubly-linked queue of Threads loading a superclass for this class SeenThread* _loadInstanceThreadQ; // loadInstance thread - // can be multiple threads if classloader object lock broken by application - // or if classloader supports parallel classloading + // This can't be multiple threads since class loading waits for + // this token to be removed. SeenThread* _defineThreadQ; // queue of Threads trying to define this class // including _definer diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index 2ede5d1aacb..27e559d9523 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -570,12 +570,9 @@ void SystemDictionary::double_lock_wait(Thread* thread, Handle lockObject) { // super class loading here. // This also is critical in cases where the original thread gets stalled // even in non-circularity situations. -// Note: must call resolve_super_or_fail even if null super - -// 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 +// and we are done. If this returns a 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) { @@ -584,14 +581,7 @@ InstanceKlass* SystemDictionary::handle_parallel_super_load( Dictionary* dictionary = loader_data->dictionary(); unsigned int name_hash = dictionary->compute_hash(name); - // superk is not used, resolve_super called for circularity check only - // This code is reached in two situations. One if this thread - // is loading the same class twice (e.g. ClassCircularity, or - // java.lang.instrument). - // The second is if another thread started the resolve_super first - // and has not yet finished. - // In both cases the original caller will clean up the placeholder - // entry on error. + // superk is not used; resolve_super_or_fail is called for circularity check only. Klass* superk = SystemDictionary::resolve_super_or_fail(name, superclassname, class_loader, @@ -603,7 +593,6 @@ InstanceKlass* SystemDictionary::handle_parallel_super_load( // Serial class loaders and bootstrap classloader do wait for superclass loads if (!class_loader.is_null() && is_parallelCapable(class_loader)) { MutexLocker mu(THREAD, SystemDictionary_lock); - // Check if classloading completed while we were loading superclass or waiting return dictionary->find_class(name_hash, name); } @@ -759,10 +748,8 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, // but only allows a single thread to load a class/classloader pair. // The LOAD_INSTANCE placeholder is the mechanism for mutual exclusion. // case 2. parallelCapable user level classloaders - // These class loaders don't lock the object until load_instance_class is - // called after this placeholder is added. - // Allow parallel classloading of a class/classloader pair where mutual - // exclusion is provided by this lock in the class loader Java code. + // These class loaders lock a per-class object lock when ClassLoader.loadClass() + // is called. A LOAD_INSTANCE placeholder isn't used for mutual exclusion. // case 3. traditional classloaders that rely on the classloader object lock // There should be no need for need for LOAD_INSTANCE, except: // case 4. traditional class loaders that break the classloader object lock @@ -771,65 +758,64 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, // 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. - { + if (class_loader.is_null() || !is_parallelCapable(class_loader)) { MutexLocker mu(THREAD, SystemDictionary_lock); - if (class_loader.is_null() || !is_parallelCapable(class_loader)) { - PlaceholderEntry* oldprobe = placeholders()->get_entry(name_hash, name, loader_data); - if (oldprobe != NULL) { - // only need check_seen_thread once, not on each loop - // 6341374 java/lang/Instrument with -Xcomp - if (oldprobe->check_seen_thread(THREAD, PlaceholderTable::LOAD_INSTANCE)) { - throw_circularity_error = true; - } else { - // case 3: traditional: should never see load_in_progress. - while (!class_has_been_loaded && oldprobe != NULL && oldprobe->instance_load_in_progress()) { - - // case 1: bootstrap classloader: prevent futile classloading, - // wait on first requestor - if (class_loader.is_null()) { - SystemDictionary_lock->wait(); - } else { + PlaceholderEntry* oldprobe = placeholders()->get_entry(name_hash, name, loader_data); + if (oldprobe != NULL) { + // only need check_seen_thread once, not on each loop + // 6341374 java/lang/Instrument with -Xcomp + if (oldprobe->check_seen_thread(THREAD, PlaceholderTable::LOAD_INSTANCE)) { + throw_circularity_error = true; + } else { + // case 3: traditional: should never see load_in_progress. + while (!class_has_been_loaded && oldprobe != NULL && oldprobe->instance_load_in_progress()) { + + // case 1: bootstrap classloader: prevent futile classloading, + // wait on first requestor + if (class_loader.is_null()) { + SystemDictionary_lock->wait(); + } else { // case 4: traditional with broken classloader lock. wait on first // requestor. - double_lock_wait(THREAD, lockObject); - } - // Check if classloading completed while we were waiting - InstanceKlass* check = dictionary->find_class(name_hash, name); - if (check != NULL) { - // Klass is already loaded, so just return it - loaded_class = check; - class_has_been_loaded = true; - } - // check if other thread failed to load and cleaned up - oldprobe = placeholders()->get_entry(name_hash, name, loader_data); + double_lock_wait(THREAD, lockObject); + } + // Check if classloading completed while we were waiting + InstanceKlass* check = dictionary->find_class(name_hash, name); + if (check != NULL) { + // Klass is already loaded, so just return it + loaded_class = check; + class_has_been_loaded = true; } + // check if other thread failed to load and cleaned up + oldprobe = placeholders()->get_entry(name_hash, name, loader_data); } } } - // All cases: add LOAD_INSTANCE while holding the SystemDictionary_lock + // Add LOAD_INSTANCE while holding the SystemDictionary_lock if (!throw_circularity_error && !class_has_been_loaded) { - PlaceholderEntry* newprobe = placeholders()->find_and_add(name_hash, name, loader_data, - PlaceholderTable::LOAD_INSTANCE, NULL, THREAD); - load_instance_added = true; - // For class loaders that do not acquire the classloader object lock, - // 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 + // For the bootclass loader, if the thread did not catch another thread holding + // the LOAD_INSTANCE token, we need to check whether it completed loading + // while holding the SD_lock. InstanceKlass* check = dictionary->find_class(name_hash, name); if (check != NULL) { // Klass is already loaded, so return it after checking/adding protection domain loaded_class = check; class_has_been_loaded = true; + } else { + // Now we've got the LOAD_INSTANCE token. Threads will wait on loading to complete for this thread. + PlaceholderEntry* newprobe = placeholders()->find_and_add(name_hash, name, loader_data, + PlaceholderTable::LOAD_INSTANCE, + NULL, + THREAD); + load_instance_added = true; } } } // must throw error outside of owning lock if (throw_circularity_error) { - assert(!HAS_PENDING_EXCEPTION && load_instance_added == false,"circularity error cleanup"); + assert(!HAS_PENDING_EXCEPTION && !load_instance_added, "circularity error cleanup"); ResourceMark rm(THREAD); THROW_MSG_NULL(vmSymbols::java_lang_ClassCircularityError(), name->as_C_string()); } @@ -1812,17 +1798,6 @@ void SystemDictionary::initialize(TRAPS) { } } -#ifdef ASSERT -// Verify that this placeholder exists since this class is in the middle of loading. -void verify_placeholder(Symbol* class_name, ClassLoaderData* loader_data) { - // Only parallel capable class loaders use placeholder table for define class. - assert_locked_or_safepoint(SystemDictionary_lock); - unsigned int name_hash = placeholders()->compute_hash(class_name); - Symbol* ph_check = placeholders()->find_entry(name_hash, class_name, loader_data); - assert(ph_check != NULL, "This placeholder should exist"); -} -#endif // ASSERT - // Constraints on class loaders. The details of the algorithm can be // found in the OOPSLA'98 paper "Dynamic Class Loading in the Java // Virtual Machine" by Sheng Liang and Gilad Bracha. The basic idea is @@ -1862,8 +1837,6 @@ void SystemDictionary::check_constraints(unsigned int name_hash, } } - DEBUG_ONLY(if (is_parallelCapable(class_loader)) verify_placeholder(name, loader_data)); - if (throwException == false) { if (constraints()->check_or_update(k, class_loader, name) == false) { throwException = true; -- GitLab From a7726390cc00eed9833574ca716f724bd9689952 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 10 Feb 2021 15:08:34 +0000 Subject: [PATCH 008/367] 8261298: LinuxPackage.c, getJvmLauncherLibPath RPM->DEB typo Reviewed-by: asemenyuk, almatvee, herrick --- src/jdk.jpackage/linux/native/applauncher/LinuxPackage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jdk.jpackage/linux/native/applauncher/LinuxPackage.c b/src/jdk.jpackage/linux/native/applauncher/LinuxPackage.c index fc7edf3624a..5e3ef362d2e 100644 --- a/src/jdk.jpackage/linux/native/applauncher/LinuxPackage.c +++ b/src/jdk.jpackage/linux/native/applauncher/LinuxPackage.c @@ -312,7 +312,7 @@ char* getJvmLauncherLibPath(void) { } else { if (PACKAGE_TYPE_RPM == pkg->type) { pkgQueryCmd = "rpm -ql '%s' 2>/dev/null"; - } else if (PACKAGE_TYPE_RPM == pkg->type) { + } else if (PACKAGE_TYPE_DEB == pkg->type) { pkgQueryCmd = "dpkg -L '%s' 2>/dev/null"; } else { /* Should never happen */ -- GitLab From 4caeb39f01b13b5472d8dacb268262fd418fd0c4 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Wed, 10 Feb 2021 16:33:56 +0000 Subject: [PATCH 009/367] 8260380: Upgrade to LittleCMS 2.12 Reviewed-by: jdv, serb --- src/java.desktop/share/legal/lcms.md | 2 +- .../share/native/liblcms/cmsalpha.c | 10 +- .../share/native/liblcms/cmscgats.c | 21 +- .../share/native/liblcms/cmscnvrt.c | 93 ++- .../share/native/liblcms/cmsgamma.c | 61 +- .../share/native/liblcms/cmsintrp.c | 529 ++++++------------ .../share/native/liblcms/cmsio0.c | 31 +- .../share/native/liblcms/cmslut.c | 4 +- .../share/native/liblcms/cmsnamed.c | 20 +- .../share/native/liblcms/cmsopt.c | 35 +- .../share/native/liblcms/cmspack.c | 2 +- .../share/native/liblcms/cmspcs.c | 2 +- .../share/native/liblcms/cmsplugin.c | 8 + .../share/native/liblcms/cmsps2.c | 11 +- .../share/native/liblcms/cmssamp.c | 4 +- .../share/native/liblcms/cmstypes.c | 9 +- .../share/native/liblcms/cmsxform.c | 10 +- src/java.desktop/share/native/liblcms/lcms2.h | 8 +- .../share/native/liblcms/lcms2_internal.h | 16 +- .../share/native/liblcms/lcms2_plugin.h | 23 +- 20 files changed, 431 insertions(+), 468 deletions(-) diff --git a/src/java.desktop/share/legal/lcms.md b/src/java.desktop/share/legal/lcms.md index 0dce053fe55..1977a6b1597 100644 --- a/src/java.desktop/share/legal/lcms.md +++ b/src/java.desktop/share/legal/lcms.md @@ -1,4 +1,4 @@ -## Little Color Management System (LCMS) v2.11 +## Little Color Management System (LCMS) v2.12 ### LCMS License
diff --git a/src/java.desktop/share/native/liblcms/cmsalpha.c b/src/java.desktop/share/native/liblcms/cmsalpha.c
index 1b31782f47b..49ff22df764 100644
--- a/src/java.desktop/share/native/liblcms/cmsalpha.c
+++ b/src/java.desktop/share/native/liblcms/cmsalpha.c
@@ -104,7 +104,7 @@ static
 void from8to16(void* dst, const void* src)
 {
        cmsUInt8Number n = *(cmsUInt8Number*)src;
-       *(cmsUInt16Number*) dst = FROM_8_TO_16(n);
+       *(cmsUInt16Number*) dst = (cmsUInt16Number) FROM_8_TO_16(n);
 }
 
 static
@@ -117,13 +117,13 @@ void from8to16SE(void* dst, const void* src)
 static
 void from8toFLT(void* dst, const void* src)
 {
-       *(cmsFloat32Number*)dst = (*(cmsUInt8Number*)src) / 255.0f;
+       *(cmsFloat32Number*)dst = (cmsFloat32Number) (*(cmsUInt8Number*)src) / 255.0f;
 }
 
 static
 void from8toDBL(void* dst, const void* src)
 {
-       *(cmsFloat64Number*)dst = (*(cmsUInt8Number*)src) / 255.0;
+       *(cmsFloat64Number*)dst = (cmsFloat64Number) (*(cmsUInt8Number*)src) / 255.0;
 }
 
 static
@@ -182,13 +182,13 @@ void from16SEtoFLT(void* dst, const void* src)
 static
 void from16toDBL(void* dst, const void* src)
 {
-       *(cmsFloat64Number*)dst = (*(cmsUInt16Number*)src) / 65535.0f;
+       *(cmsFloat64Number*)dst = (cmsFloat64Number) (*(cmsUInt16Number*)src) / 65535.0;
 }
 
 static
 void from16SEtoDBL(void* dst, const void* src)
 {
-    *(cmsFloat64Number*)dst = (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0f;
+    *(cmsFloat64Number*)dst = (cmsFloat64Number) (CHANGE_ENDIAN(*(cmsUInt16Number*)src)) / 65535.0;
 }
 
 static
diff --git a/src/java.desktop/share/native/liblcms/cmscgats.c b/src/java.desktop/share/native/liblcms/cmscgats.c
index a26b1cc0407..07109b1e449 100644
--- a/src/java.desktop/share/native/liblcms/cmscgats.c
+++ b/src/java.desktop/share/native/liblcms/cmscgats.c
@@ -1525,6 +1525,14 @@ cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE  h, int n, const char *Sample)
     return SetDataFormat(it8, n, Sample);
 }
 
+// A safe atoi that returns 0 when NULL input is given
+static
+cmsInt32Number satoi(const char* b)
+{
+    if (b == NULL) return 0;
+    return atoi(b);
+}
+
 static
 void AllocateDataSet(cmsIT8* it8)
 {
@@ -1532,14 +1540,15 @@ void AllocateDataSet(cmsIT8* it8)
 
     if (t -> Data) return;    // Already allocated
 
-    t-> nSamples   = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
-    t-> nPatches   = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
+    t-> nSamples   = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
+    t-> nPatches   = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
 
     if (t -> nSamples < 0 || t->nSamples > 0x7ffe || t->nPatches < 0 || t->nPatches > 0x7ffe)
     {
         SynError(it8, "AllocateDataSet: too much data");
     }
     else {
+        // Some dumb analizers warns of possible overflow here, just take a look couple of lines above.
         t->Data = (char**)AllocChunk(it8, ((cmsUInt32Number)t->nSamples + 1) * ((cmsUInt32Number)t->nPatches + 1) * sizeof(char*));
         if (t->Data == NULL) {
 
@@ -1705,11 +1714,11 @@ void WriteHeader(cmsIT8* it8, SAVESTREAM* fp)
                     break;
 
             case WRITE_HEXADECIMAL:
-                    Writef(fp, "\t0x%X", atoi(p ->Value));
+                    Writef(fp, "\t0x%X", satoi(p ->Value));
                     break;
 
             case WRITE_BINARY:
-                    Writef(fp, "\t0x%B", atoi(p ->Value));
+                    Writef(fp, "\t0x%B", satoi(p ->Value));
                     break;
 
             case WRITE_PAIR:
@@ -1738,7 +1747,7 @@ void WriteDataFormat(SAVESTREAM* fp, cmsIT8* it8)
 
        WriteStr(fp, "BEGIN_DATA_FORMAT\n");
        WriteStr(fp, " ");
-       nSamples = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
+       nSamples = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_FIELDS"));
 
        for (i = 0; i < nSamples; i++) {
 
@@ -1761,7 +1770,7 @@ void WriteData(SAVESTREAM* fp, cmsIT8* it8)
 
        WriteStr (fp, "BEGIN_DATA\n");
 
-       t->nPatches = atoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
+       t->nPatches = satoi(cmsIT8GetProperty(it8, "NUMBER_OF_SETS"));
 
        for (i = 0; i < t-> nPatches; i++) {
 
diff --git a/src/java.desktop/share/native/liblcms/cmscnvrt.c b/src/java.desktop/share/native/liblcms/cmscnvrt.c
index fa1f8f09210..4bee13d6491 100644
--- a/src/java.desktop/share/native/liblcms/cmscnvrt.c
+++ b/src/java.desktop/share/native/liblcms/cmscnvrt.c
@@ -759,6 +759,9 @@ cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
     cmsUInt32Number ICCIntents[256];
     cmsStage*         CLUT;
     cmsUInt32Number i, nGridPoints;
+    cmsUInt32Number lastProfilePos;
+    cmsUInt32Number preservationProfilesCount;
+    cmsHPROFILE hLastProfile;
 
 
     // Sanity check
@@ -768,20 +771,36 @@ cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
     for (i=0; i < nProfiles; i++)
         ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]);
 
+
+    // Trim all CMYK devicelinks at the end
+    lastProfilePos = nProfiles - 1;
+    hLastProfile = hProfiles[lastProfilePos];
+
+    while (lastProfilePos > 1)
+    {
+        hLastProfile = hProfiles[--lastProfilePos];
+        if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData ||
+            cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass)
+            break;
+    }
+
+    preservationProfilesCount = lastProfilePos + 1;
+
     // Check for non-cmyk profiles
     if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData ||
-        cmsGetColorSpace(hProfiles[nProfiles-1]) != cmsSigCmykData)
+        !(cmsGetColorSpace(hLastProfile) == cmsSigCmykData ||
+        cmsGetDeviceClass(hLastProfile) == cmsSigOutputClass))
            return DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags);
 
-    memset(&bp, 0, sizeof(bp));
-
     // Allocate an empty LUT for holding the result
     Result = cmsPipelineAlloc(ContextID, 4, 4);
     if (Result == NULL) return NULL;
 
+    memset(&bp, 0, sizeof(bp));
+
     // Create a LUT holding normal ICC transform
     bp.cmyk2cmyk = DefaultICCintents(ContextID,
-        nProfiles,
+                                     preservationProfilesCount,
         ICCIntents,
         hProfiles,
         BPC,
@@ -793,7 +812,7 @@ cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
     // Now, compute the tone curve
     bp.KTone = _cmsBuildKToneCurve(ContextID,
         4096,
-        nProfiles,
+                                    preservationProfilesCount,
         ICCIntents,
         hProfiles,
         BPC,
@@ -818,6 +837,19 @@ cmsPipeline*  BlackPreservingKOnlyIntents(cmsContext     ContextID,
     if (!cmsStageSampleCLut16bit(CLUT, BlackPreservingGrayOnlySampler, (void*) &bp, 0))
         goto Error;
 
+
+    // Insert possible devicelinks at the end
+    for (i = lastProfilePos + 1; i < nProfiles; i++)
+    {
+        cmsPipeline* devlink = _cmsReadDevicelinkLUT(hProfiles[i], ICCIntents[i]);
+        if (devlink == NULL)
+            goto Error;
+
+        if (!cmsPipelineCat(Result, devlink))
+            goto Error;
+    }
+
+
     // Get rid of xform and tone curve
     cmsPipelineFree(bp.cmyk2cmyk);
     cmsFreeToneCurve(bp.KTone);
@@ -936,6 +968,8 @@ int BlackPreservingSampler(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER c
     return TRUE;
 }
 
+
+
 // This is the entry for black-plane preserving, which are non-ICC
 static
 cmsPipeline* BlackPreservingKPlaneIntents(cmsContext     ContextID,
@@ -947,10 +981,14 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext     ContextID,
                                           cmsUInt32Number dwFlags)
 {
     PreserveKPlaneParams bp;
+
     cmsPipeline*    Result = NULL;
     cmsUInt32Number ICCIntents[256];
     cmsStage*         CLUT;
     cmsUInt32Number i, nGridPoints;
+    cmsUInt32Number lastProfilePos;
+    cmsUInt32Number preservationProfilesCount;
+    cmsHPROFILE hLastProfile;
     cmsHPROFILE hLab;
 
     // Sanity check
@@ -960,32 +998,45 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext     ContextID,
     for (i=0; i < nProfiles; i++)
         ICCIntents[i] = TranslateNonICCIntents(TheIntents[i]);
 
+    // Trim all CMYK devicelinks at the end
+    lastProfilePos = nProfiles - 1;
+    hLastProfile = hProfiles[lastProfilePos];
+
+    while (lastProfilePos > 1)
+    {
+        hLastProfile = hProfiles[--lastProfilePos];
+        if (cmsGetColorSpace(hLastProfile) != cmsSigCmykData ||
+            cmsGetDeviceClass(hLastProfile) != cmsSigLinkClass)
+            break;
+    }
+
+    preservationProfilesCount = lastProfilePos + 1;
+
     // Check for non-cmyk profiles
     if (cmsGetColorSpace(hProfiles[0]) != cmsSigCmykData ||
-        !(cmsGetColorSpace(hProfiles[nProfiles-1]) == cmsSigCmykData ||
-        cmsGetDeviceClass(hProfiles[nProfiles-1]) == cmsSigOutputClass))
+        !(cmsGetColorSpace(hLastProfile) == cmsSigCmykData ||
+        cmsGetDeviceClass(hLastProfile) == cmsSigOutputClass))
            return  DefaultICCintents(ContextID, nProfiles, ICCIntents, hProfiles, BPC, AdaptationStates, dwFlags);
 
     // Allocate an empty LUT for holding the result
     Result = cmsPipelineAlloc(ContextID, 4, 4);
     if (Result == NULL) return NULL;
 
-
     memset(&bp, 0, sizeof(bp));
 
     // We need the input LUT of the last profile, assuming this one is responsible of
     // black generation. This LUT will be searched in inverse order.
-    bp.LabK2cmyk = _cmsReadInputLUT(hProfiles[nProfiles-1], INTENT_RELATIVE_COLORIMETRIC);
+    bp.LabK2cmyk = _cmsReadInputLUT(hLastProfile, INTENT_RELATIVE_COLORIMETRIC);
     if (bp.LabK2cmyk == NULL) goto Cleanup;
 
     // Get total area coverage (in 0..1 domain)
-    bp.MaxTAC = cmsDetectTAC(hProfiles[nProfiles-1]) / 100.0;
+    bp.MaxTAC = cmsDetectTAC(hLastProfile) / 100.0;
     if (bp.MaxTAC <= 0) goto Cleanup;
 
 
     // Create a LUT holding normal ICC transform
     bp.cmyk2cmyk = DefaultICCintents(ContextID,
-                                         nProfiles,
+                                         preservationProfilesCount,
                                          ICCIntents,
                                          hProfiles,
                                          BPC,
@@ -994,7 +1045,7 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext     ContextID,
     if (bp.cmyk2cmyk == NULL) goto Cleanup;
 
     // Now the tone curve
-    bp.KTone = _cmsBuildKToneCurve(ContextID, 4096, nProfiles,
+    bp.KTone = _cmsBuildKToneCurve(ContextID, 4096, preservationProfilesCount,
                                    ICCIntents,
                                    hProfiles,
                                    BPC,
@@ -1004,14 +1055,14 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext     ContextID,
 
     // To measure the output, Last profile to Lab
     hLab = cmsCreateLab4ProfileTHR(ContextID, NULL);
-    bp.hProofOutput = cmsCreateTransformTHR(ContextID, hProfiles[nProfiles-1],
+    bp.hProofOutput = cmsCreateTransformTHR(ContextID, hLastProfile,
                                          CHANNELS_SH(4)|BYTES_SH(2), hLab, TYPE_Lab_DBL,
                                          INTENT_RELATIVE_COLORIMETRIC,
                                          cmsFLAGS_NOCACHE|cmsFLAGS_NOOPTIMIZE);
     if ( bp.hProofOutput == NULL) goto Cleanup;
 
     // Same as anterior, but lab in the 0..1 range
-    bp.cmyk2Lab = cmsCreateTransformTHR(ContextID, hProfiles[nProfiles-1],
+    bp.cmyk2Lab = cmsCreateTransformTHR(ContextID, hLastProfile,
                                          FLOAT_SH(1)|CHANNELS_SH(4)|BYTES_SH(4), hLab,
                                          FLOAT_SH(1)|CHANNELS_SH(3)|BYTES_SH(4),
                                          INTENT_RELATIVE_COLORIMETRIC,
@@ -1034,6 +1085,18 @@ cmsPipeline* BlackPreservingKPlaneIntents(cmsContext     ContextID,
 
     cmsStageSampleCLut16bit(CLUT, BlackPreservingSampler, (void*) &bp, 0);
 
+    // Insert possible devicelinks at the end
+    for (i = lastProfilePos + 1; i < nProfiles; i++)
+    {
+        cmsPipeline* devlink = _cmsReadDevicelinkLUT(hProfiles[i], ICCIntents[i]);
+        if (devlink == NULL)
+            goto Cleanup;
+
+        if (!cmsPipelineCat(Result, devlink))
+            goto Cleanup;
+    }
+
+
 Cleanup:
 
     if (bp.cmyk2cmyk) cmsPipelineFree(bp.cmyk2cmyk);
@@ -1046,6 +1109,8 @@ Cleanup:
     return Result;
 }
 
+
+
 // Link routines ------------------------------------------------------------------------------------------------------
 
 // Chain several profiles into a single LUT. It just checks the parameters and then calls the handler
diff --git a/src/java.desktop/share/native/liblcms/cmsgamma.c b/src/java.desktop/share/native/liblcms/cmsgamma.c
index 4ccbf4d2a2b..f266f2e05a6 100644
--- a/src/java.desktop/share/native/liblcms/cmsgamma.c
+++ b/src/java.desktop/share/native/liblcms/cmsgamma.c
@@ -88,11 +88,11 @@ static cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFl
 
 // The built-in list
 static _cmsParametricCurvesCollection DefaultCurves = {
-    9,                                  // # of curve types
-    { 1, 2, 3, 4, 5, 6, 7, 8, 108 },    // Parametric curve ID
-    { 1, 3, 4, 5, 7, 4, 5, 5, 1 },      // Parameters by type
-    DefaultEvalParametricFn,            // Evaluator
-    NULL                                // Next in chain
+    10,                                      // # of curve types
+    { 1, 2, 3, 4, 5, 6, 7, 8, 108, 109 },    // Parametric curve ID
+    { 1, 3, 4, 5, 7, 4, 5, 5,   1,   1 },    // Parameters by type
+    DefaultEvalParametricFn,                 // Evaluator
+    NULL                                     // Next in chain
 };
 
 // Duplicates the zone of memory used by the plug-in in the new context
@@ -338,6 +338,32 @@ Error:
 }
 
 
+// Generates a sigmoidal function with desired steepness.
+cmsINLINE double sigmoid_base(double k, double t)
+{
+    return (1.0 / (1.0 + exp(-k * t))) - 0.5;
+}
+
+cmsINLINE double inverted_sigmoid_base(double k, double t)
+{
+    return -log((1.0 / (t + 0.5)) - 1.0) / k;
+}
+
+cmsINLINE double sigmoid_factory(double k, double t)
+{
+    double correction = 0.5 / sigmoid_base(k, 1);
+
+    return correction * sigmoid_base(k, 2.0 * t - 1.0) + 0.5;
+}
+
+cmsINLINE double inverse_sigmoid_factory(double k, double t)
+{
+    double correction = 0.5 / sigmoid_base(k, 1);
+
+    return (inverted_sigmoid_base(k, (t - 0.5) / correction) + 1.0) / 2.0;
+}
+
+
 // Parametric Fn using floating point
 static
 cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Number Params[], cmsFloat64Number R)
@@ -669,6 +695,7 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
        }
        break;
 
+
    // S-Shaped: (1 - (1-x)^1/g)^1/g
    case 108:
        if (fabs(Params[0]) < MATRIX_DET_TOLERANCE)
@@ -686,6 +713,15 @@ cmsFloat64Number DefaultEvalParametricFn(cmsInt32Number Type, const cmsFloat64Nu
         Val = 1 - pow(1 - pow(R, Params[0]), Params[0]);
         break;
 
+    // Sigmoidals
+    case 109:
+        Val = sigmoid_factory(Params[0], R);
+        break;
+
+    case -109:
+        Val = inverse_sigmoid_factory(Params[0], R);
+        break;
+
     default:
         // Unsupported parametric curve. Should never reach here
         return 0;
@@ -971,7 +1007,7 @@ cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID,
     //Iterate
     for (i=0; i <  nResultingPoints; i++) {
 
-        t = (cmsFloat32Number) i / (nResultingPoints-1);
+        t = (cmsFloat32Number) i / (cmsFloat32Number)(nResultingPoints-1);
         x = cmsEvalToneCurveFloat(X,  t);
         Res[i] = cmsEvalToneCurveFloat(Yreversed, x);
     }
@@ -1185,6 +1221,7 @@ cmsBool  CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda
     cmsBool SuccessStatus = TRUE;
     cmsFloat32Number *w, *y, *z;
     cmsUInt32Number i, nItems, Zeros, Poles;
+    cmsBool notCheck = FALSE;
 
     if (Tab != NULL && Tab->InterpParams != NULL)
     {
@@ -1212,6 +1249,12 @@ cmsBool  CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda
                         w[i + 1] = 1.0;
                     }
 
+                    if (lambda < 0)
+                    {
+                        notCheck = TRUE;
+                        lambda = -lambda;
+                    }
+
                     if (smooth2(ContextID, w, y, z, (cmsFloat32Number)lambda, (int)nItems))
                     {
                         // Do some reality - checking...
@@ -1224,7 +1267,7 @@ cmsBool  CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda
                             if (z[i] < z[i - 1])
                             {
                                 cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic.");
-                                SuccessStatus = FALSE;
+                                SuccessStatus = notCheck;
                                 break;
                             }
                         }
@@ -1232,13 +1275,13 @@ cmsBool  CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda
                         if (SuccessStatus && Zeros > (nItems / 3))
                         {
                             cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros.");
-                            SuccessStatus = FALSE;
+                            SuccessStatus = notCheck;
                         }
 
                         if (SuccessStatus && Poles > (nItems / 3))
                         {
                             cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles.");
-                            SuccessStatus = FALSE;
+                            SuccessStatus = notCheck;
                         }
 
                         if (SuccessStatus) // Seems ok
diff --git a/src/java.desktop/share/native/liblcms/cmsintrp.c b/src/java.desktop/share/native/liblcms/cmsintrp.c
index 435c87cc7a7..8f2d0130e82 100644
--- a/src/java.desktop/share/native/liblcms/cmsintrp.c
+++ b/src/java.desktop/share/native/liblcms/cmsintrp.c
@@ -434,12 +434,13 @@ void BilinearInterp16(CMSREGISTER const cmsUInt16Number Input[],
            const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
            int        OutChan, TotalOut;
            cmsS15Fixed16Number    fx, fy;
-  CMSREGISTER int        rx, ry;
-           int        x0, y0;
-  CMSREGISTER int        X0, X1, Y0, Y1;
-           int        d00, d01, d10, d11,
-                      dx0, dx1,
-                      dxy;
+           CMSREGISTER int        rx, ry;
+           int                    x0, y0;
+           CMSREGISTER int        X0, X1, Y0, Y1;
+
+           int                    d00, d01, d10, d11,
+                                  dx0, dx1,
+                                  dxy;
 
     TotalOut   = p -> nOutputs;
 
@@ -495,11 +496,12 @@ void TrilinearInterpFloat(const cmsFloat32Number Input[],
     int        x0, y0, z0,
                X0, Y0, Z0, X1, Y1, Z1;
     int        TotalOut, OutChan;
+
     cmsFloat32Number      fx, fy, fz,
-        d000, d001, d010, d011,
-        d100, d101, d110, d111,
-        dx00, dx01, dx10, dx11,
-        dxy0, dxy1, dxyz;
+                          d000, d001, d010, d011,
+                          d100, d101, d110, d111,
+                          dx00, dx01, dx10, dx11,
+                          dxy0, dxy1, dxyz;
 
     TotalOut   = p -> nOutputs;
 
@@ -565,13 +567,13 @@ void TrilinearInterp16(CMSREGISTER const cmsUInt16Number Input[],
            const cmsUInt16Number* LutTable = (cmsUInt16Number*) p ->Table;
            int        OutChan, TotalOut;
            cmsS15Fixed16Number    fx, fy, fz;
-  CMSREGISTER int        rx, ry, rz;
-           int        x0, y0, z0;
-  CMSREGISTER int        X0, X1, Y0, Y1, Z0, Z1;
-           int        d000, d001, d010, d011,
-                      d100, d101, d110, d111,
-                      dx00, dx01, dx10, dx11,
-                      dxy0, dxy1, dxyz;
+           CMSREGISTER int        rx, ry, rz;
+           int                    x0, y0, z0;
+           CMSREGISTER int        X0, X1, Y0, Y1, Z0, Z1;
+           int                    d000, d001, d010, d011,
+                                  d100, d101, d110, d111,
+                                  dx00, dx01, dx10, dx11,
+                                  dxy0, dxy1, dxyz;
 
     TotalOut   = p -> nOutputs;
 
@@ -639,8 +641,8 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
 {
     const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
     cmsFloat32Number     px, py, pz;
-    int        x0, y0, z0,
-               X0, Y0, Z0, X1, Y1, Z1;
+    int                  x0, y0, z0,
+                         X0, Y0, Z0, X1, Y1, Z1;
     cmsFloat32Number     rx, ry, rz;
     cmsFloat32Number     c0, c1=0, c2=0, c3=0;
     int                  OutChan, TotalOut;
@@ -730,9 +732,6 @@ void TetrahedralInterpFloat(const cmsFloat32Number Input[],
 
 #undef DENS
 
-
-
-
 static CMS_NO_SANITIZE
 void TetrahedralInterp16(CMSREGISTER const cmsUInt16Number Input[],
                          CMSREGISTER cmsUInt16Number Output[],
@@ -743,7 +742,7 @@ void TetrahedralInterp16(CMSREGISTER const cmsUInt16Number Input[],
     cmsS15Fixed16Number rx, ry, rz;
     int x0, y0, z0;
     cmsS15Fixed16Number c0, c1, c2, c3, Rest;
-    cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1;
+    cmsUInt32Number X0, X1, Y0, Y1, Z0, Z1;
     cmsUInt32Number TotalOut = p -> nOutputs;
 
     fx = _cmsToFixedDomain((int) Input[0] * p -> Domain[0]);
@@ -767,7 +766,7 @@ void TetrahedralInterp16(CMSREGISTER const cmsUInt16Number Input[],
     Z0 = p -> opta[0] * z0;
     Z1 = (Input[2] == 0xFFFFU ? 0 : p->opta[0]);
 
-    LutTable = &LutTable[X0+Y0+Z0];
+    LutTable += X0+Y0+Z0;
 
     // Output should be computed as x = ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest))
     // which expands as: x = (Rest + ((Rest+0x7fff)/0xFFFF) + 0x8000)>>16
@@ -1051,8 +1050,6 @@ void Eval4Inputs(CMSREGISTER const cmsUInt16Number Input[],
 
 // For more that 3 inputs (i.e., CMYK)
 // evaluate two 3-dimensional interpolations and then linearly interpolate between them.
-
-
 static
 void Eval4InputsFloat(const cmsFloat32Number Input[],
                       cmsFloat32Number Output[],
@@ -1095,351 +1092,102 @@ void Eval4InputsFloat(const cmsFloat32Number Input[],
        }
 }
 
-
-static CMS_NO_SANITIZE
-void Eval5Inputs(CMSREGISTER const cmsUInt16Number Input[],
-                 CMSREGISTER cmsUInt16Number Output[],
-
-                 CMSREGISTER const cmsInterpParams* p16)
-{
-       const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
-       cmsS15Fixed16Number fk;
-       cmsS15Fixed16Number k0, rk;
-       int K0, K1;
-       const cmsUInt16Number* T;
-       cmsUInt32Number i;
-       cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
-       cmsInterpParams p1;
-
-
-       fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
-       k0 = FIXED_TO_INT(fk);
-       rk = FIXED_REST_TO_INT(fk);
-
-       K0 = p16 -> opta[4] * k0;
-       K1 = p16 -> opta[4] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
-
-       p1 = *p16;
-       memmove(&p1.Domain[0], &p16 ->Domain[1], 4*sizeof(cmsUInt32Number));
-
-       T = LutTable + K0;
-       p1.Table = T;
-
-       Eval4Inputs(Input + 1, Tmp1, &p1);
-
-       T = LutTable + K1;
-       p1.Table = T;
-
-       Eval4Inputs(Input + 1, Tmp2, &p1);
-
-       for (i=0; i < p16 -> nOutputs; i++) {
-
-              Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
-       }
-
-}
-
-
-static
-void Eval5InputsFloat(const cmsFloat32Number Input[],
-                      cmsFloat32Number Output[],
-                      const cmsInterpParams* p)
-{
-       const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
-       cmsFloat32Number rest;
-       cmsFloat32Number pk;
-       int k0, K0, K1;
-       const cmsFloat32Number* T;
-       cmsUInt32Number i;
-       cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
-       cmsInterpParams p1;
-
-       pk = fclamp(Input[0]) * p->Domain[0];
-       k0 = _cmsQuickFloor(pk);
-       rest = pk - (cmsFloat32Number) k0;
-
-       K0 = p -> opta[4] * k0;
-       K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[4]);
-
-       p1 = *p;
-       memmove(&p1.Domain[0], &p ->Domain[1], 4*sizeof(cmsUInt32Number));
-
-       T = LutTable + K0;
-       p1.Table = T;
-
-       Eval4InputsFloat(Input + 1,  Tmp1, &p1);
-
-       T = LutTable + K1;
-       p1.Table = T;
-
-       Eval4InputsFloat(Input + 1,  Tmp2, &p1);
-
-       for (i=0; i < p -> nOutputs; i++) {
-
-              cmsFloat32Number y0 = Tmp1[i];
-              cmsFloat32Number y1 = Tmp2[i];
-
-              Output[i] = y0 + (y1 - y0) * rest;
-       }
-}
-
-
-
-static CMS_NO_SANITIZE
-void Eval6Inputs(CMSREGISTER const cmsUInt16Number Input[],
-                 CMSREGISTER cmsUInt16Number Output[],
-                 CMSREGISTER const cmsInterpParams* p16)
-{
-       const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
-       cmsS15Fixed16Number fk;
-       cmsS15Fixed16Number k0, rk;
-       int K0, K1;
-       const cmsUInt16Number* T;
-       cmsUInt32Number i;
-       cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
-       cmsInterpParams p1;
-
-       fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
-       k0 = FIXED_TO_INT(fk);
-       rk = FIXED_REST_TO_INT(fk);
-
-       K0 = p16 -> opta[5] * k0;
-       K1 = p16 -> opta[5] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
-
-       p1 = *p16;
-       memmove(&p1.Domain[0], &p16 ->Domain[1], 5*sizeof(cmsUInt32Number));
-
-       T = LutTable + K0;
-       p1.Table = T;
-
-       Eval5Inputs(Input + 1, Tmp1, &p1);
-
-       T = LutTable + K1;
-       p1.Table = T;
-
-       Eval5Inputs(Input + 1, Tmp2, &p1);
-
-       for (i=0; i < p16 -> nOutputs; i++) {
-
-              Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
-       }
-
-}
-
-
-static
-void Eval6InputsFloat(const cmsFloat32Number Input[],
-                      cmsFloat32Number Output[],
-                      const cmsInterpParams* p)
-{
-       const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
-       cmsFloat32Number rest;
-       cmsFloat32Number pk;
-       int k0, K0, K1;
-       const cmsFloat32Number* T;
-       cmsUInt32Number i;
-       cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
-       cmsInterpParams p1;
-
-       pk = fclamp(Input[0]) * p->Domain[0];
-       k0 = _cmsQuickFloor(pk);
-       rest = pk - (cmsFloat32Number) k0;
-
-       K0 = p -> opta[5] * k0;
-       K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[5]);
-
-       p1 = *p;
-       memmove(&p1.Domain[0], &p ->Domain[1], 5*sizeof(cmsUInt32Number));
-
-       T = LutTable + K0;
-       p1.Table = T;
-
-       Eval5InputsFloat(Input + 1,  Tmp1, &p1);
-
-       T = LutTable + K1;
-       p1.Table = T;
-
-       Eval5InputsFloat(Input + 1,  Tmp2, &p1);
-
-       for (i=0; i < p -> nOutputs; i++) {
-
-              cmsFloat32Number y0 = Tmp1[i];
-              cmsFloat32Number y1 = Tmp2[i];
-
-              Output[i] = y0 + (y1 - y0) * rest;
-       }
-}
-
-
-static CMS_NO_SANITIZE
-void Eval7Inputs(CMSREGISTER const cmsUInt16Number Input[],
-                 CMSREGISTER cmsUInt16Number Output[],
-                 CMSREGISTER const cmsInterpParams* p16)
-{
-       const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
-       cmsS15Fixed16Number fk;
-       cmsS15Fixed16Number k0, rk;
-       int K0, K1;
-       const cmsUInt16Number* T;
-       cmsUInt32Number i;
-       cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
-       cmsInterpParams p1;
-
-
-       fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
-       k0 = FIXED_TO_INT(fk);
-       rk = FIXED_REST_TO_INT(fk);
-
-       K0 = p16 -> opta[6] * k0;
-       K1 = p16 -> opta[6] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
-
-       p1 = *p16;
-       memmove(&p1.Domain[0], &p16 ->Domain[1], 6*sizeof(cmsUInt32Number));
-
-       T = LutTable + K0;
-       p1.Table = T;
-
-       Eval6Inputs(Input + 1, Tmp1, &p1);
-
-       T = LutTable + K1;
-       p1.Table = T;
-
-       Eval6Inputs(Input + 1, Tmp2, &p1);
-
-       for (i=0; i < p16 -> nOutputs; i++) {
-              Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
-       }
-}
-
-
-static
-void Eval7InputsFloat(const cmsFloat32Number Input[],
-                      cmsFloat32Number Output[],
-                      const cmsInterpParams* p)
-{
-       const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
-       cmsFloat32Number rest;
-       cmsFloat32Number pk;
-       int k0, K0, K1;
-       const cmsFloat32Number* T;
-       cmsUInt32Number i;
-       cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
-       cmsInterpParams p1;
-
-       pk = fclamp(Input[0]) * p->Domain[0];
-       k0 = _cmsQuickFloor(pk);
-       rest = pk - (cmsFloat32Number) k0;
-
-       K0 = p -> opta[6] * k0;
-       K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[6]);
-
-       p1 = *p;
-       memmove(&p1.Domain[0], &p ->Domain[1], 6*sizeof(cmsUInt32Number));
-
-       T = LutTable + K0;
-       p1.Table = T;
-
-       Eval6InputsFloat(Input + 1,  Tmp1, &p1);
-
-       T = LutTable + K1;
-       p1.Table = T;
-
-       Eval6InputsFloat(Input + 1,  Tmp2, &p1);
-
-
-       for (i=0; i < p -> nOutputs; i++) {
-
-              cmsFloat32Number y0 = Tmp1[i];
-              cmsFloat32Number y1 = Tmp2[i];
-
-              Output[i] = y0 + (y1 - y0) * rest;
-
-       }
-}
-
-static CMS_NO_SANITIZE
-void Eval8Inputs(CMSREGISTER const cmsUInt16Number Input[],
-                 CMSREGISTER cmsUInt16Number Output[],
-                 CMSREGISTER const cmsInterpParams* p16)
-{
-       const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;
-       cmsS15Fixed16Number fk;
-       cmsS15Fixed16Number k0, rk;
-       int K0, K1;
-       const cmsUInt16Number* T;
-       cmsUInt32Number i;
-       cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
-       cmsInterpParams p1;
-
-       fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);
-       k0 = FIXED_TO_INT(fk);
-       rk = FIXED_REST_TO_INT(fk);
-
-       K0 = p16 -> opta[7] * k0;
-       K1 = p16 -> opta[7] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));
-
-       p1 = *p16;
-       memmove(&p1.Domain[0], &p16 ->Domain[1], 7*sizeof(cmsUInt32Number));
-
-       T = LutTable + K0;
-       p1.Table = T;
-
-       Eval7Inputs(Input + 1, Tmp1, &p1);
-
-       T = LutTable + K1;
-       p1.Table = T;
-       Eval7Inputs(Input + 1, Tmp2, &p1);
-
-       for (i=0; i < p16 -> nOutputs; i++) {
-              Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);
-       }
+#define EVAL_FNS(N,NM) static CMS_NO_SANITIZE \
+void Eval##N##Inputs(CMSREGISTER const cmsUInt16Number Input[], CMSREGISTER cmsUInt16Number Output[], CMSREGISTER const cmsInterpParams* p16)\
+{\
+       const cmsUInt16Number* LutTable = (cmsUInt16Number*) p16 -> Table;\
+       cmsS15Fixed16Number fk;\
+       cmsS15Fixed16Number k0, rk;\
+       int K0, K1;\
+       const cmsUInt16Number* T;\
+       cmsUInt32Number i;\
+       cmsUInt16Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];\
+       cmsInterpParams p1;\
+\
+       fk = _cmsToFixedDomain((cmsS15Fixed16Number) Input[0] * p16 -> Domain[0]);\
+       k0 = FIXED_TO_INT(fk);\
+       rk = FIXED_REST_TO_INT(fk);\
+\
+       K0 = p16 -> opta[NM] * k0;\
+       K1 = p16 -> opta[NM] * (k0 + (Input[0] != 0xFFFFU ? 1 : 0));\
+\
+       p1 = *p16;\
+       memmove(&p1.Domain[0], &p16 ->Domain[1], NM*sizeof(cmsUInt32Number));\
+\
+       T = LutTable + K0;\
+       p1.Table = T;\
+\
+       Eval##NM##Inputs(Input + 1, Tmp1, &p1);\
+\
+       T = LutTable + K1;\
+       p1.Table = T;\
+\
+       Eval##NM##Inputs(Input + 1, Tmp2, &p1);\
+\
+       for (i=0; i < p16 -> nOutputs; i++) {\
+\
+              Output[i] = LinearInterp(rk, Tmp1[i], Tmp2[i]);\
+       }\
+}\
+\
+static void Eval##N##InputsFloat(const cmsFloat32Number Input[], \
+                                 cmsFloat32Number Output[],\
+                                 const cmsInterpParams * p)\
+{\
+       const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;\
+       cmsFloat32Number rest;\
+       cmsFloat32Number pk;\
+       int k0, K0, K1;\
+       const cmsFloat32Number* T;\
+       cmsUInt32Number i;\
+       cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];\
+       cmsInterpParams p1;\
+\
+       pk = fclamp(Input[0]) * p->Domain[0];\
+       k0 = _cmsQuickFloor(pk);\
+       rest = pk - (cmsFloat32Number) k0;\
+\
+       K0 = p -> opta[NM] * k0;\
+       K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[NM]);\
+\
+       p1 = *p;\
+       memmove(&p1.Domain[0], &p ->Domain[1], NM*sizeof(cmsUInt32Number));\
+\
+       T = LutTable + K0;\
+       p1.Table = T;\
+\
+       Eval##NM##InputsFloat(Input + 1, Tmp1, &p1);\
+\
+       T = LutTable + K1;\
+       p1.Table = T;\
+\
+       Eval##NM##InputsFloat(Input + 1, Tmp2, &p1);\
+\
+       for (i=0; i < p -> nOutputs; i++) {\
+\
+              cmsFloat32Number y0 = Tmp1[i];\
+              cmsFloat32Number y1 = Tmp2[i];\
+\
+              Output[i] = y0 + (y1 - y0) * rest;\
+       }\
 }
 
 
+/**
+* Thanks to Carles Llopis for the templating idea
+*/
+EVAL_FNS(5, 4)
+EVAL_FNS(6, 5)
+EVAL_FNS(7, 6)
+EVAL_FNS(8, 7)
+EVAL_FNS(9, 8)
+EVAL_FNS(10, 9)
+EVAL_FNS(11, 10)
+EVAL_FNS(12, 11)
+EVAL_FNS(13, 12)
+EVAL_FNS(14, 13)
+EVAL_FNS(15, 14)
 
-static
-void Eval8InputsFloat(const cmsFloat32Number Input[],
-                      cmsFloat32Number Output[],
-                      const cmsInterpParams* p)
-{
-       const cmsFloat32Number* LutTable = (cmsFloat32Number*) p -> Table;
-       cmsFloat32Number rest;
-       cmsFloat32Number pk;
-       int k0, K0, K1;
-       const cmsFloat32Number* T;
-       cmsUInt32Number i;
-       cmsFloat32Number Tmp1[MAX_STAGE_CHANNELS], Tmp2[MAX_STAGE_CHANNELS];
-       cmsInterpParams p1;
-
-       pk = fclamp(Input[0]) * p->Domain[0];
-       k0 = _cmsQuickFloor(pk);
-       rest = pk - (cmsFloat32Number) k0;
-
-       K0 = p -> opta[7] * k0;
-       K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[7]);
-
-       p1 = *p;
-       memmove(&p1.Domain[0], &p ->Domain[1], 7*sizeof(cmsUInt32Number));
-
-       T = LutTable + K0;
-       p1.Table = T;
-
-       Eval7InputsFloat(Input + 1,  Tmp1, &p1);
-
-       T = LutTable + K1;
-       p1.Table = T;
-
-       Eval7InputsFloat(Input + 1,  Tmp2, &p1);
-
-
-       for (i=0; i < p -> nOutputs; i++) {
-
-              cmsFloat32Number y0 = Tmp1[i];
-              cmsFloat32Number y1 = Tmp2[i];
-
-              Output[i] = y0 + (y1 - y0) * rest;
-       }
-}
 
 // The default factory
 static
@@ -1540,6 +1288,53 @@ cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cm
                    Interpolation.Lerp16    =  Eval8Inputs;
                break;
 
+           case 9:
+               if (IsFloat)
+                   Interpolation.LerpFloat = Eval9InputsFloat;
+               else
+                   Interpolation.Lerp16 = Eval9Inputs;
+               break;
+
+           case 10:
+               if (IsFloat)
+                   Interpolation.LerpFloat = Eval10InputsFloat;
+               else
+                   Interpolation.Lerp16 = Eval10Inputs;
+               break;
+
+           case 11:
+               if (IsFloat)
+                   Interpolation.LerpFloat = Eval11InputsFloat;
+               else
+                   Interpolation.Lerp16 = Eval11Inputs;
+               break;
+
+           case 12:
+               if (IsFloat)
+                   Interpolation.LerpFloat = Eval12InputsFloat;
+               else
+                   Interpolation.Lerp16 = Eval12Inputs;
+               break;
+
+           case 13:
+               if (IsFloat)
+                   Interpolation.LerpFloat = Eval13InputsFloat;
+               else
+                   Interpolation.Lerp16 = Eval13Inputs;
+               break;
+
+           case 14:
+               if (IsFloat)
+                   Interpolation.LerpFloat = Eval14InputsFloat;
+               else
+                   Interpolation.Lerp16 = Eval14Inputs;
+               break;
+
+           case 15:
+               if (IsFloat)
+                   Interpolation.LerpFloat = Eval15InputsFloat;
+               else
+                   Interpolation.Lerp16 = Eval15Inputs;
                break;
 
            default:
diff --git a/src/java.desktop/share/native/liblcms/cmsio0.c b/src/java.desktop/share/native/liblcms/cmsio0.c
index 6c219722ae7..70be6a6ad14 100644
--- a/src/java.desktop/share/native/liblcms/cmsio0.c
+++ b/src/java.desktop/share/native/liblcms/cmsio0.c
@@ -290,7 +290,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromMem(cmsContext ContextID, void *Buff
 
             _cmsFree(ContextID, fm);
             _cmsFree(ContextID, iohandler);
-            cmsSignalError(ContextID, cmsERROR_READ, "Couldn't allocate %ld bytes for profile", size);
+            cmsSignalError(ContextID, cmsERROR_READ, "Couldn't allocate %ld bytes for profile", (long) size);
             return NULL;
         }
 
@@ -1232,25 +1232,28 @@ cmsBool SaveTags(_cmsICCPROFILE* Icc, _cmsICCPROFILE* FileOrig)
             // In this case a blind copy of the block data is performed
             if (FileOrig != NULL && Icc -> TagOffsets[i]) {
 
-                cmsUInt32Number TagSize   = FileOrig -> TagSizes[i];
-                cmsUInt32Number TagOffset = FileOrig -> TagOffsets[i];
-                void* Mem;
+                if (FileOrig->IOhandler != NULL)
+                {
+                    cmsUInt32Number TagSize = FileOrig->TagSizes[i];
+                    cmsUInt32Number TagOffset = FileOrig->TagOffsets[i];
+                    void* Mem;
 
-                if (!FileOrig ->IOhandler->Seek(FileOrig ->IOhandler, TagOffset)) return FALSE;
+                    if (!FileOrig->IOhandler->Seek(FileOrig->IOhandler, TagOffset)) return FALSE;
 
-                Mem = _cmsMalloc(Icc ->ContextID, TagSize);
-                if (Mem == NULL) return FALSE;
+                    Mem = _cmsMalloc(Icc->ContextID, TagSize);
+                    if (Mem == NULL) return FALSE;
 
-                if (FileOrig ->IOhandler->Read(FileOrig->IOhandler, Mem, TagSize, 1) != 1) return FALSE;
-                if (!io ->Write(io, TagSize, Mem)) return FALSE;
-                _cmsFree(Icc ->ContextID, Mem);
+                    if (FileOrig->IOhandler->Read(FileOrig->IOhandler, Mem, TagSize, 1) != 1) return FALSE;
+                    if (!io->Write(io, TagSize, Mem)) return FALSE;
+                    _cmsFree(Icc->ContextID, Mem);
 
-                Icc -> TagSizes[i] = (io ->UsedSpace - Begin);
+                    Icc->TagSizes[i] = (io->UsedSpace - Begin);
 
 
-                // Align to 32 bit boundary.
-                if (! _cmsWriteAlignment(io))
-                    return FALSE;
+                    // Align to 32 bit boundary.
+                    if (!_cmsWriteAlignment(io))
+                        return FALSE;
+                }
             }
 
             continue;
diff --git a/src/java.desktop/share/native/liblcms/cmslut.c b/src/java.desktop/share/native/liblcms/cmslut.c
index f20e185c44a..6eb803fe558 100644
--- a/src/java.desktop/share/native/liblcms/cmslut.c
+++ b/src/java.desktop/share/native/liblcms/cmslut.c
@@ -1366,7 +1366,7 @@ void _LUTeval16(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Num
 
 // Does evaluate the LUT on cmsFloat32Number-basis.
 static
-void _LUTevalFloat(CMSREGISTER const cmsFloat32Number In[], CMSREGISTER cmsFloat32Number Out[], const void* D)
+void _LUTevalFloat(const cmsFloat32Number In[], cmsFloat32Number Out[], const void* D)
 {
     cmsPipeline* lut = (cmsPipeline*) D;
     cmsStage *mpe;
@@ -1687,7 +1687,7 @@ cmsUInt32Number CMSEXPORT cmsPipelineStageCount(const cmsPipeline* lut)
 // This function may be used to set the optional evaluator and a block of private data. If private data is being used, an optional
 // duplicator and free functions should also be specified in order to duplicate the LUT construct. Use NULL to inhibit such functionality.
 void CMSEXPORT _cmsPipelineSetOptimizationParameters(cmsPipeline* Lut,
-                                        _cmsOPTeval16Fn Eval16,
+                                        _cmsPipelineEval16Fn Eval16,
                                         void* PrivateData,
                                         _cmsFreeUserDataFn FreePrivateDataFn,
                                         _cmsDupUserDataFn  DupPrivateDataFn)
diff --git a/src/java.desktop/share/native/liblcms/cmsnamed.c b/src/java.desktop/share/native/liblcms/cmsnamed.c
index 9ab2ea1796a..95a3b5ef8e1 100644
--- a/src/java.desktop/share/native/liblcms/cmsnamed.c
+++ b/src/java.desktop/share/native/liblcms/cmsnamed.c
@@ -209,12 +209,16 @@ cmsBool AddMLUBlock(cmsMLU* mlu, cmsUInt32Number size, const wchar_t *Block,
 
 // Convert from a 3-char code to a cmsUInt16Number. It is done in this way because some
 // compilers don't properly align beginning of strings
-
 static
 cmsUInt16Number strTo16(const char str[3])
 {
-    const cmsUInt8Number* ptr8 = (const cmsUInt8Number*)str;
-    cmsUInt16Number n = (cmsUInt16Number)(((cmsUInt16Number)ptr8[0] << 8) | ptr8[1]);
+    const cmsUInt8Number* ptr8;
+    cmsUInt16Number n;
+
+    // For non-existent strings
+    if (str == NULL) return 0;
+    ptr8 = (const cmsUInt8Number*)str;
+    n = (cmsUInt16Number)(((cmsUInt16Number)ptr8[0] << 8) | ptr8[1]);
 
     return n;
 }
@@ -229,6 +233,7 @@ void strFrom16(char str[3], cmsUInt16Number n)
 }
 
 // Add an ASCII entry. Do not add any \0 termination (ICC1v43_2010-12.pdf page 61)
+// In the case the user explicitely sets an empty string, we force a \0
 cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const char CountryCode[3], const char* ASCIIString)
 {
     cmsUInt32Number i, len = (cmsUInt32Number) strlen(ASCIIString);
@@ -239,6 +244,12 @@ cmsBool CMSEXPORT cmsMLUsetASCII(cmsMLU* mlu, const char LanguageCode[3], const
 
     if (mlu == NULL) return FALSE;
 
+    // len == 0 would prevent operation, so we set a empty string pointing to zero
+    if (len == 0)
+    {
+        len = 1;
+    }
+
     WStr = (wchar_t*) _cmsCalloc(mlu ->ContextID, len,  sizeof(wchar_t));
     if (WStr == NULL) return FALSE;
 
@@ -276,6 +287,9 @@ cmsBool  CMSEXPORT cmsMLUsetWide(cmsMLU* mlu, const char Language[3], const char
     if (WideString == NULL) return FALSE;
 
     len = (cmsUInt32Number) (mywcslen(WideString)) * sizeof(wchar_t);
+    if (len == 0)
+        len = sizeof(wchar_t);
+
     return AddMLUBlock(mlu, len, WideString, Lang, Cntry);
 }
 
diff --git a/src/java.desktop/share/native/liblcms/cmsopt.c b/src/java.desktop/share/native/liblcms/cmsopt.c
index 5b4b1ea6a64..e83b2e0be6d 100644
--- a/src/java.desktop/share/native/liblcms/cmsopt.c
+++ b/src/java.desktop/share/native/liblcms/cmsopt.c
@@ -408,7 +408,20 @@ Prelin16Data* PrelinOpt16alloc(cmsContext ContextID,
 
 
     p16 -> EvalCurveOut16 = (_cmsInterpFn16*) _cmsCalloc(ContextID, nOutputs, sizeof(_cmsInterpFn16));
+    if (p16->EvalCurveOut16 == NULL)
+    {
+        _cmsFree(ContextID, p16);
+        return NULL;
+    }
+
     p16 -> ParamsCurveOut16 = (cmsInterpParams**) _cmsCalloc(ContextID, nOutputs, sizeof(cmsInterpParams* ));
+    if (p16->ParamsCurveOut16 == NULL)
+    {
+
+        _cmsFree(ContextID, p16->EvalCurveOut16);
+        _cmsFree(ContextID, p16);
+        return NULL;
+    }
 
     for (i=0; i < nOutputs; i++) {
 
@@ -435,7 +448,9 @@ Prelin16Data* PrelinOpt16alloc(cmsContext ContextID,
 // Sampler implemented by another LUT. This is a clean way to precalculate the devicelink 3D CLUT for
 // almost any transform. We use floating point precision and then convert from floating point to 16 bits.
 static
-cmsInt32Number XFormSampler16(CMSREGISTER const cmsUInt16Number In[], CMSREGISTER cmsUInt16Number Out[], CMSREGISTER void* Cargo)
+cmsInt32Number XFormSampler16(CMSREGISTER const cmsUInt16Number In[],
+                              CMSREGISTER cmsUInt16Number Out[],
+                              CMSREGISTER void* Cargo)
 {
     cmsPipeline* Lut = (cmsPipeline*) Cargo;
     cmsFloat32Number InFloat[cmsMAXCHANNELS], OutFloat[cmsMAXCHANNELS];
@@ -794,7 +809,7 @@ Error:
 
     if (DataSetIn == NULL && DataSetOut == NULL) {
 
-        _cmsPipelineSetOptimizationParameters(Dest, (_cmsOPTeval16Fn) DataCLUT->Params->Interpolation.Lerp16, DataCLUT->Params, NULL, NULL);
+        _cmsPipelineSetOptimizationParameters(Dest, (_cmsPipelineEval16Fn) DataCLUT->Params->Interpolation.Lerp16, DataCLUT->Params, NULL, NULL);
     }
     else {
 
@@ -939,8 +954,8 @@ void* Prelin8dup(cmsContext ContextID, const void* ptr)
 #define DENS(i,j,k) (LutTable[(i)+(j)+(k)+OutChan])
 static CMS_NO_SANITIZE
 void PrelinEval8(CMSREGISTER const cmsUInt16Number Input[],
-                  CMSREGISTER cmsUInt16Number Output[],
-                  CMSREGISTER const void* D)
+                 CMSREGISTER cmsUInt16Number Output[],
+                 CMSREGISTER const void* D)
 {
 
     cmsUInt8Number         r, g, b;
@@ -957,9 +972,9 @@ void PrelinEval8(CMSREGISTER const cmsUInt16Number Input[],
     g = (cmsUInt8Number) (Input[1] >> 8);
     b = (cmsUInt8Number) (Input[2] >> 8);
 
-    X0 = X1 = (cmsS15Fixed16Number) p8->X0[r];
-    Y0 = Y1 = (cmsS15Fixed16Number) p8->Y0[g];
-    Z0 = Z1 = (cmsS15Fixed16Number) p8->Z0[b];
+    X0 = (cmsS15Fixed16Number) p8->X0[r];
+    Y0 = (cmsS15Fixed16Number) p8->Y0[g];
+    Z0 = (cmsS15Fixed16Number) p8->Z0[b];
 
     rx = p8 ->rx[r];
     ry = p8 ->ry[g];
@@ -1361,8 +1376,8 @@ Curves16Data* CurvesAlloc(cmsContext ContextID, cmsUInt32Number nCurves, cmsUInt
 
 static
 void FastEvaluateCurves8(CMSREGISTER const cmsUInt16Number In[],
-                          CMSREGISTER cmsUInt16Number Out[],
-                          CMSREGISTER const void* D)
+                         CMSREGISTER cmsUInt16Number Out[],
+                         CMSREGISTER const void* D)
 {
     Curves16Data* Data = (Curves16Data*) D;
     int x;
@@ -1922,7 +1937,7 @@ cmsBool  _cmsRegisterOptimizationPlugin(cmsContext ContextID, cmsPluginBase* Dat
 }
 
 // The entry point for LUT optimization
-cmsBool _cmsOptimizePipeline(cmsContext ContextID,
+cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
                              cmsPipeline**    PtrLut,
                              cmsUInt32Number  Intent,
                              cmsUInt32Number* InputFormat,
diff --git a/src/java.desktop/share/native/liblcms/cmspack.c b/src/java.desktop/share/native/liblcms/cmspack.c
index ca0d2877c3e..0ec3edab5d5 100644
--- a/src/java.desktop/share/native/liblcms/cmspack.c
+++ b/src/java.desktop/share/native/liblcms/cmspack.c
@@ -2836,7 +2836,7 @@ cmsUInt8Number* UnrollHalfTo16(CMSREGISTER _cmsTRANSFORM* info,
 
         if (Reverse) v = maximum - v;
 
-        wIn[index] = _cmsQuickSaturateWord(v * maximum);
+        wIn[index] = _cmsQuickSaturateWord((cmsFloat64Number) v * maximum);
     }
 
 
diff --git a/src/java.desktop/share/native/liblcms/cmspcs.c b/src/java.desktop/share/native/liblcms/cmspcs.c
index 31744a6c973..6c628ed5e46 100644
--- a/src/java.desktop/share/native/liblcms/cmspcs.c
+++ b/src/java.desktop/share/native/liblcms/cmspcs.c
@@ -685,7 +685,7 @@ cmsFloat64Number CMSEXPORT cmsCIE2000DeltaE(const cmsCIELab* Lab1, const cmsCIEL
 
 // This function returns a number of gridpoints to be used as LUT table. It assumes same number
 // of gripdpoints in all dimensions. Flags may override the choice.
-cmsUInt32Number _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags)
+cmsUInt32Number CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags)
 {
     cmsUInt32Number nChannels;
 
diff --git a/src/java.desktop/share/native/liblcms/cmsplugin.c b/src/java.desktop/share/native/liblcms/cmsplugin.c
index bff4adc25a9..037e6cbcdf1 100644
--- a/src/java.desktop/share/native/liblcms/cmsplugin.c
+++ b/src/java.desktop/share/native/liblcms/cmsplugin.c
@@ -527,6 +527,7 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
     int len;
     cmsUInt8Number Buffer[2048];
     cmsBool rc;
+    cmsUInt8Number* ptr;
 
     _cmsAssert(io != NULL);
     _cmsAssert(frm != NULL);
@@ -539,6 +540,13 @@ cmsBool CMSEXPORT _cmsIOPrintf(cmsIOHANDLER* io, const char* frm, ...)
         return FALSE;   // Truncated, which is a fatal error for us
     }
 
+    // setlocale may be active, no commas are needed in PS generator
+    // and PS generator is our only client
+    for (ptr = Buffer; *ptr; ptr++)
+    {
+        if (*ptr == ',') *ptr = '.';
+    }
+
     rc = io ->Write(io, (cmsUInt32Number) len, Buffer);
 
     va_end(args);
diff --git a/src/java.desktop/share/native/liblcms/cmsps2.c b/src/java.desktop/share/native/liblcms/cmsps2.c
index d02d6b55a3b..e5274540064 100644
--- a/src/java.desktop/share/native/liblcms/cmsps2.c
+++ b/src/java.desktop/share/native/liblcms/cmsps2.c
@@ -558,9 +558,10 @@ void Emit1Gamma(cmsIOHANDLER* m, cmsToneCurve* Table, const char* name)
 // Compare gamma table
 
 static
-cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, cmsUInt32Number nEntries)
+cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, cmsUInt32Number nG1, cmsUInt32Number nG2)
 {
-    return memcmp(g1, g2, nEntries* sizeof(cmsUInt16Number)) == 0;
+    if (nG1 != nG2) return FALSE;
+    return memcmp(g1, g2, nG1 * sizeof(cmsUInt16Number)) == 0;
 }
 
 
@@ -576,12 +577,12 @@ void EmitNGamma(cmsIOHANDLER* m, cmsUInt32Number n, cmsToneCurve* g[], const cha
     {
         if (g[i] == NULL) return; // Error
 
-        if (i > 0 && GammaTableEquals(g[i-1]->Table16, g[i]->Table16, g[i]->nEntries)) {
+        if (i > 0 && GammaTableEquals(g[i-1]->Table16, g[i]->Table16, g[i-1]->nEntries, g[i]->nEntries)) {
 
             _cmsIOPrintf(m, "/%s%d /%s%d load def\n", nameprefix, i, nameprefix, i-1);
         }
         else {
-            snprintf(buffer, sizeof(buffer), "%s%d", nameprefix, i);
+            snprintf(buffer, sizeof(buffer), "%s%d", nameprefix, (int) i);
             buffer[sizeof(buffer)-1] = '\0';
             Emit1Gamma(m, g[i], buffer);
         }
@@ -836,7 +837,7 @@ int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, cmsUInt32Number Inte
 
     if (cmsStageType(mpe) == cmsSigCurveSetElemType) {
 
-        numchans = cmsStageOutputChannels(mpe);
+        numchans = (int) cmsStageOutputChannels(mpe);
         for (i = 0; i < numchans; ++i) {
             snprintf(buffer, sizeof(buffer), "lcms2gammaproc%d", i);
             buffer[sizeof(buffer) - 1] = '\0';
diff --git a/src/java.desktop/share/native/liblcms/cmssamp.c b/src/java.desktop/share/native/liblcms/cmssamp.c
index 5609eab8d4b..d3836420b3f 100644
--- a/src/java.desktop/share/native/liblcms/cmssamp.c
+++ b/src/java.desktop/share/native/liblcms/cmssamp.c
@@ -112,10 +112,10 @@ cmsBool  BlackPointAsDarkerColorant(cmsHPROFILE    hInput,
         return FALSE;
     }
 
-    // Create a formatter which has n channels and floating point
+    // Create a formatter which has n channels and no floating point
     dwFormat = cmsFormatterForColorspaceOfProfile(hInput, 2, FALSE);
 
-   // Try to get black by using black colorant
+    // Try to get black by using black colorant
     Space = cmsGetColorSpace(hInput);
 
     // This function returns darker colorant in 16 bits for several spaces
diff --git a/src/java.desktop/share/native/liblcms/cmstypes.c b/src/java.desktop/share/native/liblcms/cmstypes.c
index fc667b9a9b4..006f98b084d 100644
--- a/src/java.desktop/share/native/liblcms/cmstypes.c
+++ b/src/java.desktop/share/native/liblcms/cmstypes.c
@@ -1895,6 +1895,7 @@ cmsBool  Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
     mpe = NewLUT -> Elements;
     if (mpe ->Type == cmsSigMatrixElemType) {
 
+        if (mpe->InputChannels != 3 || mpe->OutputChannels != 3) return FALSE;
         MatMPE = (_cmsStageMatrixData*) mpe ->Data;
         mpe = mpe -> Next;
     }
@@ -1920,7 +1921,6 @@ cmsBool  Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
         return FALSE;
     }
 
-
     if (clut == NULL)
         clutPoints = 0;
     else
@@ -1935,15 +1935,13 @@ cmsBool  Type_LUT8_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io,
 
     if (MatMPE != NULL) {
 
-                for (i = 0; i < n; i++)
+                for (i = 0; i < 9; i++)
                 {
                         if (!_cmsWrite15Fixed16Number(io, MatMPE->Double[i])) return FALSE;
                 }
     }
     else {
 
-                if (n != 9) return FALSE;
-
         if (!_cmsWrite15Fixed16Number(io, 1)) return FALSE;
         if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
         if (!_cmsWrite15Fixed16Number(io, 0)) return FALSE;
@@ -3029,6 +3027,9 @@ void *Type_ColorantTable_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER
     }
 
     List = cmsAllocNamedColorList(self ->ContextID, Count, 0, "", "");
+    if (List == NULL)
+        return NULL;
+
     for (i=0; i < Count; i++) {
 
         if (io ->Read(io, Name, 32, 1) != 1) goto Error;
diff --git a/src/java.desktop/share/native/liblcms/cmsxform.c b/src/java.desktop/share/native/liblcms/cmsxform.c
index 162e69e4bc3..6a2170c8fd2 100644
--- a/src/java.desktop/share/native/liblcms/cmsxform.c
+++ b/src/java.desktop/share/native/liblcms/cmsxform.c
@@ -302,7 +302,7 @@ void FloatXFORM(_cmsTRANSFORM* p,
     strideIn = 0;
     strideOut = 0;
     memset(fIn, 0, sizeof(fIn));
-    memset(fOut, 0, sizeof(fIn));
+    memset(fOut, 0, sizeof(fOut));
 
     for (i = 0; i < LineCount; i++) {
 
@@ -476,7 +476,7 @@ void TransformOnePixelWithGamutCheck(_cmsTRANSFORM* p,
     p ->GamutCheck ->Eval16Fn(wIn, &wOutOfGamut, p ->GamutCheck ->Data);
     if (wOutOfGamut >= 1) {
 
-        cmsUInt16Number i;
+        cmsUInt32Number i;
         _cmsAlarmCodesChunkType* ContextAlarmCodes = (_cmsAlarmCodesChunkType*) _cmsContextGetClientChunk(p->ContextID, AlarmCodesContext);
 
         for (i=0; i < p ->Lut->OutputChannels; i++) {
@@ -803,6 +803,12 @@ void CMSEXPORT _cmsGetTransformFormattersFloat(struct _cmstransform_struct *CMMc
      if (ToOutput)  *ToOutput  = CMMcargo ->ToOutputFloat;
 }
 
+// returns original flags
+cmsUInt32Number CMSEXPORT _cmsGetTransformFlags(struct _cmstransform_struct* CMMcargo)
+{
+    _cmsAssert(CMMcargo != NULL);
+    return CMMcargo->dwOriginalFlags;
+}
 
 // Allocate transform struct and set it to defaults. Ask the optimization plug-in about if those formats are proper
 // for separated transforms. If this is the case,
diff --git a/src/java.desktop/share/native/liblcms/lcms2.h b/src/java.desktop/share/native/liblcms/lcms2.h
index 8d5373919bb..69ada9ede64 100644
--- a/src/java.desktop/share/native/liblcms/lcms2.h
+++ b/src/java.desktop/share/native/liblcms/lcms2.h
@@ -30,7 +30,7 @@
 //---------------------------------------------------------------------------------
 //
 //  Little Color Management System
-//  Copyright (c) 1998-2020 Marti Maria Saguer
+//  Copyright (c) 1998-2021 Marti Maria Saguer
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the "Software"),
@@ -52,7 +52,7 @@
 //
 //---------------------------------------------------------------------------------
 //
-// Version 2.11
+// Version 2.12
 //
 
 #ifndef _lcms2_H
@@ -110,7 +110,7 @@ extern "C" {
 #endif
 
 // Version/release
-#define LCMS_VERSION        2100
+#define LCMS_VERSION        2120
 
 // I will give the chance of redefining basic types for compilers that are not fully C99 compliant
 #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
@@ -1299,7 +1299,7 @@ typedef cmsInt32Number (* cmsSAMPLERFLOAT)(CMSREGISTER const cmsFloat32Number In
 #define SAMPLER_INSPECT     0x01000000
 
 // For CLUT only
-CMSAPI cmsBool           CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe,    cmsSAMPLER16 Sampler, void* Cargo, cmsUInt32Number dwFlags);
+CMSAPI cmsBool           CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void* Cargo, cmsUInt32Number dwFlags);
 CMSAPI cmsBool           CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler, void* Cargo, cmsUInt32Number dwFlags);
 
 // Slicers
diff --git a/src/java.desktop/share/native/liblcms/lcms2_internal.h b/src/java.desktop/share/native/liblcms/lcms2_internal.h
index e1698f27ba2..d1c78208b82 100644
--- a/src/java.desktop/share/native/liblcms/lcms2_internal.h
+++ b/src/java.desktop/share/native/liblcms/lcms2_internal.h
@@ -27,7 +27,7 @@
 // However, the following notice accompanied the original version of this
 // file:
 //
-//---------------------------------------------------------------------------------
+
 //
 //  Little Color Management System
 //  Copyright (c) 1998-2020 Marti Maria Saguer
@@ -937,13 +937,7 @@ cmsStage*                          _cmsStageClipNegatives(cmsContext ContextID,
 
 
 // For curve set only
-cmsToneCurve**     _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
-
-
-// Pipeline Evaluator (in floating point)
-typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[],
-                                         cmsFloat32Number Out[],
-                                         const void* Data);
+cmsToneCurve**  _cmsStageGetPtrToCurveSet(const cmsStage* mpe);
 
 struct _cmsPipeline_struct {
 
@@ -953,7 +947,7 @@ struct _cmsPipeline_struct {
     // Data & evaluators
     void *Data;
 
-   _cmsOPTeval16Fn         Eval16Fn;
+   _cmsPipelineEval16Fn    Eval16Fn;
    _cmsPipelineEvalFloatFn EvalFloatFn;
    _cmsFreeUserDataFn      FreeDataFn;
    _cmsDupUserDataFn       DupDataFn;
@@ -1000,14 +994,14 @@ cmsSEQ* _cmsCompileProfileSequence(cmsContext ContextID, cmsUInt32Number nProfil
 
 CMSCHECKPOINT cmsUInt16Number  CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples);
 
-cmsUInt32Number  _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
+CMSAPI cmsUInt32Number  CMSEXPORT _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags);
 
 cmsBool          _cmsEndPointsBySpace(cmsColorSpaceSignature Space,
                                       cmsUInt16Number **White,
                                       cmsUInt16Number **Black,
                                       cmsUInt32Number *nOutputs);
 
-cmsBool          _cmsOptimizePipeline(cmsContext ContextID,
+CMSAPI cmsBool CMSEXPORT _cmsOptimizePipeline(cmsContext ContextID,
                                       cmsPipeline**    Lut,
                                       cmsUInt32Number  Intent,
                                       cmsUInt32Number* InputFormat,
diff --git a/src/java.desktop/share/native/liblcms/lcms2_plugin.h b/src/java.desktop/share/native/liblcms/lcms2_plugin.h
index 7818e86eb6a..61e963ff5f8 100644
--- a/src/java.desktop/share/native/liblcms/lcms2_plugin.h
+++ b/src/java.desktop/share/native/liblcms/lcms2_plugin.h
@@ -315,7 +315,7 @@ typedef union {
 #define CMS_LERP_FLAGS_TRILINEAR          0x0100        // Hint only
 
 
-#define MAX_INPUT_DIMENSIONS 8
+#define MAX_INPUT_DIMENSIONS 15
 
 typedef struct _cms_interp_struc {  // Used on all interpolations. Supplied by lcms2 when calling the interpolation function
 
@@ -576,22 +576,28 @@ typedef struct {
 // the optimization  search. Or FALSE if it is unable to optimize and want to give a chance
 // to the rest of optimizers.
 
-typedef void     (* _cmsOPTeval16Fn)(CMSREGISTER const cmsUInt16Number In[],
-                                     CMSREGISTER cmsUInt16Number Out[],
-                                     CMSREGISTER const void* Data);
-
-
 typedef cmsBool  (* _cmsOPToptimizeFn)(cmsPipeline** Lut,
                                        cmsUInt32Number  Intent,
                                        cmsUInt32Number* InputFormat,
                                        cmsUInt32Number* OutputFormat,
                                        cmsUInt32Number* dwFlags);
 
+// Pipeline Evaluator (in 16 bits)
+typedef void (* _cmsPipelineEval16Fn)(CMSREGISTER const cmsUInt16Number In[],
+                                     CMSREGISTER cmsUInt16Number Out[],
+                                     const void* Data);
+
+// Pipeline Evaluator (in floating point)
+typedef void (* _cmsPipelineEvalFloatFn)(const cmsFloat32Number In[],
+                                         cmsFloat32Number Out[],
+                                         const void* Data);
+
+
 // This function may be used to set the optional evaluator and a block of private data. If private data is being used, an optional
 // duplicator and free functions should also be specified in order to duplicate the LUT construct. Use NULL to inhibit such functionality.
 
 CMSAPI void CMSEXPORT _cmsPipelineSetOptimizationParameters(cmsPipeline* Lut,
-                                               _cmsOPTeval16Fn Eval16,
+                                               _cmsPipelineEval16Fn Eval16,
                                                void* PrivateData,
                                                _cmsFreeUserDataFn FreePrivateDataFn,
                                                _cmsDupUserDataFn DupPrivateDataFn);
@@ -655,6 +661,9 @@ CMSAPI void * CMSEXPORT _cmsGetTransformUserData(struct _cmstransform_struct *CM
 CMSAPI void   CMSEXPORT _cmsGetTransformFormatters16   (struct _cmstransform_struct *CMMcargo, cmsFormatter16* FromInput, cmsFormatter16* ToOutput);
 CMSAPI void   CMSEXPORT _cmsGetTransformFormattersFloat(struct _cmstransform_struct *CMMcargo, cmsFormatterFloat* FromInput, cmsFormatterFloat* ToOutput);
 
+// Retrieve original flags
+CMSAPI cmsUInt32Number CMSEXPORT _cmsGetTransformFlags(struct _cmstransform_struct* CMMcargo);
+
 typedef struct {
       cmsPluginBase     base;
 
-- 
GitLab


From 40754f12f768ed1b32cbda187b0f43e9ee25c5c9 Mon Sep 17 00:00:00 2001
From: Prasanta Sadhukhan 
Date: Wed, 10 Feb 2021 17:26:28 +0000
Subject: [PATCH 010/367] 4841153: java.awt.geom.Rectangle2D.add(double,double)
 documented incorrectly

Reviewed-by: prr
---
 src/java.desktop/share/classes/java/awt/geom/Rectangle2D.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/java.desktop/share/classes/java/awt/geom/Rectangle2D.java b/src/java.desktop/share/classes/java/awt/geom/Rectangle2D.java
index 3431d0d60aa..b27bdce7f25 100644
--- a/src/java.desktop/share/classes/java/awt/geom/Rectangle2D.java
+++ b/src/java.desktop/share/classes/java/awt/geom/Rectangle2D.java
@@ -794,7 +794,7 @@ public abstract class Rectangle2D extends RectangularShape {
      * {@code true}. The {@code contains} method does not
      * return {@code true} for points on the right or bottom
      * edges of a rectangle. Therefore, if the added point falls on
-     * the left or bottom edge of the enlarged rectangle,
+     * the right or bottom edge of the enlarged rectangle,
      * {@code contains} returns {@code false} for that point.
      * @param newx the X coordinate of the new point
      * @param newy the Y coordinate of the new point
@@ -820,7 +820,7 @@ public abstract class Rectangle2D extends RectangularShape {
      * {@code true}. The {@code contains}
      * method does not return {@code true} for points on the right
      * or bottom edges of a rectangle. Therefore, if the added point falls
-     * on the left or bottom edge of the enlarged rectangle,
+     * on the right or bottom edge of the enlarged rectangle,
      * {@code contains} returns {@code false} for that point.
      * @param     pt the new {@code Point2D} to add to this
      * {@code Rectangle2D}.
-- 
GitLab


From cc5691c69ed2e71f99001a660c71c9b57c803e60 Mon Sep 17 00:00:00 2001
From: Alex Menkov 
Date: Wed, 10 Feb 2021 22:17:48 +0000
Subject: [PATCH 011/367] 8248162:
 serviceability/attach/RemovingUnixDomainSocketTest.java failed

Reviewed-by: cjplummer, sspitsyn
---
 test/hotspot/jtreg/ProblemList.txt                        | 2 --
 .../jtreg/serviceability/sa/ClhsdbJstackXcompStress.java  | 2 +-
 .../jtreg/serviceability/sa/JhsdbThreadInfoTest.java      | 2 +-
 .../jtreg/serviceability/sa/TestJhsdbJstackLock.java      | 2 +-
 .../serviceability/sa/sadebugd/DebugdConnectTest.java     | 8 ++++----
 test/jdk/sun/tools/jcmd/TestJcmdDefaults.java             | 2 +-
 test/jdk/sun/tools/jcmd/TestJcmdSanity.java               | 2 +-
 7 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt
index 3a565de150b..06bdea729fb 100644
--- a/test/hotspot/jtreg/ProblemList.txt
+++ b/test/hotspot/jtreg/ProblemList.txt
@@ -99,8 +99,6 @@ serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatIntervalTest.java 8214
 serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatArrayCorrectnessTest.java 8224150 generic-all
 serviceability/jvmti/ModuleAwareAgents/ThreadStart/MAAThreadStart.java 8225354 windows-all
 
-serviceability/attach/RemovingUnixDomainSocketTest.java 8248162 linux-x64
-
 #############################################################################
 
 # :hotspot_misc
diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbJstackXcompStress.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbJstackXcompStress.java
index c92bc7ded9f..da872b8dad8 100644
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbJstackXcompStress.java
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbJstackXcompStress.java
@@ -74,7 +74,7 @@ public class ClhsdbJstackXcompStress {
                 System.err.println(out.getStderr());
             }
 
-            out.stderrShouldBeEmptyIgnoreVMWarnings();
+            out.stderrShouldBeEmptyIgnoreDeprecatedWarnings();
             out.stdoutShouldNotContain("Error occurred during stack walking:");
             out.stdoutShouldContain(LingeredAppWithRecComputation.THREAD_NAME);
             List stdoutList = Arrays.asList(out.getStdout().split("\\R"));
diff --git a/test/hotspot/jtreg/serviceability/sa/JhsdbThreadInfoTest.java b/test/hotspot/jtreg/serviceability/sa/JhsdbThreadInfoTest.java
index d888b78b5c3..7cdc39175a4 100644
--- a/test/hotspot/jtreg/serviceability/sa/JhsdbThreadInfoTest.java
+++ b/test/hotspot/jtreg/serviceability/sa/JhsdbThreadInfoTest.java
@@ -68,7 +68,7 @@ public class JhsdbThreadInfoTest {
             out.shouldNotContain(" prio=0 ");
             out.shouldNotContain("   java.lang.Thread.State: UNKNOWN");
 
-            out.stderrShouldBeEmptyIgnoreVMWarnings();
+            out.stderrShouldBeEmptyIgnoreDeprecatedWarnings();
 
             System.out.println("Test Completed");
         } catch (Exception ex) {
diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java
index a10d757266a..def56bc693f 100644
--- a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java
+++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java
@@ -65,7 +65,7 @@ public class TestJhsdbJstackLock {
             out.shouldMatch("^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Thread\\)$");
             out.shouldMatch("^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Class for int\\)$");
 
-            out.stderrShouldBeEmptyIgnoreVMWarnings();
+            out.stderrShouldBeEmptyIgnoreDeprecatedWarnings();
 
             System.out.println("Test Completed");
         } finally {
diff --git a/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdConnectTest.java b/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdConnectTest.java
index f90fafe2430..a1c5e5a4af4 100644
--- a/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdConnectTest.java
+++ b/test/hotspot/jtreg/serviceability/sa/sadebugd/DebugdConnectTest.java
@@ -70,7 +70,7 @@ public class DebugdConnectTest {
         OutputAnalyzer out = runJHSDB("jstack", id);
 
         out.shouldContain("LingeredApp");
-        out.stderrShouldBeEmptyIgnoreVMWarnings();
+        out.stderrShouldBeEmptyIgnoreDeprecatedWarnings();
         out.shouldHaveExitValue(0);
     }
 
@@ -78,7 +78,7 @@ public class DebugdConnectTest {
         OutputAnalyzer out = runJHSDB("jmap", id);
 
         out.shouldContain("JVM version is");
-        out.stderrShouldBeEmptyIgnoreVMWarnings();
+        out.stderrShouldBeEmptyIgnoreDeprecatedWarnings();
         out.shouldHaveExitValue(0);
     }
 
@@ -86,7 +86,7 @@ public class DebugdConnectTest {
         OutputAnalyzer out = runJHSDB("jinfo", id);
 
         out.shouldContain("Java System Properties:");
-        out.stderrShouldBeEmptyIgnoreVMWarnings();
+        out.stderrShouldBeEmptyIgnoreDeprecatedWarnings();
         out.shouldHaveExitValue(0);
     }
 
@@ -94,7 +94,7 @@ public class DebugdConnectTest {
         OutputAnalyzer out = runJHSDB("jsnap", id);
 
         out.shouldContain("java.vm.name=");
-        out.stderrShouldBeEmptyIgnoreVMWarnings();
+        out.stderrShouldBeEmptyIgnoreDeprecatedWarnings();
         out.shouldHaveExitValue(0);
     }
 
diff --git a/test/jdk/sun/tools/jcmd/TestJcmdDefaults.java b/test/jdk/sun/tools/jcmd/TestJcmdDefaults.java
index 05b41478ea8..6f9b6aa7e10 100644
--- a/test/jdk/sun/tools/jcmd/TestJcmdDefaults.java
+++ b/test/jdk/sun/tools/jcmd/TestJcmdDefaults.java
@@ -91,7 +91,7 @@ public class TestJcmdDefaults {
      */
     private static void matchListedProcesses(OutputAnalyzer output) {
         output.stdoutShouldMatchByLine(JCMD_LIST_REGEX);
-        output.stderrShouldBeEmptyIgnoreVMWarnings();
+        output.stderrShouldBeEmptyIgnoreDeprecatedWarnings();
     }
 
     private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException {
diff --git a/test/jdk/sun/tools/jcmd/TestJcmdSanity.java b/test/jdk/sun/tools/jcmd/TestJcmdSanity.java
index 2376df99699..e44d720f3bc 100644
--- a/test/jdk/sun/tools/jcmd/TestJcmdSanity.java
+++ b/test/jdk/sun/tools/jcmd/TestJcmdSanity.java
@@ -153,7 +153,7 @@ public class TestJcmdSanity {
      */
     private static void matchPerfCounters(OutputAnalyzer output) {
         output.stdoutShouldMatchByLine(PERF_COUNTER_REGEX, null, PERF_COUNTER_REGEX);
-        output.stderrShouldBeEmptyIgnoreVMWarnings();
+        output.stderrShouldBeEmptyIgnoreDeprecatedWarnings();
     }
 
     private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException {
-- 
GitLab


From 447db62762d7882cf5593155337b8c5acd99ecd1 Mon Sep 17 00:00:00 2001
From: Sergey Bylokhov 
Date: Wed, 10 Feb 2021 23:57:32 +0000
Subject: [PATCH 012/367] 6211198: ICC_Profile.getInstance(byte[]): IAE is not
 specified

Reviewed-by: prr, pbansal
---
 .../classes/java/awt/color/ICC_Profile.java   | 12 ++----
 .../java/awt/color/GetInstanceBrokenData.java | 42 +++++++++++++++++++
 .../java/awt/color/GetInstanceNullData.java   |  2 +-
 3 files changed, 47 insertions(+), 9 deletions(-)
 create mode 100644 test/jdk/java/awt/color/GetInstanceBrokenData.java

diff --git a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java
index 8afdc638d42..3e86fcf6141 100644
--- a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java
+++ b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java
@@ -758,12 +758,13 @@ public class ICC_Profile implements Serializable {
 
     /**
      * Constructs an {@code ICC_Profile} object corresponding to the data in a
-     * byte array. Throws an {@code IllegalArgumentException} if the data does
-     * not correspond to a valid ICC Profile.
+     * byte array.
      *
      * @param  data the specified ICC Profile data
      * @return an {@code ICC_Profile} object corresponding to the data in the
      *         specified {@code data} array
+     * @throws IllegalArgumentException If the byte array does not contain valid
+     *         ICC Profile data
      */
     public static ICC_Profile getInstance(byte[] data) {
     ICC_Profile thisProfile;
@@ -957,12 +958,7 @@ public class ICC_Profile implements Serializable {
      *         Profile data
      */
     public static ICC_Profile getInstance(InputStream s) throws IOException {
-        byte[] profileData;
-        if ((profileData = getProfileDataFromStream(s)) == null) {
-            throw new IllegalArgumentException("Invalid ICC Profile Data");
-        }
-
-        return getInstance(profileData);
+        return getInstance(getProfileDataFromStream(s));
     }
 
 
diff --git a/test/jdk/java/awt/color/GetInstanceBrokenData.java b/test/jdk/java/awt/color/GetInstanceBrokenData.java
new file mode 100644
index 00000000000..1ba78177b33
--- /dev/null
+++ b/test/jdk/java/awt/color/GetInstanceBrokenData.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2021, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.color.ICC_Profile;
+
+/**
+ * @test
+ * @bug 6211198
+ * @summary IllegalArgumentException in ICC_Profile.getInstance for broken data
+ */
+public final class GetInstanceBrokenData {
+
+    public static void main(String[] argv) {
+        byte b[] = {-21, -22, -23};
+        try {
+            ICC_Profile p = ICC_Profile.getInstance(b);
+            throw new RuntimeException("IllegalArgumentException is expected");
+        } catch (IllegalArgumentException ignored) {
+            // expected
+        }
+    }
+}
diff --git a/test/jdk/java/awt/color/GetInstanceNullData.java b/test/jdk/java/awt/color/GetInstanceNullData.java
index 9543455477a..b31e3cc4d3d 100644
--- a/test/jdk/java/awt/color/GetInstanceNullData.java
+++ b/test/jdk/java/awt/color/GetInstanceNullData.java
@@ -27,7 +27,7 @@ import java.awt.color.ICC_ProfileRGB;
 
 /**
  * @test
- * @bug 4176618 7042594
+ * @bug 4176618 7042594 6211198
  * @summary This interactive test verifies that passing null to
  *          ICC_ProfileRGB.getInstance() does not crash the VM.
  *          An IllegalArgumentException: Invalid ICC Profile Data should be
-- 
GitLab


From adca84cc29caebd5deeb6fea82d287cf30d62a70 Mon Sep 17 00:00:00 2001
From: Ioi Lam 
Date: Thu, 11 Feb 2021 05:11:48 +0000
Subject: [PATCH 013/367] 8260341: CDS dump VM init code does not check
 exceptions

Reviewed-by: coleenp, hseigel
---
 src/hotspot/share/classfile/classLoader.cpp   | 59 +++++++++----------
 src/hotspot/share/classfile/classLoader.hpp   | 16 ++---
 .../share/classfile/classLoaderExt.cpp        | 18 +++---
 .../share/classfile/classLoaderExt.hpp        |  8 +--
 src/hotspot/share/classfile/klassFactory.cpp  |  4 +-
 .../share/classfile/systemDictionary.cpp      |  2 +-
 src/hotspot/share/memory/filemap.cpp          | 46 +++++++--------
 src/hotspot/share/memory/filemap.hpp          |  6 +-
 src/hotspot/share/memory/metaspaceShared.cpp  |  9 ++-
 src/hotspot/share/oops/instanceKlass.cpp      |  2 +-
 src/hotspot/share/oops/instanceKlass.hpp      |  4 +-
 src/hotspot/share/runtime/thread.cpp          |  4 ++
 12 files changed, 93 insertions(+), 85 deletions(-)

diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp
index d80fe19bd35..2edfa233961 100644
--- a/src/hotspot/share/classfile/classLoader.cpp
+++ b/src/hotspot/share/classfile/classLoader.cpp
@@ -287,7 +287,7 @@ ClassPathZipEntry::~ClassPathZipEntry() {
 
 u1* ClassPathZipEntry::open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS) {
     // enable call to C land
-  JavaThread* thread = JavaThread::current();
+  JavaThread* thread = THREAD->as_Java_thread();
   ThreadToNativeFromVM ttn(thread);
   // check whether zip archive contains name
   jint name_len;
@@ -501,7 +501,7 @@ void ClassLoader::trace_class_path(const char* msg, const char* name) {
   }
 }
 
-void ClassLoader::setup_bootstrap_search_path() {
+void ClassLoader::setup_bootstrap_search_path(TRAPS) {
   const char* sys_class_path = Arguments::get_sysclasspath();
   assert(sys_class_path != NULL, "System boot class path must not be NULL");
   if (PrintSharedArchiveAndExit) {
@@ -510,11 +510,11 @@ void ClassLoader::setup_bootstrap_search_path() {
   } else {
     trace_class_path("bootstrap loader class path=", sys_class_path);
   }
-  setup_boot_search_path(sys_class_path);
+  setup_bootstrap_search_path_impl(sys_class_path, CHECK);
 }
 
 #if INCLUDE_CDS
-void ClassLoader::setup_app_search_path(const char *class_path) {
+void ClassLoader::setup_app_search_path(const char *class_path, TRAPS) {
   Arguments::assert_is_dumping_archive();
 
   ResourceMark rm;
@@ -522,7 +522,7 @@ void ClassLoader::setup_app_search_path(const char *class_path) {
 
   while (cp_stream.has_next()) {
     const char* path = cp_stream.get_next();
-    update_class_path_entry_list(path, false, false, false);
+    update_class_path_entry_list(path, false, false, false, CHECK);
   }
 }
 
@@ -542,7 +542,7 @@ void ClassLoader::add_to_module_path_entries(const char* path,
 }
 
 // Add a module path to the _module_path_entries list.
-void ClassLoader::update_module_path_entry_list(const char *path, TRAPS) {
+void ClassLoader::setup_module_search_path(const char* path, TRAPS) {
   Arguments::assert_is_dumping_archive();
   struct stat st;
   if (os::stat(path, &st) != 0) {
@@ -562,10 +562,6 @@ void ClassLoader::update_module_path_entry_list(const char *path, TRAPS) {
   return;
 }
 
-void ClassLoader::setup_module_search_path(const char* path, TRAPS) {
-  update_module_path_entry_list(path, THREAD);
-}
-
 #endif // INCLUDE_CDS
 
 void ClassLoader::close_jrt_image() {
@@ -632,8 +628,7 @@ bool ClassLoader::is_in_patch_mod_entries(Symbol* module_name) {
 }
 
 // Set up the _jrt_entry if present and boot append path
-void ClassLoader::setup_boot_search_path(const char *class_path) {
-  EXCEPTION_MARK;
+void ClassLoader::setup_bootstrap_search_path_impl(const char *class_path, TRAPS) {
   ResourceMark rm(THREAD);
   ClasspathStream cp_stream(class_path);
   bool set_base_piece = true;
@@ -675,7 +670,7 @@ void ClassLoader::setup_boot_search_path(const char *class_path) {
     } else {
       // Every entry on the system boot class path after the initial base piece,
       // which is set by os::set_boot_path(), is considered an appended entry.
-      update_class_path_entry_list(path, false, true, false);
+      update_class_path_entry_list(path, false, true, false, CHECK);
     }
   }
 }
@@ -722,7 +717,7 @@ ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const str
                                                      bool is_boot_append,
                                                      bool from_class_path_attr,
                                                      TRAPS) {
-  JavaThread* thread = JavaThread::current();
+  JavaThread* thread = THREAD->as_Java_thread();
   ClassPathEntry* new_entry = NULL;
   if ((st->st_mode & S_IFMT) == S_IFREG) {
     ResourceMark rm(thread);
@@ -847,7 +842,8 @@ void ClassLoader::add_to_boot_append_entries(ClassPathEntry *new_entry) {
 // jdk/internal/loader/ClassLoaders$AppClassLoader instance.
 void ClassLoader::add_to_app_classpath_entries(const char* path,
                                                ClassPathEntry* entry,
-                                               bool check_for_duplicates) {
+                                               bool check_for_duplicates,
+                                               TRAPS) {
 #if INCLUDE_CDS
   assert(entry != NULL, "ClassPathEntry should not be NULL");
   ClassPathEntry* e = _app_classpath_entries;
@@ -871,7 +867,7 @@ void ClassLoader::add_to_app_classpath_entries(const char* path,
   }
 
   if (entry->is_jar_file()) {
-    ClassLoaderExt::process_jar_manifest(entry, check_for_duplicates);
+    ClassLoaderExt::process_jar_manifest(entry, check_for_duplicates, CHECK);
   }
 #endif
 }
@@ -881,13 +877,12 @@ bool ClassLoader::update_class_path_entry_list(const char *path,
                                                bool check_for_duplicates,
                                                bool is_boot_append,
                                                bool from_class_path_attr,
-                                               bool throw_exception) {
+                                               TRAPS) {
   struct stat st;
   if (os::stat(path, &st) == 0) {
     // File or directory found
     ClassPathEntry* new_entry = NULL;
-    Thread* THREAD = Thread::current();
-    new_entry = create_class_path_entry(path, &st, throw_exception, is_boot_append, from_class_path_attr, CHECK_(false));
+    new_entry = create_class_path_entry(path, &st, /*throw_exception=*/true, is_boot_append, from_class_path_attr, CHECK_false);
     if (new_entry == NULL) {
       return false;
     }
@@ -897,7 +892,7 @@ bool ClassLoader::update_class_path_entry_list(const char *path,
     if (is_boot_append) {
       add_to_boot_append_entries(new_entry);
     } else {
-      add_to_app_classpath_entries(path, new_entry, check_for_duplicates);
+      add_to_app_classpath_entries(path, new_entry, check_for_duplicates, CHECK_false);
     }
     return true;
   } else {
@@ -1286,7 +1281,7 @@ InstanceKlass* ClassLoader::load_class(Symbol* name, bool search_append_only, TR
     return NULL;
   }
 
-  result->set_classpath_index(classpath_index, THREAD);
+  result->set_classpath_index(classpath_index);
   return result;
 }
 
@@ -1421,7 +1416,7 @@ void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream
                                                          ik->name()->utf8_length());
   assert(file_name != NULL, "invariant");
 
-  ClassLoaderExt::record_result(classpath_index, ik, THREAD);
+  ClassLoaderExt::record_result(classpath_index, ik, CHECK);
 }
 #endif // INCLUDE_CDS
 
@@ -1430,9 +1425,7 @@ void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream
 // this list has been created, it must not change order (see class PackageInfo)
 // it can be appended to and is by jvmti.
 
-void ClassLoader::initialize() {
-  EXCEPTION_MARK;
-
+void ClassLoader::initialize(TRAPS) {
   if (UsePerfData) {
     // jvmstat performance counters
     NEWPERFTICKCOUNTER(_perf_accumulated_time, SUN_CLS, "time");
@@ -1464,7 +1457,7 @@ void ClassLoader::initialize() {
   // lookup java library entry points
   load_java_library();
   // jimage library entry points are loaded below, in lookup_vm_options
-  setup_bootstrap_search_path();
+  setup_bootstrap_search_path(CHECK);
 }
 
 char* lookup_vm_resource(JImageFile *jimage, const char *jimage_version, const char *path) {
@@ -1501,16 +1494,16 @@ char* ClassLoader::lookup_vm_options() {
 }
 
 #if INCLUDE_CDS
-void ClassLoader::initialize_shared_path() {
+void ClassLoader::initialize_shared_path(TRAPS) {
   if (Arguments::is_dumping_archive()) {
-    ClassLoaderExt::setup_search_paths();
+    ClassLoaderExt::setup_search_paths(CHECK);
   }
 }
 
 void ClassLoader::initialize_module_path(TRAPS) {
   if (Arguments::is_dumping_archive()) {
-    ClassLoaderExt::setup_module_paths(THREAD);
-    FileMapInfo::allocate_shared_path_table();
+    ClassLoaderExt::setup_module_paths(CHECK);
+    FileMapInfo::allocate_shared_path_table(CHECK);
   }
 }
 
@@ -1566,7 +1559,11 @@ int ClassLoader::compute_Object_vtable() {
 
 
 void classLoader_init1() {
-  ClassLoader::initialize();
+  EXCEPTION_MARK;
+  ClassLoader::initialize(THREAD);
+  if (HAS_PENDING_EXCEPTION) {
+    vm_exit_during_initialization("ClassLoader::initialize() failed unexpectedly");
+  }
 }
 
 // Complete the ClassPathEntry setup for the boot loader
diff --git a/src/hotspot/share/classfile/classLoader.hpp b/src/hotspot/share/classfile/classLoader.hpp
index 8df5a50b735..da057b54edb 100644
--- a/src/hotspot/share/classfile/classLoader.hpp
+++ b/src/hotspot/share/classfile/classLoader.hpp
@@ -222,11 +222,12 @@ class ClassLoader: AllStatic {
   CDS_ONLY(static ClassPathEntry* _last_app_classpath_entry;)
   CDS_ONLY(static ClassPathEntry* _module_path_entries;)
   CDS_ONLY(static ClassPathEntry* _last_module_path_entry;)
-  CDS_ONLY(static void setup_app_search_path(const char* class_path);)
+  CDS_ONLY(static void setup_app_search_path(const char* class_path, TRAPS);)
   CDS_ONLY(static void setup_module_search_path(const char* path, TRAPS);)
   static void add_to_app_classpath_entries(const char* path,
                                            ClassPathEntry* entry,
-                                           bool check_for_duplicates);
+                                           bool check_for_duplicates,
+                                           TRAPS);
   CDS_ONLY(static void add_to_module_path_entries(const char* path,
                                            ClassPathEntry* entry);)
  public:
@@ -240,8 +241,8 @@ class ClassLoader: AllStatic {
   //   - setup the boot loader's system class path
   //   - setup the boot loader's patch mod entries, if present
   //   - create the ModuleEntry for java.base
-  static void setup_bootstrap_search_path();
-  static void setup_boot_search_path(const char *class_path);
+  static void setup_bootstrap_search_path(TRAPS);
+  static void setup_bootstrap_search_path_impl(const char *class_path, TRAPS);
   static void setup_patch_mod_entries();
   static void create_javabase();
 
@@ -272,8 +273,7 @@ class ClassLoader: AllStatic {
                                            bool check_for_duplicates,
                                            bool is_boot_append,
                                            bool from_class_path_attr,
-                                           bool throw_exception=true);
-  CDS_ONLY(static void update_module_path_entry_list(const char *path, TRAPS);)
+                                           TRAPS);
   static void print_bootclasspath();
 
   // Timing
@@ -335,9 +335,9 @@ class ClassLoader: AllStatic {
   static objArrayOop get_system_packages(TRAPS);
 
   // Initialization
-  static void initialize();
+  static void initialize(TRAPS);
   static void classLoader_init2(TRAPS);
-  CDS_ONLY(static void initialize_shared_path();)
+  CDS_ONLY(static void initialize_shared_path(TRAPS);)
   CDS_ONLY(static void initialize_module_path(TRAPS);)
 
   static int compute_Object_vtable();
diff --git a/src/hotspot/share/classfile/classLoaderExt.cpp b/src/hotspot/share/classfile/classLoaderExt.cpp
index bd39fc071e5..f9003f34368 100644
--- a/src/hotspot/share/classfile/classLoaderExt.cpp
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp
@@ -65,7 +65,7 @@ void ClassLoaderExt::append_boot_classpath(ClassPathEntry* new_entry) {
   ClassLoader::add_to_boot_append_entries(new_entry);
 }
 
-void ClassLoaderExt::setup_app_search_path() {
+void ClassLoaderExt::setup_app_search_path(TRAPS) {
   Arguments::assert_is_dumping_archive();
   _app_class_paths_start_index = ClassLoader::num_boot_classpath_entries();
   char* app_class_path = os::strdup(Arguments::get_appclasspath());
@@ -77,7 +77,7 @@ void ClassLoaderExt::setup_app_search_path() {
     trace_class_path("app loader class path (skipped)=", app_class_path);
   } else {
     trace_class_path("app loader class path=", app_class_path);
-    ClassLoader::setup_app_search_path(app_class_path);
+    ClassLoader::setup_app_search_path(app_class_path, CHECK);
   }
 }
 
@@ -88,7 +88,7 @@ void ClassLoaderExt::process_module_table(ModuleEntryTable* met, TRAPS) {
       char* path = m->location()->as_C_string();
       if (strncmp(path, "file:", 5) == 0) {
         path = ClassLoader::skip_uri_protocol(path);
-        ClassLoader::setup_module_search_path(path, THREAD);
+        ClassLoader::setup_module_search_path(path, CHECK);
       }
       m = m->next();
     }
@@ -100,7 +100,7 @@ void ClassLoaderExt::setup_module_paths(TRAPS) {
                               ClassLoader::num_app_classpath_entries();
   Handle system_class_loader (THREAD, SystemDictionary::java_system_loader());
   ModuleEntryTable* met = Modules::get_module_entry_table(system_class_loader);
-  process_module_table(met, THREAD);
+  process_module_table(met, CHECK);
 }
 
 char* ClassLoaderExt::read_manifest(ClassPathEntry* entry, jint *manifest_size, bool clean_text, TRAPS) {
@@ -164,8 +164,7 @@ char* ClassLoaderExt::get_class_path_attr(const char* jar_path, char* manifest,
 }
 
 void ClassLoaderExt::process_jar_manifest(ClassPathEntry* entry,
-                                          bool check_for_duplicates) {
-  Thread* THREAD = Thread::current();
+                                          bool check_for_duplicates, TRAPS) {
   ResourceMark rm(THREAD);
   jint manifest_size;
   char* manifest = read_manifest(entry, &manifest_size, CHECK);
@@ -213,7 +212,8 @@ void ClassLoaderExt::process_jar_manifest(ClassPathEntry* entry,
         char* libname = NEW_RESOURCE_ARRAY(char, libname_len + 1);
         int n = os::snprintf(libname, libname_len + 1, "%.*s%s", dir_len, dir_name, file_start);
         assert((size_t)n == libname_len, "Unexpected number of characters in string");
-        if (ClassLoader::update_class_path_entry_list(libname, true, false, true /* from_class_path_attr */)) {
+        bool status = ClassLoader::update_class_path_entry_list(libname, true, false, true /* from_class_path_attr */, CHECK);
+        if (status) {
           trace_class_path("library = ", libname);
         } else {
           trace_class_path("library (non-existent) = ", libname);
@@ -226,8 +226,8 @@ void ClassLoaderExt::process_jar_manifest(ClassPathEntry* entry,
   }
 }
 
-void ClassLoaderExt::setup_search_paths() {
-  ClassLoaderExt::setup_app_search_path();
+void ClassLoaderExt::setup_search_paths(TRAPS) {
+  ClassLoaderExt::setup_app_search_path(CHECK);
 }
 
 void ClassLoaderExt::record_result(const s2 classpath_index,
diff --git a/src/hotspot/share/classfile/classLoaderExt.hpp b/src/hotspot/share/classfile/classLoaderExt.hpp
index cca5bed24f5..983741bc87b 100644
--- a/src/hotspot/share/classfile/classLoaderExt.hpp
+++ b/src/hotspot/share/classfile/classLoaderExt.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2021, 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
@@ -45,7 +45,7 @@ private:
   };
 
   static char* get_class_path_attr(const char* jar_path, char* manifest, jint manifest_size);
-  static void setup_app_search_path(); // Only when -Xshare:dump
+  static void setup_app_search_path(TRAPS); // Only when -Xshare:dump
   static void process_module_table(ModuleEntryTable* met, TRAPS);
   // index of first app JAR in shared classpath entry table
   static jshort _app_class_paths_start_index;
@@ -61,12 +61,12 @@ private:
   static ClassPathEntry* find_classpath_entry_from_cache(const char* path, TRAPS);
 
 public:
-  static void process_jar_manifest(ClassPathEntry* entry, bool check_for_duplicates);
+  static void process_jar_manifest(ClassPathEntry* entry, bool check_for_duplicates, TRAPS);
 
   // Called by JVMTI code to add boot classpath
   static void append_boot_classpath(ClassPathEntry* new_entry);
 
-  static void setup_search_paths();
+  static void setup_search_paths(TRAPS);
   static void setup_module_paths(TRAPS);
 
   static char* read_manifest(ClassPathEntry* entry, jint *manifest_size, TRAPS) {
diff --git a/src/hotspot/share/classfile/klassFactory.cpp b/src/hotspot/share/classfile/klassFactory.cpp
index a02d01020b5..cc12c1c7a07 100644
--- a/src/hotspot/share/classfile/klassFactory.cpp
+++ b/src/hotspot/share/classfile/klassFactory.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2015, 2021, 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
@@ -98,7 +98,7 @@ InstanceKlass* KlassFactory::check_shared_class_file_load_hook(
       }
 
       if (class_loader.is_null()) {
-        new_ik->set_classpath_index(path_index, THREAD);
+        new_ik->set_classpath_index(path_index);
       }
 
       return new_ik;
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
index 27e559d9523..7318400b0e5 100644
--- a/src/hotspot/share/classfile/systemDictionary.cpp
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -1360,7 +1360,7 @@ void SystemDictionary::load_shared_class_misc(InstanceKlass* ik, ClassLoaderData
   // package was loaded.
   if (loader_data->is_the_null_class_loader_data()) {
     int path_index = ik->shared_classpath_index();
-    ik->set_classpath_index(path_index, THREAD);
+    ik->set_classpath_index(path_index);
   }
 
   // notify a class loaded from shared object
diff --git a/src/hotspot/share/memory/filemap.cpp b/src/hotspot/share/memory/filemap.cpp
index 551a93b89c7..944f719d9c3 100644
--- a/src/hotspot/share/memory/filemap.cpp
+++ b/src/hotspot/share/memory/filemap.cpp
@@ -304,7 +304,7 @@ void FileMapHeader::print(outputStream* st) {
 
 void SharedClassPathEntry::init_as_non_existent(const char* path, TRAPS) {
   _type = non_existent_entry;
-  set_name(path, THREAD);
+  set_name(path, CHECK);
 }
 
 void SharedClassPathEntry::init(bool is_modules_image,
@@ -343,12 +343,12 @@ void SharedClassPathEntry::init(bool is_modules_image,
   // No need to save the name of the module file, as it will be computed at run time
   // to allow relocation of the JDK directory.
   const char* name = is_modules_image  ? "" : cpe->name();
-  set_name(name, THREAD);
+  set_name(name, CHECK);
 }
 
 void SharedClassPathEntry::set_name(const char* name, TRAPS) {
   size_t len = strlen(name) + 1;
-  _name = MetadataFactory::new_array(ClassLoaderData::the_null_class_loader_data(), (int)len, THREAD);
+  _name = MetadataFactory::new_array(ClassLoaderData::the_null_class_loader_data(), (int)len, CHECK);
   strcpy(_name->data(), name);
 }
 
@@ -358,12 +358,12 @@ void SharedClassPathEntry::copy_from(SharedClassPathEntry* ent, ClassLoaderData*
   _timestamp = ent->_timestamp;
   _filesize = ent->_filesize;
   _from_class_path_attr = ent->_from_class_path_attr;
-  set_name(ent->name(), THREAD);
+  set_name(ent->name(), CHECK);
 
   if (ent->is_jar() && !ent->is_signed() && ent->manifest() != NULL) {
     Array* buf = MetadataFactory::new_array(loader_data,
                                                     ent->manifest_size(),
-                                                    THREAD);
+                                                    CHECK);
     char* p = (char*)(buf->data());
     memcpy(p, ent->manifest(), ent->manifest_size());
     set_manifest(buf);
@@ -449,7 +449,7 @@ void SharedPathTable::metaspace_pointers_do(MetaspaceClosure* it) {
   }
 }
 
-void SharedPathTable::dumptime_init(ClassLoaderData* loader_data, Thread* THREAD) {
+void SharedPathTable::dumptime_init(ClassLoaderData* loader_data, TRAPS) {
   size_t entry_size = sizeof(SharedClassPathEntry);
   int num_entries = 0;
   num_entries += ClassLoader::num_boot_classpath_entries();
@@ -458,7 +458,7 @@ void SharedPathTable::dumptime_init(ClassLoaderData* loader_data, Thread* THREAD
   num_entries += FileMapInfo::num_non_existent_class_paths();
   size_t bytes = entry_size * num_entries;
 
-  _table = MetadataFactory::new_array(loader_data, (int)bytes, THREAD);
+  _table = MetadataFactory::new_array(loader_data, (int)bytes, CHECK);
   _size = num_entries;
 }
 
@@ -466,44 +466,43 @@ void SharedPathTable::dumptime_init(ClassLoaderData* loader_data, Thread* THREAD
 // It is needed because some Java code continues to execute after dynamic dump has finished.
 // However, during dynamic dump, we have modified FileMapInfo::_shared_path_table so
 // FileMapInfo::shared_path(i) returns incorrect information in ClassLoader::record_result().
-void FileMapInfo::copy_shared_path_table(ClassLoaderData* loader_data, Thread* THREAD) {
+void FileMapInfo::copy_shared_path_table(ClassLoaderData* loader_data, TRAPS) {
   size_t entry_size = sizeof(SharedClassPathEntry);
   size_t bytes = entry_size * _shared_path_table.size();
 
-  _saved_shared_path_table = SharedPathTable(MetadataFactory::new_array(loader_data, (int)bytes, THREAD),
-                                             _shared_path_table.size());
+  Array* array = MetadataFactory::new_array(loader_data, (int)bytes, CHECK);
+  _saved_shared_path_table = SharedPathTable(array, _shared_path_table.size());
 
   for (int i = 0; i < _shared_path_table.size(); i++) {
-    _saved_shared_path_table.path_at(i)->copy_from(shared_path(i), loader_data, THREAD);
+    _saved_shared_path_table.path_at(i)->copy_from(shared_path(i), loader_data, CHECK);
   }
 }
 
-void FileMapInfo::allocate_shared_path_table() {
+void FileMapInfo::allocate_shared_path_table(TRAPS) {
   Arguments::assert_is_dumping_archive();
 
-  EXCEPTION_MARK; // The following calls should never throw, but would exit VM on error.
   ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
   ClassPathEntry* jrt = ClassLoader::get_jrt_entry();
 
   assert(jrt != NULL,
          "No modular java runtime image present when allocating the CDS classpath entry table");
 
-  _shared_path_table.dumptime_init(loader_data, THREAD);
+  _shared_path_table.dumptime_init(loader_data, CHECK);
 
   // 1. boot class path
   int i = 0;
-  i = add_shared_classpaths(i, "boot",   jrt, THREAD);
-  i = add_shared_classpaths(i, "app",    ClassLoader::app_classpath_entries(), THREAD);
-  i = add_shared_classpaths(i, "module", ClassLoader::module_path_entries(), THREAD);
+  i = add_shared_classpaths(i, "boot",   jrt, CHECK);
+  i = add_shared_classpaths(i, "app",    ClassLoader::app_classpath_entries(), CHECK);
+  i = add_shared_classpaths(i, "module", ClassLoader::module_path_entries(), CHECK);
 
   for (int x = 0; x < num_non_existent_class_paths(); x++, i++) {
     const char* path = _non_existent_class_paths->at(x);
-    shared_path(i)->init_as_non_existent(path, THREAD);
+    shared_path(i)->init_as_non_existent(path, CHECK);
   }
 
   assert(i == _shared_path_table.size(), "number of shared path entry mismatch");
 
-  copy_shared_path_table(loader_data, THREAD);
+  copy_shared_path_table(loader_data, CHECK);
 }
 
 int FileMapInfo::add_shared_classpaths(int i, const char* which, ClassPathEntry *cpe, TRAPS) {
@@ -513,9 +512,9 @@ int FileMapInfo::add_shared_classpaths(int i, const char* which, ClassPathEntry
     const char* type = (is_jrt ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
     log_info(class, path)("add %s shared path (%s) %s", which, type, cpe->name());
     SharedClassPathEntry* ent = shared_path(i);
-    ent->init(is_jrt, is_module_path, cpe, THREAD);
+    ent->init(is_jrt, is_module_path, cpe, CHECK_0);
     if (cpe->is_jar_file()) {
-      update_jar_manifest(cpe, ent, THREAD);
+      update_jar_manifest(cpe, ent, CHECK_0);
     }
     if (is_jrt) {
       cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
@@ -670,7 +669,7 @@ void FileMapInfo::update_jar_manifest(ClassPathEntry *cpe, SharedClassPathEntry*
       manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK);
       Array* buf = MetadataFactory::new_array(loader_data,
                                                       manifest_size,
-                                                      THREAD);
+                                                      CHECK);
       char* p = (char*)(buf->data());
       memcpy(p, manifest, manifest_size);
       ent->set_manifest(buf);
@@ -2364,7 +2363,8 @@ ClassFileStream* FileMapInfo::open_stream_for_jvmti(InstanceKlass* ik, Handle cl
                                                                       name->utf8_length());
   ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
   ClassFileStream* cfs = cpe->open_stream_for_loader(file_name, loader_data, THREAD);
-  assert(cfs != NULL, "must be able to read the classfile data of shared classes for built-in loaders.");
+  assert(!HAS_PENDING_EXCEPTION &&
+         cfs != NULL, "must be able to read the classfile data of shared classes for built-in loaders.");
   log_debug(cds, jvmti)("classfile data for %s [%d: %s] = %d bytes", class_name, path_index,
                         cfs->source(), cfs->length());
   return cfs;
diff --git a/src/hotspot/share/memory/filemap.hpp b/src/hotspot/share/memory/filemap.hpp
index b402f995590..7b00b1b5878 100644
--- a/src/hotspot/share/memory/filemap.hpp
+++ b/src/hotspot/share/memory/filemap.hpp
@@ -117,7 +117,7 @@ public:
   SharedPathTable() : _table(NULL), _size(0) {}
   SharedPathTable(Array* table, int size) : _table(table), _size(size) {}
 
-  void dumptime_init(ClassLoaderData* loader_data, Thread* THREAD);
+  void dumptime_init(ClassLoaderData* loader_data, TRAPS);
   void metaspace_pointers_do(MetaspaceClosure* it);
 
   int size() {
@@ -498,8 +498,8 @@ public:
   // Stop CDS sharing and unmap CDS regions.
   static void stop_sharing_and_unmap(const char* msg);
 
-  static void allocate_shared_path_table();
-  static void copy_shared_path_table(ClassLoaderData* loader_data, Thread* THREAD);
+  static void allocate_shared_path_table(TRAPS);
+  static void copy_shared_path_table(ClassLoaderData* loader_data, TRAPS);
   static int add_shared_classpaths(int i, const char* which, ClassPathEntry *cpe, TRAPS);
   static void check_nonempty_dir_in_shared_path_table();
   bool validate_shared_path_table();
diff --git a/src/hotspot/share/memory/metaspaceShared.cpp b/src/hotspot/share/memory/metaspaceShared.cpp
index 7603b4a4a57..9bc8bfc7742 100644
--- a/src/hotspot/share/memory/metaspaceShared.cpp
+++ b/src/hotspot/share/memory/metaspaceShared.cpp
@@ -816,8 +816,15 @@ void MetaspaceShared::link_and_cleanup_shared_classes(TRAPS) {
 }
 
 void MetaspaceShared::prepare_for_dumping() {
+  Arguments::assert_is_dumping_archive();
   Arguments::check_unsupported_dumping_properties();
-  ClassLoader::initialize_shared_path();
+
+  EXCEPTION_MARK;
+  ClassLoader::initialize_shared_path(THREAD);
+  if (HAS_PENDING_EXCEPTION) {
+    java_lang_Throwable::print(PENDING_EXCEPTION, tty);
+    vm_exit_during_initialization("ClassLoader::initialize_shared_path() failed unexpectedly");
+  }
 }
 
 // Preload classes from a list, populate the shared spaces and dump to a
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index 38aed251bf7..2acc5344aa9 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -2934,7 +2934,7 @@ void InstanceKlass::set_package(ClassLoaderData* loader_data, PackageEntry* pkg_
 // in an unnamed module.  It is also used to indicate (for all packages whose
 // classes are loaded by the boot loader) that at least one of the package's
 // classes has been loaded.
-void InstanceKlass::set_classpath_index(s2 path_index, TRAPS) {
+void InstanceKlass::set_classpath_index(s2 path_index) {
   if (_package_entry != NULL) {
     DEBUG_ONLY(PackageEntryTable* pkg_entry_tbl = ClassLoaderData::the_null_class_loader_data()->packages();)
     assert(pkg_entry_tbl->lookup_only(_package_entry->name()) == _package_entry, "Should be same");
diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp
index bf9ecc94733..2b038ed4322 100644
--- a/src/hotspot/share/oops/instanceKlass.hpp
+++ b/src/hotspot/share/oops/instanceKlass.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2021, 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
@@ -524,7 +524,7 @@ public:
   // packages returned by get_system_packages().
   // For packages whose classes are loaded from the boot loader class path, the
   // classpath_index indicates which entry on the boot loader class path.
-  void set_classpath_index(s2 path_index, TRAPS);
+  void set_classpath_index(s2 path_index);
   bool is_same_class_package(const Klass* class2) const;
   bool is_same_class_package(oop other_class_loader, const Symbol* other_class_name) const;
 
diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp
index 45c4896c5e3..cc7c6519bc9 100644
--- a/src/hotspot/share/runtime/thread.cpp
+++ b/src/hotspot/share/runtime/thread.cpp
@@ -3361,6 +3361,10 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
 #if INCLUDE_CDS
   // capture the module path info from the ModuleEntryTable
   ClassLoader::initialize_module_path(THREAD);
+  if (HAS_PENDING_EXCEPTION) {
+    java_lang_Throwable::print(PENDING_EXCEPTION, tty);
+    vm_exit_during_initialization("ClassLoader::initialize_module_path() failed unexpectedly");
+  }
 #endif
 
 #if INCLUDE_JVMCI
-- 
GitLab


From 837bd8930d0a010110f1318b947c036609d3aa33 Mon Sep 17 00:00:00 2001
From: Thomas Stuefe 
Date: Thu, 11 Feb 2021 05:31:11 +0000
Subject: [PATCH 014/367] 8261548: ProblemList
 runtime/NMT/CheckForProperDetailStackTrace.java

Reviewed-by: jwilhelm
---
 test/hotspot/jtreg/ProblemList.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt
index 06bdea729fb..e231c5f0ad7 100644
--- a/test/hotspot/jtreg/ProblemList.txt
+++ b/test/hotspot/jtreg/ProblemList.txt
@@ -85,6 +85,7 @@ gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java 8241293 macosx-x64
 runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP_JFR.java 8253437 windows-x64
 runtime/cds/DeterministicDump.java 8253495 generic-all
 runtime/jni/terminatedThread/TestTerminatedThread.java 8219652 aix-ppc64
+runtime/NMT/CheckForProperDetailStackTrace.java 8261520 generic-all
 runtime/ReservedStack/ReservedStackTest.java 8231031 generic-all
 containers/docker/TestJFRWithJMX.java 8256417 linux-5.4.17-2011.5.3.el8uek.x86_64
 
-- 
GitLab


From 49cf13d2fb1581342cda8c43360ac931e52a4d3e Mon Sep 17 00:00:00 2001
From: Aleksey Shipilev 
Date: Thu, 11 Feb 2021 08:53:21 +0000
Subject: [PATCH 015/367] 8261449: Micro-optimize JVM_LatestUserDefinedLoader

Reviewed-by: dholmes, stuefe, alanb
---
 src/hotspot/share/prims/jvm.cpp      | 10 +++++++---
 src/hotspot/share/runtime/vframe.cpp |  9 ---------
 src/hotspot/share/runtime/vframe.hpp |  4 ----
 3 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
index 53ffb2cef3e..c33810d3967 100644
--- a/src/hotspot/share/prims/jvm.cpp
+++ b/src/hotspot/share/prims/jvm.cpp
@@ -3287,10 +3287,14 @@ JVM_END
 
 JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env))
   for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
-    vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection
-    oop loader = vfst.method()->method_holder()->class_loader();
+    InstanceKlass* ik = vfst.method()->method_holder();
+    oop loader = ik->class_loader();
     if (loader != NULL && !SystemDictionary::is_platform_class_loader(loader)) {
-      return JNIHandles::make_local(THREAD, loader);
+      // Skip reflection related frames
+      if (!ik->is_subclass_of(vmClasses::reflect_MethodAccessorImpl_klass()) &&
+          !ik->is_subclass_of(vmClasses::reflect_ConstructorAccessorImpl_klass())) {
+        return JNIHandles::make_local(THREAD, loader);
+      }
     }
   }
   return NULL;
diff --git a/src/hotspot/share/runtime/vframe.cpp b/src/hotspot/share/runtime/vframe.cpp
index 5fa4e13e11a..9cd129c65d1 100644
--- a/src/hotspot/share/runtime/vframe.cpp
+++ b/src/hotspot/share/runtime/vframe.cpp
@@ -562,15 +562,6 @@ void vframeStreamCommon::skip_prefixed_method_and_wrappers() {
   }
 }
 
-
-void vframeStreamCommon::skip_reflection_related_frames() {
-  while (!at_end() &&
-          (method()->method_holder()->is_subclass_of(vmClasses::reflect_MethodAccessorImpl_klass()) ||
-           method()->method_holder()->is_subclass_of(vmClasses::reflect_ConstructorAccessorImpl_klass()))) {
-    next();
-  }
-}
-
 javaVFrame* vframeStreamCommon::asJavaVFrame() {
   javaVFrame* result = NULL;
   if (_mode == compiled_mode) {
diff --git a/src/hotspot/share/runtime/vframe.hpp b/src/hotspot/share/runtime/vframe.hpp
index 52e58403094..487d064d3ff 100644
--- a/src/hotspot/share/runtime/vframe.hpp
+++ b/src/hotspot/share/runtime/vframe.hpp
@@ -328,10 +328,6 @@ class vframeStreamCommon : StackObj {
   // Implements security traversal. Skips depth no. of frame including
   // special security frames and prefixed native methods
   void security_get_caller_frame(int depth);
-
-  // Helper routine for JVM_LatestUserDefinedLoader -- needed for 1.4
-  // reflection implementation
-  void skip_reflection_related_frames();
 };
 
 class vframeStream : public vframeStreamCommon {
-- 
GitLab


From 16623734005f47579e702b2844e45b6c1d6b1b08 Mon Sep 17 00:00:00 2001
From: Patrick Concannon 
Date: Thu, 11 Feb 2021 10:00:31 +0000
Subject: [PATCH 016/367] 8235139: Deprecate the socket impl factory mechanism

Reviewed-by: dfuchs, alanb, chegar
---
 .../classes/java/net/DatagramSocket.java      | 11 +++++++
 .../share/classes/java/net/ServerSocket.java  | 22 +++++++-------
 .../share/classes/java/net/Socket.java        | 30 ++++++++-----------
 3 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/src/java.base/share/classes/java/net/DatagramSocket.java b/src/java.base/share/classes/java/net/DatagramSocket.java
index 195894a57d7..ffd113ecf21 100644
--- a/src/java.base/share/classes/java/net/DatagramSocket.java
+++ b/src/java.base/share/classes/java/net/DatagramSocket.java
@@ -1132,7 +1132,18 @@ public class DatagramSocket implements java.io.Closeable {
      * @see       java.net.DatagramSocketImplFactory#createDatagramSocketImpl()
      * @see       SecurityManager#checkSetFactory
      * @since 1.3
+     *
+     * @deprecated Use {@link DatagramChannel}, or subclass {@code DatagramSocket}
+     *    directly.
+     *    
This method provided a way in early JDK releases to replace the + * system wide implementation of {@code DatagramSocket}. It has been mostly + * obsolete since Java 1.4. If required, a {@code DatagramSocket} can be + * created to use a custom implementation by extending {@code DatagramSocket} + * and using the {@linkplain #DatagramSocket(DatagramSocketImpl) protected + * constructor} that takes an {@linkplain DatagramSocketImpl implementation} + * as a parameter. */ + @Deprecated(since = "17") public static synchronized void setDatagramSocketImplFactory(DatagramSocketImplFactory fac) throws IOException diff --git a/src/java.base/share/classes/java/net/ServerSocket.java b/src/java.base/share/classes/java/net/ServerSocket.java index 249c09b9674..30574780f14 100644 --- a/src/java.base/share/classes/java/net/ServerSocket.java +++ b/src/java.base/share/classes/java/net/ServerSocket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2021, 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 @@ -41,10 +41,7 @@ import sun.net.PlatformSocketImpl; * based on that request, and then possibly returns a result to the requester. *

* The actual work of the server socket is performed by an instance - * of the {@code SocketImpl} class. An application can - * change the socket factory that creates the socket - * implementation to configure itself to create sockets - * appropriate to the local firewall. + * of the {@code SocketImpl} class. * *

The {@code ServerSocket} class defines convenience * methods to set and get several socket options. This class also @@ -76,7 +73,6 @@ import sun.net.PlatformSocketImpl; * Additional (implementation specific) options may also be supported. * * @see java.net.SocketImpl - * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory) * @see java.nio.channels.ServerSocketChannel * @since 1.0 */ @@ -164,8 +160,6 @@ public class ServerSocket implements java.io.Closeable { * 0 and 65535, inclusive. * * @see java.net.SocketImpl - * @see java.net.SocketImplFactory#createSocketImpl() - * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory) * @see SecurityManager#checkListen */ public ServerSocket(int port) throws IOException { @@ -217,8 +211,6 @@ public class ServerSocket implements java.io.Closeable { * 0 and 65535, inclusive. * * @see java.net.SocketImpl - * @see java.net.SocketImplFactory#createSocketImpl() - * @see java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory) * @see SecurityManager#checkListen */ public ServerSocket(int port, int backlog) throws IOException { @@ -929,7 +921,17 @@ public class ServerSocket implements java.io.Closeable { * {@code checkSetFactory} method doesn't allow the operation. * @see java.net.SocketImplFactory#createSocketImpl() * @see SecurityManager#checkSetFactory + * @deprecated Use a {@link javax.net.ServerSocketFactory} and subclass {@code ServerSocket} + * directly. + *
This method provided a way in early JDK releases to replace the + * system wide implementation of {@code ServerSocket}. It has been mostly + * obsolete since Java 1.4. If required, a {@code ServerSocket} can be + * created to use a custom implementation by extending {@code ServerSocket} + * and using the {@linkplain #ServerSocket(SocketImpl) protected + * constructor} that takes an {@linkplain SocketImpl implementation} + * as a parameter. */ + @Deprecated(since = "17") public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException { if (factory != null) { throw new SocketException("factory already defined"); diff --git a/src/java.base/share/classes/java/net/Socket.java b/src/java.base/share/classes/java/net/Socket.java index 3357dbfe777..82509978947 100644 --- a/src/java.base/share/classes/java/net/Socket.java +++ b/src/java.base/share/classes/java/net/Socket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2021, 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 @@ -33,8 +33,6 @@ import java.io.IOException; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.nio.channels.SocketChannel; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Objects; import java.util.Set; import java.util.Collections; @@ -45,10 +43,7 @@ import java.util.Collections; * between two machines. *

* The actual work of the socket is performed by an instance of the - * {@code SocketImpl} class. An application, by changing - * the socket factory that creates the socket implementation, - * can configure itself to create sockets appropriate to the local - * firewall. + * {@code SocketImpl} class. * *

The {@code Socket} class defines convenience * methods to set and get several socket options. This class also @@ -96,7 +91,6 @@ import java.util.Collections; * * Additional (implementation specific) options may also be supported. * - * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory) * @see java.net.SocketImpl * @see java.nio.channels.SocketChannel * @since 1.0 @@ -282,9 +276,7 @@ public class Socket implements java.io.Closeable { * @throws IllegalArgumentException if the port parameter is outside * the specified range of valid port values, which is between * 0 and 65535, inclusive. - * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory) * @see java.net.SocketImpl - * @see java.net.SocketImplFactory#createSocketImpl() * @see SecurityManager#checkConnect */ public Socket(String host, int port) @@ -318,9 +310,7 @@ public class Socket implements java.io.Closeable { * the specified range of valid port values, which is between * 0 and 65535, inclusive. * @throws NullPointerException if {@code address} is null. - * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory) * @see java.net.SocketImpl - * @see java.net.SocketImplFactory#createSocketImpl() * @see SecurityManager#checkConnect */ public Socket(InetAddress address, int port) throws IOException { @@ -448,9 +438,7 @@ public class Socket implements java.io.Closeable { * @throws IllegalArgumentException if the port parameter is outside * the specified range of valid port values, which is between * 0 and 65535, inclusive. - * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory) * @see java.net.SocketImpl - * @see java.net.SocketImplFactory#createSocketImpl() * @see SecurityManager#checkConnect * @deprecated Use DatagramSocket instead for UDP transport. */ @@ -492,9 +480,7 @@ public class Socket implements java.io.Closeable { * the specified range of valid port values, which is between * 0 and 65535, inclusive. * @throws NullPointerException if {@code host} is null. - * @see java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory) * @see java.net.SocketImpl - * @see java.net.SocketImplFactory#createSocketImpl() * @see SecurityManager#checkConnect * @deprecated Use DatagramSocket instead for UDP transport. */ @@ -1761,7 +1747,17 @@ public class Socket implements java.io.Closeable { * {@code checkSetFactory} method doesn't allow the operation. * @see java.net.SocketImplFactory#createSocketImpl() * @see SecurityManager#checkSetFactory - */ + * @deprecated Use a {@link javax.net.SocketFactory} and subclass {@code Socket} + * directly. + *
This method provided a way in early JDK releases to replace the + * system wide implementation of {@code Socket}. It has been mostly + * obsolete since Java 1.4. If required, a {@code Socket} can be + * created to use a custom implementation by extending {@code Socket} + * and using the {@linkplain #Socket(SocketImpl) protected + * constructor} that takes an {@linkplain SocketImpl implementation} + * as a parameter. + */ + @Deprecated(since = "17") public static synchronized void setSocketImplFactory(SocketImplFactory fac) throws IOException { -- GitLab From 3ede231dec1c5aca94a39f995b47421301b1db0a Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Thu, 11 Feb 2021 10:16:09 +0000 Subject: [PATCH 017/367] 8259430: C2: assert(in_vt->length() == out_vt->length()) failed: mismatch on number of elements Reviewed-by: kvn, thartmann --- src/hotspot/share/opto/vectornode.cpp | 37 +++++++++++++++------------ test/jdk/ProblemList-Xcomp.txt | 1 - 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index 0979adce7a0..3870d1089f4 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -1225,25 +1225,30 @@ Node* VectorUnboxNode::Ideal(PhaseGVN* phase, bool can_reshape) { ciKlass* vbox_klass = vbox->box_type()->klass(); const TypeVect* in_vt = vbox->vec_type(); const TypeVect* out_vt = type()->is_vect(); - assert(in_vt->length() == out_vt->length(), "mismatch on number of elements"); - Node* value = vbox->in(VectorBoxNode::Value); - - bool is_vector_mask = vbox_klass->is_subclass_of(ciEnv::current()->vector_VectorMask_klass()); - bool is_vector_shuffle = vbox_klass->is_subclass_of(ciEnv::current()->vector_VectorShuffle_klass()); - if (is_vector_mask) { - // VectorUnbox (VectorBox vmask) ==> VectorLoadMask (VectorStoreMask vmask) - value = phase->transform(VectorStoreMaskNode::make(*phase, value, in_vt->element_basic_type(), in_vt->length())); - return new VectorLoadMaskNode(value, out_vt); - } else if (is_vector_shuffle) { - if (is_shuffle_to_vector()) { - // VectorUnbox (VectorBox vshuffle) ==> VectorCastB2X vshuffle - return new VectorCastB2XNode(value, out_vt); + + if (in_vt->length() == out_vt->length()) { + Node* value = vbox->in(VectorBoxNode::Value); + + bool is_vector_mask = vbox_klass->is_subclass_of(ciEnv::current()->vector_VectorMask_klass()); + bool is_vector_shuffle = vbox_klass->is_subclass_of(ciEnv::current()->vector_VectorShuffle_klass()); + if (is_vector_mask) { + // VectorUnbox (VectorBox vmask) ==> VectorLoadMask (VectorStoreMask vmask) + value = phase->transform(VectorStoreMaskNode::make(*phase, value, in_vt->element_basic_type(), in_vt->length())); + return new VectorLoadMaskNode(value, out_vt); + } else if (is_vector_shuffle) { + if (is_shuffle_to_vector()) { + // VectorUnbox (VectorBox vshuffle) ==> VectorCastB2X vshuffle + return new VectorCastB2XNode(value, out_vt); + } else { + // VectorUnbox (VectorBox vshuffle) ==> VectorLoadShuffle vshuffle + return new VectorLoadShuffleNode(value, out_vt); + } } else { - // VectorUnbox (VectorBox vshuffle) ==> VectorLoadShuffle vshuffle - return new VectorLoadShuffleNode(value, out_vt); + // Vector type mismatch is only supported for masks and shuffles, but sometimes it happens in pathological cases. } } else { - assert(false, "type mismatch on vector: %s", vbox_klass->name()->as_utf8()); + // Vector length mismatch. + // Sometimes happen in pathological cases (e.g., when unboxing happens in effectively dead code). } } } diff --git a/test/jdk/ProblemList-Xcomp.txt b/test/jdk/ProblemList-Xcomp.txt index 6f1f7f36b74..77b61348af5 100644 --- a/test/jdk/ProblemList-Xcomp.txt +++ b/test/jdk/ProblemList-Xcomp.txt @@ -29,4 +29,3 @@ java/lang/invoke/MethodHandles/CatchExceptionTest.java 8146623 generic-all java/util/stream/test/org/openjdk/tests/java/util/stream/SpliteratorTest.java 8256368 generic-all -jdk/incubator/vector/VectorHash.java 8259430 generic-all -- GitLab From a9c36805c49f9f3435bbb55f99db5221aeff4b07 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Thu, 11 Feb 2021 10:16:37 +0000 Subject: [PATCH 018/367] 8261250: Dependencies: Remove unused dependency types Reviewed-by: kvn, thartmann --- src/hotspot/share/code/dependencies.cpp | 220 ++---------------------- src/hotspot/share/code/dependencies.hpp | 47 +---- 2 files changed, 15 insertions(+), 252 deletions(-) diff --git a/src/hotspot/share/code/dependencies.cpp b/src/hotspot/share/code/dependencies.cpp index 862e673fc5d..d52478adda6 100644 --- a/src/hotspot/share/code/dependencies.cpp +++ b/src/hotspot/share/code/dependencies.cpp @@ -99,32 +99,12 @@ void Dependencies::assert_abstract_with_unique_concrete_subtype(ciKlass* ctxk, c assert_common_2(abstract_with_unique_concrete_subtype, ctxk, conck); } -void Dependencies::assert_abstract_with_no_concrete_subtype(ciKlass* ctxk) { - check_ctxk_abstract(ctxk); - assert_common_1(abstract_with_no_concrete_subtype, ctxk); -} - -void Dependencies::assert_concrete_with_no_concrete_subtype(ciKlass* ctxk) { - check_ctxk_concrete(ctxk); - assert_common_1(concrete_with_no_concrete_subtype, ctxk); -} - void Dependencies::assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm) { check_ctxk(ctxk); check_unique_method(ctxk, uniqm); assert_common_2(unique_concrete_method, ctxk, uniqm); } -void Dependencies::assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2) { - check_ctxk(ctxk); - assert_common_3(abstract_with_exclusive_concrete_subtypes_2, ctxk, k1, k2); -} - -void Dependencies::assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2) { - check_ctxk(ctxk); - assert_common_3(exclusive_concrete_methods_2, ctxk, m1, m2); -} - void Dependencies::assert_has_no_finalizable_subclasses(ciKlass* ctxk) { check_ctxk(ctxk); assert_common_1(no_finalizable_subclasses, ctxk); @@ -266,47 +246,6 @@ void Dependencies::assert_common_2(DepType dept, deps->append(x1); } -void Dependencies::assert_common_3(DepType dept, - ciKlass* ctxk, ciBaseObject* x, ciBaseObject* x2) { - assert(dep_context_arg(dept) == 0, "sanity"); - assert(dep_args(dept) == 3, "sanity"); - log_dependency(dept, ctxk, x, x2); - GrowableArray* deps = _deps[dept]; - - // try to normalize an unordered pair: - bool swap = false; - switch (dept) { - case abstract_with_exclusive_concrete_subtypes_2: - swap = (x->ident() > x2->ident() && x->as_metadata()->as_klass() != ctxk); - break; - case exclusive_concrete_methods_2: - swap = (x->ident() > x2->ident() && x->as_metadata()->as_method()->holder() != ctxk); - break; - default: - break; - } - if (swap) { ciBaseObject* t = x; x = x2; x2 = t; } - - // see if the same (or a similar) dep is already recorded - if (note_dep_seen(dept, x) && note_dep_seen(dept, x2)) { - // look in this bucket for redundant assertions - const int stride = 3; - for (int i = deps->length(); (i -= stride) >= 0; ) { - ciBaseObject* y = deps->at(i+1); - ciBaseObject* y2 = deps->at(i+2); - if (x == y && x2 == y2) { // same subjects; check the context - if (maybe_merge_ctxk(deps, i+0, ctxk)) { - return; - } - } - } - } - // append the assertion in the correct bucket: - deps->append(ctxk); - deps->append(x); - deps->append(x2); -} - #if INCLUDE_JVMCI bool Dependencies::maybe_merge_ctxk(GrowableArray* deps, int ctxk_i, DepValue ctxk2_dv) { @@ -473,10 +412,7 @@ size_t Dependencies::estimate_size_in_bytes() { ciKlass* Dependencies::ctxk_encoded_as_null(DepType dept, ciBaseObject* x) { switch (dept) { - case abstract_with_exclusive_concrete_subtypes_2: - return x->as_metadata()->as_klass(); case unique_concrete_method: - case exclusive_concrete_methods_2: return x->as_metadata()->as_method()->holder(); default: return NULL; // let NULL be NULL @@ -486,11 +422,7 @@ ciKlass* Dependencies::ctxk_encoded_as_null(DepType dept, ciBaseObject* x) { Klass* Dependencies::ctxk_encoded_as_null(DepType dept, Metadata* x) { assert(must_be_in_vm(), "raw oops here"); switch (dept) { - case abstract_with_exclusive_concrete_subtypes_2: - assert(x->is_klass(), "sanity"); - return (Klass*) x; case unique_concrete_method: - case exclusive_concrete_methods_2: assert(x->is_method(), "sanity"); return ((Method*)x)->method_holder(); default: @@ -593,11 +525,7 @@ const char* Dependencies::_dep_name[TYPE_LIMIT] = { "evol_method", "leaf_type", "abstract_with_unique_concrete_subtype", - "abstract_with_no_concrete_subtype", - "concrete_with_no_concrete_subtype", "unique_concrete_method", - "abstract_with_exclusive_concrete_subtypes_2", - "exclusive_concrete_methods_2", "no_finalizable_subclasses", "call_site_target_value" }; @@ -607,11 +535,7 @@ int Dependencies::_dep_args[TYPE_LIMIT] = { 1, // evol_method m 1, // leaf_type ctxk 2, // abstract_with_unique_concrete_subtype ctxk, k - 1, // abstract_with_no_concrete_subtype ctxk - 1, // concrete_with_no_concrete_subtype ctxk 2, // unique_concrete_method ctxk, m - 3, // unique_concrete_subtypes_2 ctxk, k1, k2 - 3, // unique_concrete_methods_2 ctxk, m1, m2 1, // no_finalizable_subclasses ctxk 2 // call_site_target_value call_site, method_handle }; @@ -1347,8 +1271,8 @@ static bool count_find_witness_calls() { Klass* ClassHierarchyWalker::find_witness_in(KlassDepChange& changes, - Klass* context_type, - bool participants_hide_witnesses) { + Klass* context_type, + bool participants_hide_witnesses) { assert(changes.involves_context(context_type), "irrelevant dependency"); Klass* new_type = changes.new_type(); @@ -1398,8 +1322,8 @@ Klass* ClassHierarchyWalker::find_witness_in(KlassDepChange& changes, // If top_level_call is false, skip testing the context type, // because the caller has already considered it. Klass* ClassHierarchyWalker::find_witness_anywhere(Klass* context_type, - bool participants_hide_witnesses, - bool top_level_call) { + bool participants_hide_witnesses, + bool top_level_call) { // Current thread must be in VM (not native mode, as in CI): assert(must_be_in_vm(), "raw oops here"); // Must not move the class hierarchy during this check: @@ -1498,8 +1422,8 @@ Klass* ClassHierarchyWalker::find_witness_anywhere(Klass* context_type, // since the recursive call sees sub as the context_type.) if (do_counts) { NOT_PRODUCT(deps_find_witness_recursions++); } Klass* witness = find_witness_anywhere(sub, - participants_hide_witnesses, - /*top_level_call=*/ false); + participants_hide_witnesses, + /*top_level_call=*/ false); if (witness != NULL) return witness; } } @@ -1606,32 +1530,12 @@ Klass* Dependencies::check_leaf_type(Klass* ctxk) { // This allows the compiler to narrow occurrences of ctxk by conck, // when dealing with the types of actual instances. Klass* Dependencies::check_abstract_with_unique_concrete_subtype(Klass* ctxk, - Klass* conck, - KlassDepChange* changes) { + Klass* conck, + KlassDepChange* changes) { ClassHierarchyWalker wf(conck); return wf.find_witness_subtype(ctxk, changes); } -// If a non-concrete class has no concrete subtypes, it is not (yet) -// instantiatable. This can allow the compiler to make some paths go -// dead, if they are gated by a test of the type. -Klass* Dependencies::check_abstract_with_no_concrete_subtype(Klass* ctxk, - KlassDepChange* changes) { - // Find any concrete subtype, with no participants: - ClassHierarchyWalker wf; - return wf.find_witness_subtype(ctxk, changes); -} - - -// If a concrete class has no concrete subtypes, it can always be -// exactly typed. This allows the use of a cheaper type test. -Klass* Dependencies::check_concrete_with_no_concrete_subtype(Klass* ctxk, - KlassDepChange* changes) { - // Find any concrete subtype, with only the ctxk as participant: - ClassHierarchyWalker wf(ctxk); - return wf.find_witness_subtype(ctxk, changes); -} - // Find the unique concrete proper subtype of ctxk, or NULL if there // is more than one concrete proper subtype. If there are no concrete @@ -1645,22 +1549,6 @@ Klass* Dependencies::find_unique_concrete_subtype(Klass* ctxk) { if (wit != NULL) return NULL; // Too many witnesses. Klass* conck = wf.participant(0); if (conck == NULL) { -#ifndef PRODUCT - // Make sure the dependency mechanism will pass this discovery: - if (VerifyDependencies) { - // Turn off dependency tracing while actually testing deps. - FlagSetting fs(TraceDependencies, false); - if (!Dependencies::is_concrete_klass(ctxk)) { - guarantee(NULL == - (void *)check_abstract_with_no_concrete_subtype(ctxk), - "verify dep."); - } else { - guarantee(NULL == - (void *)check_concrete_with_no_concrete_subtype(ctxk), - "verify dep."); - } - } -#endif //PRODUCT return ctxk; // Return ctxk as a flag for "no subtypes". } else { #ifndef PRODUCT @@ -1679,76 +1567,12 @@ Klass* Dependencies::find_unique_concrete_subtype(Klass* ctxk) { } } -// Test the assertion that the k[12] are the only concrete subtypes of ctxk, -// except possibly for further subtypes of k[12] themselves. -// The context type must be abstract. The types k1 and k2 are themselves -// allowed to have further concrete subtypes. -Klass* Dependencies::check_abstract_with_exclusive_concrete_subtypes( - Klass* ctxk, - Klass* k1, - Klass* k2, - KlassDepChange* changes) { - ClassHierarchyWalker wf; - wf.add_participant(k1); - wf.add_participant(k2); - return wf.find_witness_subtype(ctxk, changes); -} - -// Search ctxk for concrete implementations. If there are klen or fewer, -// pack them into the given array and return the number. -// Otherwise, return -1, meaning the given array would overflow. -// (Note that a return of 0 means there are exactly no concrete subtypes.) -// In this search, if ctxk is concrete, it will be reported alone. -// For any type CC reported, no proper subtypes of CC will be reported. -int Dependencies::find_exclusive_concrete_subtypes(Klass* ctxk, - int klen, - Klass* karray[]) { - ClassHierarchyWalker wf; - wf.record_witnesses(klen); - Klass* wit = wf.find_witness_subtype(ctxk); - if (wit != NULL) return -1; // Too many witnesses. - int num = wf.num_participants(); - assert(num <= klen, "oob"); - // Pack the result array with the good news. - for (int i = 0; i < num; i++) - karray[i] = wf.participant(i); -#ifndef PRODUCT - // Make sure the dependency mechanism will pass this discovery: - if (VerifyDependencies) { - // Turn off dependency tracing while actually testing deps. - FlagSetting fs(TraceDependencies, false); - switch (Dependencies::is_concrete_klass(ctxk)? -1: num) { - case -1: // ctxk was itself concrete - guarantee(num == 1 && karray[0] == ctxk, "verify dep."); - break; - case 0: - guarantee(NULL == (void *)check_abstract_with_no_concrete_subtype(ctxk), - "verify dep."); - break; - case 1: - guarantee(NULL == (void *) - check_abstract_with_unique_concrete_subtype(ctxk, karray[0]), - "verify dep."); - break; - case 2: - guarantee(NULL == (void *) - check_abstract_with_exclusive_concrete_subtypes(ctxk, - karray[0], - karray[1]), - "verify dep."); - break; - default: - ShouldNotReachHere(); // klen > 2 yet supported - } - } -#endif //PRODUCT - return num; -} // If a class (or interface) has a unique concrete method uniqm, return NULL. // Otherwise, return a class that contains an interfering method. -Klass* Dependencies::check_unique_concrete_method(Klass* ctxk, Method* uniqm, - KlassDepChange* changes) { +Klass* Dependencies::check_unique_concrete_method(Klass* ctxk, + Method* uniqm, + KlassDepChange* changes) { // Here is a missing optimization: If uniqm->is_final(), // we don't really need to search beneath it for overrides. // This is probably not important, since we don't use dependencies @@ -1792,16 +1616,6 @@ Method* Dependencies::find_unique_concrete_method(Klass* ctxk, Method* m) { return fm; } -Klass* Dependencies::check_exclusive_concrete_methods(Klass* ctxk, - Method* m1, - Method* m2, - KlassDepChange* changes) { - ClassHierarchyWalker wf(m1); - wf.add_participant(m1->method_holder()); - wf.add_participant(m2->method_holder()); - return wf.find_witness_definer(ctxk, changes); -} - Klass* Dependencies::check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes) { Klass* search_at = ctxk; if (changes != NULL) @@ -1854,21 +1668,9 @@ Klass* Dependencies::DepStream::check_klass_dependency(KlassDepChange* changes) case abstract_with_unique_concrete_subtype: witness = check_abstract_with_unique_concrete_subtype(context_type(), type_argument(1), changes); break; - case abstract_with_no_concrete_subtype: - witness = check_abstract_with_no_concrete_subtype(context_type(), changes); - break; - case concrete_with_no_concrete_subtype: - witness = check_concrete_with_no_concrete_subtype(context_type(), changes); - break; case unique_concrete_method: witness = check_unique_concrete_method(context_type(), method_argument(1), changes); break; - case abstract_with_exclusive_concrete_subtypes_2: - witness = check_abstract_with_exclusive_concrete_subtypes(context_type(), type_argument(1), type_argument(2), changes); - break; - case exclusive_concrete_methods_2: - witness = check_exclusive_concrete_methods(context_type(), method_argument(1), method_argument(2), changes); - break; case no_finalizable_subclasses: witness = check_has_no_finalizable_subclasses(context_type(), changes); break; diff --git a/src/hotspot/share/code/dependencies.hpp b/src/hotspot/share/code/dependencies.hpp index 4366201ef19..55bbc11502a 100644 --- a/src/hotspot/share/code/dependencies.hpp +++ b/src/hotspot/share/code/dependencies.hpp @@ -116,12 +116,6 @@ class Dependencies: public ResourceObj { // An abstract class CX has exactly one concrete subtype CC. abstract_with_unique_concrete_subtype, - // The type CX is purely abstract, with no concrete subtype* at all. - abstract_with_no_concrete_subtype, - - // The concrete CX is free of concrete proper subtypes. - concrete_with_no_concrete_subtype, - // Given a method M1 and a context class CX, the set MM(CX, M1) of // "concrete matching methods" in CX of M1 is the set of every // concrete M2 for which it is possible to create an invokevirtual @@ -140,23 +134,6 @@ class Dependencies: public ResourceObj { // than {M1}. unique_concrete_method, // one unique concrete method under CX - // An "exclusive" assertion concerns two methods or subtypes, and - // declares that there are at most two (or perhaps later N>2) - // specific items that jointly satisfy the restriction. - // We list all items explicitly rather than just giving their - // count, for robustness in the face of complex schema changes. - - // A context class CX (which may be either abstract or concrete) - // has two exclusive concrete subtypes* C1, C2 if every concrete - // subtype* of CX is either C1 or C2. Note that if neither C1 or C2 - // are equal to CX, then CX itself must be abstract. But it is - // also possible (for example) that C1 is CX (a concrete class) - // and C2 is a proper subtype of C1. - abstract_with_exclusive_concrete_subtypes_2, - - // This dependency asserts that MM(CX, M1) is no greater than {M1,M2}. - exclusive_concrete_methods_2, - // This dependency asserts that no instances of class or it's // subclasses require finalization registration. no_finalizable_subclasses, @@ -348,18 +325,13 @@ class Dependencies: public ResourceObj { void assert_common_1(DepType dept, ciBaseObject* x); void assert_common_2(DepType dept, ciBaseObject* x0, ciBaseObject* x1); - void assert_common_3(DepType dept, ciKlass* ctxk, ciBaseObject* x1, ciBaseObject* x2); public: // Adding assertions to a new dependency set at compile time: void assert_evol_method(ciMethod* m); void assert_leaf_type(ciKlass* ctxk); void assert_abstract_with_unique_concrete_subtype(ciKlass* ctxk, ciKlass* conck); - void assert_abstract_with_no_concrete_subtype(ciKlass* ctxk); - void assert_concrete_with_no_concrete_subtype(ciKlass* ctxk); void assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm); - void assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2); - void assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2); void assert_has_no_finalizable_subclasses(ciKlass* ctxk); void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle); @@ -426,18 +398,8 @@ class Dependencies: public ResourceObj { // Checking old assertions at run-time (in the VM only): static Klass* check_evol_method(Method* m); static Klass* check_leaf_type(Klass* ctxk); - static Klass* check_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck, - KlassDepChange* changes = NULL); - static Klass* check_abstract_with_no_concrete_subtype(Klass* ctxk, - KlassDepChange* changes = NULL); - static Klass* check_concrete_with_no_concrete_subtype(Klass* ctxk, - KlassDepChange* changes = NULL); - static Klass* check_unique_concrete_method(Klass* ctxk, Method* uniqm, - KlassDepChange* changes = NULL); - static Klass* check_abstract_with_exclusive_concrete_subtypes(Klass* ctxk, Klass* k1, Klass* k2, - KlassDepChange* changes = NULL); - static Klass* check_exclusive_concrete_methods(Klass* ctxk, Method* m1, Method* m2, - KlassDepChange* changes = NULL); + static Klass* check_abstract_with_unique_concrete_subtype(Klass* ctxk, Klass* conck, KlassDepChange* changes = NULL); + static Klass* check_unique_concrete_method(Klass* ctxk, Method* uniqm, KlassDepChange* changes = NULL); static Klass* check_has_no_finalizable_subclasses(Klass* ctxk, KlassDepChange* changes = NULL); static Klass* check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes = NULL); // A returned Klass* is NULL if the dependency assertion is still @@ -455,9 +417,8 @@ class Dependencies: public ResourceObj { // It is used by DepStream::spot_check_dependency_at. // Detecting possible new assertions: - static Klass* find_unique_concrete_subtype(Klass* ctxk); - static Method* find_unique_concrete_method(Klass* ctxk, Method* m); - static int find_exclusive_concrete_subtypes(Klass* ctxk, int klen, Klass* k[]); + static Klass* find_unique_concrete_subtype(Klass* ctxk); + static Method* find_unique_concrete_method(Klass* ctxk, Method* m); // Create the encoding which will be stored in an nmethod. void encode_content_bytes(); -- GitLab From 5e1b8092d21518dc06c1ceee0a201d1d522a78e8 Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Thu, 11 Feb 2021 10:41:59 +0000 Subject: [PATCH 019/367] 8261444: Remove unused fields in Lower Reviewed-by: vromero --- .../share/classes/com/sun/tools/javac/comp/Lower.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java index 28d99a6032b..6d465a235f9 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java @@ -92,11 +92,8 @@ public class Lower extends TreeTranslator { private DiagnosticPosition make_pos; private final ConstFold cfolder; private final Target target; - private final Source source; private final TypeEnvs typeEnvs; private final Name dollarAssertionsDisabled; - private final Name classDollar; - private final Name dollarCloseResource; private final Types types; private final boolean debugLower; private final boolean disableProtectedAccessors; // experimental @@ -114,14 +111,9 @@ public class Lower extends TreeTranslator { make = TreeMaker.instance(context); cfolder = ConstFold.instance(context); target = Target.instance(context); - source = Source.instance(context); typeEnvs = TypeEnvs.instance(context); dollarAssertionsDisabled = names. fromString(target.syntheticNameChar() + "assertionsDisabled"); - classDollar = names. - fromString("class" + target.syntheticNameChar()); - dollarCloseResource = names. - fromString(target.syntheticNameChar() + "closeResource"); types = Types.instance(context); Options options = Options.instance(context); -- GitLab From 8b6ab31d313de61a0ef39722bc8e5fe0e10a8279 Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Thu, 11 Feb 2021 10:43:56 +0000 Subject: [PATCH 020/367] 8261418: Reduce decoder creation overheads for sun.nio.cs.ext Charsets Reviewed-by: naoto --- .../sun/nio/cs/ext/EUC_JP.java.template | 11 +- .../sun/nio/cs/ext/EUC_TW.java.template | 15 +- .../sun/nio/cs/ext/GB18030.java.template | 11 +- .../sun/nio/cs/ext/IBM29626C.java.template | 9 +- .../classes/sun/nio/cs/ext/IBM33722.java | 39 +- .../sun/nio/cs/ext/IBM964.java.template | 8 +- .../share/classes/sun/nio/cs/ext/ISCII91.java | 13 +- .../share/classes/sun/nio/cs/ext/ISO2022.java | 378 ++---------------- .../classes/sun/nio/cs/ext/ISO2022_CN.java | 55 +-- .../sun/nio/cs/ext/ISO2022_CN_CNS.java | 17 +- .../classes/sun/nio/cs/ext/ISO2022_CN_GB.java | 8 +- .../classes/sun/nio/cs/ext/ISO2022_JP.java | 35 +- .../classes/sun/nio/cs/ext/ISO2022_KR.java | 253 +++++++++++- .../nio/cs/ext/SimpleEUCEncoder.java.template | 7 +- .../openjdk/bench/java/lang/StringDecode.java | 2 +- 15 files changed, 357 insertions(+), 504 deletions(-) diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_JP.java.template b/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_JP.java.template index 1a1a9affe83..8eed590c836 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_JP.java.template +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_JP.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2021, 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 @@ -113,14 +113,10 @@ public class EUC_JP byte[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); char[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); int b1 = 0, b2 = 0; int inputSize = 0; @@ -296,13 +292,10 @@ public class EUC_JP char[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); + byte[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); int outputSize = 0; byte[] outputByte; diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_TW.java.template b/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_TW.java.template index 14620a2a40b..aa7586ae067 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_TW.java.template +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/EUC_TW.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021, 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 @@ -146,6 +146,19 @@ public class EUC_TW extends Charset implements HistoricallyNamedCharset return b >= b1Min && b <= b1Max; } + public static char decodeSingleOrReplace(int b1, int b2, int p, char replace) { + if (b1 < b1Min || b1 > b1Max || b2 < b2Min || b2 > b2Max) + return replace; + int index = (b1 - b1Min) * dbSegSize + b2 - b2Min; + char c = b2c[p].charAt(index); + if (c == UNMAPPABLE_DECODING) + return replace; + if ((b2cIsSupp[index] & (1 << p)) == 0) { + return c; + } + return replace; + } + static char[] decode(int b1, int b2, int p, char[] c1, char[] c2) { if (b1 < b1Min || b1 > b1Max || b2 < b2Min || b2 > b2Max) diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/GB18030.java.template b/src/jdk.charsets/share/classes/sun/nio/cs/ext/GB18030.java.template index 436d9e79742..fb3b8fb824f 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/GB18030.java.template +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/GB18030.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2021, 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 @@ -12332,14 +12332,10 @@ public class GB18030 byte[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); char[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); int inputSize = 1; @@ -12585,13 +12581,10 @@ public class GB18030 char[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); + byte[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); int condensedKey = 0; // expands to a four byte sequence int hiByte = 0, loByte = 0; diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM29626C.java.template b/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM29626C.java.template index 2a1e8604ad1..4a35873f524 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM29626C.java.template +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM29626C.java.template @@ -212,14 +212,10 @@ public class IBM29626C byte[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); char[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); int b1 = 0, b2 = 0; int inputSize = 0; @@ -484,13 +480,10 @@ public class IBM29626C char[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); + byte[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); int outputSize = 0; byte[] outputByte; diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM33722.java b/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM33722.java index 6af1d2189c1..7cdf17797d0 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM33722.java +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM33722.java @@ -1,6 +1,5 @@ - /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -65,15 +64,8 @@ public class IBM33722 protected static class Decoder extends CharsetDecoder { - private final int G0 = 0; - private final int G1 = 1; - private final int G2 = 2; - private final int G3 = 3; - private final int G4 = 4; - private final int SS2 = 0x8E; - private final int SS3 = 0x8F; - - private int firstByte, state; + private static final int SS2 = 0x8E; + private static final int SS3 = 0x8F; public Decoder(Charset cs) { super(cs, 1.0f, 1.0f); @@ -83,19 +75,16 @@ public class IBM33722 byte[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); + char[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); try { while (sp < sl) { int byte1, byte2; int inputSize = 1; - char outputChar = '\uFFFD'; + char outputChar; byte1 = sa[sp] & 0xff; if (byte1 == SS2) { @@ -157,7 +146,7 @@ public class IBM33722 while (src.hasRemaining()) { int byte1, byte2; int inputSize = 1; - char outputChar = '\uFFFD'; + char outputChar; byte1 = src.get() & 0xff; if (byte1 == SS2) { @@ -212,16 +201,16 @@ public class IBM33722 } protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) { - if (true && src.hasArray() && dst.hasArray()) + if (src.hasArray() && dst.hasArray()) return decodeArrayLoop(src, dst); else return decodeBufferLoop(src, dst); } - private final static String byteToCharTable; - private final static String mappingTableG1; - private final static String mappingTableG2; - private final static String mappingTableG3; + private static final String byteToCharTable; + private static final String mappingTableG1; + private static final String mappingTableG2; + private static final String mappingTableG3; static { byteToCharTable = "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007" + @@ -2749,9 +2738,9 @@ public class IBM33722 21792, 192, 73, 21824, 41, 2344, 2344, 0, }; - private final static String index2; - private final static String index2a; - private final static String index2b; + private static final String index2; + private static final String index2a; + private static final String index2b; static { index2 = "\u0000\uA1F1\u0000\uA1F2\u0000\uA2CC\u0000\uA1B1\u0000\uA2C3" + // 0 - 4 diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM964.java.template b/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM964.java.template index b4cf94a2952..50f40aa6805 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM964.java.template +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM964.java.template @@ -1,6 +1,5 @@ - /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -76,13 +75,10 @@ public class IBM964 byte[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); + char[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); try { while (sp < sl) { diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISCII91.java b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISCII91.java index 1e691599197..54933058e73 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISCII91.java +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISCII91.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2021, 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 @@ -500,14 +500,10 @@ public class ISCII91 extends Charset implements HistoricallyNamedCharset byte[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); char[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); try { while (sp < sl) { @@ -821,15 +817,10 @@ public class ISCII91 extends Charset implements HistoricallyNamedCharset char[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); + byte[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); - - int outputSize = 0; try { char inputChar; diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022.java b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022.java index 7c56c8e5fbc..041ab301d64 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022.java +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2021, 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 @@ -39,359 +39,33 @@ import sun.nio.cs.Surrogate; abstract class ISO2022 extends Charset { - - private static final byte ISO_ESC = 0x1b; - private static final byte ISO_SI = 0x0f; - private static final byte ISO_SO = 0x0e; - private static final byte ISO_SS2_7 = 0x4e; - private static final byte ISO_SS3_7 = 0x4f; - private static final byte MSB = (byte)0x80; - private static final char REPLACE_CHAR = '\uFFFD'; - private static final byte minDesignatorLength = 3; - public ISO2022(String csname, String[] aliases) { super(csname, aliases); } - public CharsetDecoder newDecoder() { - return new Decoder(this); - } - - public CharsetEncoder newEncoder() { - return new Encoder(this); - } - - protected static class Decoder extends CharsetDecoder { - - // Value to be filled by subclass - protected byte SODesig[][]; - protected byte SS2Desig[][] = null; - protected byte SS3Desig[][] = null; - - protected CharsetDecoder SODecoder[]; - protected CharsetDecoder SS2Decoder[] = null; - protected CharsetDecoder SS3Decoder[] = null; + public abstract CharsetDecoder newDecoder(); - private static final byte SOFlag = 0; - private static final byte SS2Flag = 1; - private static final byte SS3Flag = 2; + public abstract CharsetEncoder newEncoder(); - private int curSODes, curSS2Des, curSS3Des; - private boolean shiftout; - private CharsetDecoder tmpDecoder[]; - - protected Decoder(Charset cs) { - super(cs, 1.0f, 1.0f); - } - - protected void implReset() { - curSODes = 0; - curSS2Des = 0; - curSS3Des = 0; - shiftout = false; - } - - private char decode(byte byte1, byte byte2, byte shiftFlag) - { - byte1 |= MSB; - byte2 |= MSB; - - byte[] tmpByte = { byte1,byte2 }; - char[] tmpChar = new char[1]; - int i = 0, - tmpIndex = 0; - - switch(shiftFlag) { - case SOFlag: - tmpIndex = curSODes; - tmpDecoder = SODecoder; - break; - case SS2Flag: - tmpIndex = curSS2Des; - tmpDecoder = SS2Decoder; - break; - case SS3Flag: - tmpIndex = curSS3Des; - tmpDecoder = SS3Decoder; - break; - } + // No default Decoder implementation is provided here; the concrete + // encodings differ enough that most had been specialized for + // performance reasons, leaving the generic implementation that existed + // here before JDK-8261418 unused except by ISO2022_KR. As both a + // simplification and an optimization the implementation was moved + // there and specialized. - if (tmpDecoder != null) { - for(i = 0; i < tmpDecoder.length; i++) { - if(tmpIndex == i) { - try { - ByteBuffer bb = ByteBuffer.wrap(tmpByte,0,2); - CharBuffer cc = CharBuffer.wrap(tmpChar,0,1); - tmpDecoder[i].decode(bb, cc, true); - cc.flip(); - return cc.get(); - } catch (Exception e) {} - } - } - } - return REPLACE_CHAR; - } - - private int findDesig(byte[] in, int sp, int sl, byte[][] desigs) { - if (desigs == null) return -1; - int i = 0; - while (i < desigs.length) { - if (desigs[i] != null && sl - sp >= desigs[i].length) { - int j = 0; - while (j < desigs[i].length && in[sp+j] == desigs[i][j]) { j++; } - if (j == desigs[i].length) - return i; - } - i++; - } - return -1; - } - - private int findDesigBuf(ByteBuffer in, byte[][] desigs) { - if (desigs == null) return -1; - int i = 0; - while (i < desigs.length) { - if (desigs[i] != null && in.remaining() >= desigs[i].length) { - int j = 0; - in.mark(); - while (j < desigs[i].length && in.get() == desigs[i][j]) { j++; } - if (j == desigs[i].length) - return i; - in.reset(); - } - i++; - } - return -1; - } - - private CoderResult decodeArrayLoop(ByteBuffer src, - CharBuffer dst) - { - byte[] sa = src.array(); - int sp = src.arrayOffset() + src.position(); - int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); - - char[] da = dst.array(); - int dp = dst.arrayOffset() + dst.position(); - int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); - - int b1 = 0, b2 = 0, b3 = 0; - - try { - while (sp < sl) { - b1 = sa[sp] & 0xff; - int inputSize = 1; - switch (b1) { - case ISO_SO: - shiftout = true; - inputSize = 1; - break; - case ISO_SI: - shiftout = false; - inputSize = 1; - break; - case ISO_ESC: - if (sl - sp - 1 < minDesignatorLength) - return CoderResult.UNDERFLOW; - - int desig = findDesig(sa, sp + 1, sl, SODesig); - if (desig != -1) { - curSODes = desig; - inputSize = SODesig[desig].length + 1; - break; - } - desig = findDesig(sa, sp + 1, sl, SS2Desig); - if (desig != -1) { - curSS2Des = desig; - inputSize = SS2Desig[desig].length + 1; - break; - } - desig = findDesig(sa, sp + 1, sl, SS3Desig); - if (desig != -1) { - curSS3Des = desig; - inputSize = SS3Desig[desig].length + 1; - break; - } - if (sl - sp < 2) - return CoderResult.UNDERFLOW; - b1 = sa[sp + 1]; - switch(b1) { - case ISO_SS2_7: - if (sl - sp < 4) - return CoderResult.UNDERFLOW; - b2 = sa[sp +2]; - b3 = sa[sp +3]; - if (dl - dp <1) - return CoderResult.OVERFLOW; - da[dp] = decode((byte)b2, - (byte)b3, - SS2Flag); - dp++; - inputSize = 4; - break; - case ISO_SS3_7: - if (sl - sp < 4) - return CoderResult.UNDERFLOW; - b2 = sa[sp + 2]; - b3 = sa[sp + 3]; - if (dl - dp <1) - return CoderResult.OVERFLOW; - da[dp] = decode((byte)b2, - (byte)b3, - SS3Flag); - dp++; - inputSize = 4; - break; - default: - return CoderResult.malformedForLength(2); - } - break; - default: - if (dl - dp < 1) - return CoderResult.OVERFLOW; - if (!shiftout) { - da[dp++]=(char)(sa[sp] & 0xff); - } else { - if (dl - dp < 1) - return CoderResult.OVERFLOW; - if (sl - sp < 2) - return CoderResult.UNDERFLOW; - b2 = sa[sp+1] & 0xff; - da[dp++] = decode((byte)b1, - (byte)b2, - SOFlag); - inputSize = 2; - } - break; - } - sp += inputSize; - } - return CoderResult.UNDERFLOW; - } finally { - src.position(sp - src.arrayOffset()); - dst.position(dp - dst.arrayOffset()); - } - } - - private CoderResult decodeBufferLoop(ByteBuffer src, - CharBuffer dst) - { - int mark = src.position(); - int b1 = 0, b2 = 0, b3 = 0; - - try { - while (src.hasRemaining()) { - b1 = src.get(); - int inputSize = 1; - switch (b1) { - case ISO_SO: - shiftout = true; - break; - case ISO_SI: - shiftout = false; - break; - case ISO_ESC: - if (src.remaining() < minDesignatorLength) - return CoderResult.UNDERFLOW; - - int desig = findDesigBuf(src, SODesig); - if (desig != -1) { - curSODes = desig; - inputSize = SODesig[desig].length + 1; - break; - } - desig = findDesigBuf(src, SS2Desig); - if (desig != -1) { - curSS2Des = desig; - inputSize = SS2Desig[desig].length + 1; - break; - } - desig = findDesigBuf(src, SS3Desig); - if (desig != -1) { - curSS3Des = desig; - inputSize = SS3Desig[desig].length + 1; - break; - } - - if (src.remaining() < 1) - return CoderResult.UNDERFLOW; - b1 = src.get(); - switch(b1) { - case ISO_SS2_7: - if (src.remaining() < 2) - return CoderResult.UNDERFLOW; - b2 = src.get(); - b3 = src.get(); - if (dst.remaining() < 1) - return CoderResult.OVERFLOW; - dst.put(decode((byte)b2, - (byte)b3, - SS2Flag)); - inputSize = 4; - break; - case ISO_SS3_7: - if (src.remaining() < 2) - return CoderResult.UNDERFLOW; - b2 = src.get(); - b3 = src.get(); - if (dst.remaining() < 1) - return CoderResult.OVERFLOW; - dst.put(decode((byte)b2, - (byte)b3, - SS3Flag)); - inputSize = 4; - break; - default: - return CoderResult.malformedForLength(2); - } - break; - default: - if (dst.remaining() < 1) - return CoderResult.OVERFLOW; - if (!shiftout) { - dst.put((char)(b1 & 0xff)); - } else { - if (dst.remaining() < 1) - return CoderResult.OVERFLOW; - if (src.remaining() < 1) - return CoderResult.UNDERFLOW; - b2 = src.get() & 0xff; - dst.put(decode((byte)b1, - (byte)b2, - SOFlag)); - inputSize = 2; - } - break; - } - mark += inputSize; - } - return CoderResult.UNDERFLOW; - } catch (Exception e) { e.printStackTrace(); return CoderResult.OVERFLOW; } - finally { - src.position(mark); - } - } + protected static class Encoder extends CharsetEncoder { - protected CoderResult decodeLoop(ByteBuffer src, - CharBuffer dst) - { - if (src.hasArray() && dst.hasArray()) - return decodeArrayLoop(src, dst); - else - return decodeBufferLoop(src, dst); - } - } + private static final byte ISO_ESC = 0x1b; + private static final byte ISO_SI = 0x0f; + private static final byte ISO_SO = 0x0e; + private static final byte ISO_SS2_7 = 0x4e; + private static final byte ISO_SS3_7 = 0x4f; - protected static class Encoder extends CharsetEncoder { private final Surrogate.Parser sgp = new Surrogate.Parser(); public static final byte SS2 = (byte)0x8e; public static final byte PLANE2 = (byte)0xA2; public static final byte PLANE3 = (byte)0xA3; - private final byte MSB = (byte)0x80; protected final byte maximumDesignatorLength = 4; @@ -428,9 +102,9 @@ abstract class ISO2022 private int unicodeToNative(char unicode, byte ebyte[]) { int index = 0; - char convChar[] = {unicode}; - byte convByte[] = new byte[4]; - int converted; + char[] convChar = {unicode}; + byte[] convByte = new byte[4]; + int converted; try{ CharBuffer cc = CharBuffer.wrap(convChar); @@ -491,16 +165,13 @@ abstract class ISO2022 char[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); + byte[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); - int outputSize = 0; - byte[] outputByte = new byte[8]; + int outputSize; + byte[] outputByte = new byte[8]; newshiftout = shiftout; newSODesDefined = SODesDefined; newSS2DesDefined = SS2DesDefined; @@ -557,9 +228,8 @@ abstract class ISO2022 private CoderResult encodeBufferLoop(CharBuffer src, ByteBuffer dst) { - int outputSize = 0; - byte[] outputByte = new byte[8]; - int inputSize = 0; // Size of input + int outputSize; + byte[] outputByte = new byte[8]; newshiftout = shiftout; newSODesDefined = SODesDefined; newSS2DesDefined = SS2DesDefined; @@ -584,7 +254,7 @@ abstract class ISO2022 outputSize = 1; outputByte[0] = (byte)(inputChar & 0x7f); } - if(inputChar == '\n'){ + if (inputChar == '\n') { newSODesDefined = false; newSS2DesDefined = false; newSS3DesDefined = false; diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN.java b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN.java index 4041522754d..a026158d12d 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN.java +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -34,7 +34,6 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; -import java.nio.charset.CharacterCodingException; import sun.nio.cs.DoubleByte; import sun.nio.cs.HistoricallyNamedCharset; import sun.nio.cs.US_ASCII; @@ -86,17 +85,13 @@ public class ISO2022_CN private boolean shiftOut; private byte currentSODesig; - private static final Charset gb2312 = new EUC_CN(); - private static final Charset cns = new EUC_TW(); - private final DoubleByte.Decoder gb2312Decoder; - private final EUC_TW.Decoder cnsDecoder; + private static final DoubleByte.Decoder GB2312 = + (DoubleByte.Decoder)new EUC_CN().newDecoder(); Decoder(Charset cs) { super(cs, 1.0f, 1.0f); shiftOut = false; currentSODesig = SODesigGB; - gb2312Decoder = (DoubleByte.Decoder)gb2312.newDecoder(); - cnsDecoder = (EUC_TW.Decoder)cns.newDecoder(); } protected void implReset() { @@ -107,34 +102,30 @@ public class ISO2022_CN private char cnsDecode(byte byte1, byte byte2, byte SS) { byte1 |= MSB; byte2 |= MSB; - int p = 0; + int p; if (SS == ISO_SS2_7) p = 1; //plane 2, index -- 1 else if (SS == ISO_SS3_7) p = 2; //plane 3, index -- 2 else return REPLACE_CHAR; //never happen. - char[] ret = cnsDecoder.toUnicode(byte1 & 0xff, - byte2 & 0xff, - p); - if (ret == null || ret.length == 2) - return REPLACE_CHAR; - return ret[0]; + return EUC_TW.Decoder.decodeSingleOrReplace(byte1 & 0xff, + byte2 & 0xff, + p, + REPLACE_CHAR); } private char SODecode(byte byte1, byte byte2, byte SOD) { byte1 |= MSB; byte2 |= MSB; if (SOD == SODesigGB) { - return gb2312Decoder.decodeDouble(byte1 & 0xff, - byte2 & 0xff); + return GB2312.decodeDouble(byte1 & 0xff, + byte2 & 0xff); } else { // SOD == SODesigCNS - char[] ret = cnsDecoder.toUnicode(byte1 & 0xff, - byte2 & 0xff, - 0); - if (ret == null) - return REPLACE_CHAR; - return ret[0]; + return EUC_TW.Decoder.decodeSingleOrReplace(byte1 & 0xff, + byte2 & 0xff, + 0, + REPLACE_CHAR); } } @@ -142,9 +133,9 @@ public class ISO2022_CN CharBuffer dst) { int mark = src.position(); - byte b1 = 0, b2 = 0, b3 = 0, b4 = 0; - int inputSize = 0; - char c = REPLACE_CHAR; + byte b1, b2, b3, b4; + int inputSize; + char c; try { while (src.hasRemaining()) { b1 = src.get(); @@ -264,21 +255,17 @@ public class ISO2022_CN private CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) { - int inputSize = 0; - byte b1 = 0, b2 = 0, b3 = 0, b4 = 0; - char c = REPLACE_CHAR; + int inputSize; + byte b1, b2, b3, b4; + char c; byte[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); char[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); try { while (sp < sl) { @@ -306,7 +293,7 @@ public class ISO2022_CN if ((b3 & (byte)0x80) != 0) return CoderResult.malformedForLength(inputSize); - if (b3 == 'A'){ // "$A" + if (b3 == 'A') { // "$A" /* $A is not a legal designator sequence for ISO2022_CN, it is listed as an escape sequence for GB2312 in ISO2022-JP-2. Keep it here just for diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java index 85bba9a9cfe..3021f195ea5 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN_CNS.java @@ -29,11 +29,8 @@ package sun.nio.cs.ext; import java.nio.charset.Charset; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; -import java.nio.charset.CoderResult; import sun.nio.cs.HistoricallyNamedCharset; import sun.nio.cs.*; @@ -66,18 +63,22 @@ public class ISO2022_CN_CNS extends ISO2022 implements HistoricallyNamedCharset private static final Charset cns = new EUC_TW(); + private static final byte[] SOD = new byte[] {'$', ')', 'G' }; + private static final byte[] SS2D = new byte[] {'$', '*', 'H' }; + private static final byte[] SS3D = new byte[] {'$', '+', 'I' }; + public Encoder(Charset cs) { super(cs); - SODesig = new byte[] {'$', ')', 'G' }; - SS2Desig = new byte[] {'$', '*', 'H' }; - SS3Desig = new byte[] {'$', '+', 'I' }; + SODesig = SOD; + SS2Desig = SS2D; + SS3Desig = SS3D; ISOEncoder = cns.newEncoder(); } - private byte[] bb = new byte[4]; + private final byte[] bb = new byte[4]; public boolean canEncode(char c) { - int n = 0; + int n; return (c <= '\u007f' || (n = ((EUC_TW.Encoder)ISOEncoder).toEUC(c, bb)) == 2 || (n == 4 && bb[0] == SS2 && diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN_GB.java b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN_GB.java index 25c5e8f8570..5c53440482d 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN_GB.java +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_CN_GB.java @@ -29,11 +29,8 @@ package sun.nio.cs.ext; import java.nio.charset.Charset; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; -import java.nio.charset.CoderResult; import sun.nio.cs.*; import sun.nio.cs.HistoricallyNamedCharset; @@ -66,10 +63,13 @@ public class ISO2022_CN_GB extends ISO2022 implements HistoricallyNamedCharset private static class Encoder extends ISO2022.Encoder { private static final Charset gb2312 = new EUC_CN(); + + private static final byte[] SOD = new byte[] {'$', ')', 'A' }; + public Encoder(Charset cs) { super(cs); - SODesig = new byte[] { '$', ')', 'A'}; + SODesig = SOD; ISOEncoder = gb2312.newEncoder(); } diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_JP.java b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_JP.java index 797df1b4c38..dba95f20981 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_JP.java +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_JP.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2021, 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 @@ -172,14 +172,14 @@ public class ISO2022_JP static class Decoder extends CharsetDecoder implements DelegatableDecoder { - final static DoubleByte.Decoder DEC0208 = + static final DoubleByte.Decoder DEC0208 = (DoubleByte.Decoder)new JIS_X_0208().newDecoder(); private int currentState; private int previousState; - private DoubleByte.Decoder dec0208; - private DoubleByte.Decoder dec0212; + private final DoubleByte.Decoder dec0208; + private final DoubleByte.Decoder dec0212; private Decoder(Charset cs) { this(cs, DEC0208, null); @@ -203,20 +203,16 @@ public class ISO2022_JP private CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) { - int inputSize = 0; - int b1 = 0, b2 = 0, b3 = 0, b4 = 0; - char c = UNMAPPABLE_DECODING; + int inputSize; + int b1, b2, b3, b4; + char c; byte[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); char[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); try { while (sp < sl) { @@ -331,8 +327,8 @@ public class ISO2022_JP CharBuffer dst) { int mark = src.position(); - int b1 = 0, b2 = 0, b3 = 0, b4=0; - char c = UNMAPPABLE_DECODING; + int b1, b2, b3, b4; + char c; int inputSize = 0; try { while (src.hasRemaining()) { @@ -465,12 +461,12 @@ public class ISO2022_JP final static DoubleByte.Encoder ENC0208 = (DoubleByte.Encoder)new JIS_X_0208().newEncoder(); - private static byte[] repl = { (byte)0x21, (byte)0x29 }; + private static final byte[] repl = { (byte)0x21, (byte)0x29 }; private int currentMode = ASCII; private int replaceMode = JISX0208_1983; - private DoubleByte.Encoder enc0208; - private DoubleByte.Encoder enc0212; - private boolean doSBKANA; + private final DoubleByte.Encoder enc0208; + private final DoubleByte.Encoder enc0212; + private final boolean doSBKANA; private Encoder(Charset cs) { this(cs, ENC0208, null, true); @@ -535,13 +531,10 @@ public class ISO2022_JP char[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); + byte[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); try { while (sp < sl) { diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_KR.java b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_KR.java index 8ee8d2d56fa..7145328a2ba 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_KR.java +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/ISO2022_KR.java @@ -67,24 +67,261 @@ implements HistoricallyNamedCharset return new Encoder(this); } - private static class Decoder extends ISO2022.Decoder { - public Decoder(Charset cs) + + private static class Decoder extends CharsetDecoder { + + private static final byte[] SOD = new byte[] {'$', ')', 'C' }; + + private static final DoubleByte.Decoder KSC5601 = (DoubleByte.Decoder) + new EUC_KR().newDecoder(); + + private static final byte ISO_ESC = 0x1b; + private static final byte ISO_SI = 0x0f; + private static final byte ISO_SO = 0x0e; + private static final byte ISO_SS2_7 = 0x4e; + private static final byte ISO_SS3_7 = 0x4f; + private static final byte MSB = (byte)0x80; + private static final char REPLACE_CHAR = '\uFFFD'; + private static final byte minDesignatorLength = 3; + + private static final byte SOFlag = 0; + private static final byte SS2Flag = 1; + private static final byte SS3Flag = 2; + + private boolean shiftout; + + private Decoder(Charset cs) { + super(cs, 1.0f, 1.0f); + } + + protected void implReset() { + shiftout = false; + } + + private char decode(byte byte1, byte byte2, byte shiftFlag) { - super(cs); - SODesig = new byte[][] {{(byte)'$', (byte)')', (byte)'C'}}; - SODecoder = new CharsetDecoder[1]; + if (shiftFlag == SOFlag) { + return KSC5601.decodeDouble((byte1 | MSB) & 0xFF, (byte2 | MSB) & 0xFF); + } + return REPLACE_CHAR; + } + + private boolean findDesig(byte[] in, int sp, int sl) { + if (sl - sp >= SOD.length) { + int j = 0; + while (j < SOD.length && in[sp + j] == SOD[j]) { j++; } + return j == SOD.length; + } + return false; + } + + private boolean findDesigBuf(ByteBuffer in) { + if (in.remaining() >= SOD.length) { + int j = 0; + in.mark(); + while (j < SOD.length && in.get() == SOD[j]) { j++; } + if (j == SOD.length) + return true; + in.reset(); + } + return false; + } + + private CoderResult decodeArrayLoop(ByteBuffer src, + CharBuffer dst) + { + byte[] sa = src.array(); + int sp = src.arrayOffset() + src.position(); + int sl = src.arrayOffset() + src.limit(); + + char[] da = dst.array(); + int dp = dst.arrayOffset() + dst.position(); + int dl = dst.arrayOffset() + dst.limit(); + + int b1, b2, b3; + + try { + while (sp < sl) { + b1 = sa[sp] & 0xff; + int inputSize = 1; + switch (b1) { + case ISO_SO: + shiftout = true; + inputSize = 1; + break; + case ISO_SI: + shiftout = false; + inputSize = 1; + break; + case ISO_ESC: + if (sl - sp - 1 < minDesignatorLength) + return CoderResult.UNDERFLOW; + + if (findDesig(sa, sp + 1, sl)) { + inputSize = SOD.length + 1; + break; + } + if (sl - sp < 2) + return CoderResult.UNDERFLOW; + b1 = sa[sp + 1]; + switch (b1) { + case ISO_SS2_7: + if (sl - sp < 4) + return CoderResult.UNDERFLOW; + b2 = sa[sp +2]; + b3 = sa[sp +3]; + if (dl - dp <1) + return CoderResult.OVERFLOW; + da[dp] = decode((byte)b2, + (byte)b3, + SS2Flag); + dp++; + inputSize = 4; + break; + case ISO_SS3_7: + if (sl - sp < 4) + return CoderResult.UNDERFLOW; + b2 = sa[sp + 2]; + b3 = sa[sp + 3]; + if (dl - dp < 1) + return CoderResult.OVERFLOW; + da[dp] = decode((byte)b2, + (byte)b3, + SS3Flag); + dp++; + inputSize = 4; + break; + default: + return CoderResult.malformedForLength(2); + } + break; + default: + if (dl - dp < 1) + return CoderResult.OVERFLOW; + if (!shiftout) { + da[dp++]=(char)(sa[sp] & 0xff); + } else { + if (dl - dp < 1) + return CoderResult.OVERFLOW; + if (sl - sp < 2) + return CoderResult.UNDERFLOW; + b2 = sa[sp+1] & 0xff; + da[dp++] = decode((byte)b1, + (byte)b2, + SOFlag); + inputSize = 2; + } + break; + } + sp += inputSize; + } + return CoderResult.UNDERFLOW; + } finally { + src.position(sp - src.arrayOffset()); + dst.position(dp - dst.arrayOffset()); + } + } + + private CoderResult decodeBufferLoop(ByteBuffer src, + CharBuffer dst) + { + int mark = src.position(); + int b1, b2, b3; try { - SODecoder[0] = Holder.ksc5601_cs.newDecoder(); - } catch (Exception e) {}; + while (src.hasRemaining()) { + b1 = src.get(); + int inputSize = 1; + switch (b1) { + case ISO_SO: + shiftout = true; + break; + case ISO_SI: + shiftout = false; + break; + case ISO_ESC: + if (src.remaining() < minDesignatorLength) + return CoderResult.UNDERFLOW; + + if (findDesigBuf(src)) { + inputSize = SOD.length + 1; + break; + } + + if (src.remaining() < 1) + return CoderResult.UNDERFLOW; + b1 = src.get(); + switch(b1) { + case ISO_SS2_7: + if (src.remaining() < 2) + return CoderResult.UNDERFLOW; + b2 = src.get(); + b3 = src.get(); + if (dst.remaining() < 1) + return CoderResult.OVERFLOW; + dst.put(decode((byte)b2, + (byte)b3, + SS2Flag)); + inputSize = 4; + break; + case ISO_SS3_7: + if (src.remaining() < 2) + return CoderResult.UNDERFLOW; + b2 = src.get(); + b3 = src.get(); + if (dst.remaining() < 1) + return CoderResult.OVERFLOW; + dst.put(decode((byte)b2, + (byte)b3, + SS3Flag)); + inputSize = 4; + break; + default: + return CoderResult.malformedForLength(2); + } + break; + default: + if (dst.remaining() < 1) + return CoderResult.OVERFLOW; + if (!shiftout) { + dst.put((char)(b1 & 0xff)); + } else { + if (src.remaining() < 1) + return CoderResult.UNDERFLOW; + b2 = src.get() & 0xff; + dst.put(decode((byte)b1, + (byte)b2, + SOFlag)); + inputSize = 2; + } + break; + } + mark += inputSize; + } + return CoderResult.UNDERFLOW; + } catch (Exception e) { e.printStackTrace(); return CoderResult.OVERFLOW; } + finally { + src.position(mark); + } + } + + protected CoderResult decodeLoop(ByteBuffer src, + CharBuffer dst) + { + if (src.hasArray() && dst.hasArray()) + return decodeArrayLoop(src, dst); + else + return decodeBufferLoop(src, dst); } } private static class Encoder extends ISO2022.Encoder { + private static final byte[] SOD = new byte[] {'$', ')', 'C' }; + public Encoder(Charset cs) { super(cs); - SODesig = new byte[] {'$', ')', 'C' }; + SODesig = SOD; try { ISOEncoder = Holder.ksc5601_cs.newEncoder(); } catch (Exception e) { } diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/SimpleEUCEncoder.java.template b/src/jdk.charsets/share/classes/sun/nio/cs/ext/SimpleEUCEncoder.java.template index 25ef479bd01..0811087cd21 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/SimpleEUCEncoder.java.template +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/SimpleEUCEncoder.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -98,13 +98,10 @@ public abstract class SimpleEUCEncoder char[] sa = src.array(); int sp = src.arrayOffset() + src.position(); int sl = src.arrayOffset() + src.limit(); - assert (sp <= sl); - sp = (sp <= sl ? sp : sl); + byte[] da = dst.array(); int dp = dst.arrayOffset() + dst.position(); int dl = dst.arrayOffset() + dst.limit(); - assert (dp <= dl); - dp = (dp <= dl ? dp : dl); int index; int spaceNeeded; diff --git a/test/micro/org/openjdk/bench/java/lang/StringDecode.java b/test/micro/org/openjdk/bench/java/lang/StringDecode.java index 22cc920ead5..ace4252c7a3 100644 --- a/test/micro/org/openjdk/bench/java/lang/StringDecode.java +++ b/test/micro/org/openjdk/bench/java/lang/StringDecode.java @@ -54,7 +54,7 @@ public class StringDecode { @State(Scope.Thread) public static class WithCharset { - @Param({"US-ASCII", "ISO-8859-1", "UTF-8", "MS932", "ISO-8859-6"}) + @Param({"US-ASCII", "ISO-8859-1", "UTF-8", "MS932", "ISO-8859-6", "ISO-2022-KR"}) private String charsetName; private Charset charset; -- GitLab From 9fed6048a224f47b77373015be78cc2134402238 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 11 Feb 2021 11:57:45 +0000 Subject: [PATCH 021/367] 8261300: jpackage: rewrite while(0)/while(false) to proper blocks Reviewed-by: herrick, asemenyuk, almatvee --- .../share/native/applauncher/JvmLauncher.cpp | 44 ++++---- .../share/native/common/tstrings.cpp | 100 +++++++++--------- 2 files changed, 70 insertions(+), 74 deletions(-) diff --git a/src/jdk.jpackage/share/native/applauncher/JvmLauncher.cpp b/src/jdk.jpackage/share/native/applauncher/JvmLauncher.cpp index d16ef468229..d3d15965fe2 100644 --- a/src/jdk.jpackage/share/native/applauncher/JvmLauncher.cpp +++ b/src/jdk.jpackage/share/native/applauncher/JvmLauncher.cpp @@ -53,7 +53,7 @@ Jvm& Jvm::initFromConfigFile(const CfgFile& cfgFile) { const CfgFile::Properties& appOptions = cfgFile.getProperties( SectionName::Application); - do { + { const CfgFile::Properties::const_iterator modulepath = appOptions.find( PropertyName::modulepath); if (modulepath != appOptions.end()) { @@ -64,18 +64,18 @@ Jvm& Jvm::initFromConfigFile(const CfgFile& cfgFile) { addArgument(*it); }; } - } while (0); + } - do { + { const CfgFile::Properties::const_iterator classpath = appOptions.find( PropertyName::classpath); if (classpath != appOptions.end()) { addArgument(_T("-classpath")); addArgument(CfgFile::asPathList(*classpath)); } - } while (0); + } - do { + { const CfgFile::Properties::const_iterator splash = appOptions.find( PropertyName::splash); if (splash != appOptions.end()) { @@ -88,9 +88,9 @@ Jvm& Jvm::initFromConfigFile(const CfgFile& cfgFile) { << splashPath << "\" not found"); } } - } while (0); + } - do { + { const CfgFile::Properties& section = cfgFile.getProperties( SectionName::JavaOptions); const CfgFile::Properties::const_iterator javaOptions = section.find( @@ -102,44 +102,44 @@ Jvm& Jvm::initFromConfigFile(const CfgFile& cfgFile) { addArgument(*it); }; } - } while (0); + } - do { + { addArgument(_T("-Djpackage.app-path=") + SysInfo::getProcessModulePath()); - } while (0); + } // No validation of data in config file related to how Java app should be // launched intentionally. // Just read what is in config file and put on jvm's command line as is. - do { // Run modular app + { // Run modular app const CfgFile::Properties::const_iterator mainmodule = appOptions.find( PropertyName::mainmodule); if (mainmodule != appOptions.end()) { addArgument(_T("-m")); addArgument(CfgFile::asString(*mainmodule)); } - } while (0); + } - do { // Run main class + { // Run main class const CfgFile::Properties::const_iterator mainclass = appOptions.find( PropertyName::mainclass); if (mainclass != appOptions.end()) { addArgument(CfgFile::asString(*mainclass)); } - } while (0); + } - do { // Run jar + { // Run jar const CfgFile::Properties::const_iterator mainjar = appOptions.find( PropertyName::mainjar); if (mainjar != appOptions.end()) { addArgument(_T("-jar")); addArgument(CfgFile::asString(*mainjar)); } - } while (0); + } - do { + { const CfgFile::Properties& section = cfgFile.getProperties( SectionName::ArgOptions); const CfgFile::Properties::const_iterator arguments = section.find( @@ -151,7 +151,7 @@ Jvm& Jvm::initFromConfigFile(const CfgFile& cfgFile) { addArgument(*it); }; } - } while (0); + } return *this; } @@ -233,7 +233,7 @@ private: int initJvmlLauncherData(JvmlLauncherData* ptr) const { // Store path to JLI library just behind JvmlLauncherData header. char* curPtr = reinterpret_cast(ptr + 1); - do { + { const size_t count = sizeof(char) * (jliLibPath.size() + 1 /* trailing zero */); if (ptr) { @@ -241,7 +241,7 @@ private: ptr->jliLibPath = curPtr; } curPtr += count; - } while (false); + } // Next write array of char* pointing to JLI lib arg strings. if (ptr) { @@ -284,13 +284,13 @@ JvmlLauncherHandle Jvm::exportLauncher() const { result->jliLibPath = tstrings::toUtf8(jvmPath); #ifdef TSTRINGS_WITH_WCHAR - do { + { tstring_array::const_iterator it = args.begin(); const tstring_array::const_iterator end = args.end(); for (; it != end; ++it) { result->args.push_back(tstrings::toACP(*it)); } - } while (0); + } #else result->args = args; #endif diff --git a/src/jdk.jpackage/share/native/common/tstrings.cpp b/src/jdk.jpackage/share/native/common/tstrings.cpp index 72573d3618d..b89d1a72c66 100644 --- a/src/jdk.jpackage/share/native/common/tstrings.cpp +++ b/src/jdk.jpackage/share/native/common/tstrings.cpp @@ -207,35 +207,33 @@ namespace { */ std::string toMultiByte(const std::wstring& utf16str, int encoding) { std::string reply; - do { - int cm = WideCharToMultiByte(encoding, - 0, - utf16str.c_str(), - int(utf16str.size()), - NULL, - 0, - NULL, - NULL); - if (cm < 0) { - JP_THROW("Unexpected reply from WideCharToMultiByte()"); - } - if (0 == cm) { - break; - } + int cm = WideCharToMultiByte(encoding, + 0, + utf16str.c_str(), + int(utf16str.size()), + NULL, + 0, + NULL, + NULL); + if (cm < 0) { + JP_THROW("Unexpected reply from WideCharToMultiByte()"); + } + if (0 == cm) { + return reply; + } - reply.resize(cm); - int cm2 = WideCharToMultiByte(encoding, - 0, - utf16str.c_str(), - int(utf16str.size()), - &*reply.begin(), - cm, - NULL, - NULL); - if (cm != cm2) { - JP_THROW("Unexpected reply from WideCharToMultiByte()"); - } - } while(0); + reply.resize(cm); + int cm2 = WideCharToMultiByte(encoding, + 0, + utf16str.c_str(), + int(utf16str.size()), + &*reply.begin(), + cm, + NULL, + NULL); + if (cm != cm2) { + JP_THROW("Unexpected reply from WideCharToMultiByte()"); + } return reply; } @@ -245,31 +243,29 @@ std::string toMultiByte(const std::wstring& utf16str, int encoding) { */ std::wstring fromMultiByte(const std::string& str, int encoding) { std::wstring utf16; - do { - int cw = MultiByteToWideChar(encoding, - MB_ERR_INVALID_CHARS, - str.c_str(), - int(str.size()), - NULL, - 0); - if (cw < 0) { - JP_THROW("Unexpected reply from MultiByteToWideChar()"); - } - if (0 == cw) { - break; - } + int cw = MultiByteToWideChar(encoding, + MB_ERR_INVALID_CHARS, + str.c_str(), + int(str.size()), + NULL, + 0); + if (cw < 0) { + JP_THROW("Unexpected reply from MultiByteToWideChar()"); + } + if (0 == cw) { + return utf16; + } - utf16.resize(cw); - int cw2 = MultiByteToWideChar(encoding, - MB_ERR_INVALID_CHARS, - str.c_str(), - int(str.size()), - &*utf16.begin(), - cw); - if (cw != cw2) { - JP_THROW("Unexpected reply from MultiByteToWideChar()"); - } - } while(0); + utf16.resize(cw); + int cw2 = MultiByteToWideChar(encoding, + MB_ERR_INVALID_CHARS, + str.c_str(), + int(str.size()), + &*utf16.begin(), + cw); + if (cw != cw2) { + JP_THROW("Unexpected reply from MultiByteToWideChar()"); + } return utf16; } -- GitLab From 0a89987a9699008927268c050ca4b7e01afc30f4 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 11 Feb 2021 13:00:10 +0000 Subject: [PATCH 022/367] 8240281: Remove failing assertion code when selecting first memory state in SuperWord::co_locate_pack Reviewed-by: roland, kvn, thartmann --- src/hotspot/share/opto/superword.cpp | 19 +-- .../superword/TestPickFirstMemoryState.java | 134 ++++++++++++++++++ 2 files changed, 141 insertions(+), 12 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/loopopts/superword/TestPickFirstMemoryState.java diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp index 00f4a50f291..90ce0f99c51 100644 --- a/src/hotspot/share/opto/superword.cpp +++ b/src/hotspot/share/opto/superword.cpp @@ -2316,18 +2316,13 @@ Node* SuperWord::pick_mem_state(Node_List* pk) { assert(current->is_Mem() && in_bb(current), "unexpected memory"); assert(current != first_mem, "corrupted memory graph"); if (!independent(current, ld)) { -#ifdef ASSERT - // Added assertion code since no case has been observed that should pick the first memory state. - // Remove the assertion code whenever we find a (valid) case that really needs the first memory state. - pk->dump(); - first_mem->dump(); - last_mem->dump(); - current->dump(); - ld->dump(); - ld->in(MemNode::Memory)->dump(); - assert(false, "never observed that first memory should be picked"); -#endif - return first_mem; // A later store depends on this load, pick memory state of first load + // A later store depends on this load, pick the memory state of the first load. This can happen, for example, + // if a load pack has interleaving stores that are part of a store pack which, however, is removed at the pack + // filtering stage. This leaves us with only a load pack for which we cannot take the memory state of the + // last load as the remaining unvectorized stores could interfere since they have a dependency to the loads. + // Some stores could be executed before the load vector resulting in a wrong result. We need to take the + // memory state of the first load to prevent this. + return first_mem; } } } diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestPickFirstMemoryState.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestPickFirstMemoryState.java new file mode 100644 index 00000000000..488e32c416a --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestPickFirstMemoryState.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +/** + * @test + * @requires vm.compiler2.enabled + * @bug 8240281 + * @summary Test which needs to select the memory state of the first load in a load pack in SuperWord::co_locate_pack. + * + * @run main/othervm -Xcomp -XX:CompileCommand=compileonly,compiler.loopopts.superword.TestPickFirstMemoryState::* + * compiler.loopopts.superword.TestPickFirstMemoryState + * @run main/othervm -XX:CompileCommand=dontinline,compiler.loopopts.superword.TestPickFirstMemoryState::* + * compiler.loopopts.superword.TestPickFirstMemoryState + */ + +package compiler.loopopts.superword; + +public class TestPickFirstMemoryState { + + static int iArrFld[] = new int[50]; + + static int test() { + int x = 2; + for (int i = 50; i > 9; i--) { + // We create an AddI pack and a LoadI pack for the following loop. The StoreI pack gets filtered. When + // finding the memory state for the load pack, we cannot pick the memory state from the last load as + // the stores (which are not vectorized) could interfere and be executed before the load pack (already + // writing 'j' to iArrFld which is afterwards loaded by the load vector operation). This leads to a + // wrong result for 'x'. We must take the memory state of the first load where we have not yet assigned + // any new values ('j') to the iArrFld array. + x = 2; + for (int j = 10; j < 50; j++) { + x += iArrFld[j]; // AddI pack + LoadI pack + iArrFld[j] = j; // StoreI pack that gets removed while filtering packs + } + reset(); + } + + return x; + } + + static int test2() { + int x = 2; + int y = 3; + for (int i = 50; i > 9; i--) { + x = 2; + for (int j = 10; j < 50; j++) { + x += iArrFld[j]; + iArrFld[j] = (y++); + } + reset(); + } + return x; + } + + static int test3() { + int x = 2; + for (int i = 50; i > 9; i--) { + x = 2; + int y = i; + for (int j = 10; j < 50; j++) { + y++; + x += iArrFld[j]; + iArrFld[j] = y; + } + reset(); + } + return x; + } + + static int test4() { + int x = 2; + long y = 3L; + for (int i = 50; i > 9; i--) { + x = 2; + for (int j = 10; j < 50; j++) { + x += iArrFld[j]; + iArrFld[j] = (int)(y++); + } + reset(); + } + return x; + } + + public static void main(String[] strArr) { + for (int i = 0; i < 5000; i++) { + reset(); + int x = test(); + if (x != 202) { + throw new RuntimeException("test() wrong result: " + x); + } + x = test2(); + if (x != 202) { + throw new RuntimeException("test2() wrong result: " + x); + } + x = test3(); + if (x != 202) { + throw new RuntimeException("test3() wrong result: " + x); + } + x = test4(); + if (x != 202) { + throw new RuntimeException("test4() wrong result: " + x); + } + } + } + + public static void reset() { + for (int i = 0; i < iArrFld.length; i++) { + iArrFld[i] = 5; + } + } +} + -- GitLab From eef86a80f895f08b97ca4b8e47d793082f0ede9d Mon Sep 17 00:00:00 2001 From: Stefan Johansson Date: Thu, 11 Feb 2021 13:10:37 +0000 Subject: [PATCH 023/367] 8261029: Code heap page sizes not traced correctly using os::trace_page_sizes Reviewed-by: kvn, stuefe, thartmann --- src/hotspot/share/memory/heap.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/memory/heap.cpp b/src/hotspot/share/memory/heap.cpp index 098095fb293..fa9de515980 100644 --- a/src/hotspot/share/memory/heap.cpp +++ b/src/hotspot/share/memory/heap.cpp @@ -207,17 +207,12 @@ bool CodeHeap::reserve(ReservedSpace rs, size_t committed_size, size_t segment_s _log2_segment_size = exact_log2(segment_size); // Reserve and initialize space for _memory. - size_t page_size = os::vm_page_size(); - if (os::can_execute_large_page_memory()) { - const size_t min_pages = 8; - page_size = MIN2(os::page_size_for_region_aligned(committed_size, min_pages), - os::page_size_for_region_aligned(rs.size(), min_pages)); - } - + const size_t page_size = ReservedSpace::actual_reserved_page_size(rs); const size_t granularity = os::vm_allocation_granularity(); const size_t c_size = align_up(committed_size, page_size); + assert(c_size <= rs.size(), "alignment made committed size to large"); - os::trace_page_sizes(_name, committed_size, rs.size(), page_size, + os::trace_page_sizes(_name, c_size, rs.size(), page_size, rs.base(), rs.size()); if (!_memory.initialize(rs, c_size)) { return false; -- GitLab From 4a72cea01987c4217e5e43978ce759cdb5c7d5a9 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Thu, 11 Feb 2021 14:02:24 +0000 Subject: [PATCH 024/367] 8261509: Move per-thread StackWatermark from Thread to JavaThread class Reviewed-by: eosterlund --- src/hotspot/share/runtime/thread.hpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index d0125dcbc29..54cc4d38f30 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -274,12 +274,6 @@ class Thread: public ThreadShadow { // suspend/resume lock: used for self-suspend Monitor* _SR_lock; - // Stack watermark barriers. - StackWatermarks _stack_watermarks; - - public: - inline StackWatermarks* stack_watermarks() { return &_stack_watermarks; } - protected: enum SuspendFlags { // NOTE: avoid using the sign-bit as cc generates different test code @@ -1061,6 +1055,11 @@ class JavaThread: public Thread { friend class ThreadWaitTransition; friend class VM_Exit; + // Stack watermark barriers. + StackWatermarks _stack_watermarks; + + public: + inline StackWatermarks* stack_watermarks() { return &_stack_watermarks; } public: // Constructor -- GitLab From c342323c7ab1e38caed422dd22c9c204048c2100 Mon Sep 17 00:00:00 2001 From: Yasumasa Suenaga Date: Thu, 11 Feb 2021 14:58:03 +0000 Subject: [PATCH 025/367] 8261431: SA: Add comments about load address of executable Reviewed-by: sspitsyn, kevinw --- src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c b/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c index dff4cb3eeca..9f7c4050ef2 100644 --- a/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c +++ b/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c @@ -507,7 +507,11 @@ static uintptr_t read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehd result = exec_php->p_vaddr; ph->core->dynamic_addr = exec_php->p_vaddr; } else { // ET_DYN + // Base address of executable is based on entry point (AT_ENTRY). result = ph->core->dynamic_addr - exec_ehdr->e_entry; + + // dynamic_addr has entry point of executable. + // Thus we should subtract it. ph->core->dynamic_addr += exec_php->p_vaddr - exec_ehdr->e_entry; } print_debug("address of _DYNAMIC is 0x%lx\n", ph->core->dynamic_addr); -- GitLab From 1740de2a0d41d0689ae9bb069b93ab267a2b9495 Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Thu, 11 Feb 2021 14:58:57 +0000 Subject: [PATCH 026/367] 8261297: NMT: Final report should use scale 1 Reviewed-by: zgu --- src/hotspot/share/services/memReporter.hpp | 24 ++++++++++++---------- src/hotspot/share/services/memTracker.cpp | 17 ++++++++++----- src/hotspot/share/services/memTracker.hpp | 11 ++++------ 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/hotspot/share/services/memReporter.hpp b/src/hotspot/share/services/memReporter.hpp index 6685c102efc..70e73e5d97c 100644 --- a/src/hotspot/share/services/memReporter.hpp +++ b/src/hotspot/share/services/memReporter.hpp @@ -39,14 +39,17 @@ */ class MemReporterBase : public StackObj { private: - size_t _scale; // report in this scale - outputStream* _output; // destination + const size_t _scale; // report in this scale + outputStream* const _output; // destination public: - MemReporterBase(outputStream* out = NULL, size_t scale = K) - : _scale(scale) { - _output = (out == NULL) ? tty : out; - } + + // Default scale to use if no scale given. + static const size_t default_scale = K; + + MemReporterBase(outputStream* out, size_t scale = default_scale) : + _scale(scale), _output(out) + {} protected: inline outputStream* output() const { @@ -74,7 +77,6 @@ class MemReporterBase : public StackObj { size_t reserved_total(const MallocMemory* malloc, const VirtualMemory* vm) const; size_t committed_total(const MallocMemory* malloc, const VirtualMemory* vm) const; - // Print summary total, malloc and virtual memory void print_total(size_t reserved, size_t committed) const; void print_malloc(size_t amount, size_t count, MEMFLAGS flag = mtNone) const; @@ -100,7 +102,7 @@ class MemSummaryReporter : public MemReporterBase { public: // This constructor is for normal reporting from a recent baseline. MemSummaryReporter(MemBaseline& baseline, outputStream* output, - size_t scale = K) : MemReporterBase(output, scale), + size_t scale = default_scale) : MemReporterBase(output, scale), _malloc_snapshot(baseline.malloc_memory_snapshot()), _vm_snapshot(baseline.virtual_memory_snapshot()), _instance_class_count(baseline.instance_class_count()), @@ -125,7 +127,7 @@ class MemDetailReporter : public MemSummaryReporter { MemBaseline& _baseline; public: - MemDetailReporter(MemBaseline& baseline, outputStream* output, size_t scale = K) : + MemDetailReporter(MemBaseline& baseline, outputStream* output, size_t scale = default_scale) : MemSummaryReporter(baseline, output, scale), _baseline(baseline) { } @@ -162,7 +164,7 @@ class MemSummaryDiffReporter : public MemReporterBase { public: MemSummaryDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline, - outputStream* output, size_t scale = K) : MemReporterBase(output, scale), + outputStream* output, size_t scale = default_scale) : MemReporterBase(output, scale), _early_baseline(early_baseline), _current_baseline(current_baseline) { assert(early_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined"); assert(current_baseline.baseline_type() != MemBaseline::Not_baselined, "Not baselined"); @@ -201,7 +203,7 @@ class MemSummaryDiffReporter : public MemReporterBase { class MemDetailDiffReporter : public MemSummaryDiffReporter { public: MemDetailDiffReporter(MemBaseline& early_baseline, MemBaseline& current_baseline, - outputStream* output, size_t scale = K) : + outputStream* output, size_t scale = default_scale) : MemSummaryDiffReporter(early_baseline, current_baseline, output, scale) { } // Generate detail comparison report diff --git a/src/hotspot/share/services/memTracker.cpp b/src/hotspot/share/services/memTracker.cpp index 5fcbc7cc664..1791e21602f 100644 --- a/src/hotspot/share/services/memTracker.cpp +++ b/src/hotspot/share/services/memTracker.cpp @@ -170,7 +170,14 @@ bool MemTracker::transition_to(NMT_TrackingLevel level) { return true; } +// Report during error reporting. +void MemTracker::error_report(outputStream* output) { + if (tracking_level() >= NMT_summary) { + report(true, output, MemReporterBase::default_scale); // just print summary for error case. + } +} +// Report when handling PrintNMTStatistics before VM shutdown. static volatile bool g_final_report_did_run = false; void MemTracker::final_report(outputStream* output) { // This function is called during both error reporting and normal VM exit. @@ -181,25 +188,25 @@ void MemTracker::final_report(outputStream* output) { if (Atomic::cmpxchg(&g_final_report_did_run, false, true) == false) { NMT_TrackingLevel level = tracking_level(); if (level >= NMT_summary) { - report(level == NMT_summary, output); + report(level == NMT_summary, output, 1); } } } -void MemTracker::report(bool summary_only, outputStream* output) { +void MemTracker::report(bool summary_only, outputStream* output, size_t scale) { assert(output != NULL, "No output stream"); MemBaseline baseline; if (baseline.baseline(summary_only)) { if (summary_only) { - MemSummaryReporter rpt(baseline, output); + MemSummaryReporter rpt(baseline, output, scale); rpt.report(); } else { - MemDetailReporter rpt(baseline, output); + MemDetailReporter rpt(baseline, output, scale); rpt.report(); output->print("Metaspace:"); // The basic metaspace report avoids any locking and should be safe to // be called at any time. - MetaspaceUtils::print_basic_report(output, K); + MetaspaceUtils::print_basic_report(output, scale); } } } diff --git a/src/hotspot/share/services/memTracker.hpp b/src/hotspot/share/services/memTracker.hpp index 7097144c242..1e7b394dc82 100644 --- a/src/hotspot/share/services/memTracker.hpp +++ b/src/hotspot/share/services/memTracker.hpp @@ -286,13 +286,10 @@ class MemTracker : AllStatic { return NMTQuery_lock; } - // Make a final report or report for hs_err file. - static void error_report(outputStream* output) { - if (tracking_level() >= NMT_summary) { - report(true, output); // just print summary for error case. - } - } + // Report during error reporting. + static void error_report(outputStream* output); + // Report when handling PrintNMTStatistics before VM shutdown. static void final_report(outputStream* output); // Stored baseline @@ -308,7 +305,7 @@ class MemTracker : AllStatic { private: static NMT_TrackingLevel init_tracking_level(); - static void report(bool summary_only, outputStream* output); + static void report(bool summary_only, outputStream* output, size_t scale); private: // Tracking level -- GitLab From 75c8489ce8ad7a544d188a4dd6463c39ba3a1dec Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Thu, 11 Feb 2021 18:10:42 +0000 Subject: [PATCH 027/367] 8261604: ProblemList jdk/dynalink/TypeConverterFactoryMemoryLeakTest.java Reviewed-by: hseigel --- test/jdk/ProblemList.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 297e13c5e99..43f9747f9ce 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -821,6 +821,8 @@ javax/rmi/ssl/SSLSocketParametersTest.sh 8162906 generic- javax/script/Test7.java 8239361 generic-all +jdk/dynalink/TypeConverterFactoryMemoryLeakTest.java 8261483 generic-all + ############################################################################ # jdk_jfr -- GitLab From f4cfd758342a9afc8cc0fb2bb400ed8c791e0588 Mon Sep 17 00:00:00 2001 From: John Jiang Date: Thu, 11 Feb 2021 18:25:31 +0000 Subject: [PATCH 028/367] 8261510: Use RFC numbers and protocol titles in sun.security.ssl.SSLExtension comments Reviewed-by: wetmore, xuelei --- .../sun/security/ssl/SSLExtension.java | 127 +++++++++--------- 1 file changed, 62 insertions(+), 65 deletions(-) diff --git a/src/java.base/share/classes/sun/security/ssl/SSLExtension.java b/src/java.base/share/classes/sun/security/ssl/SSLExtension.java index c6bbc6c77e5..47272f8e0b8 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLExtension.java @@ -35,7 +35,7 @@ import sun.security.ssl.SSLHandshake.HandshakeMessage; import sun.security.util.HexDumpEncoder; enum SSLExtension implements SSLStringizer { - // Extensions defined in RFC 6066 + // Extensions defined in RFC 6066 (TLS Extensions: Extension Definitions) CH_SERVER_NAME (0x0000, "server_name", SSLHandshake.CLIENT_HELLO, ProtocolVersion.PROTOCOLS_TO_13, @@ -63,6 +63,7 @@ enum SSLExtension implements SSLStringizer { null, null, ServerNameExtension.shStringizer), + CH_MAX_FRAGMENT_LENGTH (0x0001, "max_fragment_length", SSLHandshake.CLIENT_HELLO, ProtocolVersion.PROTOCOLS_TO_13, @@ -90,6 +91,7 @@ enum SSLExtension implements SSLStringizer { MaxFragExtension.eeOnTradeConsumer, null, MaxFragExtension.maxFragLenStringizer), + CLIENT_CERTIFICATE_URL (0x0002, "client_certificate_url"), TRUSTED_CA_KEYS (0x0003, "trusted_ca_keys"), TRUNCATED_HMAC (0x0004, "truncated_hmac"), @@ -123,17 +125,17 @@ enum SSLExtension implements SSLStringizer { null, CertStatusExtension.certStatusRespStringizer), - // extensions defined in RFC 4681 + // Extensions defined in RFC 4681 (TLS User Mapping Extension) USER_MAPPING (0x0006, "user_mapping"), - // extensions defined in RFC 5878 + // Extensions defined in RFC 5878 (TLS Authorization Extensions) CLIENT_AUTHZ (0x0007, "client_authz"), SERVER_AUTHZ (0x0008, "server_authz"), - // extensions defined in RFC 5081 + // Extensions defined in RFC 6091 (Using OpenPGP Keys for TLS Authentication) CERT_TYPE (0x0009, "cert_type"), - // extensions defined in RFC 4492 (ECC) + // Extensions defined in RFC 8422 (ECC Cipher Suites for TLS Versions 1.2 and Earlier) CH_SUPPORTED_GROUPS (0x000A, "supported_groups", SSLHandshake.CLIENT_HELLO, ProtocolVersion.PROTOCOLS_TO_13, @@ -172,55 +174,16 @@ enum SSLExtension implements SSLStringizer { null, ECPointFormatsExtension.epfStringizer), - // extensions defined in RFC 5054 + // Extensions defined in RFC 5054 (Using the SRP Protocol for TLS Authentication) SRP (0x000C, "srp"), - // extensions defined in RFC 5246 - CH_SIGNATURE_ALGORITHMS (0x000D, "signature_algorithms", - SSLHandshake.CLIENT_HELLO, - ProtocolVersion.PROTOCOLS_12_13, - SignatureAlgorithmsExtension.chNetworkProducer, - SignatureAlgorithmsExtension.chOnLoadConsumer, - SignatureAlgorithmsExtension.chOnLoadAbsence, - SignatureAlgorithmsExtension.chOnTradeConsumer, - SignatureAlgorithmsExtension.chOnTradeAbsence, - SignatureAlgorithmsExtension.ssStringizer), - CR_SIGNATURE_ALGORITHMS (0x000D, "signature_algorithms", - SSLHandshake.CERTIFICATE_REQUEST, - ProtocolVersion.PROTOCOLS_OF_13, - SignatureAlgorithmsExtension.crNetworkProducer, - SignatureAlgorithmsExtension.crOnLoadConsumer, - SignatureAlgorithmsExtension.crOnLoadAbsence, - SignatureAlgorithmsExtension.crOnTradeConsumer, - null, - SignatureAlgorithmsExtension.ssStringizer), - - CH_SIGNATURE_ALGORITHMS_CERT (0x0032, "signature_algorithms_cert", - SSLHandshake.CLIENT_HELLO, - ProtocolVersion.PROTOCOLS_12_13, - CertSignAlgsExtension.chNetworkProducer, - CertSignAlgsExtension.chOnLoadConsumer, - null, - CertSignAlgsExtension.chOnTradeConsumer, - null, - CertSignAlgsExtension.ssStringizer), - CR_SIGNATURE_ALGORITHMS_CERT (0x0032, "signature_algorithms_cert", - SSLHandshake.CERTIFICATE_REQUEST, - ProtocolVersion.PROTOCOLS_OF_13, - CertSignAlgsExtension.crNetworkProducer, - CertSignAlgsExtension.crOnLoadConsumer, - null, - CertSignAlgsExtension.crOnTradeConsumer, - null, - CertSignAlgsExtension.ssStringizer), - - // extensions defined in RFC 5764 + // Extensions defined in RFC 5764 (DTLS Extension to Establish Keys for the SRTP) USE_SRTP (0x000E, "use_srtp"), - // extensions defined in RFC 6520 + // Extensions defined in RFC 6520 (TLS and DTLS Heartbeat Extension) HEARTBEAT (0x000E, "heartbeat"), - // extension defined in RFC 7301 (ALPN) + // Extensions defined in RFC 7301 (TLS Application-Layer Protocol Negotiation Extension) CH_ALPN (0x0010, "application_layer_protocol_negotiation", SSLHandshake.CLIENT_HELLO, ProtocolVersion.PROTOCOLS_TO_13, @@ -249,7 +212,7 @@ enum SSLExtension implements SSLStringizer { null, AlpnExtension.alpnStringizer), - // extensions defined in RFC 6961 + // Extensions defined in RFC 6961 (TLS Multiple Certificate Status Request Extension) CH_STATUS_REQUEST_V2 (0x0011, "status_request_v2", SSLHandshake.CLIENT_HELLO, ProtocolVersion.PROTOCOLS_TO_12, @@ -269,20 +232,20 @@ enum SSLExtension implements SSLStringizer { null, CertStatusExtension.certStatusReqV2Stringizer), - // extensions defined in RFC 6962 + // Extensions defined in RFC 6962 (Certificate Transparency) SIGNED_CERT_TIMESTAMP (0x0012, "signed_certificate_timestamp"), - // extensions defined in RFC 7250 + // Extensions defined in RFC 7250 (Using Raw Public Keys in TLS and DTLS) CLIENT_CERT_TYPE (0x0013, "client_certificate_type"), SERVER_CERT_TYPE (0x0014, "server_certificate_type"), - // extensions defined in RFC 7685 + // Extensions defined in RFC 7685 (TLS ClientHello Padding Extension) PADDING (0x0015, "padding"), - // extensions defined in RFC 7366 + // Extensions defined in RFC 7366 (Encrypt-then-MAC for TLS and DTLS) ENCRYPT_THEN_MAC (0x0016, "encrypt_then_mac"), - // extensions defined in RFC 7627 + // Extensions defined in RFC 7627 (TLS Session Hash and Extended Master Secret Extension) CH_EXTENDED_MASTER_SECRET (0x0017, "extended_master_secret", SSLHandshake.CLIENT_HELLO, ProtocolVersion.PROTOCOLS_TO_12, @@ -302,13 +265,13 @@ enum SSLExtension implements SSLStringizer { null, ExtendedMasterSecretExtension.emsStringizer), - // extensions defined in RFC draft-ietf-tokbind-negotiation - TOKEN_BINDING (0x0018, "token_binding "), + // Extensions defined in RFC 8472 (TLS Extension for Token Binding Protocol Negotiation) + TOKEN_BINDING (0x0018, "token_binding"), - // extensions defined in RFC 7924 + // Extensions defined in RFC 7924 (TLS Cached Information Extension) CACHED_INFO (0x0019, "cached_info"), - // extensions defined in RFC 5077 + // Extensions defined in RFC 5077 (TLS Session Resumption without Server-Side State) CH_SESSION_TICKET (0x0023, "session_ticket", SSLHandshake.CLIENT_HELLO, ProtocolVersion.PROTOCOLS_10_12, @@ -319,7 +282,6 @@ enum SSLExtension implements SSLStringizer { null, SessionTicketExtension.steStringizer), //null), - SH_SESSION_TICKET (0x0023, "session_ticket", SSLHandshake.SERVER_HELLO, ProtocolVersion.PROTOCOLS_10_12, @@ -331,7 +293,26 @@ enum SSLExtension implements SSLStringizer { SessionTicketExtension.steStringizer), //null), - // extensions defined in TLS 1.3 + // Extensions defined in RFC 8446 (TLS Protocol Version 1.3) + CH_SIGNATURE_ALGORITHMS (0x000D, "signature_algorithms", + SSLHandshake.CLIENT_HELLO, + ProtocolVersion.PROTOCOLS_12_13, + SignatureAlgorithmsExtension.chNetworkProducer, + SignatureAlgorithmsExtension.chOnLoadConsumer, + SignatureAlgorithmsExtension.chOnLoadAbsence, + SignatureAlgorithmsExtension.chOnTradeConsumer, + SignatureAlgorithmsExtension.chOnTradeAbsence, + SignatureAlgorithmsExtension.ssStringizer), + CR_SIGNATURE_ALGORITHMS (0x000D, "signature_algorithms", + SSLHandshake.CERTIFICATE_REQUEST, + ProtocolVersion.PROTOCOLS_OF_13, + SignatureAlgorithmsExtension.crNetworkProducer, + SignatureAlgorithmsExtension.crOnLoadConsumer, + SignatureAlgorithmsExtension.crOnLoadAbsence, + SignatureAlgorithmsExtension.crOnTradeConsumer, + null, + SignatureAlgorithmsExtension.ssStringizer), + CH_EARLY_DATA (0x002A, "early_data"), EE_EARLY_DATA (0x002A, "early_data"), NST_EARLY_DATA (0x002A, "early_data"), @@ -347,7 +328,6 @@ enum SSLExtension implements SSLStringizer { SupportedVersionsExtension.chStringizer), SH_SUPPORTED_VERSIONS (0x002B, "supported_versions", SSLHandshake.SERVER_HELLO, - // and HelloRetryRequest ProtocolVersion.PROTOCOLS_OF_13, SupportedVersionsExtension.shNetworkProducer, SupportedVersionsExtension.shOnLoadConsumer, @@ -406,7 +386,6 @@ enum SSLExtension implements SSLStringizer { null, PskKeyExchangeModesExtension.chOnTradeAbsence, PskKeyExchangeModesExtension.pkemStringizer), - CH_CERTIFICATE_AUTHORITIES (0x002F, "certificate_authorities", SSLHandshake.CLIENT_HELLO, ProtocolVersion.PROTOCOLS_OF_13, @@ -416,7 +395,6 @@ enum SSLExtension implements SSLStringizer { null, null, CertificateAuthoritiesExtension.ssStringizer), - CR_CERTIFICATE_AUTHORITIES (0x002F, "certificate_authorities", SSLHandshake.CERTIFICATE_REQUEST, ProtocolVersion.PROTOCOLS_OF_13, @@ -430,6 +408,25 @@ enum SSLExtension implements SSLStringizer { OID_FILTERS (0x0030, "oid_filters"), POST_HANDSHAKE_AUTH (0x0030, "post_handshake_auth"), + CH_SIGNATURE_ALGORITHMS_CERT (0x0032, "signature_algorithms_cert", + SSLHandshake.CLIENT_HELLO, + ProtocolVersion.PROTOCOLS_12_13, + CertSignAlgsExtension.chNetworkProducer, + CertSignAlgsExtension.chOnLoadConsumer, + null, + CertSignAlgsExtension.chOnTradeConsumer, + null, + CertSignAlgsExtension.ssStringizer), + CR_SIGNATURE_ALGORITHMS_CERT (0x0032, "signature_algorithms_cert", + SSLHandshake.CERTIFICATE_REQUEST, + ProtocolVersion.PROTOCOLS_OF_13, + CertSignAlgsExtension.crNetworkProducer, + CertSignAlgsExtension.crOnLoadConsumer, + null, + CertSignAlgsExtension.crOnTradeConsumer, + null, + CertSignAlgsExtension.ssStringizer), + CH_KEY_SHARE (0x0033, "key_share", SSLHandshake.CLIENT_HELLO, ProtocolVersion.PROTOCOLS_OF_13, @@ -462,7 +459,7 @@ enum SSLExtension implements SSLStringizer { null, null, null, null, KeyShareExtension.hrrStringizer), - // Extensions defined in RFC 5746 + // Extensions defined in RFC 5746 (TLS Renegotiation Indication Extension) CH_RENEGOTIATION_INFO (0xff01, "renegotiation_info", SSLHandshake.CLIENT_HELLO, ProtocolVersion.PROTOCOLS_TO_12, @@ -482,7 +479,7 @@ enum SSLExtension implements SSLStringizer { null, RenegoInfoExtension.rniStringizer), - // TLS 1.3 PSK extension must be last + // RFC 8446 (TLS Protocol Version 1.3) PSK extension must be last CH_PRE_SHARED_KEY (0x0029, "pre_shared_key", SSLHandshake.CLIENT_HELLO, ProtocolVersion.PROTOCOLS_OF_13, -- GitLab From bf47a479b91607b769c57a9bd26236fc21bc5c1f Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Thu, 11 Feb 2021 22:05:12 +0000 Subject: [PATCH 029/367] 8261282: Lazy initialization of built-in ICC_Profile/ColorSpace classes is too lazy Reviewed-by: azvegint --- .../classes/java/awt/color/ColorSpace.java | 117 ++++----------- .../classes/java/awt/color/ICC_Profile.java | 135 ++++++------------ .../classes/java/awt/image/ColorModel.java | 10 +- .../classes/sun/java2d/cmm/CMSManager.java | 12 +- .../java/awt/color/BuiltInDataVariation.java | 78 ++++++++++ test/jdk/java/awt/color/HotStaticLocks.java | 66 +++++++++ 6 files changed, 219 insertions(+), 199 deletions(-) create mode 100644 test/jdk/java/awt/color/BuiltInDataVariation.java create mode 100644 test/jdk/java/awt/color/HotStaticLocks.java diff --git a/src/java.desktop/share/classes/java/awt/color/ColorSpace.java b/src/java.desktop/share/classes/java/awt/color/ColorSpace.java index 89fd39c565d..501ddafc684 100644 --- a/src/java.desktop/share/classes/java/awt/color/ColorSpace.java +++ b/src/java.desktop/share/classes/java/awt/color/ColorSpace.java @@ -39,8 +39,6 @@ import java.io.Serial; import java.io.Serializable; import java.lang.annotation.Native; -import sun.java2d.cmm.CMSManager; - /** * This abstract class is used to serve as a color space tag to identify the * specific color space of a {@code Color} object or, via a {@code ColorModel} @@ -112,12 +110,22 @@ public abstract class ColorSpace implements Serializable { private final int numComponents; private transient String [] compName = null; - // Cache of singletons for the predefined color spaces. - private static ColorSpace sRGBspace; - private static ColorSpace XYZspace; - private static ColorSpace PYCCspace; - private static ColorSpace GRAYspace; - private static ColorSpace LINEAR_RGBspace; + /** + * The lazy cache of singletons for the predefined built-in color spaces. + */ + private interface BuiltInSpace { + + ColorSpace SRGB = new ICC_ColorSpace(ICC_Profile.getInstance(CS_sRGB)); + + ColorSpace LRGB = + new ICC_ColorSpace(ICC_Profile.getInstance(CS_LINEAR_RGB)); + + ColorSpace XYZ = new ICC_ColorSpace(ICC_Profile.getInstance(CS_CIEXYZ)); + + ColorSpace PYCC = new ICC_ColorSpace(ICC_Profile.getInstance(CS_PYCC)); + + ColorSpace GRAY = new ICC_ColorSpace(ICC_Profile.getInstance(CS_GRAY)); + } /** * Any of the family of XYZ color spaces. @@ -289,88 +297,24 @@ public abstract class ColorSpace implements Serializable { * Returns a {@code ColorSpace} representing one of the specific predefined * color spaces. * - * @param colorspace a specific color space identified by one of the - * predefined class constants (e.g. {@code CS_sRGB}, - * {@code CS_LINEAR_RGB}, {@code CS_CIEXYZ}, {@code CS_GRAY}, or - * {@code CS_PYCC}) + * @param cspace a specific color space identified by one of the predefined + * class constants (e.g. {@code CS_sRGB}, {@code CS_LINEAR_RGB}, + * {@code CS_CIEXYZ}, {@code CS_GRAY}, or {@code CS_PYCC}) * @return the requested {@code ColorSpace} object */ // NOTE: This method may be called by privileged threads. // DO NOT INVOKE CLIENT CODE ON THIS THREAD! - public static ColorSpace getInstance (int colorspace) - { - ColorSpace theColorSpace; - - switch (colorspace) { - case CS_sRGB: - synchronized(ColorSpace.class) { - if (sRGBspace == null) { - ICC_Profile theProfile = ICC_Profile.getInstance (CS_sRGB); - sRGBspace = new ICC_ColorSpace (theProfile); - } - - theColorSpace = sRGBspace; + public static ColorSpace getInstance(int cspace) { + return switch (cspace) { + case CS_sRGB -> BuiltInSpace.SRGB; + case CS_LINEAR_RGB -> BuiltInSpace.LRGB; + case CS_CIEXYZ -> BuiltInSpace.XYZ; + case CS_PYCC -> BuiltInSpace.PYCC; + case CS_GRAY -> BuiltInSpace.GRAY; + default -> { + throw new IllegalArgumentException("Unknown color space"); } - break; - - case CS_CIEXYZ: - synchronized(ColorSpace.class) { - if (XYZspace == null) { - ICC_Profile theProfile = - ICC_Profile.getInstance (CS_CIEXYZ); - XYZspace = new ICC_ColorSpace (theProfile); - } - - theColorSpace = XYZspace; - } - break; - - case CS_PYCC: - synchronized(ColorSpace.class) { - if (PYCCspace == null) { - ICC_Profile theProfile = ICC_Profile.getInstance (CS_PYCC); - PYCCspace = new ICC_ColorSpace (theProfile); - } - - theColorSpace = PYCCspace; - } - break; - - - case CS_GRAY: - synchronized(ColorSpace.class) { - if (GRAYspace == null) { - ICC_Profile theProfile = ICC_Profile.getInstance (CS_GRAY); - GRAYspace = new ICC_ColorSpace (theProfile); - /* to allow access from java.awt.ColorModel */ - CMSManager.GRAYspace = GRAYspace; - } - - theColorSpace = GRAYspace; - } - break; - - - case CS_LINEAR_RGB: - synchronized(ColorSpace.class) { - if (LINEAR_RGBspace == null) { - ICC_Profile theProfile = - ICC_Profile.getInstance(CS_LINEAR_RGB); - LINEAR_RGBspace = new ICC_ColorSpace (theProfile); - /* to allow access from java.awt.ColorModel */ - CMSManager.LINEAR_RGBspace = LINEAR_RGBspace; - } - - theColorSpace = LINEAR_RGBspace; - } - break; - - - default: - throw new IllegalArgumentException ("Unknown color space"); - } - - return theColorSpace; + }; } /** @@ -380,8 +324,7 @@ public abstract class ColorSpace implements Serializable { * {@code false} if it is not */ public boolean isCS_sRGB () { - /* REMIND - make sure we know sRGBspace exists already */ - return (this == sRGBspace); + return this == BuiltInSpace.SRGB; } /** diff --git a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java index 3e86fcf6141..9b0d484d643 100644 --- a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java +++ b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java @@ -94,14 +94,31 @@ public class ICC_Profile implements Serializable { private transient volatile Profile cmmProfile; private transient volatile ProfileDeferralInfo deferralInfo; - // Registry of singleton profile objects for specific color spaces - // defined in the ColorSpace class (e.g. CS_sRGB), see - // getInstance(int cspace) factory method. - private static ICC_Profile sRGBprofile; - private static ICC_Profile XYZprofile; - private static ICC_Profile PYCCprofile; - private static ICC_Profile GRAYprofile; - private static ICC_Profile LINEAR_RGBprofile; + /** + * The lazy registry of singleton profile objects for specific built-in + * color spaces defined in the ColorSpace class (e.g. CS_sRGB), + * see getInstance(int cspace) factory method. + */ + private interface BuiltInProfile { + /* + * Deferral is only used for standard profiles. Enabling the appropriate + * access privileges is handled at a lower level. + */ + ICC_Profile SRGB = new ICC_ProfileRGB(new ProfileDeferralInfo( + "sRGB.pf", ColorSpace.TYPE_RGB, 3, CLASS_DISPLAY)); + + ICC_Profile LRGB = new ICC_ProfileRGB(new ProfileDeferralInfo( + "LINEAR_RGB.pf", ColorSpace.TYPE_RGB, 3, CLASS_DISPLAY)); + + ICC_Profile XYZ = new ICC_Profile(new ProfileDeferralInfo( + "CIEXYZ.pf", ColorSpace.TYPE_XYZ, 3, CLASS_ABSTRACT)); + + ICC_Profile PYCC = new ICC_Profile(new ProfileDeferralInfo( + "PYCC.pf", ColorSpace.TYPE_3CLR, 3, CLASS_COLORSPACECONVERSION)); + + ICC_Profile GRAY = new ICC_ProfileGray(new ProfileDeferralInfo( + "GRAY.pf", ColorSpace.TYPE_GRAY, 1, CLASS_DISPLAY)); + } /** * Profile class is input. @@ -818,89 +835,17 @@ public class ICC_Profile implements Serializable { * @throws IllegalArgumentException If {@code cspace} is not one of the * predefined color space types */ - public static ICC_Profile getInstance (int cspace) { - ICC_Profile thisProfile = null; - switch (cspace) { - case ColorSpace.CS_sRGB: - synchronized(ICC_Profile.class) { - if (sRGBprofile == null) { - /* - * Deferral is only used for standard profiles. - * Enabling the appropriate access privileges is handled - * at a lower level. - */ - ProfileDeferralInfo pdi = - new ProfileDeferralInfo("sRGB.pf", - ColorSpace.TYPE_RGB, 3, - CLASS_DISPLAY); - sRGBprofile = new ICC_ProfileRGB(pdi); - } - thisProfile = sRGBprofile; - } - - break; - - case ColorSpace.CS_CIEXYZ: - synchronized(ICC_Profile.class) { - if (XYZprofile == null) { - ProfileDeferralInfo pdi = - new ProfileDeferralInfo("CIEXYZ.pf", - ColorSpace.TYPE_XYZ, 3, - CLASS_ABSTRACT); - XYZprofile = new ICC_Profile(pdi); - } - thisProfile = XYZprofile; - } - - break; - - case ColorSpace.CS_PYCC: - synchronized(ICC_Profile.class) { - if (PYCCprofile == null) { - ProfileDeferralInfo pdi = - new ProfileDeferralInfo("PYCC.pf", - ColorSpace.TYPE_3CLR, 3, - CLASS_COLORSPACECONVERSION); - PYCCprofile = new ICC_Profile(pdi); - } - thisProfile = PYCCprofile; - } - - break; - - case ColorSpace.CS_GRAY: - synchronized(ICC_Profile.class) { - if (GRAYprofile == null) { - ProfileDeferralInfo pdi = - new ProfileDeferralInfo("GRAY.pf", - ColorSpace.TYPE_GRAY, 1, - CLASS_DISPLAY); - GRAYprofile = new ICC_ProfileGray(pdi); - } - thisProfile = GRAYprofile; - } - - break; - - case ColorSpace.CS_LINEAR_RGB: - synchronized(ICC_Profile.class) { - if (LINEAR_RGBprofile == null) { - ProfileDeferralInfo pdi = - new ProfileDeferralInfo("LINEAR_RGB.pf", - ColorSpace.TYPE_RGB, 3, - CLASS_DISPLAY); - LINEAR_RGBprofile = new ICC_ProfileRGB(pdi); - } - thisProfile = LINEAR_RGBprofile; + public static ICC_Profile getInstance(int cspace) { + return switch (cspace) { + case ColorSpace.CS_sRGB -> BuiltInProfile.SRGB; + case ColorSpace.CS_LINEAR_RGB -> BuiltInProfile.LRGB; + case ColorSpace.CS_CIEXYZ -> BuiltInProfile.XYZ; + case ColorSpace.CS_PYCC -> BuiltInProfile.PYCC; + case ColorSpace.CS_GRAY -> BuiltInProfile.GRAY; + default -> { + throw new IllegalArgumentException("Unknown color space"); } - - break; - - default: - throw new IllegalArgumentException("Unknown color space"); - } - - return thisProfile; + }; } /** @@ -1803,15 +1748,15 @@ public class ICC_Profile implements Serializable { s.defaultWriteObject(); String csName = null; - if (this == sRGBprofile) { + if (this == BuiltInProfile.SRGB) { csName = "CS_sRGB"; - } else if (this == XYZprofile) { + } else if (this == BuiltInProfile.XYZ) { csName = "CS_CIEXYZ"; - } else if (this == PYCCprofile) { + } else if (this == BuiltInProfile.PYCC) { csName = "CS_PYCC"; - } else if (this == GRAYprofile) { + } else if (this == BuiltInProfile.GRAY) { csName = "CS_GRAY"; - } else if (this == LINEAR_RGBprofile) { + } else if (this == BuiltInProfile.LRGB) { csName = "CS_LINEAR_RGB"; } diff --git a/src/java.desktop/share/classes/java/awt/image/ColorModel.java b/src/java.desktop/share/classes/java/awt/image/ColorModel.java index c4c8f80af7a..8f4dd445821 100644 --- a/src/java.desktop/share/classes/java/awt/image/ColorModel.java +++ b/src/java.desktop/share/classes/java/awt/image/ColorModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2021, 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 @@ -1705,15 +1705,11 @@ public abstract class ColorModel implements Transparency{ static Map lg16Toog16Map = null; // 16-bit linear to 16-bit "other" gray static boolean isLinearRGBspace(ColorSpace cs) { - // Note: CMM.LINEAR_RGBspace will be null if the linear - // RGB space has not been created yet. - return (cs == CMSManager.LINEAR_RGBspace); + return cs == ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB); } static boolean isLinearGRAYspace(ColorSpace cs) { - // Note: CMM.GRAYspace will be null if the linear - // gray space has not been created yet. - return (cs == CMSManager.GRAYspace); + return cs == ColorSpace.getInstance(ColorSpace.CS_GRAY); } static byte[] getLinearRGB8TosRGB8LUT() { diff --git a/src/java.desktop/share/classes/sun/java2d/cmm/CMSManager.java b/src/java.desktop/share/classes/sun/java2d/cmm/CMSManager.java index 4d9f09c5905..024ea437e4f 100644 --- a/src/java.desktop/share/classes/sun/java2d/cmm/CMSManager.java +++ b/src/java.desktop/share/classes/sun/java2d/cmm/CMSManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2021, 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 @@ -26,20 +26,12 @@ package sun.java2d.cmm; import java.awt.color.CMMException; -import java.awt.color.ColorSpace; import java.awt.color.ICC_Profile; import java.security.AccessController; import sun.security.action.GetPropertyAction; -public class CMSManager { - public static ColorSpace GRAYspace; // These two fields allow access - public static ColorSpace LINEAR_RGBspace; // to java.awt.color.ColorSpace - // private fields from other - // packages. The fields are set - // by java.awt.color.ColorSpace - // and read by - // java.awt.image.ColorModel. +public final class CMSManager { private static PCMM cmmImpl = null; diff --git a/test/jdk/java/awt/color/BuiltInDataVariation.java b/test/jdk/java/awt/color/BuiltInDataVariation.java new file mode 100644 index 00000000000..16528ee2600 --- /dev/null +++ b/test/jdk/java/awt/color/BuiltInDataVariation.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.color.ColorSpace; +import java.awt.color.ICC_ColorSpace; +import java.awt.color.ICC_Profile; +import java.util.Arrays; +import java.util.Set; + +import static java.awt.color.ColorSpace.*; + +/** + * @test + * @bug 8261282 + * @summary Checks that all built-in profiles and data are different. + */ +public final class BuiltInDataVariation { + + public static void main(String[] args) { + testColorProfiles(); + testColorSpaces(); + } + + private static void testColorProfiles() { + ICC_Profile srgb = ICC_Profile.getInstance(CS_sRGB); + ICC_Profile lrgb = ICC_Profile.getInstance(CS_LINEAR_RGB); + ICC_Profile xyz = ICC_Profile.getInstance(CS_CIEXYZ); + ICC_Profile pycc = ICC_Profile.getInstance(CS_PYCC); + ICC_Profile gray = ICC_Profile.getInstance(CS_GRAY); + + test(srgb, lrgb, xyz, pycc, gray); + test(Arrays.hashCode(srgb.getData()), Arrays.hashCode(lrgb.getData()), + Arrays.hashCode(xyz.getData()), Arrays.hashCode(pycc.getData()), + Arrays.hashCode(gray.getData())); + } + + private static void testColorSpaces() { + var srgb = (ICC_ColorSpace) ColorSpace.getInstance(CS_sRGB); + var lrgb = (ICC_ColorSpace) ColorSpace.getInstance(CS_LINEAR_RGB); + var xyz = (ICC_ColorSpace) ColorSpace.getInstance(CS_CIEXYZ); + var pycc = (ICC_ColorSpace) ColorSpace.getInstance(CS_PYCC); + var gray = (ICC_ColorSpace) ColorSpace.getInstance(CS_GRAY); + + test(srgb, lrgb, xyz, pycc, gray); + test(srgb.getProfile(), lrgb.getProfile(), xyz.getProfile(), + pycc.getProfile(), gray.getProfile()); + test(Arrays.hashCode(srgb.getProfile().getData()), + Arrays.hashCode(lrgb.getProfile().getData()), + Arrays.hashCode(xyz.getProfile().getData()), + Arrays.hashCode(pycc.getProfile().getData()), + Arrays.hashCode(gray.getProfile().getData())); + } + + private static void test(Object srgb, Object lrgb, Object xyz, + Object pycc, Object gray) { + Set.of(srgb, lrgb, xyz, pycc, gray); + } +} diff --git a/test/jdk/java/awt/color/HotStaticLocks.java b/test/jdk/java/awt/color/HotStaticLocks.java new file mode 100644 index 00000000000..95762b6da20 --- /dev/null +++ b/test/jdk/java/awt/color/HotStaticLocks.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.color.ColorSpace; +import java.awt.color.ICC_Profile; + +import static java.awt.color.ColorSpace.CS_CIEXYZ; +import static java.awt.color.ColorSpace.CS_GRAY; +import static java.awt.color.ColorSpace.CS_LINEAR_RGB; +import static java.awt.color.ColorSpace.CS_PYCC; +import static java.awt.color.ColorSpace.CS_sRGB; + +/** + * @test + * @bug 8261282 + * @summary Checks static locks in the ColorSpace/ICC_Profile classes. + */ +public final class HotStaticLocks { + + public static void main(String[] args) throws Exception { + testICCProfile(); + testColorSpace(); + } + + private static void testICCProfile() throws Exception { + int[] spaces = {CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ, CS_PYCC, CS_GRAY}; + for (int cs : spaces) { + synchronized (ICC_Profile.class) { + Thread t = new Thread(() -> ICC_Profile.getInstance(cs)); + t.start(); + t.join(); + } + } + } + + private static void testColorSpace() throws Exception { + int[] spaces = {CS_sRGB, CS_LINEAR_RGB, CS_CIEXYZ, CS_PYCC, CS_GRAY}; + for (int cs : spaces) { + synchronized (ColorSpace.class) { + Thread t = new Thread(() -> ColorSpace.getInstance(cs)); + t.start(); + t.join(); + } + } + } +} -- GitLab From 60a2072a430ef00f32ab81651781445d0958c027 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Thu, 11 Feb 2021 23:31:37 +0000 Subject: [PATCH 030/367] 8260431: com/sun/jdi/JdbOptions.java failed with "RuntimeException: 'prop[boo] = >foo<' missing from stdout/stderr" Reviewed-by: sspitsyn, cjplummer --- test/jdk/com/sun/jdi/JdbOptions.java | 71 ++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/test/jdk/com/sun/jdi/JdbOptions.java b/test/jdk/com/sun/jdi/JdbOptions.java index b6fb965e319..114aa3ddd50 100644 --- a/test/jdk/com/sun/jdi/JdbOptions.java +++ b/test/jdk/com/sun/jdi/JdbOptions.java @@ -34,9 +34,17 @@ import lib.jdb.Jdb; import lib.jdb.JdbCommand; import jdk.test.lib.process.OutputAnalyzer; +import java.io.IOException; +import java.io.PrintStream; import java.lang.management.ManagementFactory; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; class JbdOptionsTarg { static final String OK_MSG = "JbdOptionsTarg: OK"; @@ -49,47 +57,62 @@ class JbdOptionsTarg { return "prop[" + name + "] = >" + value + "<"; } - public static void main(String[] args) { - System.out.println(OK_MSG); - // print all args - List vmArgs = ManagementFactory.getRuntimeMXBean().getInputArguments(); - for (String s: vmArgs) { - System.out.println(argString(s)); - } - // print requested sys.props - for (String p: args) { - System.out.println(propString(p, System.getProperty(p))); + /** + * 1st argument is a filename to redirect application output, + * the rest are names of the properties to dump. + */ + public static void main(String[] args) throws IOException { + String outFile = args[0]; + try (PrintStream out = new PrintStream(outFile, StandardCharsets.UTF_8)) { + out.println(OK_MSG); + // print all args + List vmArgs = ManagementFactory.getRuntimeMXBean().getInputArguments(); + for (String s : vmArgs) { + out.println(argString(s)); + } + // print requested sys.props (skip 1st arg which is output filename) + for (int i=1; i < args.length; i++) { + String p = args[i]; + out.println(propString(p, System.getProperty(p))); + } } } } public class JdbOptions { + private static final String outFilename = UUID.randomUUID().toString() + ".out"; + private static final Path outPath = Paths.get(outFilename); private static final String targ = JbdOptionsTarg.class.getName(); public static void main(String[] args) throws Exception { // the simplest case test("-connect", - "com.sun.jdi.CommandLineLaunch:vmexec=java,options=-client -XX:+PrintVMOptions,main=" + targ) + "com.sun.jdi.CommandLineLaunch:vmexec=java,options=-client -XX:+PrintVMOptions" + + ",main=" + targ + " " + outFilename) .expectedArg("-XX:+PrintVMOptions"); // pass property through 'options' test("-connect", - "com.sun.jdi.CommandLineLaunch:vmexec=java,options='-Dboo=foo',main=" + targ + " boo") + "com.sun.jdi.CommandLineLaunch:vmexec=java,options='-Dboo=foo'" + + ",main=" + targ + " " + outFilename + " boo") .expectedProp("boo", "foo"); // property with spaces test("-connect", - "com.sun.jdi.CommandLineLaunch:vmexec=java,options=\"-Dboo=foo 2\",main=" + targ + " boo") + "com.sun.jdi.CommandLineLaunch:vmexec=java,options=\"-Dboo=foo 2\"" + + ",main=" + targ + " " + outFilename + " boo") .expectedProp("boo", "foo 2"); // property with spaces (with single quotes) test("-connect", - "com.sun.jdi.CommandLineLaunch:vmexec=java,options='-Dboo=foo 2',main=" + targ + " boo") + "com.sun.jdi.CommandLineLaunch:vmexec=java,options='-Dboo=foo 2'" + + ",main=" + targ + " " + outFilename + " boo") .expectedProp("boo", "foo 2"); // properties with spaces (with single quotes) test("-connect", - "com.sun.jdi.CommandLineLaunch:vmexec=java,options=-Dboo=foo '-Dboo2=foo 2',main=" + targ + " boo boo2") + "com.sun.jdi.CommandLineLaunch:vmexec=java,options=-Dboo=foo '-Dboo2=foo 2'" + + ",main=" + targ + " " + outFilename + " boo boo2") .expectedProp("boo", "foo") .expectedProp("boo2", "foo 2"); @@ -98,7 +121,7 @@ public class JdbOptions { "com.sun.jdi.CommandLineLaunch:vmexec=java,options=\"-client\" \"-XX:+PrintVMOptions\"" + " -XX:+IgnoreUnrecognizedVMOptions" + " \"-XX:StartFlightRecording=dumponexit=true,maxsize=500M\" \"-XX:FlightRecorderOptions=repository=jfrrep\"" - + ",main=" + targ) + + ",main=" + targ + " " + outFilename) .expectedArg("-XX:StartFlightRecording=dumponexit=true,maxsize=500M") .expectedArg("-XX:FlightRecorderOptions=repository=jfrrep"); @@ -107,7 +130,7 @@ public class JdbOptions { "com.sun.jdi.CommandLineLaunch:vmexec=java,options='-client' '-XX:+PrintVMOptions'" + " -XX:+IgnoreUnrecognizedVMOptions" + " '-XX:StartFlightRecording=dumponexit=true,maxsize=500M' '-XX:FlightRecorderOptions=repository=jfrrep'" - + ",main=" + targ) + + ",main=" + targ + " " + outFilename) .expectedArg("-XX:StartFlightRecording=dumponexit=true,maxsize=500M") .expectedArg("-XX:FlightRecorderOptions=repository=jfrrep"); @@ -120,7 +143,7 @@ public class JdbOptions { + " -XX:+IgnoreUnrecognizedVMOptions" + " \"-XX:StartFlightRecording=dumponexit=true,maxsize=500M\"" + " '-XX:FlightRecorderOptions=repository=jfrrep'" - + ",main=" + targ + " prop1 prop2 prop3 prop4") + + ",main=" + targ + " " + outFilename + " prop1 prop2 prop3 prop4") .expectedProp("prop1", "val1") .expectedProp("prop2", "val 2") .expectedProp("prop3", "val3") @@ -154,12 +177,18 @@ public class JdbOptions { .map(s -> s.replace("\"", "\\\"")) .toArray(String[]::new); } + try (Jdb jdb = new Jdb(args)) { jdb.waitForSimplePrompt(1024, true); // 1024 lines should be enough jdb.command(JdbCommand.run().allowExit()); - OutputAnalyzer out = new OutputAnalyzer(jdb.getJdbOutput()); - out.shouldContain(JbdOptionsTarg.OK_MSG); - return new TestResult(out); } + String output = Files.readAllLines(outPath, StandardCharsets.UTF_8).stream() + .collect(Collectors.joining(System.getProperty("line.separator"))); + Files.deleteIfExists(outPath); + System.out.println("Debuggee output: ["); + System.out.println(output); + System.out.println("]"); + OutputAnalyzer out = new OutputAnalyzer(output); + return new TestResult(out); } } -- GitLab From 92ff891877f228894c8fd4c77170a1cd793b9cd6 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 12 Feb 2021 07:50:28 +0000 Subject: [PATCH 031/367] 8261593: Do not use NULL pointer as write buffer parameter in jfrEmergencyDump.cpp write_repository_files Reviewed-by: stuefe, mgronlun --- .../share/jfr/recorder/repository/jfrEmergencyDump.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp index 45a3db36338..55c1b7ece4c 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp @@ -369,9 +369,10 @@ static void write_emergency_dump_file(const RepositoryIterator& iterator) { if (copy_block == NULL) { log_error(jfr, system)("Unable to malloc memory during jfr emergency dump"); log_error(jfr, system)("Unable to write jfr emergency dump file"); + } else { + write_repository_files(iterator, copy_block, block_size); + os::free(copy_block); } - write_repository_files(iterator, copy_block, block_size); - os::free(copy_block); } void JfrEmergencyDump::on_vm_error(const char* repository_path) { -- GitLab From 6a84ec68c3e20ef971ab523e82e178b6ab4e371e Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Fri, 12 Feb 2021 08:19:08 +0000 Subject: [PATCH 032/367] 8260044: Parallel GC: Concurrent allocation after heap expansion may cause unnecessary full gc 8260045: Parallel GC: Waiting on ExpandHeap_lock may cause "expansion storm" Loop to retry allocation if expand succeeds. Treat space available after obtaining expand lock as expand success. Reviewed-by: tschatzl, iwalulya, sjohanss --- .../share/gc/parallel/mutableSpace.cpp | 9 ++++ .../share/gc/parallel/mutableSpace.hpp | 5 ++ src/hotspot/share/gc/parallel/psOldGen.cpp | 49 +++++++++++-------- src/hotspot/share/gc/parallel/psOldGen.hpp | 12 +++-- 4 files changed, 51 insertions(+), 24 deletions(-) diff --git a/src/hotspot/share/gc/parallel/mutableSpace.cpp b/src/hotspot/share/gc/parallel/mutableSpace.cpp index 62b52fecd9d..defb1ffd04e 100644 --- a/src/hotspot/share/gc/parallel/mutableSpace.cpp +++ b/src/hotspot/share/gc/parallel/mutableSpace.cpp @@ -215,6 +215,15 @@ bool MutableSpace::cas_deallocate(HeapWord *obj, size_t size) { return Atomic::cmpxchg(top_addr(), expected_top, obj) == expected_top; } +// Only used by oldgen allocation. +bool MutableSpace::needs_expand(size_t word_size) const { + assert_lock_strong(ExpandHeap_lock); + // Holding the lock means end is stable. So while top may be advancing + // via concurrent allocations, there is no need to order the reads of top + // and end here, unlike in cas_allocate. + return pointer_delta(end(), top()) < word_size; +} + void MutableSpace::oop_iterate(OopIterateClosure* cl) { HeapWord* obj_addr = bottom(); HeapWord* t = top(); diff --git a/src/hotspot/share/gc/parallel/mutableSpace.hpp b/src/hotspot/share/gc/parallel/mutableSpace.hpp index 3e9b0a1514c..b6bb131828f 100644 --- a/src/hotspot/share/gc/parallel/mutableSpace.hpp +++ b/src/hotspot/share/gc/parallel/mutableSpace.hpp @@ -142,6 +142,11 @@ class MutableSpace: public CHeapObj { virtual HeapWord* cas_allocate(size_t word_size); // Optional deallocation. Used in NUMA-allocator. bool cas_deallocate(HeapWord *obj, size_t size); + // Return true if this space needs to be expanded in order to satisfy an + // allocation request of the indicated size. Concurrent allocations and + // resizes may change the result of a later call. Used by oldgen allocator. + // precondition: holding ExpandHeap_lock + bool needs_expand(size_t word_size) const; // Iteration. void oop_iterate(OopIterateClosure* cl); diff --git a/src/hotspot/share/gc/parallel/psOldGen.cpp b/src/hotspot/share/gc/parallel/psOldGen.cpp index 1b97f949628..44c7901571a 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.cpp +++ b/src/hotspot/share/gc/parallel/psOldGen.cpp @@ -178,19 +178,31 @@ void PSOldGen::object_iterate_block(ObjectClosure* cl, size_t block_index) { } } -HeapWord* PSOldGen::expand_and_cas_allocate(size_t word_size) { - expand(word_size*HeapWordSize); +bool PSOldGen::expand_for_allocate(size_t word_size) { + assert(word_size > 0, "allocating zero words?"); + bool result = true; + { + MutexLocker x(ExpandHeap_lock); + // Avoid "expand storms" by rechecking available space after obtaining + // the lock, because another thread may have already made sufficient + // space available. If insufficient space available, that will remain + // true until we expand, since we have the lock. Other threads may take + // the space we need before we can allocate it, regardless of whether we + // expand. That's okay, we'll just try expanding again. + if (object_space()->needs_expand(word_size)) { + result = expand(word_size*HeapWordSize); + } + } if (GCExpandToAllocateDelayMillis > 0) { os::naked_sleep(GCExpandToAllocateDelayMillis); } - return cas_allocate_noexpand(word_size); + return result; } -void PSOldGen::expand(size_t bytes) { - if (bytes == 0) { - return; - } - MutexLocker x(ExpandHeap_lock); +bool PSOldGen::expand(size_t bytes) { + assert_lock_strong(ExpandHeap_lock); + assert_locked_or_safepoint(Heap_lock); + assert(bytes > 0, "precondition"); const size_t alignment = virtual_space()->alignment(); size_t aligned_bytes = align_up(bytes, alignment); size_t aligned_expand_bytes = align_up(MinHeapDeltaBytes, alignment); @@ -200,13 +212,11 @@ void PSOldGen::expand(size_t bytes) { // providing a page per lgroup. Alignment is larger or equal to the page size. aligned_expand_bytes = MAX2(aligned_expand_bytes, alignment * os::numa_get_groups_num()); } - if (aligned_bytes == 0){ - // The alignment caused the number of bytes to wrap. An expand_by(0) will - // return true with the implication that and expansion was done when it - // was not. A call to expand implies a best effort to expand by "bytes" - // but not a guarantee. Align down to give a best effort. This is likely - // the most that the generation can expand since it has some capacity to - // start with. + if (aligned_bytes == 0) { + // The alignment caused the number of bytes to wrap. A call to expand + // implies a best effort to expand by "bytes" but not a guarantee. Align + // down to give a best effort. This is likely the most that the generation + // can expand since it has some capacity to start with. aligned_bytes = align_down(bytes, alignment); } @@ -224,14 +234,13 @@ void PSOldGen::expand(size_t bytes) { if (success && GCLocker::is_active_and_needs_gc()) { log_debug(gc)("Garbage collection disabled, expanded heap instead"); } + return success; } bool PSOldGen::expand_by(size_t bytes) { assert_lock_strong(ExpandHeap_lock); assert_locked_or_safepoint(Heap_lock); - if (bytes == 0) { - return true; // That's what virtual_space()->expand_by(0) would return - } + assert(bytes > 0, "precondition"); bool result = virtual_space()->expand_by(bytes); if (result) { if (ZapUnusedHeapArea) { @@ -268,7 +277,7 @@ bool PSOldGen::expand_to_reserved() { assert_lock_strong(ExpandHeap_lock); assert_locked_or_safepoint(Heap_lock); - bool result = true; + bool result = false; const size_t remaining_bytes = virtual_space()->uncommitted_size(); if (remaining_bytes > 0) { result = expand_by(remaining_bytes); @@ -323,10 +332,10 @@ void PSOldGen::resize(size_t desired_free_space) { } if (new_size > current_size) { size_t change_bytes = new_size - current_size; + MutexLocker x(ExpandHeap_lock); expand(change_bytes); } else { size_t change_bytes = current_size - new_size; - // shrink doesn't grab this lock, expand does. Is that right? MutexLocker x(ExpandHeap_lock); shrink(change_bytes); } diff --git a/src/hotspot/share/gc/parallel/psOldGen.hpp b/src/hotspot/share/gc/parallel/psOldGen.hpp index dd0e7fe1e83..53947a94898 100644 --- a/src/hotspot/share/gc/parallel/psOldGen.hpp +++ b/src/hotspot/share/gc/parallel/psOldGen.hpp @@ -79,8 +79,8 @@ class PSOldGen : public CHeapObj { return res; } - HeapWord* expand_and_cas_allocate(size_t word_size); - void expand(size_t bytes); + bool expand_for_allocate(size_t word_size); + bool expand(size_t bytes); bool expand_by(size_t bytes); bool expand_to_reserved(); @@ -135,8 +135,12 @@ class PSOldGen : public CHeapObj { void resize(size_t desired_free_space); HeapWord* allocate(size_t word_size) { - HeapWord* res = cas_allocate_noexpand(word_size); - return (res == NULL) ? expand_and_cas_allocate(word_size) : res; + HeapWord* res; + do { + res = cas_allocate_noexpand(word_size); + // Retry failed allocation if expand succeeds. + } while ((res == nullptr) && expand_for_allocate(word_size)); + return res; } // Iteration. -- GitLab From 0779addeb798f765701811f9de45d66ac3844864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Fri, 12 Feb 2021 08:27:52 +0000 Subject: [PATCH 033/367] 8255059: Regressions >5% in all Javadoc benchmarks in 16-b19 Reviewed-by: jjg --- .../resources/releases/element-list-10.txt | 65 ++- ...{package-list-9.txt => element-list-9.txt} | 443 ++++++++++-------- .../internal/doclets/toolkit/util/Extern.java | 44 +- 3 files changed, 334 insertions(+), 218 deletions(-) rename src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/releases/{package-list-9.txt => element-list-9.txt} (83%) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/releases/element-list-10.txt b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/releases/element-list-10.txt index 16518f6620e..57462b7ebca 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/releases/element-list-10.txt +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/releases/element-list-10.txt @@ -1,4 +1,6 @@ +module:java.activation javax.activation +module:java.base java.io java.lang java.lang.annotation @@ -50,22 +52,24 @@ javax.security.auth.login javax.security.auth.spi javax.security.auth.x500 javax.security.cert +module:java.compiler javax.annotation.processing javax.lang.model javax.lang.model.element javax.lang.model.type javax.lang.model.util javax.tools +module:java.corba javax.activity javax.rmi javax.rmi.CORBA org.omg.CORBA -org.omg.CORBA_2_3 -org.omg.CORBA_2_3.portable org.omg.CORBA.DynAnyPackage org.omg.CORBA.ORBPackage -org.omg.CORBA.portable org.omg.CORBA.TypeCodePackage +org.omg.CORBA.portable +org.omg.CORBA_2_3 +org.omg.CORBA_2_3.portable org.omg.CosNaming org.omg.CosNaming.NamingContextExtPackage org.omg.CosNaming.NamingContextPackage @@ -83,11 +87,13 @@ org.omg.PortableServer org.omg.PortableServer.CurrentPackage org.omg.PortableServer.POAManagerPackage org.omg.PortableServer.POAPackage -org.omg.PortableServer.portable org.omg.PortableServer.ServantLocatorPackage +org.omg.PortableServer.portable org.omg.SendingContext org.omg.stub.java.rmi +module:java.datatransfer java.awt.datatransfer +module:java.desktop java.applet java.awt java.awt.color @@ -138,9 +144,13 @@ javax.swing.text.html.parser javax.swing.text.rtf javax.swing.tree javax.swing.undo +module:java.instrument java.lang.instrument +module:java.jnlp javax.jnlp +module:java.logging java.util.logging +module:java.management java.lang.management javax.management javax.management.loading @@ -150,31 +160,43 @@ javax.management.openmbean javax.management.relation javax.management.remote javax.management.timer +module:java.management.rmi javax.management.remote.rmi +module:java.naming javax.naming javax.naming.directory javax.naming.event javax.naming.ldap javax.naming.spi +module:java.prefs java.util.prefs +module:java.rmi java.rmi java.rmi.activation java.rmi.dgc java.rmi.registry java.rmi.server javax.rmi.ssl +module:java.scripting javax.script +module:java.security.jgss javax.security.auth.kerberos org.ietf.jgss +module:java.security.sasl javax.security.sasl +module:java.smartcardio javax.smartcardio +module:java.sql java.sql javax.sql javax.transaction.xa +module:java.sql.rowset javax.sql.rowset javax.sql.rowset.serial javax.sql.rowset.spi +module:java.transaction javax.transaction +module:java.xml javax.xml javax.xml.catalog javax.xml.datatype @@ -200,18 +222,21 @@ org.w3c.dom.views org.xml.sax org.xml.sax.ext org.xml.sax.helpers +module:java.xml.bind javax.xml.bind javax.xml.bind.annotation javax.xml.bind.annotation.adapters javax.xml.bind.attachment javax.xml.bind.helpers javax.xml.bind.util +module:java.xml.crypto javax.xml.crypto javax.xml.crypto.dom javax.xml.crypto.dsig javax.xml.crypto.dsig.dom javax.xml.crypto.dsig.keyinfo javax.xml.crypto.dsig.spec +module:java.xml.ws javax.jws javax.jws.soap javax.xml.soap @@ -223,7 +248,9 @@ javax.xml.ws.soap javax.xml.ws.spi javax.xml.ws.spi.http javax.xml.ws.wsaddressing +module:java.xml.ws.annotation javax.annotation +module:javafx.base javafx.beans javafx.beans.binding javafx.beans.property @@ -234,11 +261,14 @@ javafx.collections.transformation javafx.event javafx.util javafx.util.converter +module:javafx.controls javafx.scene.chart javafx.scene.control javafx.scene.control.cell javafx.scene.control.skin +module:javafx.fxml javafx.fxml +module:javafx.graphics javafx.animation javafx.application javafx.concurrent @@ -257,57 +287,84 @@ javafx.scene.shape javafx.scene.text javafx.scene.transform javafx.stage +module:javafx.media javafx.scene.media +module:javafx.swing javafx.embed.swing +module:javafx.web javafx.scene.web +module:jdk.accessibility com.sun.java.accessibility.util +module:jdk.attach com.sun.tools.attach com.sun.tools.attach.spi +module:jdk.compiler com.sun.source.doctree com.sun.source.tree com.sun.source.util com.sun.tools.javac +module:jdk.dynalink jdk.dynalink jdk.dynalink.beans jdk.dynalink.linker jdk.dynalink.linker.support jdk.dynalink.support +module:jdk.httpserver com.sun.net.httpserver com.sun.net.httpserver.spi +module:jdk.incubator.httpclient jdk.incubator.http +module:jdk.jartool com.sun.jarsigner jdk.security.jarsigner +module:jdk.javadoc com.sun.javadoc com.sun.tools.javadoc jdk.javadoc.doclet +module:jdk.jconsole com.sun.tools.jconsole +module:jdk.jdi com.sun.jdi com.sun.jdi.connect com.sun.jdi.connect.spi com.sun.jdi.event com.sun.jdi.request +module:jdk.jfr jdk.jfr jdk.jfr.consumer +module:jdk.jshell jdk.jshell jdk.jshell.execution jdk.jshell.spi jdk.jshell.tool +module:jdk.jsobject netscape.javascript +module:jdk.management com.sun.management +module:jdk.management.cmm jdk.management.cmm +module:jdk.management.jfr jdk.management.jfr +module:jdk.management.resource jdk.management.resource +module:jdk.net jdk.net +module:jdk.packager.services jdk.packager.services jdk.packager.services.singleton +module:jdk.scripting.nashorn jdk.nashorn.api.scripting jdk.nashorn.api.tree +module:jdk.sctp com.sun.nio.sctp +module:jdk.security.auth com.sun.security.auth com.sun.security.auth.callback com.sun.security.auth.login com.sun.security.auth.module +module:jdk.security.jgss com.sun.security.jgss +module:jdk.xml.dom org.w3c.dom.css org.w3c.dom.html org.w3c.dom.stylesheets diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/releases/package-list-9.txt b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/releases/element-list-9.txt similarity index 83% rename from src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/releases/package-list-9.txt rename to src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/releases/element-list-9.txt index 24c17a899bb..69f4efa95a7 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/releases/package-list-9.txt +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/releases/element-list-9.txt @@ -1,52 +1,10 @@ -com.sun.jarsigner -com.sun.java.accessibility.util -com.sun.javadoc -com.sun.jdi -com.sun.jdi.connect -com.sun.jdi.connect.spi -com.sun.jdi.event -com.sun.jdi.request -com.sun.management -com.sun.net.httpserver -com.sun.net.httpserver.spi -com.sun.nio.sctp -com.sun.security.auth -com.sun.security.auth.callback -com.sun.security.auth.login -com.sun.security.auth.module -com.sun.security.jgss -com.sun.source.doctree -com.sun.source.tree -com.sun.source.util -com.sun.tools.attach -com.sun.tools.attach.spi -com.sun.tools.doclets -com.sun.tools.doclets.standard -com.sun.tools.javac -com.sun.tools.javadoc -com.sun.tools.jconsole -java.applet -java.awt -java.awt.color -java.awt.datatransfer -java.awt.desktop -java.awt.dnd -java.awt.event -java.awt.font -java.awt.geom -java.awt.im -java.awt.im.spi -java.awt.image -java.awt.image.renderable -java.awt.print -java.beans -java.beans.beancontext +module:java.activation +javax.activation +module:java.base java.io java.lang java.lang.annotation -java.lang.instrument java.lang.invoke -java.lang.management java.lang.module java.lang.ref java.lang.reflect @@ -61,17 +19,11 @@ java.nio.charset.spi java.nio.file java.nio.file.attribute java.nio.file.spi -java.rmi -java.rmi.activation -java.rmi.dgc -java.rmi.registry -java.rmi.server java.security java.security.acl java.security.cert java.security.interfaces java.security.spec -java.sql java.text java.text.spi java.time @@ -85,56 +37,79 @@ java.util.concurrent.atomic java.util.concurrent.locks java.util.function java.util.jar -java.util.logging -java.util.prefs java.util.regex java.util.spi java.util.stream java.util.zip -javafx.animation -javafx.application -javafx.beans -javafx.beans.binding -javafx.beans.property -javafx.beans.property.adapter -javafx.beans.value -javafx.collections -javafx.collections.transformation -javafx.concurrent -javafx.css -javafx.css.converter -javafx.embed.swing -javafx.event -javafx.fxml -javafx.geometry -javafx.print -javafx.scene -javafx.scene.canvas -javafx.scene.chart -javafx.scene.control -javafx.scene.control.cell -javafx.scene.control.skin -javafx.scene.effect -javafx.scene.image -javafx.scene.input -javafx.scene.layout -javafx.scene.media -javafx.scene.paint -javafx.scene.shape -javafx.scene.text -javafx.scene.transform -javafx.scene.web -javafx.stage -javafx.util -javafx.util.converter -javax.accessibility -javax.activation -javax.activity -javax.annotation -javax.annotation.processing javax.crypto javax.crypto.interfaces javax.crypto.spec +javax.net +javax.net.ssl +javax.security.auth +javax.security.auth.callback +javax.security.auth.login +javax.security.auth.spi +javax.security.auth.x500 +javax.security.cert +module:java.compiler +javax.annotation.processing +javax.lang.model +javax.lang.model.element +javax.lang.model.type +javax.lang.model.util +javax.tools +module:java.corba +javax.activity +javax.rmi +javax.rmi.CORBA +org.omg.CORBA +org.omg.CORBA.DynAnyPackage +org.omg.CORBA.ORBPackage +org.omg.CORBA.TypeCodePackage +org.omg.CORBA.portable +org.omg.CORBA_2_3 +org.omg.CORBA_2_3.portable +org.omg.CosNaming +org.omg.CosNaming.NamingContextExtPackage +org.omg.CosNaming.NamingContextPackage +org.omg.Dynamic +org.omg.DynamicAny +org.omg.DynamicAny.DynAnyFactoryPackage +org.omg.DynamicAny.DynAnyPackage +org.omg.IOP +org.omg.IOP.CodecFactoryPackage +org.omg.IOP.CodecPackage +org.omg.Messaging +org.omg.PortableInterceptor +org.omg.PortableInterceptor.ORBInitInfoPackage +org.omg.PortableServer +org.omg.PortableServer.CurrentPackage +org.omg.PortableServer.POAManagerPackage +org.omg.PortableServer.POAPackage +org.omg.PortableServer.ServantLocatorPackage +org.omg.PortableServer.portable +org.omg.SendingContext +org.omg.stub.java.rmi +module:java.datatransfer +java.awt.datatransfer +module:java.desktop +java.applet +java.awt +java.awt.color +java.awt.desktop +java.awt.dnd +java.awt.event +java.awt.font +java.awt.geom +java.awt.im +java.awt.im.spi +java.awt.image +java.awt.image.renderable +java.awt.print +java.beans +java.beans.beancontext +javax.accessibility javax.imageio javax.imageio.event javax.imageio.metadata @@ -143,54 +118,14 @@ javax.imageio.plugins.jpeg javax.imageio.plugins.tiff javax.imageio.spi javax.imageio.stream -javax.jnlp -javax.jws -javax.jws.soap -javax.lang.model -javax.lang.model.element -javax.lang.model.type -javax.lang.model.util -javax.management -javax.management.loading -javax.management.modelmbean -javax.management.monitor -javax.management.openmbean -javax.management.relation -javax.management.remote -javax.management.remote.rmi -javax.management.timer -javax.naming -javax.naming.directory -javax.naming.event -javax.naming.ldap -javax.naming.spi -javax.net -javax.net.ssl javax.print javax.print.attribute javax.print.attribute.standard javax.print.event -javax.rmi -javax.rmi.CORBA -javax.rmi.ssl -javax.script -javax.security.auth -javax.security.auth.callback -javax.security.auth.kerberos -javax.security.auth.login -javax.security.auth.spi -javax.security.auth.x500 -javax.security.cert -javax.security.sasl -javax.smartcardio javax.sound.midi javax.sound.midi.spi javax.sound.sampled javax.sound.sampled.spi -javax.sql -javax.sql.rowset -javax.sql.rowset.serial -javax.sql.rowset.spi javax.swing javax.swing.border javax.swing.colorchooser @@ -209,27 +144,64 @@ javax.swing.text.html.parser javax.swing.text.rtf javax.swing.tree javax.swing.undo -javax.tools -javax.transaction +module:java.instrument +java.lang.instrument +module:java.jnlp +javax.jnlp +module:java.logging +java.util.logging +module:java.management +java.lang.management +javax.management +javax.management.loading +javax.management.modelmbean +javax.management.monitor +javax.management.openmbean +javax.management.relation +javax.management.remote +javax.management.timer +module:java.management.rmi +javax.management.remote.rmi +module:java.naming +javax.naming +javax.naming.directory +javax.naming.event +javax.naming.ldap +javax.naming.spi +module:java.prefs +java.util.prefs +module:java.rmi +java.rmi +java.rmi.activation +java.rmi.dgc +java.rmi.registry +java.rmi.server +javax.rmi.ssl +module:java.scripting +javax.script +module:java.security.jgss +javax.security.auth.kerberos +org.ietf.jgss +module:java.security.sasl +javax.security.sasl +module:java.smartcardio +javax.smartcardio +module:java.sql +java.sql +javax.sql javax.transaction.xa +module:java.sql.rowset +javax.sql.rowset +javax.sql.rowset.serial +javax.sql.rowset.spi +module:java.transaction +javax.transaction +module:java.xml javax.xml -javax.xml.bind -javax.xml.bind.annotation -javax.xml.bind.annotation.adapters -javax.xml.bind.attachment -javax.xml.bind.helpers -javax.xml.bind.util javax.xml.catalog -javax.xml.crypto -javax.xml.crypto.dom -javax.xml.crypto.dsig -javax.xml.crypto.dsig.dom -javax.xml.crypto.dsig.keyinfo -javax.xml.crypto.dsig.spec javax.xml.datatype javax.xml.namespace javax.xml.parsers -javax.xml.soap javax.xml.stream javax.xml.stream.events javax.xml.stream.util @@ -239,6 +211,35 @@ javax.xml.transform.sax javax.xml.transform.stax javax.xml.transform.stream javax.xml.validation +javax.xml.xpath +org.w3c.dom +org.w3c.dom.bootstrap +org.w3c.dom.events +org.w3c.dom.ls +org.w3c.dom.ranges +org.w3c.dom.traversal +org.w3c.dom.views +org.xml.sax +org.xml.sax.ext +org.xml.sax.helpers +module:java.xml.bind +javax.xml.bind +javax.xml.bind.annotation +javax.xml.bind.annotation.adapters +javax.xml.bind.attachment +javax.xml.bind.helpers +javax.xml.bind.util +module:java.xml.crypto +javax.xml.crypto +javax.xml.crypto.dom +javax.xml.crypto.dsig +javax.xml.crypto.dsig.dom +javax.xml.crypto.dsig.keyinfo +javax.xml.crypto.dsig.spec +module:java.xml.ws +javax.jws +javax.jws.soap +javax.xml.soap javax.xml.ws javax.xml.ws.handler javax.xml.ws.handler.soap @@ -247,69 +248,125 @@ javax.xml.ws.soap javax.xml.ws.spi javax.xml.ws.spi.http javax.xml.ws.wsaddressing -javax.xml.xpath +module:java.xml.ws.annotation +javax.annotation +module:javafx.base +javafx.beans +javafx.beans.binding +javafx.beans.property +javafx.beans.property.adapter +javafx.beans.value +javafx.collections +javafx.collections.transformation +javafx.event +javafx.util +javafx.util.converter +module:javafx.controls +javafx.scene.chart +javafx.scene.control +javafx.scene.control.cell +javafx.scene.control.skin +module:javafx.fxml +javafx.fxml +module:javafx.graphics +javafx.animation +javafx.application +javafx.concurrent +javafx.css +javafx.css.converter +javafx.geometry +javafx.print +javafx.scene +javafx.scene.canvas +javafx.scene.effect +javafx.scene.image +javafx.scene.input +javafx.scene.layout +javafx.scene.paint +javafx.scene.shape +javafx.scene.text +javafx.scene.transform +javafx.stage +module:javafx.media +javafx.scene.media +module:javafx.swing +javafx.embed.swing +module:javafx.web +javafx.scene.web +module:jdk.accessibility +com.sun.java.accessibility.util +module:jdk.attach +com.sun.tools.attach +com.sun.tools.attach.spi +module:jdk.compiler +com.sun.source.doctree +com.sun.source.tree +com.sun.source.util +com.sun.tools.javac +module:jdk.dynalink jdk.dynalink jdk.dynalink.beans jdk.dynalink.linker jdk.dynalink.linker.support jdk.dynalink.support +module:jdk.httpserver +com.sun.net.httpserver +com.sun.net.httpserver.spi +module:jdk.incubator.httpclient jdk.incubator.http +module:jdk.jartool +com.sun.jarsigner +jdk.security.jarsigner +module:jdk.javadoc +com.sun.javadoc +com.sun.tools.doclets +com.sun.tools.doclets.standard +com.sun.tools.javadoc jdk.javadoc.doclet +module:jdk.jconsole +com.sun.tools.jconsole +module:jdk.jdi +com.sun.jdi +com.sun.jdi.connect +com.sun.jdi.connect.spi +com.sun.jdi.event +com.sun.jdi.request +module:jdk.jfr jdk.jfr jdk.jfr.consumer +module:jdk.jshell jdk.jshell jdk.jshell.execution jdk.jshell.spi jdk.jshell.tool +module:jdk.jsobject +netscape.javascript +module:jdk.management +com.sun.management +module:jdk.management.cmm jdk.management.cmm +module:jdk.management.jfr jdk.management.jfr +module:jdk.management.resource jdk.management.resource -jdk.nashorn.api.scripting -jdk.nashorn.api.tree +module:jdk.net jdk.net +module:jdk.packager.services jdk.packager.services -jdk.security.jarsigner -netscape.javascript -org.ietf.jgss -org.omg.CORBA -org.omg.CORBA_2_3 -org.omg.CORBA_2_3.portable -org.omg.CORBA.DynAnyPackage -org.omg.CORBA.ORBPackage -org.omg.CORBA.portable -org.omg.CORBA.TypeCodePackage -org.omg.CosNaming -org.omg.CosNaming.NamingContextExtPackage -org.omg.CosNaming.NamingContextPackage -org.omg.Dynamic -org.omg.DynamicAny -org.omg.DynamicAny.DynAnyFactoryPackage -org.omg.DynamicAny.DynAnyPackage -org.omg.IOP -org.omg.IOP.CodecFactoryPackage -org.omg.IOP.CodecPackage -org.omg.Messaging -org.omg.PortableInterceptor -org.omg.PortableInterceptor.ORBInitInfoPackage -org.omg.PortableServer -org.omg.PortableServer.CurrentPackage -org.omg.PortableServer.POAManagerPackage -org.omg.PortableServer.POAPackage -org.omg.PortableServer.portable -org.omg.PortableServer.ServantLocatorPackage -org.omg.SendingContext -org.omg.stub.java.rmi -org.w3c.dom -org.w3c.dom.bootstrap +module:jdk.scripting.nashorn +jdk.nashorn.api.scripting +jdk.nashorn.api.tree +module:jdk.sctp +com.sun.nio.sctp +module:jdk.security.auth +com.sun.security.auth +com.sun.security.auth.callback +com.sun.security.auth.login +com.sun.security.auth.module +module:jdk.security.jgss +com.sun.security.jgss +module:jdk.xml.dom org.w3c.dom.css -org.w3c.dom.events org.w3c.dom.html -org.w3c.dom.ls -org.w3c.dom.ranges org.w3c.dom.stylesheets -org.w3c.dom.traversal -org.w3c.dom.views org.w3c.dom.xpath -org.xml.sax -org.xml.sax.ext -org.xml.sax.helpers diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java index 19b1e8483d8..88231ea8e5f 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java @@ -262,8 +262,8 @@ public class Extern { if (elementListUrl == null) { reporter.print(Kind.WARNING, resources.getText("doclet.Resource_error", elementListPath.getPath())); } else { - try { - readListFromURL(docUrl, elementListUrl); + try (InputStream in = open(elementListUrl)) { + readElementList(in, docUrl, false, versionNumber); } catch (IOException exc) { throw new Fault(resources.getText( "doclet.Resource_error", elementListPath.getPath()), exc); @@ -280,7 +280,7 @@ public class Extern { * @return the resource path */ private DocPath getPlatformElementList(int version) { - String filename = version <= 9 + String filename = version <= 8 ? "package-list-" + version + ".txt" : "element-list-" + version + ".txt"; return DocPaths.RESOURCES.resolve("releases").resolve(filename); @@ -426,7 +426,9 @@ public class Extern { private void readElementListFromURL(String urlpath, URL elemlisturlpath) throws Fault { try { URL link = elemlisturlpath.toURI().resolve(DocPaths.ELEMENT_LIST.getPath()).toURL(); - readListFromURL(urlpath, link); + try (InputStream in = open(link)) { + readElementList(in, urlpath, false, 0); + } } catch (URISyntaxException | MalformedURLException exc) { throw new Fault(resources.getText("doclet.MalformedURL", elemlisturlpath.toString()), exc); } catch (IOException exc) { @@ -443,7 +445,9 @@ public class Extern { private void readPackageListFromURL(String urlpath, URL elemlisturlpath) throws Fault { try { URL link = elemlisturlpath.toURI().resolve(DocPaths.PACKAGE_LIST.getPath()).toURL(); - readListFromURL(urlpath, link); + try (InputStream in = open(link)) { + readElementList(in, urlpath, false, 0); + } } catch (URISyntaxException | MalformedURLException exc) { throw new Fault(resources.getText("doclet.MalformedURL", elemlisturlpath.toString()), exc); } catch (IOException exc) { @@ -451,18 +455,6 @@ public class Extern { } } - /** - * Read an element or package list from file. - * - * @param urlpath URL or path to the packages - * @param elementlistpath URL to read "element-list" file from - */ - private void readListFromURL(String urlpath, URL elementlistpath) throws IOException { - try (InputStream in = open(elementlistpath)) { - readElementList(in, urlpath, false); - } - } - /** * Read the "element-list" file which is available locally. * @@ -498,7 +490,7 @@ public class Extern { boolean pathIsRelative = !isUrl(path) && !DocFile.createFileForInput(configuration, path).isAbsolute(); - readElementList(file.openInputStream(), path, pathIsRelative); + readElementList(file.openInputStream(), path, pathIsRelative, 0); } else { throw new Fault(resources.getText("doclet.File_error", file.getPath()), null); } @@ -514,9 +506,11 @@ public class Extern { * @param input InputStream from the "element-list" file. * @param path URL or the directory path to the elements. * @param relative Is path relative? + * @param platformVersion The version of platform libraries the element list belongs to, + * or {@code 0} if it does not belong to a platform libraries doc bundle. * @throws IOException if there is a problem reading or closing the stream */ - private void readElementList(InputStream input, String path, boolean relative) + private void readElementList(InputStream input, String path, boolean relative, int platformVersion) throws IOException { try (BufferedReader in = new BufferedReader(new InputStreamReader(input))) { String elemname; @@ -533,12 +527,20 @@ public class Extern { moduleItems.put(moduleName, item); } else { DocPath pkgPath = DocPath.create(elemname.replace('.', '/')); - if (moduleName != null) { + // Although being modular, JDKs 9 and 10 do not use module names in javadoc URL paths. + if (moduleName != null && platformVersion != 9 && platformVersion != 10) { elempath = elempath.resolve(DocPath.create(moduleName).resolve(pkgPath)); } else { elempath = elempath.resolve(pkgPath); } - String actualModuleName = checkLinkCompatibility(elemname, moduleName, path, issueWarning); + String actualModuleName; + // For user provided libraries we check whether modularity matches the actual library. + // We trust modularity to be correct for platform library element lists. + if (platformVersion == 0) { + actualModuleName = checkLinkCompatibility(elemname, moduleName, path, issueWarning); + } else { + actualModuleName = moduleName == null ? DocletConstants.DEFAULT_ELEMENT_NAME : moduleName; + } Item item = new Item(elemname, elempath, relative); packageItems.computeIfAbsent(actualModuleName, k -> new TreeMap<>()) .putIfAbsent(elemname, item); // first-one-wins semantics -- GitLab From da9895a0a4790813bbfce0788160182de0771ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Fri, 12 Feb 2021 08:32:47 +0000 Subject: [PATCH 034/367] 8261499: Simplify HTML for javadoc links Reviewed-by: jjg --- .../html/AbstractExecutableMemberWriter.java | 29 +- .../formats/html/AbstractMemberWriter.java | 14 +- .../formats/html/AbstractTreeWriter.java | 6 +- .../formats/html/AllClassesIndexWriter.java | 4 +- ...nnotationTypeRequiredMemberWriterImpl.java | 10 +- .../doclets/formats/html/ClassUseWriter.java | 18 +- .../doclets/formats/html/ClassWriterImpl.java | 30 +- .../html/ConstantsSummaryWriterImpl.java | 10 +- .../formats/html/EnumConstantWriterImpl.java | 10 +- .../doclets/formats/html/FieldWriterImpl.java | 14 +- .../formats/html/HtmlDocletWriter.java | 107 ++++--- ...kFactoryImpl.java => HtmlLinkFactory.java} | 24 +- .../{LinkInfoImpl.java => HtmlLinkInfo.java} | 35 ++- .../formats/html/HtmlSerialFieldWriter.java | 12 +- .../doclets/formats/html/IndexWriter.java | 15 +- .../formats/html/MethodWriterImpl.java | 22 +- .../formats/html/ModuleWriterImpl.java | 6 +- .../formats/html/NestedClassWriterImpl.java | 14 +- .../formats/html/PackageWriterImpl.java | 4 +- .../formats/html/PropertyWriterImpl.java | 20 +- .../html/SerializedFormWriterImpl.java | 4 +- .../doclets/formats/html/Signatures.java | 20 +- .../formats/html/TagletWriterImpl.java | 10 +- .../doclets/formats/html/markup/Links.java | 37 +-- .../doclets/toolkit/util/links/LinkInfo.java | 6 - .../testAnchorNames/TestAnchorNames.java | 40 +-- .../TestAnnotationTypes.java | 4 +- .../doclet/testClassLinks/TestClassLinks.java | 6 +- .../doclet/testClassTree/TestClassTree.java | 17 +- .../testConstructors/TestConstructors.java | 12 +- .../TestEnumConstructor.java | 4 +- .../testHtmlTableTags/TestHtmlTableTags.java | 60 ++-- .../javadoc/doclet/testIndex/TestIndex.java | 29 +- .../TestIndexInPackageFiles.java | 10 +- .../doclet/testInterface/TestInterface.java | 4 +- .../javadoc/doclet/testJavaFX/TestJavaFX.java | 40 +-- .../TestLinksWithNoDeprecatedOption.java | 8 +- .../TestMemberInheritance.java | 50 ++- .../testMemberSummary/TestMemberSummary.java | 13 +- .../doclet/testModules/TestModules.java | 16 +- .../TestNewLanguageFeatures.java | 131 ++++---- .../doclet/testOrdering/TestOrdering.java | 150 +++++---- .../TestOverrideMethods.java | 73 ++--- .../TestPrivateClasses.java | 10 +- .../doclet/testProperty/TestProperty.java | 8 +- .../testRecordTypes/TestRecordTypes.java | 40 +-- .../javadoc/doclet/testSearch/TestSearch.java | 297 +++++++++--------- .../doclet/testSummaryTag/TestSummaryTag.java | 24 +- .../TestSystemPropertyTaglet.java | 84 ++--- .../TestTypeAnnotations.java | 54 ++-- .../testTypeParams/TestTypeParameters.java | 8 +- .../doclet/testUseOption/TestUseOption.java | 26 +- 52 files changed, 847 insertions(+), 852 deletions(-) rename src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/{LinkFactoryImpl.java => HtmlLinkFactory.java} (93%) rename src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/{LinkInfoImpl.java => HtmlLinkInfo.java} (92%) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java index 33cd75c4aef..b7d033557fb 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java @@ -44,12 +44,12 @@ import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; import jdk.javadoc.internal.doclets.toolkit.Content; import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants; -import static jdk.javadoc.internal.doclets.formats.html.LinkInfoImpl.Kind.EXECUTABLE_MEMBER_PARAM; -import static jdk.javadoc.internal.doclets.formats.html.LinkInfoImpl.Kind.MEMBER; -import static jdk.javadoc.internal.doclets.formats.html.LinkInfoImpl.Kind.MEMBER_DEPRECATED_PREVIEW; -import static jdk.javadoc.internal.doclets.formats.html.LinkInfoImpl.Kind.MEMBER_TYPE_PARAMS; -import static jdk.javadoc.internal.doclets.formats.html.LinkInfoImpl.Kind.RECEIVER_TYPE; -import static jdk.javadoc.internal.doclets.formats.html.LinkInfoImpl.Kind.THROWS_TYPE; +import static jdk.javadoc.internal.doclets.formats.html.HtmlLinkInfo.Kind.EXECUTABLE_MEMBER_PARAM; +import static jdk.javadoc.internal.doclets.formats.html.HtmlLinkInfo.Kind.MEMBER; +import static jdk.javadoc.internal.doclets.formats.html.HtmlLinkInfo.Kind.MEMBER_DEPRECATED_PREVIEW; +import static jdk.javadoc.internal.doclets.formats.html.HtmlLinkInfo.Kind.MEMBER_TYPE_PARAMS; +import static jdk.javadoc.internal.doclets.formats.html.HtmlLinkInfo.Kind.RECEIVER_TYPE; +import static jdk.javadoc.internal.doclets.formats.html.HtmlLinkInfo.Kind.THROWS_TYPE; /** * Print method and constructor info. @@ -77,7 +77,7 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite * @return the type parameters. */ protected Content getTypeParameters(ExecutableElement member) { - LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, MEMBER_TYPE_PARAMS, member); + HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration, MEMBER_TYPE_PARAMS, member); return writer.getTypeParameterLinks(linkInfo); } @@ -96,7 +96,7 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite content.add(signature); return writer.getDocLink(MEMBER_DEPRECATED_PREVIEW, utils.getEnclosingTypeElement(member), - member, content, false); + member, content, null, false); } /** @@ -108,11 +108,10 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite * @param tdSummary the content tree to which the link will be added */ @Override - protected void addSummaryLink(LinkInfoImpl.Kind context, TypeElement te, Element member, - Content tdSummary) { + protected void addSummaryLink(HtmlLinkInfo.Kind context, TypeElement te, Element member, + Content tdSummary) { ExecutableElement ee = (ExecutableElement)member; - Content memberLink = HtmlTree.SPAN(HtmlStyle.memberNameLink, - writer.getDocLink(context, te, ee, name(ee))); + Content memberLink = writer.getDocLink(context, te, ee, name(ee), HtmlStyle.memberNameLink); Content code = HtmlTree.CODE(memberLink); addParameters(ee, code); tdSummary.add(code); @@ -140,7 +139,7 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite */ protected void addParam(ExecutableElement member, VariableElement param, TypeMirror paramType, boolean isVarArg, Content tree) { - Content link = writer.getLink(new LinkInfoImpl(configuration, EXECUTABLE_MEMBER_PARAM, + Content link = writer.getLink(new HtmlLinkInfo(configuration, EXECUTABLE_MEMBER_PARAM, paramType).varargs(isVarArg)); tree.add(link); if(name(param).length() > 0) { @@ -159,7 +158,7 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite * @param tree the content tree to which the information will be added. */ protected void addReceiver(ExecutableElement member, TypeMirror rcvrType, Content tree) { - var info = new LinkInfoImpl(configuration, RECEIVER_TYPE, rcvrType); + var info = new HtmlLinkInfo(configuration, RECEIVER_TYPE, rcvrType); info.linkToSelf = false; tree.add(writer.getLink(info)); tree.add(Entity.NO_BREAK_SPACE); @@ -290,7 +289,7 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite htmlTree.add(","); htmlTree.add(DocletConstants.NL); } - Content link = writer.getLink(new LinkInfoImpl(configuration, THROWS_TYPE, t)); + Content link = writer.getLink(new HtmlLinkInfo(configuration, THROWS_TYPE, t)); htmlTree.add(link); } return htmlTree; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java index 144b8e42647..0cecb03c3b9 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractMemberWriter.java @@ -147,7 +147,7 @@ public abstract class AbstractMemberWriter implements MemberSummaryWriter, Membe * @param tdSummary the content tree to which the link will be added */ protected void addSummaryLink(TypeElement typeElement, Element member, Content tdSummary) { - addSummaryLink(LinkInfoImpl.Kind.MEMBER, typeElement, member, tdSummary); + addSummaryLink(HtmlLinkInfo.Kind.MEMBER, typeElement, member, tdSummary); } /** @@ -158,8 +158,8 @@ public abstract class AbstractMemberWriter implements MemberSummaryWriter, Membe * @param member the member to be documented * @param tdSummary the content tree to which the summary link will be added */ - protected abstract void addSummaryLink(LinkInfoImpl.Kind context, - TypeElement typeElement, Element member, Content tdSummary); + protected abstract void addSummaryLink(HtmlLinkInfo.Kind context, + TypeElement typeElement, Element member, Content tdSummary); /** * Adds the inherited summary link for the member. @@ -210,8 +210,8 @@ public abstract class AbstractMemberWriter implements MemberSummaryWriter, Membe } } code.add( - writer.getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.SUMMARY_RETURN_TYPE, type))); + writer.getLink(new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.SUMMARY_RETURN_TYPE, type))); } tdSummaryType.add(code); } @@ -336,8 +336,8 @@ public abstract class AbstractMemberWriter implements MemberSummaryWriter, Membe typeContent.add(name); } addSummaryLink(utils.isClass(element) || utils.isInterface(element) - ? LinkInfoImpl.Kind.CLASS_USE - : LinkInfoImpl.Kind.MEMBER, + ? HtmlLinkInfo.Kind.CLASS_USE + : HtmlLinkInfo.Kind.MEMBER, te, element, typeContent); Content desc = new ContentBuilder(); writer.addSummaryLinkComment(this, element, desc); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractTreeWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractTreeWriter.java index 0b7ecf21c1d..96ee6251a4e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractTreeWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractTreeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2021, 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 @@ -154,7 +154,7 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter { } else { contentTree.add(", "); } - addPreQualifiedClassLink(LinkInfoImpl.Kind.TREE, intf, contentTree); + addPreQualifiedClassLink(HtmlLinkInfo.Kind.TREE, intf, contentTree); } } } @@ -171,6 +171,6 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter { * @param contentTree the content tree to which the information will be added */ protected void addPartialInfo(TypeElement typeElement, Content contentTree) { - addPreQualifiedStrongClassLink(LinkInfoImpl.Kind.TREE, typeElement, contentTree); + addPreQualifiedStrongClassLink(HtmlLinkInfo.Kind.TREE, typeElement, contentTree); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java index 83c79884103..1d021608fc8 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AllClassesIndexWriter.java @@ -151,8 +151,8 @@ public class AllClassesIndexWriter extends HtmlDocletWriter { */ protected void addTableRow(Table table, TypeElement klass) { List rowContents = new ArrayList<>(); - Content classLink = getLink(new LinkInfoImpl( - configuration, LinkInfoImpl.Kind.INDEX, klass)); + Content classLink = getLink(new HtmlLinkInfo( + configuration, HtmlLinkInfo.Kind.INDEX, klass)); ContentBuilder description = new ContentBuilder(); Set flags = utils.elementFlags(klass); if (flags.contains(ElementFlag.PREVIEW)) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java index 4e867a1325c..bb08a645389 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java @@ -184,10 +184,10 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter } @Override - protected void addSummaryLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element member, - Content tdSummary) { - Content memberLink = HtmlTree.SPAN(HtmlStyle.memberNameLink, - writer.getDocLink(context, member, name(member))); + protected void addSummaryLink(HtmlLinkInfo.Kind context, TypeElement typeElement, Element member, + Content tdSummary) { + Content memberLink = writer.getDocLink(context, utils.getEnclosingTypeElement(member), member, + name(member), HtmlStyle.memberNameLink); Content code = HtmlTree.CODE(memberLink); tdSummary.add(code); } @@ -206,7 +206,7 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter @Override protected Content getSummaryLink(Element member) { String name = utils.getFullyQualifiedName(member) + "." + member.getSimpleName(); - return writer.getDocLink(LinkInfoImpl.Kind.MEMBER_DEPRECATED_PREVIEW, member, name); + return writer.getDocLink(HtmlLinkInfo.Kind.MEMBER_DEPRECATED_PREVIEW, member, name); } protected Comment selectComment(Comment c1, Comment c2) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java index 1f02961b59e..cd48a91e026 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java @@ -252,8 +252,8 @@ public class ClassUseWriter extends SubWriterHolderWriter { protected void addPackageList(Content contentTree) { Content caption = contents.getContent( "doclet.ClassUse_Packages.that.use.0", - getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.CLASS_USE_HEADER, typeElement))); + getLink(new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.CLASS_USE_HEADER, typeElement))); Table table = new Table(HtmlStyle.summaryTable) .setCaption(caption) .setHeader(getPackageTableHeader()) @@ -277,8 +277,8 @@ public class ClassUseWriter extends SubWriterHolderWriter { } Content caption = contents.getContent( "doclet.ClassUse_PackageAnnotation", - getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.CLASS_USE_HEADER, typeElement))); + getLink(new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.CLASS_USE_HEADER, typeElement))); Table table = new Table(HtmlStyle.summaryTable) .setCaption(caption) @@ -304,7 +304,7 @@ public class ClassUseWriter extends SubWriterHolderWriter { HtmlTree htmlTree = HtmlTree.SECTION(HtmlStyle.detail) .setId(htmlIds.forPackage(pkg)); Content link = contents.getContent("doclet.ClassUse_Uses.of.0.in.1", - getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, + getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.CLASS_USE_HEADER, typeElement)), getPackageLink(pkg, utils.getPackageName(pkg))); Content heading = HtmlTree.HEADING(Headings.TypeUse.SUMMARY_HEADING, link); @@ -337,8 +337,8 @@ public class ClassUseWriter extends SubWriterHolderWriter { * @param contentTree the content tree to which the class use information will be added */ protected void addClassUse(PackageElement pkg, Content contentTree) { - Content classLink = getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.CLASS_USE_HEADER, typeElement)); + Content classLink = getLink(new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.CLASS_USE_HEADER, typeElement)); Content pkgLink = getPackageLink(pkg, utils.getPackageName(pkg)); classSubWriter.addUseInfo(pkgToClassAnnotations.get(pkg), contents.getContent("doclet.ClassUse_Annotation", classLink, @@ -437,8 +437,8 @@ public class ClassUseWriter extends SubWriterHolderWriter { protected Navigation getNavBar(PageMode pageMode, Element element) { Content mdleLinkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement), contents.moduleLabel); - Content classLinkContent = getLink(new LinkInfoImpl( - configuration, LinkInfoImpl.Kind.CLASS_USE_HEADER, typeElement) + Content classLinkContent = getLink(new HtmlLinkInfo( + configuration, HtmlLinkInfo.Kind.CLASS_USE_HEADER, typeElement) .label(resources.getText("doclet.Class")) .skipPreview(true)); return super.getNavBar(pageMode, element) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java index 7d99e7f149f..28f78c7ccc9 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java @@ -127,8 +127,8 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite pkgNameDiv.add(pkgNameContent); div.add(pkgNameDiv); } - LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.CLASS_HEADER, typeElement); + HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.CLASS_HEADER, typeElement); //Let's not link to ourselves in the header. linkInfo.linkToSelf = false; Content heading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING, @@ -267,7 +267,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite Content content = new ContentBuilder(); if (type.equals(typeElement.asType())) { Content typeParameters = getTypeParameterLinks( - new LinkInfoImpl(configuration, LinkInfoImpl.Kind.TREE, + new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.TREE, typeElement)); if (configuration.shouldExcludeQualifier(utils.containingPackage(typeElement).toString())) { content.add(utils.asTypeElement(type).getSimpleName()); @@ -277,8 +277,8 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite content.add(typeParameters); } } else { - Content link = getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.CLASS_TREE_PARENT, type) + Content link = getLink(new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.CLASS_TREE_PARENT, type) .label(configuration.getClassName(utils.asTypeElement(type)))); content.add(link); } @@ -316,7 +316,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite if (!subclasses.isEmpty()) { HtmlTree dl = HtmlTree.DL(HtmlStyle.notes); dl.add(HtmlTree.DT(contents.subclassesLabel)); - dl.add(HtmlTree.DD(getClassLinks(LinkInfoImpl.Kind.SUBCLASSES, subclasses))); + dl.add(HtmlTree.DD(getClassLinks(HtmlLinkInfo.Kind.SUBCLASSES, subclasses))); classInfoTree.add(dl); } } @@ -329,7 +329,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite if (!subInterfaces.isEmpty()) { Content dl = HtmlTree.DL(HtmlStyle.notes); dl.add(HtmlTree.DT(contents.subinterfacesLabel)); - dl.add(HtmlTree.DD(getClassLinks(LinkInfoImpl.Kind.SUBINTERFACES, subInterfaces))); + dl.add(HtmlTree.DD(getClassLinks(HtmlLinkInfo.Kind.SUBINTERFACES, subInterfaces))); classInfoTree.add(dl); } } @@ -349,7 +349,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite if (!implcl.isEmpty()) { HtmlTree dl = HtmlTree.DL(HtmlStyle.notes); dl.add(HtmlTree.DT(contents.implementingClassesLabel)); - dl.add(HtmlTree.DD(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_CLASSES, implcl))); + dl.add(HtmlTree.DD(getClassLinks(HtmlLinkInfo.Kind.IMPLEMENTED_CLASSES, implcl))); classInfoTree.add(dl); } } @@ -361,7 +361,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite if (utils.isClass(typeElement) && !interfaces.isEmpty()) { HtmlTree dl = HtmlTree.DL(HtmlStyle.notes); dl.add(HtmlTree.DT(contents.allImplementedInterfacesLabel)); - dl.add(HtmlTree.DD(getClassLinks(LinkInfoImpl.Kind.IMPLEMENTED_INTERFACES, interfaces))); + dl.add(HtmlTree.DD(getClassLinks(HtmlLinkInfo.Kind.IMPLEMENTED_INTERFACES, interfaces))); classInfoTree.add(dl); } } @@ -375,7 +375,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite if (utils.isInterface(typeElement) && !interfaces.isEmpty()) { HtmlTree dl = HtmlTree.DL(HtmlStyle.notes); dl.add(HtmlTree.DT(contents.allSuperinterfacesLabel)); - dl.add(HtmlTree.DD(getClassLinks(LinkInfoImpl.Kind.SUPER_INTERFACES, interfaces))); + dl.add(HtmlTree.DD(getClassLinks(HtmlLinkInfo.Kind.SUPER_INTERFACES, interfaces))); classInfoTree.add(dl); } } @@ -393,8 +393,8 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite ? contents.enclosingInterfaceLabel : contents.enclosingClassLabel)); Content dd = new HtmlTree(TagName.DD); - dd.add(getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.CLASS, e))); + dd.add(getLink(new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.CLASS, e))); dl.add(dd); classInfoTree.add(dl); return null; @@ -450,7 +450,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite * @param list the list of classes * @return a content tree for the class list */ - private Content getClassLinks(LinkInfoImpl.Kind context, Collection list) { + private Content getClassLinks(HtmlLinkInfo.Kind context, Collection list) { Content content = new ContentBuilder(); boolean isFirst = true; for (Object type : list) { @@ -463,11 +463,11 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite // TODO: should we simply split this method up to avoid instanceof ? if (type instanceof TypeElement) { Content link = getLink( - new LinkInfoImpl(configuration, context, (TypeElement)(type))); + new HtmlLinkInfo(configuration, context, (TypeElement)(type))); content.add(HtmlTree.CODE(link)); } else { Content link = getLink( - new LinkInfoImpl(configuration, context, ((TypeMirror)type))); + new HtmlLinkInfo(configuration, context, ((TypeMirror)type))); content.add(HtmlTree.CODE(link)); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java index 1e708788767..367c738c4d7 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConstantsSummaryWriterImpl.java @@ -184,8 +184,8 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons //generate links backward only to public classes. Content classlink = (utils.isPublic(typeElement) || utils.isProtected(typeElement)) ? - getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.CONSTANT_SUMMARY, typeElement)) : + getLink(new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.CONSTANT_SUMMARY, typeElement)) : new StringContent(utils.getFullyQualifiedName(typeElement)); PackageElement enclosingPackage = utils.containingPackage(typeElement); @@ -222,8 +222,8 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons code.add(modifier); code.add(Entity.NO_BREAK_SPACE); } - Content type = getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.CONSTANT_SUMMARY, member.asType())); + Content type = getLink(new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.CONSTANT_SUMMARY, member.asType())); code.add(type); typeContent.add(code); return typeContent; @@ -236,7 +236,7 @@ public class ConstantsSummaryWriterImpl extends HtmlDocletWriter implements Cons * @return the name column of the constant table row */ private Content getNameColumn(VariableElement member) { - Content nameContent = getDocLink(LinkInfoImpl.Kind.CONSTANT_SUMMARY, + Content nameContent = getDocLink(HtmlLinkInfo.Kind.CONSTANT_SUMMARY, member, member.getSimpleName()); return HtmlTree.CODE(nameContent); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java index b4fdc3f7c7c..d831df7c881 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/EnumConstantWriterImpl.java @@ -157,10 +157,10 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter } @Override - protected void addSummaryLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element member, - Content tdSummary) { - Content memberLink = HtmlTree.SPAN(HtmlStyle.memberNameLink, - writer.getDocLink(context, member, name(member))); + protected void addSummaryLink(HtmlLinkInfo.Kind context, TypeElement typeElement, Element member, + Content tdSummary) { + Content memberLink = writer.getDocLink(context, utils.getEnclosingTypeElement(member), member, + name(member), HtmlStyle.memberNameLink); Content code = HtmlTree.CODE(memberLink); tdSummary.add(code); } @@ -177,7 +177,7 @@ public class EnumConstantWriterImpl extends AbstractMemberWriter @Override protected Content getSummaryLink(Element member) { String name = utils.getFullyQualifiedName(member) + "." + member.getSimpleName(); - return writer.getDocLink(LinkInfoImpl.Kind.MEMBER_DEPRECATED_PREVIEW, member, name); + return writer.getDocLink(HtmlLinkInfo.Kind.MEMBER_DEPRECATED_PREVIEW, member, name); } @Override diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java index f97a12ae655..5a938144c90 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/FieldWriterImpl.java @@ -161,7 +161,7 @@ public class FieldWriterImpl extends AbstractMemberWriter @Override public void addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree) { Content classLink = writer.getPreQualifiedClassLink( - LinkInfoImpl.Kind.MEMBER, typeElement); + HtmlLinkInfo.Kind.MEMBER, typeElement); Content label; if (options.summarizeOverriddenMethods()) { label = new StringContent(utils.isClass(typeElement) @@ -181,10 +181,10 @@ public class FieldWriterImpl extends AbstractMemberWriter } @Override - protected void addSummaryLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element member, - Content tdSummary) { - Content memberLink = HtmlTree.SPAN(HtmlStyle.memberNameLink, - writer.getDocLink(context, typeElement , member, name(member))); + protected void addSummaryLink(HtmlLinkInfo.Kind context, TypeElement typeElement, Element member, + Content tdSummary) { + Content memberLink = writer.getDocLink(context, typeElement , member, name(member), + HtmlStyle.memberNameLink); Content code = HtmlTree.CODE(memberLink); tdSummary.add(code); } @@ -192,7 +192,7 @@ public class FieldWriterImpl extends AbstractMemberWriter @Override protected void addInheritedSummaryLink(TypeElement typeElement, Element member, Content linksTree) { linksTree.add( - writer.getDocLink(LinkInfoImpl.Kind.MEMBER, typeElement, member, name(member))); + writer.getDocLink(HtmlLinkInfo.Kind.MEMBER, typeElement, member, name(member))); } @Override @@ -203,7 +203,7 @@ public class FieldWriterImpl extends AbstractMemberWriter @Override protected Content getSummaryLink(Element member) { String name = utils.getFullyQualifiedName(member) + "." + member.getSimpleName(); - return writer.getDocLink(LinkInfoImpl.Kind.MEMBER_DEPRECATED_PREVIEW, member, name); + return writer.getDocLink(HtmlLinkInfo.Kind.MEMBER_DEPRECATED_PREVIEW, member, name); } @Override diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java index f548d1cce13..af797cebe2d 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java @@ -750,8 +750,8 @@ public class HtmlDocletWriter { * * @return the link for the given class. */ - public Content getLink(LinkInfoImpl linkInfo) { - LinkFactoryImpl factory = new LinkFactoryImpl(this); + public Content getLink(HtmlLinkInfo linkInfo) { + HtmlLinkFactory factory = new HtmlLinkFactory(this); return factory.getLink(linkInfo); } @@ -761,8 +761,8 @@ public class HtmlDocletWriter { * @param linkInfo the information about the link. * @return the type for the given class. */ - public Content getTypeParameterLinks(LinkInfoImpl linkInfo) { - LinkFactoryImpl factory = new LinkFactoryImpl(this); + public Content getTypeParameterLinks(HtmlLinkInfo linkInfo) { + HtmlLinkFactory factory = new HtmlLinkFactory(this); return factory.getTypeParameterLinks(linkInfo); } @@ -775,12 +775,12 @@ public class HtmlDocletWriter { * @param refMemName the name of the member being referenced. This should * be null or empty string if no member is being referenced. * @param label the label for the external link. - * @param strong true if the link should be strong. + * @param style optional style for the link. * @param code true if the label should be code font. * @return the link */ public Content getCrossClassLink(TypeElement classElement, String refMemName, - Content label, boolean strong, boolean code) { + Content label, HtmlStyle style, boolean code) { if (classElement != null) { String className = utils.getSimpleName(classElement); PackageElement packageElement = utils.containingPackage(classElement); @@ -798,8 +798,7 @@ public class HtmlDocletWriter { DocLink link = configuration.extern.getExternalLink(packageElement, pathToRoot, className + ".html", refMemName); return links.createLink(link, - (label == null) || label.isEmpty() ? defaultLabel : label, - strong, + (label == null) || label.isEmpty() ? defaultLabel : label, style, resources.getText("doclet.Href_Class_Or_Interface_Title", utils.getPackageName(packageElement)), true); } @@ -831,9 +830,9 @@ public class HtmlDocletWriter { * @param element to link to * @return a content tree for the link */ - public Content getQualifiedClassLink(LinkInfoImpl.Kind context, Element element) { - LinkInfoImpl linkInfoImpl = new LinkInfoImpl(configuration, context, (TypeElement)element); - return getLink(linkInfoImpl.label(utils.getFullyQualifiedName(element))); + public Content getQualifiedClassLink(HtmlLinkInfo.Kind context, Element element) { + HtmlLinkInfo htmlLinkInfo = new HtmlLinkInfo(configuration, context, (TypeElement)element); + return getLink(htmlLinkInfo.label(utils.getFullyQualifiedName(element))); } /** @@ -843,8 +842,8 @@ public class HtmlDocletWriter { * @param typeElement to link to * @param contentTree the content tree to which the link will be added */ - public void addPreQualifiedClassLink(LinkInfoImpl.Kind context, TypeElement typeElement, Content contentTree) { - addPreQualifiedClassLink(context, typeElement, false, contentTree); + public void addPreQualifiedClassLink(HtmlLinkInfo.Kind context, TypeElement typeElement, Content contentTree) { + addPreQualifiedClassLink(context, typeElement, null, contentTree); } /** @@ -855,13 +854,13 @@ public class HtmlDocletWriter { * @param typeElement the class to link to. * @return the link with the package portion of the label in plain text. */ - public Content getPreQualifiedClassLink(LinkInfoImpl.Kind context, TypeElement typeElement) { + public Content getPreQualifiedClassLink(HtmlLinkInfo.Kind context, TypeElement typeElement) { ContentBuilder classlink = new ContentBuilder(); PackageElement pkg = utils.containingPackage(typeElement); if (pkg != null && ! configuration.shouldExcludeQualifier(pkg.getSimpleName().toString())) { classlink.add(getEnclosingPackageName(typeElement)); } - classlink.add(getLink(new LinkInfoImpl(configuration, + classlink.add(getLink(new HtmlLinkInfo(configuration, context, typeElement).label(utils.getSimpleName(typeElement)))); return classlink; } @@ -873,18 +872,18 @@ public class HtmlDocletWriter { * * @param context the id of the context where the link will be added * @param typeElement the class to link to - * @param isStrong true if the link should be strong + * @param style optional style for the link * @param contentTree the content tree to which the link with be added */ - public void addPreQualifiedClassLink(LinkInfoImpl.Kind context, - TypeElement typeElement, boolean isStrong, Content contentTree) { + public void addPreQualifiedClassLink(HtmlLinkInfo.Kind context, + TypeElement typeElement, HtmlStyle style, Content contentTree) { PackageElement pkg = utils.containingPackage(typeElement); if(pkg != null && ! configuration.shouldExcludeQualifier(pkg.getSimpleName().toString())) { contentTree.add(getEnclosingPackageName(typeElement)); } - LinkInfoImpl linkinfo = new LinkInfoImpl(configuration, context, typeElement) + HtmlLinkInfo linkinfo = new HtmlLinkInfo(configuration, context, typeElement) .label(utils.getSimpleName(typeElement)) - .strong(isStrong); + .style(style); Content link = getLink(linkinfo); contentTree.add(link); } @@ -918,8 +917,8 @@ public class HtmlDocletWriter { * @param typeElement the class to link to * @param contentTree the content tree to which the link with be added */ - public void addPreQualifiedStrongClassLink(LinkInfoImpl.Kind context, TypeElement typeElement, Content contentTree) { - addPreQualifiedClassLink(context, typeElement, true, contentTree); + public void addPreQualifiedStrongClassLink(HtmlLinkInfo.Kind context, TypeElement typeElement, Content contentTree) { + addPreQualifiedClassLink(context, typeElement, HtmlStyle.typeNameLink, contentTree); } /** @@ -930,9 +929,9 @@ public class HtmlDocletWriter { * @param label the label for the link * @return a content tree for the element link */ - public Content getDocLink(LinkInfoImpl.Kind context, Element element, CharSequence label) { + public Content getDocLink(HtmlLinkInfo.Kind context, Element element, CharSequence label) { return getDocLink(context, utils.getEnclosingTypeElement(element), element, - new StringContent(label), false); + new StringContent(label), null, false); } /** @@ -946,9 +945,9 @@ public class HtmlDocletWriter { * @param label the label for the link. * @return the link for the given member. */ - public Content getDocLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element element, + public Content getDocLink(HtmlLinkInfo.Kind context, TypeElement typeElement, Element element, CharSequence label) { - return getDocLink(context, typeElement, element, label, false); + return getDocLink(context, typeElement, element, new StringContent(label), null, false); } /** @@ -960,11 +959,28 @@ public class HtmlDocletWriter { * inheriting comments. * @param element the member being linked to. * @param label the label for the link. + * @param style optional style for the link. * @return the link for the given member. */ - public Content getDocLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element element, + public Content getDocLink(HtmlLinkInfo.Kind context, TypeElement typeElement, Element element, + CharSequence label, HtmlStyle style) { + return getDocLink(context, typeElement, element, new StringContent(label), style, false); + } + + /** + * Return the link for the given member. + * + * @param context the id of the context where the link will be printed. + * @param typeElement the typeElement that we should link to. This is not + * not necessarily the type containing element since we may be + * inheriting comments. + * @param element the member being linked to. + * @param label the label for the link. + * @return the link for the given member. + */ + public Content getDocLink(HtmlLinkInfo.Kind context, TypeElement typeElement, Element element, CharSequence label, boolean isProperty) { - return getDocLink(context, typeElement, element, new StringContent(label), isProperty); + return getDocLink(context, typeElement, element, new StringContent(label), null, isProperty); } /** @@ -976,11 +992,12 @@ public class HtmlDocletWriter { * inheriting comments. * @param element the member being linked to. * @param label the label for the link. + * @param style optional style to use for the link. * @param isProperty true if the element parameter is a JavaFX property. * @return the link for the given member. */ - public Content getDocLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element element, - Content label, boolean isProperty) { + public Content getDocLink(HtmlLinkInfo.Kind context, TypeElement typeElement, Element element, + Content label, HtmlStyle style, boolean isProperty) { if (!utils.isLinkable(typeElement, element)) { return label; } @@ -988,16 +1005,18 @@ public class HtmlDocletWriter { if (utils.isExecutableElement(element)) { ExecutableElement ee = (ExecutableElement)element; HtmlId id = isProperty ? htmlIds.forProperty(ee) : htmlIds.forMember(ee); - return getLink(new LinkInfoImpl(configuration, context, typeElement) + return getLink(new HtmlLinkInfo(configuration, context, typeElement) .label(label) .where(id.name()) + .style(style) .targetMember(element)); } if (utils.isVariableElement(element) || utils.isTypeElement(element)) { - return getLink(new LinkInfoImpl(configuration, context, typeElement) + return getLink(new HtmlLinkInfo(configuration, context, typeElement) .label(label) .where(element.getSimpleName().toString()) + .style(style) .targetMember(element)); } @@ -1071,12 +1090,12 @@ public class HtmlDocletWriter { TypeMirror refType = ch.getReferencedType(see); if (refType != null) { return plainOrCode(isLinkPlain, getLink( - new LinkInfoImpl(configuration, LinkInfoImpl.Kind.DEFAULT, refType))); + new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.DEFAULT, refType))); } } label = plainOrCode(isLinkPlain, new StringContent(utils.getSimpleName(refClass))); } - return getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.DEFAULT, refClass) + return getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.DEFAULT, refClass) .label(label)); } else if (refMem == null) { // Must be a member reference since refClass is not null and refMemName is not null. @@ -1132,8 +1151,8 @@ public class HtmlDocletWriter { text = plainOrCode(kind == LINK_PLAIN, new StringContent(refMemName)); - return getDocLink(LinkInfoImpl.Kind.SEE_TAG, containing, - refMem, (label.isEmpty() ? text: label), false); + return getDocLink(HtmlLinkInfo.Kind.SEE_TAG, containing, + refMem, (label.isEmpty() ? text: label), null, false); } } @@ -1752,8 +1771,8 @@ public class HtmlDocletWriter { } annotation = new ContentBuilder(); isAnnotationDocumented = false; - LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.ANNOTATION, annotationElement); + HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.ANNOTATION, annotationElement); Map pairs = aDesc.getElementValues(); // If the annotation is synthesized, do not print the container. if (utils.configuration.workArounds.isSynthesized(aDesc)) { @@ -1828,7 +1847,7 @@ public class HtmlDocletWriter { * @param map annotation type element to annotation value pairs * @param linkBreak if true, add new line between each member value */ - private void addAnnotations(TypeElement annotationDoc, LinkInfoImpl linkInfo, + private void addAnnotations(TypeElement annotationDoc, HtmlLinkInfo linkInfo, ContentBuilder annotation, Map map, boolean linkBreak) { @@ -1855,7 +1874,7 @@ public class HtmlDocletWriter { } String simpleName = element.getSimpleName().toString(); if (multipleValues || !"value".equals(simpleName)) { // Omit "value=" where unnecessary - annotation.add(getDocLink(LinkInfoImpl.Kind.ANNOTATION, element, simpleName)); + annotation.add(getDocLink(HtmlLinkInfo.Kind.ANNOTATION, element, simpleName)); annotation.add("="); } AnnotationValue annotationValue = map.get(element); @@ -1944,8 +1963,8 @@ public class HtmlDocletWriter { return new SimpleTypeVisitor9() { @Override public Content visitDeclared(DeclaredType t, Void p) { - LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.ANNOTATION, t); + HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.ANNOTATION, t); String name = utils.isIncluded(t.asElement()) ? t.asElement().getSimpleName().toString() : utils.getFullyQualifiedName(t.asElement()); @@ -1969,7 +1988,7 @@ public class HtmlDocletWriter { } @Override public Content visitEnumConstant(VariableElement c, Void p) { - return getDocLink(LinkInfoImpl.Kind.ANNOTATION, c, c.getSimpleName()); + return getDocLink(HtmlLinkInfo.Kind.ANNOTATION, c, c.getSimpleName()); } @Override public Content visitArray(List vals, Void p) { @@ -2257,7 +2276,7 @@ public class HtmlDocletWriter { elements.stream() .sorted((te1, te2) -> te1.getSimpleName().toString().compareTo(te2.getSimpleName().toString())) .distinct() - .map(te -> getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.CLASS, te).label(HtmlTree.CODE(new StringContent(te.getSimpleName()))).skipPreview(true))) + .map(te -> getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.CLASS, te).label(HtmlTree.CODE(new StringContent(te.getSimpleName()))).skipPreview(true))) .forEach(c -> { links.add(sep[0]); links.add(c); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkFactoryImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java similarity index 93% rename from src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkFactoryImpl.java rename to src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java index 59cc14ed05b..e1a61db1bc4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkFactoryImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java @@ -57,12 +57,12 @@ import jdk.javadoc.internal.doclets.toolkit.util.links.LinkInfo; * This code and its internal interfaces are subject to change or * deletion without notice. */ -public class LinkFactoryImpl extends LinkFactory { +public class HtmlLinkFactory extends LinkFactory { private final HtmlDocletWriter m_writer; private final DocPaths docPaths; - public LinkFactoryImpl(HtmlDocletWriter writer) { + public HtmlLinkFactory(HtmlDocletWriter writer) { super(writer.configuration.utils); m_writer = writer; docPaths = writer.configuration.docPaths; @@ -76,7 +76,7 @@ public class LinkFactoryImpl extends LinkFactory { @Override protected Content getClassLink(LinkInfo linkInfo) { BaseConfiguration configuration = m_writer.configuration; - LinkInfoImpl classLinkInfo = (LinkInfoImpl) linkInfo; + HtmlLinkInfo classLinkInfo = (HtmlLinkInfo) linkInfo; TypeElement typeElement = classLinkInfo.typeElement; // Create a tool tip if we are linking to a class or interface. Don't // create one if we are linking to a member. @@ -94,7 +94,7 @@ public class LinkFactoryImpl extends LinkFactory { if (!hasWhere && showPreview) { flags = utils.elementFlags(typeElement); target = typeElement; - } else if ((classLinkInfo.context == LinkInfoImpl.Kind.SEE_TAG || classLinkInfo.context == LinkInfoImpl.Kind.MEMBER_DEPRECATED_PREVIEW) && + } else if ((classLinkInfo.context == HtmlLinkInfo.Kind.SEE_TAG || classLinkInfo.context == HtmlLinkInfo.Kind.MEMBER_DEPRECATED_PREVIEW) && classLinkInfo.targetMember != null && showPreview) { flags = utils.elementFlags(classLinkInfo.targetMember); target = classLinkInfo.targetMember; @@ -112,7 +112,7 @@ public class LinkFactoryImpl extends LinkFactory { link.add(m_writer.links.createLink( filename.fragment(classLinkInfo.where), label, - classLinkInfo.isStrong, + classLinkInfo.style, title)); if (flags.contains(ElementFlag.PREVIEW)) { link.add(HtmlTree.SUP(m_writer.links.createLink( @@ -125,7 +125,7 @@ public class LinkFactoryImpl extends LinkFactory { } else { Content crossLink = m_writer.getCrossClassLink( typeElement, classLinkInfo.where, - label, classLinkInfo.isStrong, true); + label, classLinkInfo.style, true); if (crossLink != null) { link.add(crossLink); if (flags.contains(ElementFlag.PREVIEW)) { @@ -133,7 +133,7 @@ public class LinkFactoryImpl extends LinkFactory { typeElement, m_writer.htmlIds.forPreviewSection(target).name(), m_writer.contents.previewMark, - false, false))); + null, false))); } return link; } @@ -172,7 +172,7 @@ public class LinkFactoryImpl extends LinkFactory { if (many) { links.add(","); links.add(Entity.ZERO_WIDTH_SPACE); - if (((LinkInfoImpl) linkInfo).getContext() == LinkInfoImpl.Kind.MEMBER_TYPE_PARAMS) { + if (((HtmlLinkInfo) linkInfo).getContext() == HtmlLinkInfo.Kind.MEMBER_TYPE_PARAMS) { links.add(DocletConstants.NL); } } @@ -192,8 +192,8 @@ public class LinkFactoryImpl extends LinkFactory { * @return the link */ protected Content getTypeParameterLink(LinkInfo linkInfo, TypeMirror typeParam) { - LinkInfoImpl typeLinkInfo = new LinkInfoImpl(m_writer.configuration, - ((LinkInfoImpl) linkInfo).getContext(), typeParam).skipPreview(true); + HtmlLinkInfo typeLinkInfo = new HtmlLinkInfo(m_writer.configuration, + ((HtmlLinkInfo) linkInfo).getContext(), typeParam).skipPreview(true); typeLinkInfo.excludeTypeBounds = linkInfo.excludeTypeBounds; typeLinkInfo.excludeTypeParameterLinks = linkInfo.excludeTypeParameterLinks; typeLinkInfo.linkToSelf = linkInfo.linkToSelf; @@ -209,7 +209,7 @@ public class LinkFactoryImpl extends LinkFactory { } else if (utils.isTypeVariable(linkInfo.type)) { // TODO: use the context for now, and special case for Receiver_Types, // which takes the default case. - switch (((LinkInfoImpl)linkInfo).context) { + switch (((HtmlLinkInfo)linkInfo).context) { case MEMBER_TYPE_PARAMS: case EXECUTABLE_MEMBER_PARAM: case CLASS_SIGNATURE: @@ -271,7 +271,7 @@ public class LinkFactoryImpl extends LinkFactory { * * @param linkInfo the information about the link. */ - private DocPath getPath(LinkInfoImpl linkInfo) { + private DocPath getPath(HtmlLinkInfo linkInfo) { return m_writer.pathToRoot.resolve(docPaths.forClass(linkInfo.typeElement)); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkInfoImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkInfo.java similarity index 92% rename from src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkInfoImpl.java rename to src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkInfo.java index fe512d80c88..91f264f2b0c 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/LinkInfoImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkInfo.java @@ -31,6 +31,7 @@ import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; +import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; import jdk.javadoc.internal.doclets.toolkit.Content; import jdk.javadoc.internal.doclets.toolkit.util.Utils; @@ -43,7 +44,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.links.LinkInfo; * This code and its internal interfaces are subject to change or * deletion without notice. */ -public class LinkInfoImpl extends LinkInfo { +public class HtmlLinkInfo extends LinkInfo { public enum Kind { DEFAULT, @@ -241,6 +242,11 @@ public class LinkInfoImpl extends LinkInfo { */ public Element targetMember; + /** + * Optional style for the link. + */ + public HtmlStyle style = null; + public final Utils utils; /** @@ -250,7 +256,7 @@ public class LinkInfoImpl extends LinkInfo { * @param context the context of the link. * @param ee the member to link to. */ - public LinkInfoImpl(HtmlConfiguration configuration, Kind context, ExecutableElement ee) { + public HtmlLinkInfo(HtmlConfiguration configuration, Kind context, ExecutableElement ee) { this.configuration = configuration; this.utils = configuration.utils; this.executableElement = ee; @@ -269,7 +275,7 @@ public class LinkInfoImpl extends LinkInfo { * @param context the context of the link. * @param typeElement the class to link to. */ - public LinkInfoImpl(HtmlConfiguration configuration, Kind context, TypeElement typeElement) { + public HtmlLinkInfo(HtmlConfiguration configuration, Kind context, TypeElement typeElement) { this.configuration = configuration; this.utils = configuration.utils; this.typeElement = typeElement; @@ -283,7 +289,7 @@ public class LinkInfoImpl extends LinkInfo { * @param context the context of the link. * @param type the class to link to. */ - public LinkInfoImpl(HtmlConfiguration configuration, Kind context, TypeMirror type) { + public HtmlLinkInfo(HtmlConfiguration configuration, Kind context, TypeMirror type) { this.configuration = configuration; this.utils = configuration.utils; this.type = type; @@ -294,7 +300,7 @@ public class LinkInfoImpl extends LinkInfo { * Set the label for the link. * @param label plain-text label for the link */ - public LinkInfoImpl label(CharSequence label) { + public HtmlLinkInfo label(CharSequence label) { this.label = new StringContent(label); return this; } @@ -302,23 +308,23 @@ public class LinkInfoImpl extends LinkInfo { /** * Set the label for the link. */ - public LinkInfoImpl label(Content label) { + public HtmlLinkInfo label(Content label) { this.label = label; return this; } /** - * Set whether or not the link should be strong. + * Sets the style to be used for the link. */ - public LinkInfoImpl strong(boolean strong) { - this.isStrong = strong; + public HtmlLinkInfo style(HtmlStyle style) { + this.style = style; return this; } /** * Set whether or not this is a link to a varargs parameter. */ - public LinkInfoImpl varargs(boolean varargs) { + public HtmlLinkInfo varargs(boolean varargs) { this.isVarArg = varargs; return this; } @@ -326,7 +332,7 @@ public class LinkInfoImpl extends LinkInfo { /** * Set the fragment specifier for the link. */ - public LinkInfoImpl where(String where) { + public HtmlLinkInfo where(String where) { this.where = where; return this; } @@ -334,7 +340,7 @@ public class LinkInfoImpl extends LinkInfo { /** * Set the member this link points to (if any). */ - public LinkInfoImpl targetMember(Element el) { + public HtmlLinkInfo targetMember(Element el) { this.targetMember = el; return this; } @@ -342,7 +348,7 @@ public class LinkInfoImpl extends LinkInfo { /** * Set whether or not the preview flags should be skipped for this link. */ - public LinkInfoImpl skipPreview(boolean skipPreview) { + public HtmlLinkInfo skipPreview(boolean skipPreview) { this.skipPreview = skipPreview; return this; } @@ -430,9 +436,10 @@ public class LinkInfoImpl extends LinkInfo { @Override public String toString() { - return "LinkInfoImpl{" + + return "HtmlLinkInfo{" + "context=" + context + ", where=" + where + + ", style=" + style + super.toString() + '}'; } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java index 039b3d45550..242b23d08dd 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlSerialFieldWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2021, 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 @@ -34,7 +34,6 @@ import javax.lang.model.type.TypeMirror; import com.sun.source.doctree.DocTree; import com.sun.source.doctree.SerialTree; -import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.TagName; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; @@ -42,7 +41,6 @@ import jdk.javadoc.internal.doclets.formats.html.markup.RawHtml; import jdk.javadoc.internal.doclets.formats.html.markup.StringContent; import jdk.javadoc.internal.doclets.toolkit.Content; import jdk.javadoc.internal.doclets.toolkit.SerializedFormWriter; -import jdk.javadoc.internal.doclets.toolkit.taglets.TagletWriter; import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper; /** @@ -121,8 +119,8 @@ public class HtmlSerialFieldWriter extends FieldWriterImpl if (fieldType == null) { pre.add(fieldTypeStr); } else { - Content fieldContent = writer.getLink(new LinkInfoImpl( - configuration, LinkInfoImpl.Kind.SERIAL_MEMBER, fieldType)); + Content fieldContent = writer.getLink(new HtmlLinkInfo( + configuration, HtmlLinkInfo.Kind.SERIAL_MEMBER, fieldType)); pre.add(fieldContent); } pre.add(fieldDimensions + " "); @@ -136,8 +134,8 @@ public class HtmlSerialFieldWriter extends FieldWriterImpl Content heading = HtmlTree.HEADING(TagName.H5, nameContent); contentTree.add(heading); Content pre = new HtmlTree(TagName.PRE); - Content fieldContent = writer.getLink(new LinkInfoImpl( - configuration, LinkInfoImpl.Kind.SERIAL_MEMBER, fieldType)); + Content fieldContent = writer.getLink(new HtmlLinkInfo( + configuration, HtmlLinkInfo.Kind.SERIAL_MEMBER, fieldType)); pre.add(fieldContent); pre.add(" "); pre.add(fieldName); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java index 35103b38115..f88c74c1af8 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexWriter.java @@ -214,8 +214,8 @@ public class IndexWriter extends HtmlDocletWriter { case RECORD: case ANNOTATION_TYPE: case INTERFACE: - dt = HtmlTree.DT(getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.INDEX, (TypeElement) element).strong(true))); + dt = HtmlTree.DT(getLink(new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.INDEX, (TypeElement) element).style(HtmlStyle.typeNameLink))); dt.add(" - "); addClassInfo((TypeElement) element, dt); break; @@ -225,9 +225,8 @@ public class IndexWriter extends HtmlDocletWriter { case FIELD: case ENUM_CONSTANT: TypeElement containingType = item.getContainingTypeElement(); - dt = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.memberNameLink, - getDocLink(LinkInfoImpl.Kind.INDEX, containingType, element, - new StringContent(label), false))); + dt = HtmlTree.DT(getDocLink(HtmlLinkInfo.Kind.INDEX, containingType, element, + label, HtmlStyle.memberNameLink)); dt.add(" - "); addMemberDesc(element, containingType, dt); break; @@ -269,7 +268,7 @@ public class IndexWriter extends HtmlDocletWriter { String itemPath = pathToRoot.isEmpty() ? "" : pathToRoot.getPath() + "/"; itemPath += item.getUrl(); HtmlTree labelLink = HtmlTree.A(itemPath, new StringContent(item.getLabel())); - Content dt = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.searchTagLink, labelLink)); + Content dt = HtmlTree.DT(labelLink.setStyle(HtmlStyle.searchTagLink)); dt.add(" - "); dt.add(contents.getContent("doclet.Search_tag_in", item.getHolder())); dlTree.add(dt); @@ -339,8 +338,8 @@ public class IndexWriter extends HtmlDocletWriter { default -> throw new IllegalArgumentException(member.getKind().toString()); }; contentTree.add(contents.getContent(resource, kindName)).add(" "); - addPreQualifiedClassLink(LinkInfoImpl.Kind.INDEX, enclosing, - false, contentTree); + addPreQualifiedClassLink(HtmlLinkInfo.Kind.INDEX, enclosing, + null, contentTree); } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java index 0baee37c51d..5ef2a15e554 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java @@ -150,7 +150,7 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter writer.addInlineComment(method, methodDocTree); } else { Content link = - writer.getDocLink(LinkInfoImpl.Kind.EXECUTABLE_ELEMENT_COPY, + writer.getDocLink(HtmlLinkInfo.Kind.EXECUTABLE_ELEMENT_COPY, holder, method, utils.isIncluded(holder) ? utils.getSimpleName(holder) @@ -213,7 +213,7 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter @Override public void addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree) { Content classLink = writer.getPreQualifiedClassLink( - LinkInfoImpl.Kind.MEMBER, typeElement); + HtmlLinkInfo.Kind.MEMBER, typeElement); Content label; if (options.summarizeOverriddenMethods()) { label = new StringContent(utils.isClass(typeElement) @@ -269,22 +269,22 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter if (method != null) { Contents contents = writer.contents; Content label; - LinkInfoImpl.Kind context; + HtmlLinkInfo.Kind context; if (utils.isAbstract(holder) && utils.isAbstract(method)){ //Abstract method is implemented from abstract class, //not overridden label = contents.specifiedByLabel; - context = LinkInfoImpl.Kind.METHOD_SPECIFIED_BY; + context = HtmlLinkInfo.Kind.METHOD_SPECIFIED_BY; } else { label = contents.overridesLabel; - context = LinkInfoImpl.Kind.METHOD_OVERRIDES; + context = HtmlLinkInfo.Kind.METHOD_OVERRIDES; } dl.add(HtmlTree.DT(label)); Content overriddenTypeLink = - writer.getLink(new LinkInfoImpl(writer.configuration, context, overriddenType)); + writer.getLink(new HtmlLinkInfo(writer.configuration, context, overriddenType)); Content codeOverriddenTypeLink = HtmlTree.CODE(overriddenTypeLink); Content methlink = writer.getLink( - new LinkInfoImpl(writer.configuration, LinkInfoImpl.Kind.MEMBER, holder) + new HtmlLinkInfo(writer.configuration, HtmlLinkInfo.Kind.MEMBER, holder) .where(writer.htmlIds.forMember(method).name()) .label(method.getSimpleName())); Content codeMethLink = HtmlTree.CODE(methlink); @@ -321,12 +321,12 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter for (ExecutableElement implementedMeth : implementedMethods) { TypeMirror intfac = vmt.getImplementedMethodHolder(method, implementedMeth); intfac = utils.getDeclaredType(utils.getEnclosingTypeElement(method), intfac); - Content intfaclink = writer.getLink(new LinkInfoImpl( - writer.configuration, LinkInfoImpl.Kind.METHOD_SPECIFIED_BY, intfac)); + Content intfaclink = writer.getLink(new HtmlLinkInfo( + writer.configuration, HtmlLinkInfo.Kind.METHOD_SPECIFIED_BY, intfac)); Content codeIntfacLink = HtmlTree.CODE(intfaclink); dl.add(HtmlTree.DT(contents.specifiedByLabel)); Content methlink = writer.getDocLink( - LinkInfoImpl.Kind.MEMBER, implementedMeth, + HtmlLinkInfo.Kind.MEMBER, implementedMeth, implementedMeth.getSimpleName()); Content codeMethLink = HtmlTree.CODE(methlink); Content dd = HtmlTree.DD(codeMethLink); @@ -347,7 +347,7 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter protected Content getReturnType(ExecutableElement method) { TypeMirror type = utils.getReturnType(typeElement, method); if (type != null) { - return writer.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.RETURN_TYPE, type)); + return writer.getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.RETURN_TYPE, type)); } return new ContentBuilder(); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java index 1ce1933e322..9a1f464277d 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java @@ -726,7 +726,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW if (!displayServiceDirective(t, usesTrees)) { continue; } - typeLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, t)); + typeLinkContent = getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.PACKAGE, t)); Content summary = new ContentBuilder(); if (display(usesTrees)) { description = usesTrees.get(t); @@ -756,7 +756,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW continue; } implSet = entry.getValue(); - Content srvLinkContent = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, srv)); + Content srvLinkContent = getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.PACKAGE, srv)); Content desc = new ContentBuilder(); if (display(providesTrees)) { description = providesTrees.get(srv); @@ -776,7 +776,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW String sep = ""; for (TypeElement impl : implSet) { desc.add(sep); - desc.add(getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.PACKAGE, impl))); + desc.add(getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.PACKAGE, impl))); sep = ", "; } desc.add(")"); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NestedClassWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NestedClassWriterImpl.java index 7a8545e7e7f..0d7b09884f8 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NestedClassWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/NestedClassWriterImpl.java @@ -101,7 +101,7 @@ public class NestedClassWriterImpl extends AbstractMemberWriter @Override public void addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree) { - Content classLink = writer.getPreQualifiedClassLink(LinkInfoImpl.Kind.MEMBER, typeElement); + Content classLink = writer.getPreQualifiedClassLink(HtmlLinkInfo.Kind.MEMBER, typeElement); Content label; if (options.summarizeOverriddenMethods()) { label = new StringContent(utils.isInterface(typeElement) @@ -120,10 +120,10 @@ public class NestedClassWriterImpl extends AbstractMemberWriter } @Override - protected void addSummaryLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element member, - Content tdSummary) { - Content memberLink = HtmlTree.SPAN(HtmlStyle.memberNameLink, - writer.getLink(new LinkInfoImpl(configuration, context, (TypeElement)member))); + protected void addSummaryLink(HtmlLinkInfo.Kind context, TypeElement typeElement, Element member, + Content tdSummary) { + Content memberLink = writer.getLink(new HtmlLinkInfo(configuration, context, (TypeElement)member) + .style(HtmlStyle.typeNameLink)); Content code = HtmlTree.CODE(memberLink); tdSummary.add(code); } @@ -131,7 +131,7 @@ public class NestedClassWriterImpl extends AbstractMemberWriter @Override protected void addInheritedSummaryLink(TypeElement typeElement, Element member, Content linksTree) { linksTree.add( - writer.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER, + writer.getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.MEMBER, (TypeElement)member))); } @@ -142,6 +142,6 @@ public class NestedClassWriterImpl extends AbstractMemberWriter @Override protected Content getSummaryLink(Element member) { - return writer.getQualifiedClassLink(LinkInfoImpl.Kind.MEMBER_DEPRECATED_PREVIEW, member); + return writer.getQualifiedClassLink(HtmlLinkInfo.Kind.MEMBER_DEPRECATED_PREVIEW, member); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java index 31e5bf5411b..2661d415c5e 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java @@ -213,8 +213,8 @@ public class PackageWriterImpl extends HtmlDocletWriter if (!utils.isCoreClass(klass) || !configuration.isGeneratedDoc(klass)) { continue; } - Content classLink = getLink(new LinkInfoImpl( - configuration, LinkInfoImpl.Kind.PACKAGE, klass)); + Content classLink = getLink(new HtmlLinkInfo( + configuration, HtmlLinkInfo.Kind.PACKAGE, klass)); ContentBuilder description = new ContentBuilder(); addPreviewSummary(klass, description); if (utils.isDeprecated(klass)) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java index 81711ce4a6d..490aaa2e5ea 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java @@ -112,7 +112,7 @@ public class PropertyWriterImpl extends AbstractMemberWriter writer.addInlineComment(property, propertyDocTree); } else { Content link = - writer.getDocLink(LinkInfoImpl.Kind.PROPERTY_COPY, + writer.getDocLink(HtmlLinkInfo.Kind.PROPERTY_COPY, holder, property, utils.isIncluded(holder) ? holder.getSimpleName() : holder.getQualifiedName()); @@ -167,7 +167,7 @@ public class PropertyWriterImpl extends AbstractMemberWriter @Override public void addInheritedSummaryLabel(TypeElement typeElement, Content inheritedTree) { Content classLink = writer.getPreQualifiedClassLink( - LinkInfoImpl.Kind.MEMBER, typeElement); + HtmlLinkInfo.Kind.MEMBER, typeElement); Content label; if (options.summarizeOverriddenMethods()) { label = new StringContent(utils.isClass(typeElement) @@ -187,13 +187,13 @@ public class PropertyWriterImpl extends AbstractMemberWriter } @Override - protected void addSummaryLink(LinkInfoImpl.Kind context, TypeElement typeElement, Element member, - Content tdSummary) { - Content memberLink = HtmlTree.SPAN(HtmlStyle.memberNameLink, - writer.getDocLink(context, typeElement, + protected void addSummaryLink(HtmlLinkInfo.Kind context, TypeElement typeElement, Element member, + Content tdSummary) { + Content memberLink = writer.getDocLink(context, typeElement, member, - utils.getPropertyLabel(name(member)), - true)); + new StringContent(utils.getPropertyLabel(name(member))), + HtmlStyle.memberNameLink, + true); Content code = HtmlTree.CODE(memberLink); tdSummary.add(code); @@ -202,7 +202,7 @@ public class PropertyWriterImpl extends AbstractMemberWriter @Override protected void addInheritedSummaryLink(TypeElement typeElement, Element member, Content linksTree) { String mname = name(member); - Content content = writer.getDocLink(LinkInfoImpl.Kind.MEMBER, typeElement, member, + Content content = writer.getDocLink(HtmlLinkInfo.Kind.MEMBER, typeElement, member, utils.isProperty(mname) ? utils.getPropertyName(mname) : mname, true); linksTree.add(content); } @@ -214,7 +214,7 @@ public class PropertyWriterImpl extends AbstractMemberWriter @Override protected Content getSummaryLink(Element member) { - return writer.getDocLink(LinkInfoImpl.Kind.MEMBER_DEPRECATED_PREVIEW, member, + return writer.getDocLink(HtmlLinkInfo.Kind.MEMBER_DEPRECATED_PREVIEW, member, utils.getFullyQualifiedName(member)); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java index a71b9957fc2..3efa600dd93 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java @@ -149,13 +149,13 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter @Override public Content getClassHeader(TypeElement typeElement) { Content classLink = (isVisibleClass(typeElement)) - ? getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.DEFAULT, typeElement) + ? getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.DEFAULT, typeElement) .label(configuration.getClassName(typeElement))) : new StringContent(utils.getFullyQualifiedName(typeElement)); Content section = HtmlTree.SECTION(HtmlStyle.serializedClassDetails) .setId(htmlIds.forClass(typeElement)); Content superClassLink = typeElement.getSuperclass() != null - ? getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.SERIALIZED_FORM, + ? getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.SERIALIZED_FORM, typeElement.getSuperclass())) : null; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java index 562f2910afd..0a51ec1e666 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java @@ -97,8 +97,8 @@ public class Signatures { } else { nameSpan.addStyle(HtmlStyle.typeNameLabel).add(className); } - LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.CLASS_SIGNATURE, typeElement); + HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.CLASS_SIGNATURE, typeElement); //Let's not link to ourselves in the signature. linkInfo.linkToSelf = false; nameSpan.add(classWriter.getTypeParameterLinks(linkInfo)); @@ -115,8 +115,8 @@ public class Signatures { if (superclass != null) { content.add(DocletConstants.NL); extendsImplements.add("extends "); - Content link = classWriter.getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME, + Content link = classWriter.getLink(new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.CLASS_SIGNATURE_PARENT_NAME, superclass)); extendsImplements.add(link); } @@ -136,8 +136,8 @@ public class Signatures { } else { extendsImplements.add(", "); } - Content link = classWriter.getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.CLASS_SIGNATURE_PARENT_NAME, + Content link = classWriter.getLink(new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.CLASS_SIGNATURE_PARENT_NAME, type)); extendsImplements.add(link); } @@ -166,8 +166,8 @@ public class Signatures { } else { permitsSpan.add(", "); } - Content link = classWriter.getLink(new LinkInfoImpl(configuration, - LinkInfoImpl.Kind.PERMITTED_SUBCLASSES, + Content link = classWriter.getLink(new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.PERMITTED_SUBCLASSES, type)); permitsSpan.add(link); } @@ -190,7 +190,7 @@ public class Signatures { content.add(sep); classWriter.getAnnotations(e.getAnnotationMirrors(), false) .forEach(a -> { content.add(a).add(" "); }); - Content link = classWriter.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.RECORD_COMPONENT, + Content link = classWriter.getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.RECORD_COMPONENT, e.asType())); content.add(link); content.add(Entity.NO_BREAK_SPACE); @@ -265,7 +265,7 @@ public class Signatures { * @return this instance */ MemberSignature setType(TypeMirror type) { - this.returnType = memberWriter.writer.getLink(new LinkInfoImpl(memberWriter.configuration, LinkInfoImpl.Kind.MEMBER, type)); + this.returnType = memberWriter.writer.getLink(new HtmlLinkInfo(memberWriter.configuration, HtmlLinkInfo.Kind.MEMBER, type)); return this; } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java index 1d40e0ecbc4..5cf33b429ca 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/TagletWriterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -319,14 +319,14 @@ public class TagletWriterImpl extends TagletWriter { Element exception = ch.getException(throwsTag); Content excName; if (substituteType != null) { - excName = htmlWriter.getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER, + excName = htmlWriter.getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.MEMBER, substituteType)); } else if (exception == null) { excName = new RawHtml(ch.getExceptionName(throwsTag).toString()); } else if (exception.asType() == null) { excName = new RawHtml(utils.getFullyQualifiedName(exception)); } else { - LinkInfoImpl link = new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER, + HtmlLinkInfo link = new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.MEMBER, exception.asType()); link.excludeTypeBounds = true; excName = htmlWriter.getLink(link); @@ -345,14 +345,14 @@ public class TagletWriterImpl extends TagletWriter { @Override public Content throwsTagOutput(TypeMirror throwsType) { HtmlTree result = HtmlTree.DD(HtmlTree.CODE(htmlWriter.getLink( - new LinkInfoImpl(configuration, LinkInfoImpl.Kind.MEMBER, throwsType)))); + new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.MEMBER, throwsType)))); return result; } @Override public Content valueTagOutput(VariableElement field, String constantVal, boolean includeLink) { return includeLink - ? htmlWriter.getDocLink(LinkInfoImpl.Kind.VALUE_TAG, field, constantVal) + ? htmlWriter.getDocLink(HtmlLinkInfo.Kind.VALUE_TAG, field, constantVal) : new StringContent(constantVal); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java index 354f37b819c..52b0000b75c 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Links.java @@ -85,7 +85,7 @@ public class Links { * @return a content tree for the link */ public Content createLink(DocPath path, String label) { - return createLink(path, new StringContent(label), false, ""); + return createLink(path, new StringContent(label), null, ""); } /** @@ -101,17 +101,16 @@ public class Links { /** * Creates a link of the form {@code label}. - * If {@code strong} is set, the label will be wrapped in - * {@code ...}. + * If {@code style} is not null, it will be added as {@code class="style"} to the link. * * @param path the path for the link * @param label the content for the link - * @param strong whether to wrap the {@code label} in a SPAN element + * @param style the style for the link, or null * @param title the title for the link * @return a content tree for the link */ - public Content createLink(DocPath path, Content label, boolean strong, String title) { - return createLink(new DocLink(path), label, strong, title); + public Content createLink(DocPath path, Content label, HtmlStyle style, String title) { + return createLink(new DocLink(path), label, style, title); } /** @@ -155,44 +154,42 @@ public class Links { /** * Creates a link of the form {@code label}. - * If {@code strong} is set, the label will be wrapped in - * {@code ...}. + * If {@code style} is not null, it will be added as {@code class="style"} to the link. * * @param link the details for the link * @param label the content for the link - * @param strong whether to wrap the {@code label} in a SPAN element + * @param style the style for the link, or null * @param title the title for the link * @return a content tree for the link */ - public Content createLink(DocLink link, Content label, boolean strong, + public Content createLink(DocLink link, Content label, HtmlStyle style, String title) { - return createLink(link, label, strong, title, false); + return createLink(link, label, style, title, false); } /** * Creates a link of the form {@code label}. - * If {@code strong} is set, the label will be wrapped in - * {@code ...}. + * If {@code style} is not null, it will be added as {@code class="style"} to the link. * * @param link the details for the link * @param label the content for the link - * @param strong whether to wrap the {@code label} in a SPAN element + * @param style the style for the link, or null * @param title the title for the link * @param isExternal is the link external to the generated documentation * @return a content tree for the link */ - public Content createLink(DocLink link, Content label, boolean strong, + public Content createLink(DocLink link, Content label, HtmlStyle style, String title, boolean isExternal) { - Content body = label; - if (strong) { - body = HtmlTree.SPAN(HtmlStyle.typeNameLink, body); + HtmlTree l = HtmlTree.A(link.relativizeAgainst(file).toString(), label); + if (style != null) { + l.setStyle(style); } - HtmlTree l = HtmlTree.A(link.relativizeAgainst(file).toString(), body); if (title != null && title.length() != 0) { l.put(HtmlAttr.TITLE, title); } if (isExternal) { - l.setStyle(HtmlStyle.externalLink); + // Use addStyle as external links might have an explicit style set above as well. + l.addStyle(HtmlStyle.externalLink); } return l; } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/links/LinkInfo.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/links/LinkInfo.java index 5810f0d6c06..1907ad426d1 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/links/LinkInfo.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/links/LinkInfo.java @@ -69,11 +69,6 @@ public abstract class LinkInfo { */ public Content label; - /** - * True if the link should be strong. - */ - public boolean isStrong = false; - /** * True if we should exclude the type bounds for the type parameter. */ @@ -146,7 +141,6 @@ public abstract class LinkInfo { ", type=" + type + ", isVarArg=" + isVarArg + ", label=" + label + - ", isStrong=" + isStrong + ", excludeTypeBounds=" + excludeTypeBounds + ", excludeTypeParameterLinks=" + excludeTypeParameterLinks + ", linkToSelf=" + linkToSelf + '}'; diff --git a/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java b/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java index 22758a4f55e..7bcc787e641 100644 --- a/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java +++ b/test/langtools/jdk/javadoc/doclet/testAnchorNames/TestAnchorNames.java @@ -92,86 +92,86 @@ public class TestAnchorNames extends JavadocTester { // Test some fields checkOutput("pkg1/RegClass.html", true, "

", - "", + "", "
", - "", + "", "
", - "", + "", """
""", - "", + "", """
""", - "", + "", """
""", - "", + "", """
""", - ""); + ""); checkOutput("pkg1/DeprMemClass.html", true, """
""", - ""); + ""); // Test constructor checkOutput("pkg1/RegClass.html", true, """
""", """ - """); + """); // Test some methods checkOutput("pkg1/RegClass.html", true, """
""", """ - """, + """, """
""", - "", + "", """
""", - "", + "", """
""", """ - """, + """, """
""", """ - """, + """, """
""", """ - """, + """, """
""", """ - """); + """); checkOutput("pkg1/DeprMemClass.html", true, """
""", - ""); + ""); // Test enum checkOutput("pkg1/RegClass.Te$t_Enum.html", true, """
""", - ""); + ""); // Test nested class checkOutput("pkg1/RegClass._NestedClas$.html", true, """
""", - ""); + ""); // Test class use page checkOutput("pkg1/class-use/DeprMemClass.html", true, """ - """); + """); // Test deprecated list page checkOutput("deprecated-list.html", true, diff --git a/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java b/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java index 056a235287a..313bfc650b8 100644 --- a/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java +++ b/test/langtools/jdk/javadoc/doclet/testAnnotationTypes/TestAnnotationTypes.java @@ -60,8 +60,8 @@ public class TestAnnotationTypes extends JavadocTester { "", "

Field Summary

", """ -
""", + """, "", """
diff --git a/test/langtools/jdk/javadoc/doclet/testClassLinks/TestClassLinks.java b/test/langtools/jdk/javadoc/doclet/testClassLinks/TestClassLinks.java index a18cf462292..6a608b8c286 100644 --- a/test/langtools/jdk/javadoc/doclet/testClassLinks/TestClassLinks.java +++ b/test/langtools/jdk/javadoc/doclet/testClassLinks/TestClassLinks.java @@ -56,13 +56,13 @@ public class TestClassLinks extends JavadocTester { """ C2""", """ - C1()"""); + C1()"""); checkOutput("p/C2.html", true, """ C3""", """ - C2()"""); + C2()"""); checkOutput("p/C3.html", true, """ @@ -72,7 +72,7 @@ public class TestClassLinks extends JavadocTester { /a><T>, IT2<\ java.lang.String>""", """ - C3()"""); + C3()"""); checkOutput("p/I1.html", true, """ diff --git a/test/langtools/jdk/javadoc/doclet/testClassTree/TestClassTree.java b/test/langtools/jdk/javadoc/doclet/testClassTree/TestClassTree.java index 36a6b83c17d..75ddd5db0af 100644 --- a/test/langtools/jdk/javadoc/doclet/testClassTree/TestClassTree.java +++ b/test/langtools/jdk/javadoc/doclet/testClassTree/TestClassTree.java @@ -54,14 +54,14 @@ public class TestClassTree extends JavadocTester { checkOutput("pkg/package-tree.html", true, """
    -
  • pkg.ParentClass""", +
  • pkg.ParentClass""", """

    Annotation Interface Hierarchy

    """, """

    Enum Class Hierarchy

    @@ -71,7 +71,8 @@ public class TestClassTree extends JavadocTester {
  • java.lang.Enum<E> (implements java.lang.Comparable<T\ >, java.lang.constant.Constable, java.io.Serializable)
@@ -80,7 +81,7 @@ public class TestClassTree extends JavadocTester { checkOutput("pkg/package-tree.html", false, """ -
  • class pkg.ParentClass
  • """); +
  • class pkg.ParentClass
  • """); } } diff --git a/test/langtools/jdk/javadoc/doclet/testConstructors/TestConstructors.java b/test/langtools/jdk/javadoc/doclet/testConstructors/TestConstructors.java index c6f6361e7aa..10cbc8bbead 100644 --- a/test/langtools/jdk/javadoc/doclet/testConstructors/TestConstructors.java +++ b/test/langtools/jdk/javadoc/doclet/testConstructors/TestConstructors.java @@ -61,31 +61,31 @@ public class TestConstructors extends JavadocTester { "#%3Cinit%3E(int)">Outer(int), NestedInner(int)""", """ - Outer()""", + Outer()""", """
    """, """ - Outer​(int i)""", + Outer​(int i)""", """
    """); checkOutput("pkg1/Outer.Inner.html", true, """ - Inner()""", + Inner()""", """
    """, """ - Inner​(int i)""", + Inner​(int i)""", """
    """); checkOutput("pkg1/Outer.Inner.NestedInner.html", true, """ - NestedInner()""", + NestedInner()""", """
    """, """ - NestedInner​(int i)""", + NestedInner​(int i)""", """
    """); diff --git a/test/langtools/jdk/javadoc/doclet/testEnumConstructor/TestEnumConstructor.java b/test/langtools/jdk/javadoc/doclet/testEnumConstructor/TestEnumConstructor.java index 4b02acb766a..4012ee4bbdf 100644 --- a/test/langtools/jdk/javadoc/doclet/testEnumConstructor/TestEnumConstructor.java +++ b/test/langtools/jdk/javadoc/doclet/testEnumConstructor/TestEnumConstructor.java @@ -68,10 +68,10 @@ public class TestEnumConstructor extends JavadocTester { "Constructor Summary", "Modifier", "Constructor", "private", """ - TestEnum​(int val)"""); + TestEnum​(int val)"""); checkOutput("index-all.html", true, """ - TestEnum(int)"""); + TestEnum(int)"""); } diff --git a/test/langtools/jdk/javadoc/doclet/testHtmlTableTags/TestHtmlTableTags.java b/test/langtools/jdk/javadoc/doclet/testHtmlTableTags/TestHtmlTableTags.java index 0bfb75659cf..ee920a85ddb 100644 --- a/test/langtools/jdk/javadoc/doclet/testHtmlTableTags/TestHtmlTableTags.java +++ b/test/langtools/jdk/javadoc/doclet/testHtmlTableTags/TestHtmlTableTags.java @@ -572,7 +572,7 @@ public class TestHtmlTableTags extends JavadocTester { checkOutput("pkg1/C1.html", true, """ - +
    Test field for class.
    """, @@ -580,8 +580,8 @@ public class TestHtmlTableTags extends JavadocTester {
    void
    method1​(int a, + tab2 method-summary-table-tab4">method1​(int a, int b)
    @@ -591,7 +591,7 @@ public class TestHtmlTableTags extends JavadocTester { checkOutput("pkg2/C2.html", true, """ - +
    A test field.
    """, @@ -600,8 +600,8 @@ public class TestHtmlTableTags extends JavadocTester { ab2 method-summary-table-tab4">C1
    method​(method​(C1 param)
    @@ -610,15 +610,15 @@ public class TestHtmlTableTags extends JavadocTester { checkOutput("pkg2/C2.ModalExclusionType.html", true, """ - +
    Test comment.
    """); checkOutput("pkg2/C3.html", true, """ - +
    Comment.
    """); @@ -626,7 +626,7 @@ public class TestHtmlTableTags extends JavadocTester { checkOutput("pkg2/C4.html", true, """
    boolean
    - +
     
    """); @@ -642,16 +642,15 @@ public class TestHtmlTableTags extends JavadocTester { """
    C1.<\ - code>field\ -
    + code>field
    Test field for class.
    """, """
    C1.<\ - code>method​(C2 \ + code>metho\ + d​(C2 \ ;param)
    Method thats does some processing.
    @@ -726,14 +725,14 @@ public class TestHtmlTableTags extends JavadocTester { checkOutput("pkg1/C1.html", true, """ - +
    """, """
    void
    method1​(int a, + tab2 method-summary-table-tab4">method1​(int a, int b)
    """); @@ -741,34 +740,36 @@ public class TestHtmlTableTags extends JavadocTester { checkOutput("pkg2/C2.html", true, """ - +
    """, """
    method​(C1 param)
    + tab2 method-summary-table-tab4">method​(C1 param)
    """); checkOutput("pkg2/C2.ModalExclusionType.html", true, """ -
    +
    """); checkOutput("pkg2/C3.html", true, """ - +
    """); checkOutput("pkg2/C4.html", true, """
    boolean
    - +
    """); @@ -782,15 +783,14 @@ public class TestHtmlTableTags extends JavadocTester { """
    C1.<\ - code>field\ -
    + code>field
    """, """
    C1.<\ - code>method​(C2 \ - ;param)
    + code>metho\ + d​(C2 param)
    """); // Package use documentation diff --git a/test/langtools/jdk/javadoc/doclet/testIndex/TestIndex.java b/test/langtools/jdk/javadoc/doclet/testIndex/TestIndex.java index 60da53d2fd4..c2c789382be 100644 --- a/test/langtools/jdk/javadoc/doclet/testIndex/TestIndex.java +++ b/test/langtools/jdk/javadoc/doclet/testIndex/TestIndex.java @@ -52,31 +52,30 @@ public class TestIndex extends JavadocTester { //Test index-all.html checkOutput("index-all.html", true, """ - C<\ - /a> - Class in pkg""", + C - Class i\ + n pkg""", """ - Interface - Interface in pkg""", + Int\ + erface - Interface in pkg""", """ - AnnotationType - Annotation Interface in pkg""", + AnnotationType - Annotation Interface in pkg""", """ - Coin - Enum Class in pkg""", + Coin - Enum Class in pkg""", """ Class in <Unnamed>""", """
    -
    Java - S\ - tatic variable in class pkg.C
    +
    Java - Static variabl\ + e in class pkg.C
     
    -
    JDK - Sta\ - tic variable in class pkg.C
    +
    JDK - Static variable \ + in class pkg.C
     
    """, """ -
    Enum - Search tag in enum class pkg.Coin
    """); +
    Enum - Search tag in enum class pkg.Coin
    """); } } diff --git a/test/langtools/jdk/javadoc/doclet/testIndexInPackageFiles/TestIndexInPackageFiles.java b/test/langtools/jdk/javadoc/doclet/testIndexInPackageFiles/TestIndexInPackageFiles.java index 02b510d310e..d400c310203 100644 --- a/test/langtools/jdk/javadoc/doclet/testIndexInPackageFiles/TestIndexInPackageFiles.java +++ b/test/langtools/jdk/javadoc/doclet/testIndexInPackageFiles/TestIndexInPackageFiles.java @@ -112,15 +112,15 @@ public class TestIndexInPackageFiles extends JavadocTester { checkOutput("index-all.html", true, """ - test.name.1""", + test.name.1""", """ - test.name.2""", + test.name.2""", """ - test.name.3 - Search tag in Overview""", + test.name.3 - Search tag in Overview""", """ - test.property.1""", + test.property.1""", """ - test.property.2"""); + test.property.2"""); } } diff --git a/test/langtools/jdk/javadoc/doclet/testInterface/TestInterface.java b/test/langtools/jdk/javadoc/doclet/testInterface/TestInterface.java index 0e0e160fb19..99344a8a69c 100644 --- a/test/langtools/jdk/javadoc/doclet/testInterface/TestInterface.java +++ b/test/langtools/jdk/javadoc/doclet/testInterface/TestInterface.java @@ -136,8 +136,8 @@ public class TestInterface extends JavadocTester {
    static void
    m()
    + tab1 method-summary-table-tab4">m<\ + /a>()
    A hider method
    diff --git a/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java b/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java index 0d1a45feef4..f9f2e9fa765 100644 --- a/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java +++ b/test/langtools/jdk/javadoc/doclet/testJavaFX/TestJavaFX.java @@ -78,8 +78,10 @@ public class TestJavaFX extends JavadocTester {
    Property description:
    """, """ -
    - + +
    Defines the direction/speed at which the Timeline is expected to be played.
    """, @@ -90,11 +92,11 @@ public class TestJavaFX extends JavadocTester { "
    Property description:
    ", """ """, + tab2 method-summary-table-tab4">setTestMethodProperty()
    """, """ - +
    Defines if paused.
    """, """ @@ -320,32 +322,32 @@ public class TestJavaFX extends JavadocTester {
    <T> java.lang.Object
    alphaProperty​(java.util.List<T>\ -  foo)
    + tab2 method-summary-table-tab4">alphaProperty​(java.util.List<T> fo\ + o)
     
    java.lang.Object
    + ab2 method-summary-table-tab4">betaProperty()
     
    java.util.List<java.util.Set<? super java.\ - lang.Object>>
    + ab2 method-summary-table-tab4">java.util.List<java.util.Set<? super \ + java.lang.Object>> + tab2 method-summary-table-tab4">deltaProperty()
     
    java.util.List<java.lang.String> + b2 method-summary-table-tab4">java.util.List<java.lang.String>
    + ab2 method-summary-table-tab4">gammaProperty()
     
    """ ); diff --git a/test/langtools/jdk/javadoc/doclet/testLinksWithNoDeprecatedOption/TestLinksWithNoDeprecatedOption.java b/test/langtools/jdk/javadoc/doclet/testLinksWithNoDeprecatedOption/TestLinksWithNoDeprecatedOption.java index c8a003f87b2..dbc36a3231a 100644 --- a/test/langtools/jdk/javadoc/doclet/testLinksWithNoDeprecatedOption/TestLinksWithNoDeprecatedOption.java +++ b/test/langtools/jdk/javadoc/doclet/testLinksWithNoDeprecatedOption/TestLinksWithNoDeprecatedOption.java @@ -74,20 +74,20 @@ public class TestLinksWithNoDeprecatedOption extends JavadocTester { checkOutput("pkg/class-use/A.html", true, """ - a2"""); + a2"""); //links for deprecated items will not be found checkOutput("pkg/class-use/A.html", false, """ - deprecatedField"""); + deprecatedField"""); checkOutput("pkg/class-use/A.html", false, """ - deprecatedMethod"""); + deprecatedMethod"""); checkOutput("pkg/class-use/A.html",false, """ - B"""); + B"""); } diff --git a/test/langtools/jdk/javadoc/doclet/testMemberInheritance/TestMemberInheritance.java b/test/langtools/jdk/javadoc/doclet/testMemberInheritance/TestMemberInheritance.java index 6c4a750da59..23b5657b7a5 100644 --- a/test/langtools/jdk/javadoc/doclet/testMemberInheritance/TestMemberInheritance.java +++ b/test/langtools/jdk/javadoc/doclet/testMemberInheritance/TestMemberInheritance.java @@ -105,9 +105,9 @@ public class TestMemberInheritance extends JavadocTester {
    static java.time.Period
    between​(java.time.\ - LocalDate startDateInclusive, + tab1 method-summary-table-tab4">between​(java.time.LocalDat\ + e startDateInclusive, java.time.LocalDate endDateExclusive)
    """); checkOutput("pkg1/Implementer.html", false, @@ -131,8 +131,8 @@ public class TestMemberInheritance extends JavadocTester {
    protected abstract java.lang.String
    parentMethod​(java.lang.String t)
    + method-summary-table-tab3">\ + parentMethod​(java.lang.String t)
    Returns some value with an inherited search tag.
    @@ -162,8 +162,8 @@ public class TestMemberInheritance extends JavadocTester { checkOutput("pkg2/DocumentedNonGenericChild.html", true, """
    java.lang.String
    - +
    A field.
    """, """ @@ -180,31 +180,29 @@ public class TestMemberInheritance extends JavadocTester {
    java.lang.String
    method​(java.lang.String t)
    """, + tab2 method-summary-table-tab4">method​(java.lang.String t)
    """, """

    method

    public java.lang.String method\ - ​(java.lang.String t)
    + lass="return-type">java.lang.String metho\ + d(java.lang.String t)
    """); checkOutput("index-all.html", true, """ -
    parentField - Variable in class pkg2.DocumentedNonGenericChild +
    parentField - Variable in class pkg2.DocumentedNonGenericChild
    A field.
    """, """ -
    parentMethod(String) - Method in class pkg2.DocumentedNonGeneric\ - Child
    +
    parentMethod(String) - Method in class pkg2.DocumentedNonGenericChild
    Returns some value with an inherited search tag.
    """); @@ -245,19 +243,17 @@ public class TestMemberInheritance extends JavadocTester { checkOutput("index-files/index-9.html", true, """ -
    parentField - Variable in class pkg2.DocumentedNonGenericChild\ -
    +
    parentField - Variable in class pkg2.DocumentedNonGenericChild
    A field.
    """, """ -
    parentMethod(String) - Method in class pkg2.DocumentedNonG\ - enericChild
    +
    parentMethod(String) - Method in class pkg2.DocumentedNonGenericChild
    Returns some value with an inherited search tag.
    """); diff --git a/test/langtools/jdk/javadoc/doclet/testMemberSummary/TestMemberSummary.java b/test/langtools/jdk/javadoc/doclet/testMemberSummary/TestMemberSummary.java index 5ffe3defae9..6b2848442d5 100644 --- a/test/langtools/jdk/javadoc/doclet/testMemberSummary/TestMemberSummary.java +++ b/test/langtools/jdk/javadoc/doclet/testMemberSummary/TestMemberSummary.java @@ -55,24 +55,23 @@ public class TestMemberSummary extends JavadocTester { """ PublicChild """, + tab2 method-summary-table-tab4">returnTypeTest()""", // Check return type in member detail. """ """, """ - +
     
    """); checkOutput("pkg/PrivateParent.html", true, """
    private
    -
    PrivateParent​(int i)"""); +
    PrivateParent​(int i)
    """); // Legacy anchor dimensions (6290760) checkOutput("pkg2/A.html", true, diff --git a/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java b/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java index da5868ff3bb..5c6b8c571e9 100644 --- a/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java +++ b/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java @@ -848,20 +848,20 @@ public class TestModules extends JavadocTester { """, """
    -
    search_word - Search tag in module moduleB
    +
    se\ + arch_word - Search tag in module moduleB
     
    -
    search phrase - Search tag in module moduleA
    +
    s\ + earch phrase - Search tag in module moduleA
    with description
    """); checkOutput("index-all.html", false, """ -
    search phrase - Search tag in module moduleA
    +
    s\ + earch phrase - Search tag in module moduleA
    with description
    -
    search phrase - Search tag in module moduleA
    +
    s\ + earch phrase - Search tag in module moduleA
    with description
    """); } diff --git a/test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java b/test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java index cef801499f1..8d93d467883 100644 --- a/test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java +++ b/test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java @@ -76,7 +76,7 @@ public class TestNewLanguageFeatures extends JavadocTester { "
    Enum Constants
    ", // Detail for enum constant """ - Dime""", + Dime""", // Automatically insert documentation for values() and valueOf(). "Returns an array containing the constants of this enum class,", "Returns the enum constant of this class with the specified name", @@ -142,14 +142,13 @@ public class TestNewLanguageFeatures extends JavadocTester { // Method that returns TypeParameters """
    E[]
    + ab2 method-summary-table-tab4">E[]
    methodThatReturnsTypeParameterA&#\ - 8203;(E[] e)""", - """ + tab2 method-summary-table-tab4">methodThatReturnsTypeParameterA​(E[] e)""", + """
    public E[] methodThatReturnsTypeParameterA\ @@ -158,12 +157,12 @@ public class TestNewLanguageFeatures extends JavadocTester { """, """
    <T extends java.lang.Object & java.lang.C\ - omparable<? super T>>
    T
    + ab2 method-summary-table-tab4"><T extends java.lang.Object & java.l\ + ang.Comparable<? super T>>
    T
    methodtThatReturnsTypeParamet\ - ersB​(java.util.Collection<? extends T> coll)""", + tab2 method-summary-table-tab4">methodtThatReturnsTypeParamete\ + rsB​(java.util.Collection<? extends T> coll)""", """
    Returns TypeParameters
    """, @@ -173,9 +172,9 @@ public class TestNewLanguageFeatures extends JavadocTester { b2 method-summary-table-tab4"><X extends java.lang.Throwable>
    E
    orElseThrow​(java.util.func\ - tion.Supplier<? extends X> exceptionSupplier)""" + ab2 method-summary-table-tab4">orElseThrow​(java.util.function.Supp\ + lier<? extends X> exceptionSupplier)""" ); checkOutput("pkg/Wildcards.html", true, @@ -248,18 +247,18 @@ public class TestNewLanguageFeatures extends JavadocTester { arameters of type Foo""", """ -
    ClassUseTest1<T extends Foo & Foo2>
    """, +
    ClassUseTest1<T extends Foo & Foo2>
    """, """ """, """ - """, +
    ClassUseTes\ + t1.method​(T t)
    """, """
    Fields in pkg2\ with type parameters of type Foo with type parameters of type Foo2
    """, """ -
    ClassUseTest1<T extends Foo & Foo2>
    """, +
    ClassUseTest1<T extends Foo & Foo2>
    """, """ """, """ -
    ClassUseTest1.<\ - /span>method​(T t)
    """ +
    ClassUseTes\ + t1.method​(T t)
    """ ); // ClassUseTest2: > @@ -308,18 +307,18 @@ public class TestNewLanguageFeatures extends JavadocTester { > with type parameters of type ParamTest
    """, """ -
    ClassUseTest2<T extends ParamTest<Foo3>>
    """, + """, """ """, """ -
    ClassUseTest2.<\ - /span>method​(T t)
    """, +
    ClassUseTes\ + t2.method​(T t)
    """, """
    Fields in pkg2\ declared as ParamTest with type parameters of type Foo\ 3
    """, """ -
    ClassUseTest2<T extends ParamTest<Foo3>>
    """, + """, """ """, """ -
    ClassUseTest2.<\ - /span>method​(T t)
    """, +
    ClassUseTes\ + t2.method​(T t)
    """, """ """, """ -
    ClassUseTest3<T extends ParamTest2<java.util.Li\ - st<? extends Foo4>>&g\ - t;
    """, +
    ClassUseTest3<T extends ParamTest2<java.util.List&\ + lt;? extends Foo4>>><\ + /code>
    """, """ """, """ -
    ClassUseTest3.<\ - /span>method​(T t)
    """, +
    ClassUseTes\ + t3.method​(T t)
    """, """
    <T extends ParamTest2<java.util.List<? extends with type parameters of type Foo\ 4
    """, """ -
    ClassUseTest3<T extends ParamTest2<java.util.Li\ - st<? extends Foo4>>&g\ - t;
    """, +
    ClassUseTest3<T extends ParamTest2<java.util.List&\ + lt;? extends Foo4>>><\ + /code>
    """, """ """, """ -
    ClassUseTest3.\ - method​(T t)
    """, +
    ClassUseTes\ + t3.method​(T t)
    """, """
    Description
    void
    -
    +
    ClassUseTes\ + t3.method​(java.util.Set<Foo4> p)
     
    """, """
    Constructor parameters in pkg2<\ @@ -452,7 +451,7 @@ public class TestNewLanguageFeatures extends JavadocTester { //================================= checkOutput("index-all.html", true, """ - method(Vector<Object>)""" + method(Vector<Object>)""" ); // TODO: duplicate of previous case; left in delibarately for now to simplify comparison testing @@ -461,7 +460,7 @@ public class TestNewLanguageFeatures extends JavadocTester { //================================= checkOutput("index-all.html", true, """ - method(Vector<Object>)""" + method(Vector<Object>)""" ); } diff --git a/test/langtools/jdk/javadoc/doclet/testOrdering/TestOrdering.java b/test/langtools/jdk/javadoc/doclet/testOrdering/TestOrdering.java index e77dac4fa30..465d33f42e9 100644 --- a/test/langtools/jdk/javadoc/doclet/testOrdering/TestOrdering.java +++ b/test/langtools/jdk/javadoc/doclet/testOrdering/TestOrdering.java @@ -397,78 +397,78 @@ public class TestOrdering extends JavadocTester { checkOrder("index-all.html", composeTestVectors()); checkOrder("add0/add/package-tree.html", """ - """, + """, """ - """); + """); checkOrder("overview-tree.html", """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """, + """, """ - """); + """); } void emitFile(String pkgname, String clsname, ListOrder order) throws IOException { @@ -557,18 +557,15 @@ public class TestOrdering extends JavadocTester { checkOrder("index-all.html", "something - package something", - "something - Class in", - "something - Enum Class in", - "something - Interface in", - "something - Annotation Interface in", - "something - Variable in class", - "something() - Constructor", - """ - something() - Method in class a. - Method in class a. - Method in class something. - Class in", + "something - Enum Class in", + "something - Interface in", + "something - Annotation Interface in", + "something - Variable in class", + "something() - Constructor", + "something() - Method in class a. - Method in class a. - Method in class something.Optional Element Summary", - "four", - "one", - "three", - "two", + "four", + "one", + "three", + "two", "

    Element Details

    ", "

    one

    ", "

    two

    ", @@ -613,10 +610,10 @@ public class TestOrdering extends JavadocTester { checkOrder("pkg5/AnnoRequiredTest.html", "

    Required Element Summary

    ", - "four", - "one", - "three", - "two", + "four", + "one", + "three", + "two", "

    Element Details

    ", "

    one

    ", "

    two

    ", @@ -643,10 +640,10 @@ public class TestOrdering extends JavadocTester { checkOrder("pkg5/EnumTest.html", "

    Enum Constant Summary

    ", - "FOUR", - "ONE", - "THREE", - "TWO", + "FOUR", + "ONE", + "THREE", + "TWO", "

    Enum Constant Details

    ", "

    ONE

    ", "

    TWO

    ", @@ -655,10 +652,10 @@ public class TestOrdering extends JavadocTester { checkOrder("pkg5/FieldTest.html", "

    Field Summary

    ", - "four", - "one", - "three", - "two", + "four", + "one", + "three", + "two", "

    Field Details

    ", "

    one

    ", "

    two

    ", @@ -667,10 +664,10 @@ public class TestOrdering extends JavadocTester { checkOrder("pkg5/IntfTest.html", "

    Method Summary

    ", - "four", - "one", - "three", - "two", + "four", + "one", + "three", + "two", "

    Method Details

    ", "

    one

    ", "

    two

    ", @@ -679,10 +676,10 @@ public class TestOrdering extends JavadocTester { checkOrder("pkg5/MethodTest.html", "

    Method Summary

    ", - "four", - "one", - "three", - "two", + "four", + "one", + "three", + "two", "

    Method Details

    ", "

    one

    ", "

    two

    ", @@ -691,11 +688,10 @@ public class TestOrdering extends JavadocTester { checkOrder("pkg5/PropertyTest.html", "

    Property Summary

    ", - "four", - "one", - """ - three""", - "two", + "four", + "one", + "three", + "two", "

    Property Details

    ", "

    oneProperty

    ", "

    twoProperty

    ", diff --git a/test/langtools/jdk/javadoc/doclet/testOverriddenMethods/TestOverrideMethods.java b/test/langtools/jdk/javadoc/doclet/testOverriddenMethods/TestOverrideMethods.java index 91319de51b2..f549e1b7ee1 100644 --- a/test/langtools/jdk/javadoc/doclet/testOverriddenMethods/TestOverrideMethods.java +++ b/test/langtools/jdk/javadoc/doclet/testOverriddenMethods/TestOverrideMethods.java @@ -104,12 +104,12 @@ public class TestOverrideMethods extends JavadocTester { // Check method summary "Method Summary", "void", - "#m1()\">m1", + "#m1()\" class=\"member-name-link\">m1", "A modified method", "void", """ - #m4(java.lang.String,java.lang.String)">m4""", + #m4(java.lang.String,java.lang.String)" class="member-name-link">m4""", "java.lang.String k,", "java.lang.String", " v)", @@ -239,8 +239,8 @@ public class TestOverrideMethods extends JavadocTester { // Check Method Summary "Method Summary", - "#m()\">m", - "#n()\">n", + "#m()\" class=\"member-name-link\">m", + "#n()\" class=\"member-name-link\">n", // Check footnotes """ @@ -265,45 +265,46 @@ public class TestOverrideMethods extends JavadocTester { """

    M

    """, """ - m()""", + m()""", """ - m()""", + m()""", """ - m0()""", + m0()""", """ - m0()""", + m0()""", """ - m1()""", + m1()""", """ - m1()""", + m1()""", """ - m1()""", + m1()""", """ - m1()""", + m1()""", """ - m2()""", + m2()""", """ - m2()""", + m2()""", """ - m3()""", + m3()""", """ - m3()""", + m3()""", """ - m3()""", + m3()""", """ - m4(String, String)""", + m4(String, String)""", """ - m4(K, V)""", + m4(K, V)""", """ - m5()""", + m5()""", """ - m6()""", + m6()""", """ - m6()""", + m6()""", """ - m7()""", + m7()""", """ - m7()""", + m7()""", "Returns the enum constant of this class with the specified name.", """ Returns an array containing the constants of this enum class, in @@ -321,8 +322,8 @@ public class TestOverrideMethods extends JavadocTester {
    java.lang.String
    + tab2 method-summary-table-tab4">\ + m2()
    This is Base::m2.
    @@ -330,8 +331,8 @@ public class TestOverrideMethods extends JavadocTester {
    void
    m4()
    + ab2 method-summary-table-tab4">m4\ + ()
    This is Base::m4.
    @@ -339,8 +340,8 @@ public class TestOverrideMethods extends JavadocTester {
    java.lang.Object
    m5()
    + tab2 method-summary-table-tab4">m\ + 5()
    This is Base::m5.
    @@ -348,8 +349,8 @@ public class TestOverrideMethods extends JavadocTester {
    java.lang.Object
    m6()
    + ab2 method-summary-table-tab4">m6\ + ()
    This is Base::m6.
    @@ -357,8 +358,8 @@ public class TestOverrideMethods extends JavadocTester {
    java.lang.Object
    m7()
    + tab2 method-summary-table-tab4">m\ + 7()
    This is Base::m7.
    @@ -366,8 +367,8 @@ public class TestOverrideMethods extends JavadocTester {
    abstract java.lang.Object
    m8()
    + ab2 method-summary-table-tab3">m8\ + ()
    This is Base::m8.
    diff --git a/test/langtools/jdk/javadoc/doclet/testPrivateClasses/TestPrivateClasses.java b/test/langtools/jdk/javadoc/doclet/testPrivateClasses/TestPrivateClasses.java index 4ba978067b9..44ca031335b 100644 --- a/test/langtools/jdk/javadoc/doclet/testPrivateClasses/TestPrivateClasses.java +++ b/test/langtools/jdk/javadoc/doclet/testPrivateClasses/TestPrivateClasses.java @@ -61,10 +61,10 @@ public class TestPrivateClasses extends JavadocTester { checkOutput("pkg/PublicChild.html", true, // Field inheritence from non-public superclass. """ - fieldInheritedFromParent""", + fieldInheritedFromParent""", // Method inheritance from non-public superclass. """ - methodInheritedFromParent""", + methodInheritedFromParent""", // private class does not show up in tree """
    java.lang.Object @@ -113,10 +113,10 @@ public class TestPrivateClasses extends JavadocTester { checkOutput("pkg/PublicInterface.html", true, // Field inheritance from non-public superinterface. """ - fieldInheritedFromInterface""", + fieldInheritedFromInterface""", // Method inheritance from non-public superinterface. """ - methodInterface""", + methodInterface""", //Make sure implemented interfaces from private superclass are inherited """
    @@ -217,7 +217,7 @@ public class TestPrivateClasses extends JavadocTester { checkOutput("pkg/PrivateInterface.html", true, """ - methodInterface""" + methodInterface""" ); checkOutput("pkg2/C.html", true, diff --git a/test/langtools/jdk/javadoc/doclet/testProperty/TestProperty.java b/test/langtools/jdk/javadoc/doclet/testProperty/TestProperty.java index 073a0eb06ea..4963ca58a72 100644 --- a/test/langtools/jdk/javadoc/doclet/testProperty/TestProperty.java +++ b/test/langtools/jdk/javadoc/doclet/testProperty/TestProperty.java @@ -80,8 +80,8 @@ public class TestProperty extends JavadocTester { - +
    """, // tab classes should be used in the method table @@ -91,8 +91,8 @@ public class TestProperty extends JavadocTester { g">ObjectProperty<MyObj[]&g\ t;
    """ + tab2 method-summary-table-tab4">badProperty()
    """ ); checkOutput("pkg/MyClassT.html", true, diff --git a/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.java b/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.java index 0ecd564b1f0..f8f97a008aa 100644 --- a/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.java +++ b/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.java @@ -77,7 +77,7 @@ public class TestRecordTypes extends JavadocTester { """ public record R""", """ - R​(int r1)"""); + R​(int r1)"""); } @Test @@ -98,7 +98,7 @@ public class TestRecordTypes extends JavadocTester { """ public record R""", """ - R​(int r1)"""); + R​(int r1)"""); } @Test @@ -119,7 +119,7 @@ public class TestRecordTypes extends JavadocTester { """ public record R""", """ - R()"""); + R()"""); } @Test @@ -149,7 +149,7 @@ public class TestRecordTypes extends JavadocTester {
    r1 - This is a component.
    """, """ - R​(int r1)"""); + R​(int r1)"""); } @Test @@ -182,7 +182,7 @@ public class TestRecordTypes extends JavadocTester {
    r1 - This is a component.
    """, """ - R​(int r1)"""); + R​(int r1)"""); } @Test @@ -207,22 +207,22 @@ public class TestRecordTypes extends JavadocTester { checkOrder("p/R.html", """
    """, - "R", + "R", "Creates an instance of a R record class.", """
    """, """ - equals""", + equals""", """ Indicates whether some other object is "equal to" this one.""", """ - hashCode""", + hashCode""", "Returns a hash code value for this object.", - "r1", + "r1", """ Returns the value of the r1 record component.""", """ - toString""", + toString""", "Returns a string representation of this record class.", "Method Details", """ @@ -270,22 +270,22 @@ public class TestRecordTypes extends JavadocTester { checkOrder("p/R.html", """
    """, - "R", + "R", "Creates an instance of a R record class.", """
    """, """ - equals""", + equals""", """ Indicates whether some other object is "equal to" this one.""", """ - hashCode""", + hashCode""", "Returns a hash code value for this object.", - "r1", + "r1", """ Returns the value of the r1 record component.""", """ - toString""", + toString""", "Returns a string representation of this record class.", "Method Details", """ @@ -372,20 +372,20 @@ public class TestRecordTypes extends JavadocTester { checkOrder("p/R.html", """
    """, - "R", + "R", "User constructor.", """
    """, """ - equals""", + equals""", "User equals.", """ - hashCode""", + hashCode""", "User hashCode.", - "r1", + "r1", "User accessor.", """ - toString""", + toString""", "User toString." ); } diff --git a/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java b/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java index a13276f5270..edd14ebdd91 100644 --- a/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java +++ b/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java @@ -433,68 +433,69 @@ public class TestSearch extends JavadocTester { // Test for search tags markup in index file. checkOutput("index-all.html", expectedOutput, """ -
    phrase with spaces - Search tag in package pkg
    """, +
    \ + phrase with spaces - Search tag in package pkg
    """, """ -
    pkg - Search tag in package pkg
    """, +
    pkg - Sea\ + rch tag in package pkg
    """, """ -
    pkg2\ - .5 - Search tag in package pkg
    """, +
    pkg2.5\ + - Search tag in package pkg
    """, """ -
    r - Search tag in package pkg
    """, +
    r - Search \ + tag in package pkg
    """, """ -
    sear\ - ch phrase - Search tag in class pkg1.RegClass
    """, +
    search phr\ + ase - Search tag in class pkg1.RegClass
    """, """ -
    SearchWordWithDescription - Search tag in pkg1.RegClass.CONS\ - TANT_FIELD_1
    """, +
    SearchWordWithDescription - Search tag in pkg1.RegClass.CONSTANT_FIELD_1<\ + /dt>""", """ -
    search phrase with desc deprecated - Search t\ - ag in annotation interface pkg2.TestAnnotationType
    """, +
    search phrase with desc deprecat\ + ed - Search tag in annotation interface pkg2.TestAnnotationType
    """, """ -
    SearchTagDeprecatedClass - Search tag in class pkg2.TestClas\ - s
    """, +
    SearchTagDeprecatedClass - Search tag in class pkg2.TestClass
    """, """ -
    search phrase deprecated - Search tag in pkg2.TestEnum.ONE
    """, +
    \ + search phrase deprecated - Search tag in pkg2.TestEnum.ONE
    """, """ -
    search phrase deprecated - Search tag in pkg2.TestEnum.ONE
    """, +
    \ + search phrase deprecated - Search tag in pkg2.TestEnum.ONE
    """, """ -
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.Te\ - stError()
    """, +
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.TestError()
    """, """ -
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.Te\ - stError()
    """, +
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.TestError()
    """, """ -
    \ - SingleWord - Search tag in package pkg
    """, +
    Single\ + Word - Search tag in package pkg
    """, """ -
    nested {@index nested_tag_test} - Search tag in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE
    """, +
    nested {@index nested_tag_test} - Search ta\ + g in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE
    """, """ -
    html <span> see </span> - Search tag in pkg.AnotherClas\ - s.ModalExclusionType.APPLICATION_EXCLUDE
    """, +
    html <span> see </span> - Search tag i\ + n pkg.AnotherClass.ModalExclusionType.APPLICATION_EXCLUDE
    """, """ -
    quoted<\ - /a> - Search tag in pkg.AnotherClass.CONSTANT1
    """, +
    quoted - \ + Search tag in pkg.AnotherClass.CONSTANT1
    """, """ -
    ONE - Enum constant in enum class pkg2.TestEnum
    """, +
    ONE - Enum con\ + stant in enum class pkg2.TestEnum
    """, """ -
    THREE<\ - /span> - Enum constant in enum class pkg2.TestEnum""", +
    THREE - Enum\ + constant in enum class pkg2.TestEnum
    """, """ -
    TWO - Enum constant in enum class pkg2.TestEnum
    """); +
    TWO - Enum con\ + stant in enum class pkg2.TestEnum
    """); checkOutput("index-all.html", true, """
    class_test1 passes. Search tag s\ - earch phrase - Search tag in class pkg1.RegClass""", +
    search \ + phrase - Search tag in class pkg1.RegClass
    """, """ -
    SearchWordWithDescription - Search tag in pkg1.RegClass.C\ - ONSTANT_FIELD_1
    """, +
    SearchWordWithDescription - Search tag in pkg1.RegClass.CONSTANT_FIELD\ + _1
    """, """ -
    search phrase with desc deprecated - Searc\ - h tag in annotation interface pkg2.TestAnnotationType
    """, +
    search phrase with desc deprecated - Search tag in anno\ + tation interface pkg2.TestAnnotationType
    """, """ -
    SearchTagDeprecatedClass - Search tag in class pkg2.TestC\ - lass
    """, +
    SearchTagDeprecatedClass - Search tag in class pkg2.TestClass
    """, """ -
    search phrase deprecated - Search tag in pkg2.TestEnum.ONE""", +
    search phrase deprecated - Search tag in pkg2.TestEnum.ONE
    """, """ -
    search phrase deprecated - Search tag in pkg2.TestEnum.ONE""", +
    search phrase deprecated - Search tag in pkg2.TestEnum.ONE
    """, """ -
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError\ - .TestError()
    """, +
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.TestError()
    """, """ -
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError\ - .TestError()
    """, +
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.TestError()
    """, """ -
    SingleWord - Search tag in package pkg
    """, +
    Sin\ + gleWord - Search tag in package pkg
    """, """
    All Classes|All Packages"""); checkOutput("index-files/index-10.html", true, """ -
    phrase with spaces - Search tag in package pkg
    """, +
    phrase with spaces - Search tag in package pkg
    """, """ -
    pkg<\ - /a> - Search tag in package pkg
    """, +
    pkg - \ + Search tag in package pkg
    """, """ -
    p\ - kg2.5 - Search tag in package pkg
    """); +
    pkg2.5<\ + /a> - Search tag in package pkg
    """); checkOutput("index-files/index-12.html", true, """ -
    r - Search tag in package pkg
    """); +
    r - Sear\ + ch tag in package pkg
    """); checkOutput("index-files/index-8.html", true, """ -
    nested {@index nested_tag_test} - Search tag in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE
    """); +
    nested {@index nested_tag_test} - Search\ + tag in pkg.AnotherClass.ModalExclusionType.NO_EXCLUDE
    """); checkOutput("index-files/index-5.html", true, """ -
    html <span> see </span> - Search tag in pkg.AnotherClass.ModalExclusionType.APPLICATION_EXCLUDE
    """); +
    html <span> see </span> - Search \ + tag in pkg.AnotherClass.ModalExclusionType.APPLICATION_EXCLUDE
    """); checkOutput("index-files/index-11.html", true, """ -
    quot\ - ed - Search tag in pkg.AnotherClass.CONSTANT1
    """); +
    quoted\ + - Search tag in pkg.AnotherClass.CONSTANT1
    """); checkOutput("index-files/index-9.html", true, """ -
    ONE - Enum constant in enum class pkg2.TestEnum"""); +
    ONE - Enum \ + constant in enum class pkg2.TestEnum
    """); checkOutput("index-files/index-14.html", true, """ -
    THREE - Enum constant in enum class pkg2.TestEnum
    """, +
    THREE - E\ + num constant in enum class pkg2.TestEnum
    """, """ -
    TWO - Enum constant in enum class pkg2.TestEnum"""); +
    TWO - Enum \ + constant in enum class pkg2.TestEnum
    """); } void checkIndexNoComment() { // Test for search tags markup in index file when javadoc is executed with -nocomment. checkOutput("index-all.html", false, """ -
    phrase with spaces - Search tag in package pkg
    """, +
    \ + phrase with spaces - Search tag in package pkg
    """, """ -
    pkg - Search tag in package pkg
    """, +
    pkg - Search tag in package pkg
    """, """ -
    pkg2\ - .5 - Search tag in package pkg
    """, +
    pkg2.5\ + - Search tag in package pkg
    """, """ -
    r - Search tag in package pkg
    """, +
    r - Search tag in package pkg
    """, """ -
    sear\ - ch phrase - Search tag in class pkg1.RegClass
    """, +
    search phr\ + ase - Search tag in class pkg1.RegClass
    """, """ -
    SearchWordWithDescription - Search tag in pkg1.RegClass.CONS\ - TANT_FIELD_1
    """, +
    SearchWordWithDescription - Search tag in pkg1.RegClass.CONSTANT_FIELD_1
    """, """ -
    search phrase with desc deprecated - Search t\ - ag in annotation interface pkg2.TestAnnotationType
    """, +
    search phrase with desc deprecated - Search tag in annotat\ + ion interface pkg2.TestAnnotationType
    """, """ -
    SearchTagDeprecatedClass - Search tag in class pkg2.TestClas\ - s
    """, +
    SearchTagDeprecatedClass - Search tag in class pkg2.TestClass
    """, """ -
    \ - SingleWord - Search tag in package pkg
    """, +
    Single\ + Word - Search tag in package pkg
    """, """
    class_test1 passes. Search tag SearchTagDeprecatedClass
    """, + TagDeprecatedClass">SearchTagDeprecatedClass
    """, """
    error_test3 passes. Search tag for method SearchTagDeprecatedMethod
    """); checkOutput("index-all.html", true, """ -
    search phrase deprecated - Search tag in pkg2.TestEnum.ONE
    """, +
    \ + search phrase deprecated - Search tag in pkg2.TestEnum.ONE
    """, """ -
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.Te\ - stError()
    """); +
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.TestError()
    """); } void checkIndexNoDeprecated() { // Test for search tags markup in index file when javadoc is executed using -nodeprecated. checkOutput("index-all.html", true, """ -
    phrase with spaces - Search tag in package pkg
    """, +
    \ + phrase with spaces - Search tag in package pkg
    """, """ -
    sear\ - ch phrase - Search tag in class pkg1.RegClass
    """, +
    search phr\ + ase - Search tag in class pkg1.RegClass
    """, """ -
    SearchWordWithDescription - Search tag in pkg1.RegClass.CONS\ - TANT_FIELD_1
    """, +
    SearchWordWithDescription - Search tag in pkg1.RegClass.CONSTANT_FIELD_1
    """, """ -
    \ - SingleWord - Search tag in package pkg
    """); +
    Single\ + Word - Search tag in package pkg
    """); checkOutput("index-all.html", false, """ -
    search phrase with desc deprecated - Search t\ - ag in annotation interface pkg2.TestAnnotationType
    """, +
    search phrase with desc deprecated - Search tag in annotat\ + ion interface pkg2.TestAnnotationType
    """, """ -
    SearchTagDeprecatedClass - Search tag in class pkg2.TestClas\ - s
    """, +
    SearchTagDeprecatedClass - Search tag in class pkg2.TestClass
    """, """ -
    search phrase deprecated - Search tag in pkg2.TestEnum.ONE
    """, +
    \ + search phrase deprecated - Search tag in pkg2.TestEnum.ONE
    """, """ -
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.Te\ - stError()
    """, +
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.TestError()
    """, """
    class_test1 passes. Search tag SearchTagDeprecatedClass
    """, @@ -777,19 +768,16 @@ public class TestSearch extends JavadocTester { // Test for search tags duplication in index file. checkOutput("index-all.html", true, """ -
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.Te\ - stError()
    +
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.TestError()
    with description
    """); checkOutput("index-all.html", false, """ -
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.Te\ - stError()
    +
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.TestError()
    with description
    -
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.Te\ - stError()
    +
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.TestError()
    with description
    """); } @@ -797,19 +785,16 @@ public class TestSearch extends JavadocTester { // Test for search tags duplication in index file. checkOutput("index-files/index-13.html", true, """ -
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError\ - .TestError()
    +
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.TestError()
    with description
    """); checkOutput("index-files/index-13.html", false, """ -
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError\ - .TestError()
    +
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.TestError()
    with description
    -
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError\ - .TestError()
    +
    SearchTagDeprecatedMethod - Search tag in pkg2.TestError.TestError()
    with description
    """); } diff --git a/test/langtools/jdk/javadoc/doclet/testSummaryTag/TestSummaryTag.java b/test/langtools/jdk/javadoc/doclet/testSummaryTag/TestSummaryTag.java index add9c5d905d..be10ad818ee 100644 --- a/test/langtools/jdk/javadoc/doclet/testSummaryTag/TestSummaryTag.java +++ b/test/langtools/jdk/javadoc/doclet/testSummaryTag/TestSummaryTag.java @@ -50,33 +50,33 @@ public class TestSummaryTag extends JavadocTester { checkOutput("index-all.html", true, """
    -
    m() - Meth\ - od in class p1.A
    +
    m() - Method in class p1.A
    First sentence
    -
    m() - Meth\ - od in class p1.B
    +
    m() - Method in class p1.B
    First sentence
    -
    m1() - Me\ - thod in class p1.A
    +
    m1() - Method in class p1.\ + A
    First sentence
    -
    m2() - Me\ - thod in class p1.A
    +
    m2() - Method in class p1.\ + A
    Some html <foo>   codes
    -
    m3() - Me\ - thod in class p1.A
    +
    m3() - Method in class p1.\ + A
    First sentence
    -
    m4() - Me\ - thod in class p1.A
    +
    m4() - Method in class p1.\ + A
    First sentence i.e. the first sentence
    diff --git a/test/langtools/jdk/javadoc/doclet/testSystemPropertyTaglet/TestSystemPropertyTaglet.java b/test/langtools/jdk/javadoc/doclet/testSystemPropertyTaglet/TestSystemPropertyTaglet.java index 88ebfe6087d..516d006eb50 100644 --- a/test/langtools/jdk/javadoc/doclet/testSystemPropertyTaglet/TestSystemPropertyTaglet.java +++ b/test/langtools/jdk/javadoc/doclet/testSystemPropertyTaglet/TestSystemPropertyTaglet.java @@ -165,102 +165,102 @@ public class TestSystemPropertyTaglet extends JavadocTester { """

    T

    """, """ -
    test.property - Search tag in annotation interface mypackag\ +
    test.property - Search tag in annotation interface mypackag\ e.MyAnnotation
    System Property
    """, """ -
    test.property - Search tag in class mypackage.MyClass
    +
    test.property - Search tag in class mypackage.MyClass
    System Property
    """, """ -
    test.property - Search tag in enum class mypackage.MyEnum
    +
    test.property - Search tag in enum class mypackage.MyEnum
    System Property
    """, """ -
    test.property - Search tag in error mypackage.MyError
    +
    test.property - Search tag in error mypackage.MyError
    System Property
    """, """ -
    test.property - Search tag in exception mypackage.MyExc\ +
    test.property - Search tag in exception mypackage.MyExc\ eption
    System Property
    """, """ -
    test.property - Search tag in interface mypackage.MyInt\ +
    test.property - Search tag in interface mypackage.MyInt\ erface
    System Property
    """, """ -
    test.property - Search tag in module mymodule
    +
    test.property - Search tag in module mymodule
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyAnnotation\ +
    test.property - Search tag in mypackage.MyAnnotation\ .value()
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyClass.INT_CONST\ +
    test.property - Search tag in mypackage.MyClass.INT_CONST\ ANT
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyClass.MyClass()\ +
    test.property - Search tag in mypackage.MyClass.MyClass()\
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyClass.intField<\ +
    test.property - Search tag in mypackage.MyClass.intField<\ /dt>
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyClass.run()test.property - Search tag in mypackage.MyClass.run()
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyClass.value()test.property - Search tag in mypackage.MyClass.value()
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyEnum.X
    +
    test.property - Search tag in mypackage.MyEnum.X
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyEnum.m()
    +
    test.property - Search tag in mypackage.MyEnum.m()
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyError.MyError()\ +
    test.property - Search tag in mypackage.MyError.MyError()\
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyException.M\ +
    test.property - Search tag in mypackage.MyException.M\ yException()
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyInterface.I\ +
    test.property - Search tag in mypackage.MyInterface.I\ NT_CONSTANT
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyInterface.m\ +
    test.property - Search tag in mypackage.MyInterface.m\ ()
    System Property
    """, """ -
    test.property - Search tag in mypackage.MyInterface.m\ +
    test.property - Search tag in mypackage.MyInterface.m\ (String...)
    System Property
    """, """ -
    test.property - Search tag in package mypackagetest.property - Search tag in package mypackage
    System Property
    """, ""); diff --git a/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java b/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java index 49af127c44a..e99b7f72464 100644 --- a/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java +++ b/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java @@ -536,8 +536,8 @@ public class TestTypeAnnotations extends JavadocTester { checkOutput("typeannos/RepeatingOnConstructor.Inner.html", true, """ - Inner​(java.lang.String parameter, + Inner​(java.lang.String parameter, java.lang.String @Rep\ TypeUseA @RepType\ UseA @RepTypeUseB\ @@ -568,7 +568,8 @@ public class TestTypeAnnotations extends JavadocTester { checkOutput("typeannos/RepeatingOnField.html", true, """
    (package private) java.lang.Integer
    -
    """, + """, """
    (package private) @RepTypeUseA @RepTypeUseB @RepTypeUseB java.lang.Integer
    - +
     
    """, """ @@ -586,7 +587,8 @@ public class TestTypeAnnotations extends JavadocTester { title="annotation in typeannos">@RepTypeUseA @RepTypeUseB @RepTypeUseB java.lang.Integer
    - """, + """, """
    (package private) @RepAllContextsB @RepAllContextsB java.la\ ng.Integer
    - """, + """, """
    (package private) java.lang.String @RepTypeUseA @RepTypeUseB @RepTypeUseB []
    - """, + """, """
    test1()""", + tab2 method-summary-table-tab4">test1()""", """ (package private) @RepTypeU\ seB java.lang.String
    test2()""", + ab2 method-summary-table-tab4">test2()""", """ (package private) @RepTypeU\ seB java.lang.String
    test3()""", + tab2 method-summary-table-tab4">test3()""", """ (package private) @RepAllContextsB @RepAllContextsB java.lang.String
    test4()""", + ab2 method-summary-table-tab4">test4()""", """ - test5​(java.lang.String parameter, + test5​(java.lang.String parameter, java.lang.String @Re\ pTypeUseA @RepTyp\ eUseA @RepTypeUse\ @@ -777,15 +781,15 @@ public class TestTypeAnnotations extends JavadocTester { """ (package private) <T> java.lang.String
    genericMethod​(T t)""", + tab2 method-summary-table-tab4">genericMethod​(T t)""", """ (package private) <T> java.lang.String
    genericMethod2​(@RepTypeUseA genericMethod2​(@RepTypeUseA @RepTypeUseA @RepTypeUseB @RepTypeUseB T t)""", @@ -793,8 +797,8 @@ public class TestTypeAnnotations extends JavadocTester { """ (package private) java.lang.String
    test()""", + tab2 method-summary-table-tab4">test()""", """ java.lang.String testClassUseTest3<T exte\ - nds ParamTest2<java.uti\ - l.List<? extends Foo4>>\ - >"""); + Clas\ + sUseTest3<T extends Par\ + amTest2<java.util.List<? extends Foo4>>>"""); // Nested type parameters checkOutput("pkg/C.html", true, diff --git a/test/langtools/jdk/javadoc/doclet/testUseOption/TestUseOption.java b/test/langtools/jdk/javadoc/doclet/testUseOption/TestUseOption.java index a345628d797..c94f1264ed4 100644 --- a/test/langtools/jdk/javadoc/doclet/testUseOption/TestUseOption.java +++ b/test/langtools/jdk/javadoc/doclet/testUseOption/TestUseOption.java @@ -83,7 +83,7 @@ public class TestUseOption extends JavadocTester { ); checkOutput("pkg1/class-use/UsedClass.html", true, """ - methodInC1ReturningType""" + methodInC1ReturningType""" ); checkOutput("pkg1/class-use/UsedInterface.html", true, """ @@ -100,7 +100,7 @@ public class TestUseOption extends JavadocTester { ); checkOutput("pkg1/class-use/UsedInterface.html", true, """ - AnAbstract""" + AnAbstract""" ); checkOutput("pkg1/class-use/UsedInterface.html", true, "../C10.html#withReturningTypeParameters()" @@ -114,15 +114,15 @@ public class TestUseOption extends JavadocTester { ); checkOutput("pkg1/class-use/UsedInterface.html", true, """ - addAll""" + addAll""" ); checkOutput("pkg1/class-use/UsedInterface.html", true, """ - """ + """ ); checkOutput("pkg1/class-use/UsedInterface.html", true, """ - withTypeParametersOfType""" + withTypeParametersOfType""" ); checkOutput("pkg1/class-use/UsedInterface.html", true, """ @@ -130,8 +130,8 @@ public class TestUseOption extends JavadocTester { nterface in pkg1""", """
    interface 
    -
    SubInterface<T>\ + """ ); checkOutput("pkg1/class-use/UsedThrowable.html", true, @@ -141,8 +141,8 @@ public class TestUseOption extends JavadocTester { """
    void
    """ + \ + methodInC1ThrowsThrowable()
    """ ); } @@ -183,12 +183,12 @@ public class TestUseOption extends JavadocTester { checkExit(Exit.OK); checkUnique("unique/class-use/UseMe.html", """ - """, + """, """ - """, + """, """ - """, + """, """ - """); + """); } } -- GitLab From 9c0ec8d8485e1f1e44aee9bbde711143508759aa Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Fri, 12 Feb 2021 08:41:33 +0000 Subject: [PATCH 035/367] 8260941: Remove the conc_scan parameter for CardTable Reviewed-by: ayang, kbarrett --- .../shared/cardTableBarrierSetAssembler_aarch64.cpp | 13 ------------- src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp | 9 --------- .../gc/shared/cardTableBarrierSetAssembler_arm.cpp | 9 --------- .../gc/shared/cardTableBarrierSetAssembler_ppc.cpp | 7 ------- .../gc/shared/cardTableBarrierSetAssembler_x86.cpp | 3 --- src/hotspot/share/gc/g1/g1BarrierSet.hpp | 4 ++++ src/hotspot/share/gc/g1/g1CardTable.hpp | 2 +- src/hotspot/share/gc/parallel/psCardTable.hpp | 2 +- .../share/gc/shared/c1/cardTableBarrierSetC1.cpp | 6 ------ .../share/gc/shared/c2/cardTableBarrierSetC2.cpp | 13 +------------ src/hotspot/share/gc/shared/cardTable.cpp | 3 +-- src/hotspot/share/gc/shared/cardTable.hpp | 4 +--- src/hotspot/share/gc/shared/cardTableBarrierSet.cpp | 2 +- .../share/gc/shared/cardTableBarrierSet.inline.hpp | 7 +------ src/hotspot/share/gc/shared/cardTableRS.cpp | 4 ++-- src/hotspot/share/gc/shared/cardTableRS.hpp | 2 +- src/hotspot/share/gc/shared/genCollectedHeap.cpp | 2 +- 17 files changed, 15 insertions(+), 77 deletions(-) diff --git a/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp index 9c0a66b255a..a86e0dc5171 100644 --- a/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp @@ -38,9 +38,6 @@ void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register ob BarrierSet* bs = BarrierSet::barrier_set(); assert(bs->kind() == BarrierSet::CardTableBarrierSet, "Wrong barrier set kind"); - CardTableBarrierSet* ctbs = barrier_set_cast(bs); - CardTable* ct = ctbs->card_table(); - __ lsr(obj, obj, CardTable::card_shift); assert(CardTable::dirty_card_val() == 0, "must be"); @@ -55,19 +52,12 @@ void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register ob __ strb(zr, Address(obj, rscratch1)); __ bind(L_already_dirty); } else { - if (ct->scanned_concurrently()) { - __ membar(Assembler::StoreStore); - } __ strb(zr, Address(obj, rscratch1)); } } void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register start, Register count, Register scratch, RegSet saved_regs) { - BarrierSet* bs = BarrierSet::barrier_set(); - CardTableBarrierSet* ctbs = barrier_set_cast(bs); - CardTable* ct = ctbs->card_table(); - Label L_loop, L_done; const Register end = count; @@ -81,9 +71,6 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl __ load_byte_map_base(scratch); __ add(start, start, scratch); - if (ct->scanned_concurrently()) { - __ membar(__ StoreStore); - } __ bind(L_loop); __ strb(zr, Address(start, count)); __ subs(count, count, 1); diff --git a/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp b/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp index 5cba07805b9..f29d4c0744c 100644 --- a/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/c1_LIRGenerator_arm.cpp @@ -366,9 +366,6 @@ void LIRGenerator::set_card(LIR_Opr value, LIR_Address* card_addr) { void LIRGenerator::CardTableBarrierSet_post_barrier_helper(LIR_OprDesc* addr, LIR_Const* card_table_base) { assert(addr->is_register(), "must be a register at this point"); - CardTableBarrierSet* ctbs = barrier_set_cast(BarrierSet::barrier_set()); - CardTable* ct = ctbs->card_table(); - LIR_Opr tmp = FrameMap::LR_ptr_opr; bool load_card_table_base_const = VM_Version::supports_movw(); @@ -382,9 +379,6 @@ void LIRGenerator::CardTableBarrierSet_post_barrier_helper(LIR_OprDesc* addr, LI // byte instruction does not support the addressing mode we need. LIR_Address* card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTable::card_shift, 0, T_BOOLEAN); if (UseCondCardMark) { - if (ct->scanned_concurrently()) { - __ membar_storeload(); - } LIR_Opr cur_value = new_register(T_INT); __ move(card_addr, cur_value); @@ -394,9 +388,6 @@ void LIRGenerator::CardTableBarrierSet_post_barrier_helper(LIR_OprDesc* addr, LI set_card(tmp, card_addr); __ branch_destination(L_already_dirty->label()); } else { - if (ct->scanned_concurrently()) { - __ membar_storestore(); - } set_card(tmp, card_addr); } } diff --git a/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp b/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp index fc32418daa8..86f43597e22 100644 --- a/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/gc/shared/cardTableBarrierSetAssembler_arm.cpp @@ -128,16 +128,10 @@ void CardTableBarrierSetAssembler::store_check_part2(MacroAssembler* masm, Regis assert(bs->kind() == BarrierSet::CardTableBarrierSet, "Wrong barrier set kind"); - CardTableBarrierSet* ctbs = barrier_set_cast(bs); - CardTable* ct = ctbs->card_table(); - assert(CardTable::dirty_card_val() == 0, "Dirty card value must be 0 due to optimizations."); Address card_table_addr(card_table_base, obj, lsr, CardTable::card_shift); if (UseCondCardMark) { - if (ct->scanned_concurrently()) { - __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), noreg); - } Label already_dirty; __ ldrb(tmp, card_table_addr); @@ -147,9 +141,6 @@ void CardTableBarrierSetAssembler::store_check_part2(MacroAssembler* masm, Regis __ bind(already_dirty); } else { - if (ct->scanned_concurrently()) { - __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore), noreg); - } set_card(masm, card_table_base, card_table_addr, tmp); } } diff --git a/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp index fd0c4c6a540..a4c2afce55f 100644 --- a/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp @@ -43,14 +43,10 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register preserve) { - CardTableBarrierSet* ctbs = barrier_set_cast(BarrierSet::barrier_set()); - CardTable* ct = ctbs->card_table(); assert_different_registers(addr, count, R0); Label Lskip_loop, Lstore_loop; - if (ct->scanned_concurrently()) { __ membar(Assembler::StoreStore); } - __ sldi_(count, count, LogBytesPerHeapOop); __ beq(CCR0, Lskip_loop); // zero length __ addi(count, count, -BytesPerHeapOop); @@ -74,13 +70,10 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl void CardTableBarrierSetAssembler::card_table_write(MacroAssembler* masm, CardTable::CardValue* byte_map_base, Register tmp, Register obj) { - CardTableBarrierSet* ctbs = barrier_set_cast(BarrierSet::barrier_set()); - CardTable* ct = ctbs->card_table(); assert_different_registers(obj, tmp, R0); __ load_const_optimized(tmp, (address)byte_map_base, R0); __ srdi(obj, obj, CardTable::card_shift); __ li(R0, CardTable::dirty_card_val()); - if (ct->scanned_concurrently()) { __ membar(Assembler::StoreStore); } __ stbx(R0, tmp, obj); } diff --git a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp index c00ea223f00..9b2d2c5efed 100644 --- a/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shared/cardTableBarrierSetAssembler_x86.cpp @@ -118,9 +118,6 @@ void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register ob int dirty = CardTable::dirty_card_val(); if (UseCondCardMark) { Label L_already_dirty; - if (ct->scanned_concurrently()) { - __ membar(Assembler::StoreLoad); - } __ cmpb(card_addr, dirty); __ jcc(Assembler::equal, L_already_dirty); __ movb(card_addr, dirty); diff --git a/src/hotspot/share/gc/g1/g1BarrierSet.hpp b/src/hotspot/share/gc/g1/g1BarrierSet.hpp index 9b7ee9e93e7..8d009a9e19f 100644 --- a/src/hotspot/share/gc/g1/g1BarrierSet.hpp +++ b/src/hotspot/share/gc/g1/g1BarrierSet.hpp @@ -53,6 +53,10 @@ class G1BarrierSet: public CardTableBarrierSet { G1BarrierSet(G1CardTable* table); ~G1BarrierSet() { } + virtual bool card_mark_must_follow_store() const { + return true; + } + // Add "pre_val" to a set of objects that may have been disconnected from the // pre-marking object graph. static void enqueue(oop pre_val); diff --git a/src/hotspot/share/gc/g1/g1CardTable.hpp b/src/hotspot/share/gc/g1/g1CardTable.hpp index 3540bb9411a..925ae098b63 100644 --- a/src/hotspot/share/gc/g1/g1CardTable.hpp +++ b/src/hotspot/share/gc/g1/g1CardTable.hpp @@ -79,7 +79,7 @@ public: STATIC_ASSERT(BitsPerByte == 8); static const size_t WordAlreadyScanned = (SIZE_MAX / 255) * g1_card_already_scanned; - G1CardTable(MemRegion whole_heap): CardTable(whole_heap, /* scanned concurrently */ true), _listener() { + G1CardTable(MemRegion whole_heap): CardTable(whole_heap), _listener() { _listener.set_card_table(this); } diff --git a/src/hotspot/share/gc/parallel/psCardTable.hpp b/src/hotspot/share/gc/parallel/psCardTable.hpp index df1e0158727..d912c656741 100644 --- a/src/hotspot/share/gc/parallel/psCardTable.hpp +++ b/src/hotspot/share/gc/parallel/psCardTable.hpp @@ -51,7 +51,7 @@ class PSCardTable: public CardTable { }; public: - PSCardTable(MemRegion whole_heap) : CardTable(whole_heap, /* scanned_concurrently */ false) {} + PSCardTable(MemRegion whole_heap) : CardTable(whole_heap) {} static CardValue youngergen_card_val() { return youngergen_card; } static CardValue verify_card_val() { return verify_card; } diff --git a/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp b/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp index 106412d90b4..a89b57d8e45 100644 --- a/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp +++ b/src/hotspot/share/gc/shared/c1/cardTableBarrierSetC1.cpp @@ -83,9 +83,6 @@ void CardTableBarrierSetC1::post_barrier(LIRAccess& access, LIR_OprDesc* addr, L LIR_Opr dirty = LIR_OprFact::intConst(CardTable::dirty_card_val()); if (UseCondCardMark) { LIR_Opr cur_value = gen->new_register(T_INT); - if (ct->scanned_concurrently()) { - __ membar_storeload(); - } __ move(card_addr, cur_value); LabelObj* L_already_dirty = new LabelObj(); @@ -94,9 +91,6 @@ void CardTableBarrierSetC1::post_barrier(LIRAccess& access, LIR_OprDesc* addr, L __ move(dirty, card_addr); __ branch_destination(L_already_dirty->label()); } else { - if (ct->scanned_concurrently()) { - __ membar_storestore(); - } __ move(dirty, card_addr); } #endif diff --git a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp index be20fbc12dd..d3da34e5b27 100644 --- a/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shared/c2/cardTableBarrierSetC2.cpp @@ -58,8 +58,6 @@ void CardTableBarrierSetC2::post_barrier(GraphKit* kit, Node* val, BasicType bt, bool use_precise) const { - CardTableBarrierSet* ctbs = barrier_set_cast(BarrierSet::barrier_set()); - CardTable* ct = ctbs->card_table(); // No store check needed if we're storing a NULL or an old object // (latter case is probably a string constant). The concurrent // mark sweep garbage collector, however, needs to have all nonNull @@ -105,10 +103,6 @@ void CardTableBarrierSetC2::post_barrier(GraphKit* kit, Node* zero = __ ConI(0); // Dirty card value if (UseCondCardMark) { - if (ct->scanned_concurrently()) { - kit->insert_mem_bar(Op_MemBarVolatile, oop_store); - __ sync_kit(kit); - } // The classic GC reference write barrier is typically implemented // as a store into the global card mark table. Unfortunately // unconditional stores can result in false sharing and excessive @@ -121,12 +115,7 @@ void CardTableBarrierSetC2::post_barrier(GraphKit* kit, } // Smash zero into card - if (!ct->scanned_concurrently()) { - __ store(__ ctrl(), card_adr, zero, T_BYTE, adr_type, MemNode::unordered); - } else { - // Specialized path for CM store barrier - __ storeCM(__ ctrl(), card_adr, zero, oop_store, adr_idx, T_BYTE, adr_type); - } + __ store(__ ctrl(), card_adr, zero, T_BYTE, adr_type, MemNode::unordered); if (UseCondCardMark) { __ end_if(); diff --git a/src/hotspot/share/gc/shared/cardTable.cpp b/src/hotspot/share/gc/shared/cardTable.cpp index b2a7118e8aa..84f624b3001 100644 --- a/src/hotspot/share/gc/shared/cardTable.cpp +++ b/src/hotspot/share/gc/shared/cardTable.cpp @@ -41,8 +41,7 @@ size_t CardTable::compute_byte_map_size() { return align_up(_guard_index + 1, MAX2(_page_size, granularity)); } -CardTable::CardTable(MemRegion whole_heap, bool conc_scan) : - _scanned_concurrently(conc_scan), +CardTable::CardTable(MemRegion whole_heap) : _whole_heap(whole_heap), _guard_index(0), _last_valid_index(0), diff --git a/src/hotspot/share/gc/shared/cardTable.hpp b/src/hotspot/share/gc/shared/cardTable.hpp index f5b06ebb172..ff406eee4be 100644 --- a/src/hotspot/share/gc/shared/cardTable.hpp +++ b/src/hotspot/share/gc/shared/cardTable.hpp @@ -43,7 +43,6 @@ public: protected: // The declaration order of these const fields is important; see the // constructor before changing. - const bool _scanned_concurrently; const MemRegion _whole_heap; // the region covered by the card table size_t _guard_index; // index of very last element in the card // table; it is set to a guard value @@ -113,7 +112,7 @@ protected: static const intptr_t clean_card_row = (intptr_t)(-1); public: - CardTable(MemRegion whole_heap, bool conc_scan); + CardTable(MemRegion whole_heap); virtual ~CardTable(); virtual void initialize(); @@ -245,7 +244,6 @@ public: // But since the heap starts at some higher address, this points to somewhere // before the beginning of the actual _byte_map. CardValue* byte_map_base() const { return _byte_map_base; } - bool scanned_concurrently() const { return _scanned_concurrently; } virtual bool is_in_young(oop obj) const = 0; diff --git a/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp b/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp index 7e491c36dd5..225fca264bd 100644 --- a/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp +++ b/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp @@ -192,5 +192,5 @@ void CardTableBarrierSet::on_thread_detach(Thread* thread) { } bool CardTableBarrierSet::card_mark_must_follow_store() const { - return _card_table->scanned_concurrently(); + return false; } diff --git a/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp b/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp index f88a0dc070a..97e3c4593df 100644 --- a/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp @@ -32,12 +32,7 @@ template inline void CardTableBarrierSet::write_ref_field_post(T* field, oop newVal) { volatile CardValue* byte = _card_table->byte_for(field); - if (_card_table->scanned_concurrently()) { - // Perform a releasing store if the card table is scanned concurrently - Atomic::release_store(byte, CardTable::dirty_card_val()); - } else { - *byte = CardTable::dirty_card_val(); - } + *byte = CardTable::dirty_card_val(); } #endif // SHARE_GC_SHARED_CARDTABLEBARRIERSET_INLINE_HPP diff --git a/src/hotspot/share/gc/shared/cardTableRS.cpp b/src/hotspot/share/gc/shared/cardTableRS.cpp index cc232960a05..3dc15fb23a1 100644 --- a/src/hotspot/share/gc/shared/cardTableRS.cpp +++ b/src/hotspot/share/gc/shared/cardTableRS.cpp @@ -434,8 +434,8 @@ void CardTableRS::verify() { CardTable::verify(); } -CardTableRS::CardTableRS(MemRegion whole_heap, bool scanned_concurrently) : - CardTable(whole_heap, scanned_concurrently) { } +CardTableRS::CardTableRS(MemRegion whole_heap) : + CardTable(whole_heap) { } void CardTableRS::initialize() { CardTable::initialize(); diff --git a/src/hotspot/share/gc/shared/cardTableRS.hpp b/src/hotspot/share/gc/shared/cardTableRS.hpp index e90ab9e3134..86ea16e0957 100644 --- a/src/hotspot/share/gc/shared/cardTableRS.hpp +++ b/src/hotspot/share/gc/shared/cardTableRS.hpp @@ -45,7 +45,7 @@ class CardTableRS : public CardTable { void verify_space(Space* s, HeapWord* gen_start); public: - CardTableRS(MemRegion whole_heap, bool scanned_concurrently); + CardTableRS(MemRegion whole_heap); void younger_refs_in_space_iterate(Space* sp, HeapWord* gen_boundary, OopIterateClosure* cl); diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.cpp b/src/hotspot/share/gc/shared/genCollectedHeap.cpp index fb303850c08..e498d54da11 100644 --- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp +++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp @@ -142,7 +142,7 @@ jint GenCollectedHeap::initialize() { } CardTableRS* GenCollectedHeap::create_rem_set(const MemRegion& reserved_region) { - return new CardTableRS(reserved_region, false /* scan_concurrently */); + return new CardTableRS(reserved_region); } void GenCollectedHeap::initialize_size_policy(size_t init_eden_size, -- GitLab From 3210095a175e66e227a23c73c154c4c9a26c3584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Fri, 12 Feb 2021 09:26:42 +0000 Subject: [PATCH 036/367] 8261079: Fix support for @hidden in classes and interfaces Reviewed-by: jjg --- .../formats/html/HtmlConfiguration.java | 10 +-- .../formats/html/HtmlDocletWriter.java | 9 +- .../doclets/formats/html/HtmlLinkFactory.java | 2 +- .../formats/html/MethodWriterImpl.java | 87 ++++++++++--------- .../formats/html/PropertyWriterImpl.java | 28 +++--- .../html/SerializedFormWriterImpl.java | 5 +- .../builders/MemberSummaryBuilder.java | 5 +- .../builders/SerializedFormBuilder.java | 6 +- .../internal/doclets/toolkit/util/Utils.java | 62 ++++++++----- .../toolkit/util/VisibleMemberTable.java | 53 +++++------ .../doclet/testHiddenTag/TestHiddenTag.java | 66 ++++++++++++-- .../javadoc/doclet/testHiddenTag/pkg1/A.java | 2 +- .../doclet/testHiddenTag/pkg1/Child.java | 33 +++++++ .../doclet/testHiddenTag/pkg1/Intf.java | 53 +++++++++++ .../testHiddenTag/pkg1/InvisibleParent.java | 58 +++++++++++++ .../pkg2/UndocumentedParent.java | 56 ++++++++++++ 16 files changed, 403 insertions(+), 132 deletions(-) create mode 100644 test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/Child.java create mode 100644 test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/Intf.java create mode 100644 test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/InvisibleParent.java create mode 100644 test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg2/UndocumentedParent.java diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java index 344a2efb5e6..8179c4565a9 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java @@ -265,7 +265,7 @@ public class HtmlConfiguration extends BaseConfiguration { } docPaths = new DocPaths(utils); setCreateOverview(); - setTopFile(docEnv); + setTopFile(); initDocLint(options.doclintOpts(), tagletManager.getAllTagletNames()); return true; } @@ -277,11 +277,9 @@ public class HtmlConfiguration extends BaseConfiguration { * "package-summary.html" of the respective package if there is only one * package to document. It will be a class page(first in the sorted order), * if only classes are provided on the command line. - * - * @param docEnv the doclet environment */ - protected void setTopFile(DocletEnvironment docEnv) { - if (!checkForDeprecation(docEnv)) { + protected void setTopFile() { + if (!checkForDeprecation()) { return; } if (options.createOverview()) { @@ -313,7 +311,7 @@ public class HtmlConfiguration extends BaseConfiguration { return null; } - protected boolean checkForDeprecation(DocletEnvironment docEnv) { + protected boolean checkForDeprecation() { for (TypeElement te : getIncludedTypeElements()) { if (isGeneratedDoc(te)) { return true; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java index af797cebe2d..22bb75df807 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java @@ -313,7 +313,7 @@ public class HtmlDocletWriter { // printed. If no overridden or implementation info needs to be // printed, do not print this section. if ((!intfacs.isEmpty() - && vmt.getImplementedMethods(method).isEmpty() == false) + && !vmt.getImplementedMethods(method).isEmpty()) || overriddenMethod != null) { MethodWriterImpl.addImplementsInfo(this, method, dl); if (overriddenMethod != null) { @@ -806,13 +806,6 @@ public class HtmlDocletWriter { return null; } - public boolean isClassLinkable(TypeElement typeElement) { - if (utils.isIncluded(typeElement)) { - return configuration.isGeneratedDoc(typeElement); - } - return configuration.extern.isExternal(typeElement); - } - public DocLink getCrossPackageLink(PackageElement element) { return configuration.extern.getExternalLink(element, pathToRoot, DocPaths.PACKAGE_SUMMARY.getPath()); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java index e1a61db1bc4..4c4c1759ce4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java @@ -105,7 +105,7 @@ public class HtmlLinkFactory extends LinkFactory { Content link = new ContentBuilder(); if (utils.isIncluded(typeElement)) { - if (configuration.isGeneratedDoc(typeElement)) { + if (configuration.isGeneratedDoc(typeElement) && !utils.hasHiddenTag(typeElement)) { DocPath filename = getPath(classLinkInfo); if (linkInfo.linkToSelf || !(docPaths.forName(typeElement)).equals(m_writer.filename)) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java index 5ef2a15e554..7a28be7282d 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/MethodWriterImpl.java @@ -149,20 +149,22 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter utils.isLinkable(holder))) { writer.addInlineComment(method, methodDocTree); } else { - Content link = - writer.getDocLink(HtmlLinkInfo.Kind.EXECUTABLE_ELEMENT_COPY, - holder, method, - utils.isIncluded(holder) - ? utils.getSimpleName(holder) - : utils.getFullyQualifiedName(holder)); - Content codeLink = HtmlTree.CODE(link); - Content descfrmLabel = HtmlTree.SPAN(HtmlStyle.descfrmTypeLabel, - utils.isClass(holder) - ? contents.descfrmClassLabel - : contents.descfrmInterfaceLabel); - descfrmLabel.add(Entity.NO_BREAK_SPACE); - descfrmLabel.add(codeLink); - methodDocTree.add(HtmlTree.DIV(HtmlStyle.block, descfrmLabel)); + if (!utils.hasHiddenTag(holder) && !utils.hasHiddenTag(method)) { + Content link = + writer.getDocLink(HtmlLinkInfo.Kind.EXECUTABLE_ELEMENT_COPY, + holder, method, + utils.isIncluded(holder) + ? utils.getSimpleName(holder) + : utils.getFullyQualifiedName(holder)); + Content codeLink = HtmlTree.CODE(link); + Content descfrmLabel = HtmlTree.SPAN(HtmlStyle.descfrmTypeLabel, + utils.isClass(holder) + ? contents.descfrmClassLabel + : contents.descfrmInterfaceLabel); + descfrmLabel.add(Entity.NO_BREAK_SPACE); + descfrmLabel.add(codeLink); + methodDocTree.add(HtmlTree.DIV(HtmlStyle.block, descfrmLabel)); + } writer.addInlineComment(method, methodDocTree); } } @@ -265,36 +267,37 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter //is not visible so don't document this. return; } + if (utils.hasHiddenTag(holder) || utils.hasHiddenTag(method)) { + return; + } - if (method != null) { - Contents contents = writer.contents; - Content label; - HtmlLinkInfo.Kind context; - if (utils.isAbstract(holder) && utils.isAbstract(method)){ - //Abstract method is implemented from abstract class, - //not overridden - label = contents.specifiedByLabel; - context = HtmlLinkInfo.Kind.METHOD_SPECIFIED_BY; - } else { - label = contents.overridesLabel; - context = HtmlLinkInfo.Kind.METHOD_OVERRIDES; - } - dl.add(HtmlTree.DT(label)); - Content overriddenTypeLink = - writer.getLink(new HtmlLinkInfo(writer.configuration, context, overriddenType)); - Content codeOverriddenTypeLink = HtmlTree.CODE(overriddenTypeLink); - Content methlink = writer.getLink( - new HtmlLinkInfo(writer.configuration, HtmlLinkInfo.Kind.MEMBER, holder) - .where(writer.htmlIds.forMember(method).name()) - .label(method.getSimpleName())); - Content codeMethLink = HtmlTree.CODE(methlink); - Content dd = HtmlTree.DD(codeMethLink); - dd.add(Entity.NO_BREAK_SPACE); - dd.add(contents.inClass); - dd.add(Entity.NO_BREAK_SPACE); - dd.add(codeOverriddenTypeLink); - dl.add(dd); + Contents contents = writer.contents; + Content label; + HtmlLinkInfo.Kind context; + if (utils.isAbstract(holder) && utils.isAbstract(method)) { + //Abstract method is implemented from abstract class, + //not overridden + label = contents.specifiedByLabel; + context = HtmlLinkInfo.Kind.METHOD_SPECIFIED_BY; + } else { + label = contents.overridesLabel; + context = HtmlLinkInfo.Kind.METHOD_OVERRIDES; } + dl.add(HtmlTree.DT(label)); + Content overriddenTypeLink = + writer.getLink(new HtmlLinkInfo(writer.configuration, context, overriddenType)); + Content codeOverriddenTypeLink = HtmlTree.CODE(overriddenTypeLink); + Content methlink = writer.getLink( + new HtmlLinkInfo(writer.configuration, HtmlLinkInfo.Kind.MEMBER, holder) + .where(writer.htmlIds.forMember(method).name()) + .label(method.getSimpleName())); + Content codeMethLink = HtmlTree.CODE(methlink); + Content dd = HtmlTree.DD(codeMethLink); + dd.add(Entity.NO_BREAK_SPACE); + dd.add(contents.inClass); + dd.add(Entity.NO_BREAK_SPACE); + dd.add(codeOverriddenTypeLink); + dl.add(dd); } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java index 490aaa2e5ea..e4e11c130c3 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PropertyWriterImpl.java @@ -111,19 +111,21 @@ public class PropertyWriterImpl extends AbstractMemberWriter (!utils.isPublic(holder) || utils.isLinkable(holder))) { writer.addInlineComment(property, propertyDocTree); } else { - Content link = - writer.getDocLink(HtmlLinkInfo.Kind.PROPERTY_COPY, - holder, property, - utils.isIncluded(holder) - ? holder.getSimpleName() : holder.getQualifiedName()); - Content codeLink = HtmlTree.CODE(link); - Content descfrmLabel = HtmlTree.SPAN(HtmlStyle.descfrmTypeLabel, - utils.isClass(holder) - ? contents.descfrmClassLabel - : contents.descfrmInterfaceLabel); - descfrmLabel.add(Entity.NO_BREAK_SPACE); - descfrmLabel.add(codeLink); - propertyDocTree.add(HtmlTree.DIV(HtmlStyle.block, descfrmLabel)); + if (!utils.hasHiddenTag(holder) && !utils.hasHiddenTag(property)) { + Content link = + writer.getDocLink(HtmlLinkInfo.Kind.PROPERTY_COPY, + holder, property, + utils.isIncluded(holder) + ? holder.getSimpleName() : holder.getQualifiedName()); + Content codeLink = HtmlTree.CODE(link); + Content descfrmLabel = HtmlTree.SPAN(HtmlStyle.descfrmTypeLabel, + utils.isClass(holder) + ? contents.descfrmClassLabel + : contents.descfrmInterfaceLabel); + descfrmLabel.add(Entity.NO_BREAK_SPACE); + descfrmLabel.add(codeLink); + propertyDocTree.add(HtmlTree.DIV(HtmlStyle.block, descfrmLabel)); + } writer.addInlineComment(property, propertyDocTree); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java index 3efa600dd93..fac5e2ff126 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2021, 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 @@ -137,7 +137,8 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter * @return true if the class, that is being processed, is generated and is visible. */ public boolean isVisibleClass(TypeElement typeElement) { - return visibleClasses.contains(typeElement) && configuration.isGeneratedDoc(typeElement); + return visibleClasses.contains(typeElement) && configuration.isGeneratedDoc(typeElement) + && !utils.hasHiddenTag(typeElement); } /** diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java index 2c6641d9a6e..a3457787f87 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -409,6 +409,9 @@ public abstract class MemberSummaryBuilder extends AbstractMemberBuilder { if (inheritedClass == typeElement) { continue; } + if (utils.hasHiddenTag(inheritedClass)) { + continue; + } List members = inheritedMembersFromMap.stream() .filter(e -> utils.getEnclosingTypeElement(e) == inheritedClass) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java index cabc48511ff..0ccb1f8f4a3 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -552,10 +552,8 @@ public class SerializedFormBuilder extends AbstractBuilder { if (utils.isSerializable(te)) { if (utils.hasDocCommentTree(te) && !utils.getSerialTrees(te).isEmpty()) { return serialDocInclude(utils, te); - } else if (utils.isPublic(te) || utils.isProtected(te)) { - return true; } else { - return false; + return utils.isPublic(te) || utils.isProtected(te); } } return false; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java index bf70e39496a..1f374d53b51 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java @@ -609,7 +609,8 @@ public class Utils { } public boolean isUndocumentedEnclosure(TypeElement enclosingTypeElement) { - return (isPackagePrivate(enclosingTypeElement) || isPrivate(enclosingTypeElement)) + return (isPackagePrivate(enclosingTypeElement) || isPrivate(enclosingTypeElement) + || hasHiddenTag(enclosingTypeElement)) && !isLinkable(enclosingTypeElement); } @@ -1157,10 +1158,11 @@ public class Utils { */ public boolean isLinkable(TypeElement typeElem) { return - (typeElem != null && - (isIncluded(typeElem) && configuration.isGeneratedDoc(typeElem))) || + typeElem != null && + ((isIncluded(typeElem) && configuration.isGeneratedDoc(typeElem) && + !hasHiddenTag(typeElem)) || (configuration.extern.isExternal(typeElem) && - (isPublic(typeElem) || isProtected(typeElem))); + (isPublic(typeElem) || isProtected(typeElem)))); } /** @@ -1183,7 +1185,7 @@ public class Utils { return isLinkable((TypeElement) elem); // defer to existing behavior } - if (isIncluded(elem)) { + if (isIncluded(elem) && !hasHiddenTag(elem)) { return true; } @@ -1553,16 +1555,17 @@ public class Utils { } /** - * Returns true if the element is included, contains @hidden tag, + * Returns true if the element is included or selected, contains @hidden tag, * or if javafx flag is present and element contains @treatAsPrivate * tag. * @param e the queried element * @return true if it exists, false otherwise */ public boolean hasHiddenTag(Element e) { - // prevent needless tests on elements which are not included + // Non-included elements may still be visible via "transclusion" from undocumented enclosures, + // but we don't want to run doclint on them, possibly causing warnings or errors. if (!isIncluded(e)) { - return false; + return hasBlockTagUnchecked(e, HIDDEN); } if (options.javafx() && hasBlockTag(e, DocTree.Kind.UNKNOWN_BLOCK_TAG, "treatAsPrivate")) { @@ -2265,12 +2268,14 @@ public class Utils { } public TypeElement getEnclosingTypeElement(Element e) { - if (e.getKind() == ElementKind.PACKAGE) + if (isPackage(e) || isModule(e)) { return null; + } Element encl = e.getEnclosingElement(); - ElementKind kind = encl.getKind(); - if (kind == ElementKind.PACKAGE) + if (isPackage(encl)) { return null; + } + ElementKind kind = encl.getKind(); while (!(kind.isClass() || kind.isInterface())) { encl = encl.getEnclosingElement(); kind = encl.getKind(); @@ -2591,7 +2596,10 @@ public class Utils { } public List getBlockTags(Element element) { - DocCommentTree dcTree = getDocCommentTree(element); + return getBlockTags(getDocCommentTree(element)); + } + + public List getBlockTags(DocCommentTree dcTree) { return dcTree == null ? Collections.emptyList() : dcTree.getBlockTags(); } @@ -2641,14 +2649,26 @@ public class Utils { public boolean hasBlockTag(Element element, DocTree.Kind kind, final String tagName) { if (hasDocCommentTree(element)) { CommentHelper ch = getCommentHelper(element); - String tname = tagName != null && tagName.startsWith("@") - ? tagName.substring(1) - : tagName; - for (DocTree dt : getBlockTags(element, kind)) { + for (DocTree dt : getBlockTags(ch.dcTree)) { + if (dt.getKind() == kind && (tagName == null || ch.getTagName(dt).equals(tagName))) { + return true; + } + } + } + return false; + } + + /* + * Tests whether an element's doc comment contains a block tag without caching it or + * running doclint on it. This is done by using getDocCommentInfo(Element) to retrieve + * the doc comment info. + */ + boolean hasBlockTagUnchecked(Element element, DocTree.Kind kind) { + DocCommentInfo dcInfo = getDocCommentInfo(element); + if (dcInfo != null && dcInfo.dcTree != null) { + for (DocTree dt : getBlockTags(dcInfo.dcTree)) { if (dt.getKind() == kind) { - if (tname == null || ch.getTagName(dt).equals(tname)) { - return true; - } + return true; } } } @@ -2701,7 +2721,7 @@ public class Utils { /** * Retrieves the doc comments for a given element. - * @param element + * @param element the element * @return DocCommentTree for the Element */ public DocCommentTree getDocCommentTree0(Element element) { @@ -2759,7 +2779,7 @@ public class Utils { private DocCommentInfo getDocCommentInfo0(Element element) { // prevent nasty things downstream with overview element - if (element.getKind() != ElementKind.OTHER) { + if (!isOverviewElement(element)) { TreePath path = getTreePath(element); if (path != null) { DocCommentTree docCommentTree = docTrees.getDocCommentTree(path); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/VisibleMemberTable.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/VisibleMemberTable.java index ea30748cf2f..0d3604b4535 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/VisibleMemberTable.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/VisibleMemberTable.java @@ -126,7 +126,7 @@ public class VisibleMemberTable { private Map propertyMap = new HashMap<>(); // Keeps track of method overrides - Map overriddenMethodTable + Map overriddenMethodTable = new LinkedHashMap<>(); protected VisibleMemberTable(TypeElement typeElement, BaseConfiguration configuration, @@ -240,10 +240,10 @@ public class VisibleMemberTable { public ExecutableElement getOverriddenMethod(ExecutableElement e) { ensureInitialized(); - OverridingMethodInfo found = overriddenMethodTable.get(e); + OverriddenMethodInfo found = overriddenMethodTable.get(e); if (found != null && (found.simpleOverride || utils.isUndocumentedEnclosure(utils.getEnclosingTypeElement(e)))) { - return found.overrider; + return found.overridden; } return null; } @@ -256,9 +256,9 @@ public class VisibleMemberTable { public ExecutableElement getSimplyOverriddenMethod(ExecutableElement e) { ensureInitialized(); - OverridingMethodInfo found = overriddenMethodTable.get(e); + OverriddenMethodInfo found = overriddenMethodTable.get(e); if (found != null && found.simpleOverride) { - return found.overrider; + return found.overridden; } return null; } @@ -475,9 +475,9 @@ public class VisibleMemberTable { for (VisibleMemberTable pvmt : parents) { // Merge the lineage overrides into local table pvmt.overriddenMethodTable.entrySet().forEach(e -> { - OverridingMethodInfo p = e.getValue(); + OverriddenMethodInfo p = e.getValue(); if (!p.simpleOverride) { // consider only real overrides - List list = overriddenByTable.computeIfAbsent(p.overrider, + List list = overriddenByTable.computeIfAbsent(p.overridden, k -> new ArrayList<>()); list.add(e.getKey()); } @@ -486,19 +486,19 @@ public class VisibleMemberTable { } // Filter out inherited methods that: - // a. cannot override (private instance members) + // a. cannot be overridden (private instance members) // b. are overridden and should not be visible in this type // c. are hidden in the type being considered - // see allowInheritedMethods, which performs the above actions + // see allowInheritedMethod, which performs the above actions List list = inheritedMethods.stream() - .filter(e -> allowInheritedMethods((ExecutableElement) e, overriddenByTable, lmt)) + .filter(e -> allowInheritedMethod((ExecutableElement) e, overriddenByTable, lmt)) .collect(Collectors.toList()); // Filter out the local methods, that do not override or simply // overrides a super method, or those methods that should not // be visible. Predicate isVisible = m -> { - OverridingMethodInfo p = overriddenMethodTable.getOrDefault(m, null); + OverriddenMethodInfo p = overriddenMethodTable.getOrDefault(m, null); return p == null || !p.simpleOverride; }; List localList = lmt.getOrderedMembers(Kind.METHODS) @@ -529,9 +529,9 @@ public class VisibleMemberTable { return utils.isInterface(enclosing); } - boolean allowInheritedMethods(ExecutableElement inheritedMethod, - Map> inheritedOverriddenTable, - LocalMemberTable lmt) { + boolean allowInheritedMethod(ExecutableElement inheritedMethod, + Map> overriddenByTable, + LocalMemberTable lmt) { if (!isInherited(inheritedMethod)) return false; @@ -552,7 +552,7 @@ public class VisibleMemberTable { // in favor of concrete overriding methods, for instance those that have // API documentation and are not abstract OR default methods. if (inInterface) { - List list = inheritedOverriddenTable.get(inheritedMethod); + List list = overriddenByTable.get(inheritedMethod); if (list != null) { boolean found = list.stream() .anyMatch(this::isEnclosureInterface); @@ -586,16 +586,19 @@ public class VisibleMemberTable { TypeElement encl = utils.getEnclosingTypeElement(inheritedMethod); if (utils.isUndocumentedEnclosure(encl)) { overriddenMethodTable.computeIfAbsent(lMethod, - l -> new OverridingMethodInfo(inheritedMethod, false)); + l -> new OverriddenMethodInfo(inheritedMethod, false)); return false; } // Even with --override-methods=summary we want to include details of - // overriding method if something noteworthy has been added or changed. + // overriding method if something noteworthy has been added or changed + // either in the local overriding method or an in-between overriding method + // (as evidenced by an entry in overriddenByTable). boolean simpleOverride = utils.isSimpleOverride(lMethod) - && !overridingSignatureChanged(lMethod, inheritedMethod); + && !overridingSignatureChanged(lMethod, inheritedMethod) + && !overriddenByTable.containsKey(inheritedMethod); overriddenMethodTable.computeIfAbsent(lMethod, - l -> new OverridingMethodInfo(inheritedMethod, simpleOverride)); + l -> new OverriddenMethodInfo(inheritedMethod, simpleOverride)); return simpleOverride; } } @@ -1031,21 +1034,21 @@ public class VisibleMemberTable { } /** - * A simple container to encapsulate an overriding method + * A simple container to encapsulate an overridden method * and the type of override. */ - static class OverridingMethodInfo { - final ExecutableElement overrider; + static class OverriddenMethodInfo { + final ExecutableElement overridden; final boolean simpleOverride; - public OverridingMethodInfo(ExecutableElement overrider, boolean simpleOverride) { - this.overrider = overrider; + public OverriddenMethodInfo(ExecutableElement overridden, boolean simpleOverride) { + this.overridden = overridden; this.simpleOverride = simpleOverride; } @Override public String toString() { - return "OverridingMethodInfo[" + overrider + ",simple:" + simpleOverride + "]"; + return "OverriddenMethodInfo[" + overridden + ",simple:" + simpleOverride + "]"; } } } diff --git a/test/langtools/jdk/javadoc/doclet/testHiddenTag/TestHiddenTag.java b/test/langtools/jdk/javadoc/doclet/testHiddenTag/TestHiddenTag.java index 8612ac4d665..4f6bbb12d81 100644 --- a/test/langtools/jdk/javadoc/doclet/testHiddenTag/TestHiddenTag.java +++ b/test/langtools/jdk/javadoc/doclet/testHiddenTag/TestHiddenTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8073100 8182765 8196202 + * @bug 8073100 8182765 8196202 8261079 * @summary ensure the hidden tag works as intended * @library ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -63,9 +63,8 @@ public class TestHiddenTag extends JavadocTester { n pkg1">A.VisibleInnerExtendsInvisibleInner
    """); checkOutput("pkg1/A.html", false, - "

    ", - """ -

    """); + "invisibleField", + "invisibleMethod()"); checkOutput("pkg1/A.VisibleInner.html", true, """ @@ -82,8 +81,8 @@ public class TestHiddenTag extends JavadocTester { checkOutput("pkg1/A.VisibleInner.html", false, "../pkg1/A.VisibleInner.html#VisibleInner()", - "", - ""); + "invisibleField", + "invisibleMethod()"); checkOutput("pkg1/A.VisibleInnerExtendsInvisibleInner.html", true, """ @@ -100,12 +99,63 @@ public class TestHiddenTag extends JavadocTester { "invisibleMethod", "A.InvisibleInner"); + checkOutput("pkg1/Intf.html", true, + """ +
    """, + """ +
    """, + """ +
    All Known Implementing Classes:
    +
    Child
    + """); + + checkOutput("pkg1/Intf.html", false, + "InvisibleParent", + "invisibleDefaultMethod", + "invisibleInterfaceMethod"); + + checkOutput("pkg1/Child.html", true, + """ + InvisibleParent.VisibleInner""", + """ + visibleField""", + """ + invisibleInterfaceMethod""", + """ + visibleInterfaceMethod""", + """ + visibleMethod""", + """ + visibleDefaultMethod""", + // Invisible return or parameter types must not be linked + """ + pkg1.InvisibleParent""", + """ + (pkg1.InvisibleParent<? extends pkg1.InvisibleParent> p)"""); + + checkOutput("pkg1/Child.html", false, + "InvisibleParent.InvisibleInner", + "invisibleField", + "invisibleMethod", + "invisibleDefaultMethod"); + + checkOutput("pkg1/InvisibleParent.VisibleInner.html", true, + """ +
    Enclosing class:
    +
    pkg1.InvisibleParent<T extends pkg1.InvisibleParent>
    + """); + checkOutput("pkg1/package-summary.html", false, "A.InvisibleInner"); checkOutput("pkg1/package-tree.html", false, "A.InvisibleInner"); + checkOutput("pkg1/package-tree.html", false, "InvisibleParent.html"); + checkFiles(false, "pkg1/A.InvisibleInner.html", - "pkg1/A.InvisibleInnerExtendsVisibleInner.html"); + "pkg1/A.InvisibleInnerExtendsVisibleInner.html", + "pkg1/InvisibleParent.html", + "pkg1/InvisibleParent.InvisibleInner.html"); } } diff --git a/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/A.java b/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/A.java index 6e462475b82..87a86043f11 100644 --- a/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/A.java +++ b/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/A.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 diff --git a/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/Child.java b/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/Child.java new file mode 100644 index 00000000000..12bbb1521b3 --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/Child.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg1; + +import pkg2.UndocumentedParent; + +/** + * A visible class, extending invisible classes. + */ +public class Child extends UndocumentedParent { + +} diff --git a/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/Intf.java b/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/Intf.java new file mode 100644 index 00000000000..c3cc0f3b4bb --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/Intf.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg1; + +/** + * An visible interface + */ +public interface Intf { + + /** + * A visible interface method. + */ + void visibleInterfaceMethod(); + + /** + * An invisible interface method. + * @hidden + */ + void invisibleInterfaceMethod(); + + /** + * A visible default method. + */ + default void visibleDefaultMethod() {} + + /** + * An invisible default method. + * @hidden + */ + default void invisibleDefaultMethod() {} + +} diff --git a/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/InvisibleParent.java b/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/InvisibleParent.java new file mode 100644 index 00000000000..7fd1a1daf29 --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg1/InvisibleParent.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg1; + +/** + * @hidden + * @param + */ +public abstract class InvisibleParent implements Intf { + + @Override + public void visibleInterfaceMethod() {} + + /** + * An invisible method made visible in an implementing class. + */ + @Override + public void invisibleInterfaceMethod() {} + + /** + * A visible inner class. + */ + public static class VisibleInner { + /** + * An invisible constructor + * @hidden invisible + */ + public VisibleInner() {} + } + + /** + * An invisible inner class. + * @hidden + */ + public static class InvisibleInner {} + +} diff --git a/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg2/UndocumentedParent.java b/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg2/UndocumentedParent.java new file mode 100644 index 00000000000..687d1ce43e1 --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testHiddenTag/pkg2/UndocumentedParent.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg2; + +import pkg1.InvisibleParent; + +/** + * @hidden + * @param + */ +public class UndocumentedParent extends InvisibleParent { + + /** + * A visible field. + */ + public InvisibleParent visibleField; + + /** + * An invisible field. + * @hidden + */ + public InvisibleParent invisibleField; + + /** + * A visible method with an invisible parameter type. + */ + public void visibleMethod(InvisibleParent p) {} + + /** + * An invisible method. + * @hidden + */ + public void invisibleMethod() {} + +} -- GitLab From ebaa58d9c07f1ac3846bbf8f3736b1b3a5e0a4fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20G=C3=B6ttschkes?= Date: Fri, 12 Feb 2021 09:41:49 +0000 Subject: [PATCH 037/367] 8261505: Test test/hotspot/jtreg/gc/parallel/TestDynShrinkHeap.java killed by Linux OOM Killer Reviewed-by: sjohanss, tschatzl --- test/hotspot/jtreg/gc/parallel/TestDynShrinkHeap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/gc/parallel/TestDynShrinkHeap.java b/test/hotspot/jtreg/gc/parallel/TestDynShrinkHeap.java index 2d9478a2ebb..874087ba583 100644 --- a/test/hotspot/jtreg/gc/parallel/TestDynShrinkHeap.java +++ b/test/hotspot/jtreg/gc/parallel/TestDynShrinkHeap.java @@ -26,7 +26,7 @@ package gc.parallel; /** * @test TestDynShrinkHeap * @bug 8016479 - * @requires vm.gc.Parallel + * @requires vm.gc.Parallel & os.maxMemory > 1G * @summary Verify that the heap shrinks after full GC according to the current values of the Min/MaxHeapFreeRatio flags * @modules java.base/jdk.internal.misc * @modules jdk.management -- GitLab From 682e78e89b35c05590a5bc490e87ae3cab864c02 Mon Sep 17 00:00:00 2001 From: Anton Kozlov Date: Fri, 12 Feb 2021 10:27:47 +0000 Subject: [PATCH 038/367] 8261071: AArch64: Refactor interpreter native wrappers Reviewed-by: aph --- .../cpu/aarch64/interpreterRT_aarch64.cpp | 338 ++++++------------ .../cpu/aarch64/interpreterRT_aarch64.hpp | 8 +- 2 files changed, 119 insertions(+), 227 deletions(-) diff --git a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp index 8a89fb56a83..731e45643aa 100644 --- a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.cpp @@ -43,215 +43,103 @@ Register InterpreterRuntime::SignatureHandlerGenerator::from() { return rlocals; Register InterpreterRuntime::SignatureHandlerGenerator::to() { return sp; } Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; } +Register InterpreterRuntime::SignatureHandlerGenerator::next_gpr() { + if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) { + return as_Register(_num_reg_int_args++ + c_rarg1->encoding()); + } + return noreg; +} + +FloatRegister InterpreterRuntime::SignatureHandlerGenerator::next_fpr() { + if (_num_reg_fp_args < Argument::n_float_register_parameters_c) { + return as_FloatRegister(_num_reg_fp_args++); + } + return fnoreg; +} + +int InterpreterRuntime::SignatureHandlerGenerator::next_stack_offset() { + int ret = _stack_offset; + _stack_offset += wordSize; + return ret; +} + InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator( const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) { _masm = new MacroAssembler(buffer); - _num_int_args = (method->is_static() ? 1 : 0); - _num_fp_args = 0; + _num_reg_int_args = (method->is_static() ? 1 : 0); + _num_reg_fp_args = 0; _stack_offset = 0; } void InterpreterRuntime::SignatureHandlerGenerator::pass_int() { const Address src(from(), Interpreter::local_offset_in_bytes(offset())); - switch (_num_int_args) { - case 0: - __ ldr(c_rarg1, src); - _num_int_args++; - break; - case 1: - __ ldr(c_rarg2, src); - _num_int_args++; - break; - case 2: - __ ldr(c_rarg3, src); - _num_int_args++; - break; - case 3: - __ ldr(c_rarg4, src); - _num_int_args++; - break; - case 4: - __ ldr(c_rarg5, src); - _num_int_args++; - break; - case 5: - __ ldr(c_rarg6, src); - _num_int_args++; - break; - case 6: - __ ldr(c_rarg7, src); - _num_int_args++; - break; - default: - __ ldr(r0, src); - __ str(r0, Address(to(), _stack_offset)); - _stack_offset += wordSize; - _num_int_args++; - break; + Register reg = next_gpr(); + if (reg != noreg) { + __ ldr(reg, src); + } else { + __ ldrw(r0, src); + __ strw(r0, Address(to(), next_stack_offset())); } } void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); - switch (_num_int_args) { - case 0: - __ ldr(c_rarg1, src); - _num_int_args++; - break; - case 1: - __ ldr(c_rarg2, src); - _num_int_args++; - break; - case 2: - __ ldr(c_rarg3, src); - _num_int_args++; - break; - case 3: - __ ldr(c_rarg4, src); - _num_int_args++; - break; - case 4: - __ ldr(c_rarg5, src); - _num_int_args++; - break; - case 5: - __ ldr(c_rarg6, src); - _num_int_args++; - break; - case 6: - __ ldr(c_rarg7, src); - _num_int_args++; - break; - default: + Register reg = next_gpr(); + if (reg != noreg) { + __ ldr(reg, src); + } else { __ ldr(r0, src); - __ str(r0, Address(to(), _stack_offset)); - _stack_offset += wordSize; - _num_int_args++; - break; + __ str(r0, Address(to(), next_stack_offset())); } } void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { const Address src(from(), Interpreter::local_offset_in_bytes(offset())); - if (_num_fp_args < Argument::n_float_register_parameters_c) { - __ ldrs(as_FloatRegister(_num_fp_args++), src); + FloatRegister reg = next_fpr(); + if (reg != fnoreg) { + __ ldrs(reg, src); } else { __ ldrw(r0, src); - __ strw(r0, Address(to(), _stack_offset)); - _stack_offset += wordSize; - _num_fp_args++; + __ strw(r0, Address(to(), next_stack_offset())); } } void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); - if (_num_fp_args < Argument::n_float_register_parameters_c) { - __ ldrd(as_FloatRegister(_num_fp_args++), src); + FloatRegister reg = next_fpr(); + if (reg != fnoreg) { + __ ldrd(reg, src); } else { __ ldr(r0, src); - __ str(r0, Address(to(), _stack_offset)); - _stack_offset += wordSize; - _num_fp_args++; + __ str(r0, Address(to(), next_stack_offset())); } } void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { - - switch (_num_int_args) { - case 0: + Register reg = next_gpr(); + if (reg == c_rarg1) { assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); __ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset())); - _num_int_args++; - break; - case 1: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ mov(c_rarg2, 0); - __ ldr(temp(), r0); - Label L; - __ cbz(temp(), L); - __ mov(c_rarg2, r0); - __ bind(L); - _num_int_args++; - break; - } - case 2: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ mov(c_rarg3, 0); - __ ldr(temp(), r0); - Label L; - __ cbz(temp(), L); - __ mov(c_rarg3, r0); - __ bind(L); - _num_int_args++; - break; - } - case 3: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ mov(c_rarg4, 0); - __ ldr(temp(), r0); - Label L; - __ cbz(temp(), L); - __ mov(c_rarg4, r0); - __ bind(L); - _num_int_args++; - break; - } - case 4: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ mov(c_rarg5, 0); - __ ldr(temp(), r0); - Label L; - __ cbz(temp(), L); - __ mov(c_rarg5, r0); - __ bind(L); - _num_int_args++; - break; - } - case 5: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ mov(c_rarg6, 0); - __ ldr(temp(), r0); - Label L; - __ cbz(temp(), L); - __ mov(c_rarg6, r0); - __ bind(L); - _num_int_args++; - break; - } - case 6: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ mov(c_rarg7, 0); - __ ldr(temp(), r0); - Label L; - __ cbz(temp(), L); - __ mov(c_rarg7, r0); - __ bind(L); - _num_int_args++; - break; - } - default: - { - __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); - __ ldr(temp(), r0); - Label L; - __ cbnz(temp(), L); - __ mov(r0, zr); - __ bind(L); - __ str(r0, Address(to(), _stack_offset)); - _stack_offset += wordSize; - _num_int_args++; - break; - } + } else if (reg != noreg) { + __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); + __ mov(reg, 0); + __ ldr(temp(), r0); + Label L; + __ cbz(temp(), L); + __ mov(reg, r0); + __ bind(L); + } else { + __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); + __ ldr(temp(), r0); + Label L; + __ cbnz(temp(), L); + __ mov(r0, zr); + __ bind(L); + __ str(r0, Address(to(), next_stack_offset())); } } @@ -280,77 +168,77 @@ class SlowSignatureHandler intptr_t* _int_args; intptr_t* _fp_args; intptr_t* _fp_identifiers; - unsigned int _num_int_args; - unsigned int _num_fp_args; + unsigned int _num_reg_int_args; + unsigned int _num_reg_fp_args; - virtual void pass_int() - { - jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); + intptr_t* single_slot_addr() { + intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(0)); _from -= Interpreter::stackElementSize; - - if (_num_int_args < Argument::n_int_register_parameters_c-1) { - *_int_args++ = from_obj; - _num_int_args++; - } else { - *_to++ = from_obj; - _num_int_args++; - } + return from_addr; } - virtual void pass_long() - { - intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); + intptr_t* double_slot_addr() { + intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); _from -= 2*Interpreter::stackElementSize; + return from_addr; + } - if (_num_int_args < Argument::n_int_register_parameters_c-1) { - *_int_args++ = from_obj; - _num_int_args++; - } else { - *_to++ = from_obj; - _num_int_args++; + int pass_gpr(intptr_t value) { + if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) { + *_int_args++ = value; + return _num_reg_int_args++; } + return -1; } - virtual void pass_object() - { - intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); - _from -= Interpreter::stackElementSize; + int pass_fpr(intptr_t value) { + if (_num_reg_fp_args < Argument::n_float_register_parameters_c) { + *_fp_args++ = value; + return _num_reg_fp_args++; + } + return -1; + } - if (_num_int_args < Argument::n_int_register_parameters_c-1) { - *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr; - _num_int_args++; - } else { - *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; - _num_int_args++; + void pass_stack(intptr_t value) { + *_to++ = value; + } + + virtual void pass_int() { + jint value = *(jint*)single_slot_addr(); + if (pass_gpr(value) < 0) { + pass_stack(value); } } - virtual void pass_float() - { - jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0)); - _from -= Interpreter::stackElementSize; + virtual void pass_long() { + intptr_t value = *double_slot_addr(); + if (pass_gpr(value) < 0) { + pass_stack(value); + } + } - if (_num_fp_args < Argument::n_float_register_parameters_c) { - *_fp_args++ = from_obj; - _num_fp_args++; - } else { - *_to++ = from_obj; - _num_fp_args++; + virtual void pass_object() { + intptr_t* addr = single_slot_addr(); + intptr_t value = *addr == 0 ? NULL : (intptr_t)addr; + if (pass_gpr(value) < 0) { + pass_stack(value); } } - virtual void pass_double() - { - intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); - _from -= 2*Interpreter::stackElementSize; + virtual void pass_float() { + jint value = *(jint*)single_slot_addr(); + if (pass_fpr(value) < 0) { + pass_stack(value); + } + } - if (_num_fp_args < Argument::n_float_register_parameters_c) { - *_fp_args++ = from_obj; - *_fp_identifiers |= (1ull << _num_fp_args); // mark as double - _num_fp_args++; + virtual void pass_double() { + intptr_t value = *double_slot_addr(); + int arg = pass_fpr(value); + if (0 <= arg) { + *_fp_identifiers |= (1ull << arg); // mark as double } else { - *_to++ = from_obj; - _num_fp_args++; + pass_stack(value); } } @@ -365,8 +253,8 @@ class SlowSignatureHandler _fp_args = to - 8; _fp_identifiers = to - 9; *(int*) _fp_identifiers = 0; - _num_int_args = (method->is_static() ? 1 : 0); - _num_fp_args = 0; + _num_reg_int_args = (method->is_static() ? 1 : 0); + _num_reg_fp_args = 0; } }; diff --git a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.hpp b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.hpp index ee7c2d1bf76..023760a469f 100644 --- a/src/hotspot/cpu/aarch64/interpreterRT_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/interpreterRT_aarch64.hpp @@ -34,8 +34,8 @@ class SignatureHandlerGenerator: public NativeSignatureIterator { private: MacroAssembler* _masm; - unsigned int _num_fp_args; - unsigned int _num_int_args; + unsigned int _num_reg_fp_args; + unsigned int _num_reg_int_args; int _stack_offset; void pass_int(); @@ -44,6 +44,10 @@ class SignatureHandlerGenerator: public NativeSignatureIterator { void pass_double(); void pass_object(); + Register next_gpr(); + FloatRegister next_fpr(); + int next_stack_offset(); + public: // Creation SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer); -- GitLab From 9ffabf30c33c87ae5347b7abc76c6a2c8b4fda01 Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Fri, 12 Feb 2021 13:08:08 +0000 Subject: [PATCH 039/367] 8252971: WindowsFileAttributes does not know about Unix domain sockets Reviewed-by: alanb --- .../classes/sun/nio/fs/WindowsConstants.java | 2 + .../sun/nio/fs/WindowsFileAttributes.java | 4 + .../classes/sun/nio/fs/WindowsFileCopy.java | 6 ++ .../sun/nio/fs/WindowsFileSystemProvider.java | 12 +++ .../classes/sun/nio/fs/WindowsPath.java | 50 +++++++++- .../native/libjava/WinNTFileSystem_md.c | 60 ++++++++++++ .../native/libnio/ch/UnixDomainSockets.c | 11 +-- .../channels/unixdomain/FileAttributes.java | 97 +++++++++++++++++++ .../nio/channels/unixdomain/Security.java | 8 +- test/jdk/java/nio/channels/unixdomain/policy3 | 2 + 10 files changed, 235 insertions(+), 17 deletions(-) create mode 100644 test/jdk/java/nio/channels/unixdomain/FileAttributes.java diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsConstants.java b/src/java.base/windows/classes/sun/nio/fs/WindowsConstants.java index 5180fbe32d5..6fa8201cca9 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsConstants.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsConstants.java @@ -73,6 +73,7 @@ class WindowsConstants { // reparse point/symbolic link related constants public static final int IO_REPARSE_TAG_SYMLINK = 0xA000000C; + public static final int IO_REPARSE_TAG_AF_UNIX = 0x80000023; public static final int MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024; public static final int SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1; public static final int SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 0x2; @@ -107,6 +108,7 @@ class WindowsConstants { public static final int ERROR_NOTIFY_ENUM_DIR = 1022; public static final int ERROR_PRIVILEGE_NOT_HELD = 1314; public static final int ERROR_NONE_MAPPED = 1332; + public static final int ERROR_CANT_ACCESS_FILE = 1920; public static final int ERROR_NOT_A_REPARSE_POINT = 4390; public static final int ERROR_INVALID_REPARSE_DATA = 4392; diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java b/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java index ab29229ceef..7202f532be7 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java @@ -431,6 +431,10 @@ class WindowsFileAttributes return reparseTag == IO_REPARSE_TAG_SYMLINK; } + boolean isUnixDomainSocket() { + return reparseTag == IO_REPARSE_TAG_AF_UNIX; + } + @Override public boolean isDirectory() { // ignore FILE_ATTRIBUTE_DIRECTORY attribute if file is a sym link diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java b/src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java index 2fe40b78204..30769680dc1 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java @@ -139,6 +139,12 @@ class WindowsFileCopy { sm.checkPermission(new LinkPermission("symbolic")); } + // if source is a Unix domain socket, we don't want to copy it for various + // reasons including consistency with Unix + if (sourceAttrs.isUnixDomainSocket()) { + throw new IOException("Can not copy socket file"); + } + final String sourcePath = asWin32Path(source); final String targetPath = asWin32Path(target); diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java b/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java index 14b36305dba..f380267adff 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java @@ -334,6 +334,13 @@ class WindowsFileSystemProvider 0L); fc.close(); } catch (WindowsException exc) { + try { + if (exc.lastError() == ERROR_CANT_ACCESS_FILE && isUnixDomainSocket(file)) { + // socket file is accessible + return; + } + } catch (WindowsException ignore) {} + // Windows errors are very inconsistent when the file is a directory // (ERROR_PATH_NOT_FOUND returned for root directories for example) // so we retry by attempting to open it as a directory. @@ -346,6 +353,11 @@ class WindowsFileSystemProvider } } + private static boolean isUnixDomainSocket(WindowsPath path) throws WindowsException { + WindowsFileAttributes attrs = WindowsFileAttributes.get(path, false); + return attrs.isUnixDomainSocket(); + } + @Override public void checkAccess(Path obj, AccessMode... modes) throws IOException { WindowsPath file = WindowsPath.toWindowsPath(obj); diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java b/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java index 4b6e9068f48..eac4695b0cc 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java @@ -831,12 +831,52 @@ class WindowsPath implements Path { int flags = FILE_FLAG_BACKUP_SEMANTICS; if (!followLinks) flags |= FILE_FLAG_OPEN_REPARSE_POINT; + try { + return openFileForReadAttributeAccess(flags); + } catch (WindowsException e) { + if (followLinks && e.lastError() == ERROR_CANT_ACCESS_FILE) { + // Object could be a Unix domain socket + try { + return openSocketForReadAttributeAccess(); + } catch (WindowsException ignore) {} + } + throw e; + } + } + + private long openFileForReadAttributeAccess(int flags) + throws WindowsException + { return CreateFile(getPathForWin32Calls(), - FILE_READ_ATTRIBUTES, - (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), - 0L, - OPEN_EXISTING, - flags); + FILE_READ_ATTRIBUTES, + (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), + 0L, + OPEN_EXISTING, + flags); + } + + /** + * Returns a handle to the file if it is a socket. + * Throws WindowsException if file is not a socket + */ + private long openSocketForReadAttributeAccess() + throws WindowsException + { + // needs to specify FILE_FLAG_OPEN_REPARSE_POINT if the file is a socket + int flags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT; + + long handle = openFileForReadAttributeAccess(flags); + + try { + WindowsFileAttributes attrs = WindowsFileAttributes.readAttributes(handle); + if (!attrs.isUnixDomainSocket()) { + throw new WindowsException("not a socket"); + } + return handle; + } catch (WindowsException e) { + CloseHandle(handle); + throw e; + } } void checkRead() { diff --git a/src/java.base/windows/native/libjava/WinNTFileSystem_md.c b/src/java.base/windows/native/libjava/WinNTFileSystem_md.c index faa015f17cc..adab62ac0c3 100644 --- a/src/java.base/windows/native/libjava/WinNTFileSystem_md.c +++ b/src/java.base/windows/native/libjava/WinNTFileSystem_md.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "jni.h" #include "io_util.h" @@ -187,6 +188,60 @@ static BOOL getFileInformation(const WCHAR *path, return result; } +/** + * path is likely to be a Unix domain socket. + * Verify and if it is return its attributes + */ +static DWORD getFinalAttributesUnixSocket(const WCHAR *path) +{ + DWORD result; + BY_HANDLE_FILE_INFORMATION finfo; + REPARSE_GUID_DATA_BUFFER reparse; + + HANDLE h = CreateFileW(path, + FILE_READ_ATTRIBUTES, + FILE_SHARE_DELETE | + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | + FILE_FLAG_OPEN_REPARSE_POINT, + NULL); + + if (h == INVALID_HANDLE_VALUE) + return INVALID_FILE_ATTRIBUTES; + + + if (!GetFileInformationByHandle(h, &finfo)) { + DWORD error = GetLastError(); + if (CloseHandle(h)) { + SetLastError(error); + } + return INVALID_FILE_ATTRIBUTES; + } + + if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0) { + CloseHandle(h); + return INVALID_FILE_ATTRIBUTES; + } + + /* check the reparse tag */ + + if (DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, &reparse, + (DWORD)sizeof(reparse), &result, NULL) == 0) { + CloseHandle(h); + return INVALID_FILE_ATTRIBUTES; + } + + if (reparse.ReparseTag != IO_REPARSE_TAG_AF_UNIX) { + CloseHandle(h); + return INVALID_FILE_ATTRIBUTES; + } + + CloseHandle(h); + return finfo.dwFileAttributes; +} + /** * If the given attributes are the attributes of a reparse point, then * read and return the attributes of the special cases. @@ -217,6 +272,11 @@ DWORD getFinalAttributes(WCHAR *path) if (GetFileAttributesExW(path, GetFileExInfoStandard, &wfad)) { attr = getFinalAttributesIfReparsePoint(path, wfad.dwFileAttributes); + if (attr == INVALID_FILE_ATTRIBUTES) { + if (GetLastError() == ERROR_CANT_ACCESS_FILE) { + attr = getFinalAttributesUnixSocket(path); + } + } } else { DWORD lerr = GetLastError(); if ((lerr == ERROR_SHARING_VIOLATION || lerr == ERROR_ACCESS_DENIED) && diff --git a/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c b/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c index af033676815..1869009a1f9 100644 --- a/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c +++ b/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c @@ -92,16 +92,7 @@ Java_sun_nio_ch_UnixDomainSockets_socketSupported(JNIEnv *env, jclass cl) return JNI_FALSE; } closesocket(s); - - /* Check for build 18362 or newer, due to Windows bug described in 8259014 */ - - OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 }; - DWORDLONG cond_mask = 0; - - VER_SET_CONDITION(cond_mask, VER_BUILDNUMBER, VER_GREATER_EQUAL); - osvi.dwBuildNumber = 18362; // Windows 10 (1903) or newer - - return VerifyVersionInfoW(&osvi, VER_BUILDNUMBER, cond_mask) != 0; + return JNI_TRUE; } JNIEXPORT jint JNICALL diff --git a/test/jdk/java/nio/channels/unixdomain/FileAttributes.java b/test/jdk/java/nio/channels/unixdomain/FileAttributes.java new file mode 100644 index 00000000000..3ff92a6bc05 --- /dev/null +++ b/test/jdk/java/nio/channels/unixdomain/FileAttributes.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8252971 + * @library /test/lib + * @run testng FileAttributes + */ + +import java.io.IOException; +import java.io.File; +import java.net.*; +import java.nio.channels.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.Arrays; +import org.testng.annotations.Test; +import org.testng.SkipException; + +import static java.net.StandardProtocolFamily.UNIX; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertThrows; +import static org.testng.Assert.assertTrue; + +/** + */ +public class FileAttributes { + + @Test + public static void test() throws Exception { + checkSupported(); + Path path = null; + try (var chan = SocketChannel.open(UNIX)) { + path = Path.of("foo.sock"); + var addr = UnixDomainSocketAddress.of(path); + + chan.bind(addr); + + // Check file exists + + File f = path.toFile(); + assertTrue(f.exists(), "File.exists failed"); + + assertTrue(Files.exists(path), "Files.exists failed"); + + // Check basic attributes + BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class); + + assertFalse(attrs.isDirectory(), "file is not a directory"); + assertTrue(attrs.isOther(), "file is other"); + assertFalse(attrs.isRegularFile(), "file is not a regular file"); + assertFalse(attrs.isSymbolicLink(), "file is not a symbolic link"); + + // Check can't copy + final Path src = path; + final Path dest = Path.of("bar.sock"); + assertThrows(IOException.class, () -> Files.copy(src, dest)); + + // Check deletion + assertTrue(f.delete(), "File.delete failed"); + } finally { + Files.deleteIfExists(path); + } + } + + static void checkSupported() { + try { + SocketChannel.open(UNIX).close(); + } catch (UnsupportedOperationException e) { + throw new SkipException("Unix domain channels not supported"); + } catch (Exception e) { + // continue test to see what problem is + } + } +} diff --git a/test/jdk/java/nio/channels/unixdomain/Security.java b/test/jdk/java/nio/channels/unixdomain/Security.java index 06f52ec33b3..a207cd814e9 100644 --- a/test/jdk/java/nio/channels/unixdomain/Security.java +++ b/test/jdk/java/nio/channels/unixdomain/Security.java @@ -162,6 +162,7 @@ public class Security { public static void testPolicy3() throws Exception { Path sock1 = Path.of("sock3"); + Path sock2 = null; Files.deleteIfExists(sock1); final UnixDomainSocketAddress saddr = UnixDomainSocketAddress.of(sock1); try (var s1 = ServerSocketChannel.open(UNIX)) { @@ -169,8 +170,7 @@ public class Security { try (var s2 = ServerSocketChannel.open(UNIX)) { s2.bind(null); var add2 = (UnixDomainSocketAddress)s2.getLocalAddress(); - saddr.getPath().toFile().deleteOnExit(); - add2.getPath().toFile().deleteOnExit(); + sock2 = add2.getPath(); // Now set security manager and check if we can see addresses @@ -194,6 +194,10 @@ public class Security { throw new RuntimeException("address should have been empty"); } } + } finally { + System.setSecurityManager(null); + Files.deleteIfExists(sock1); + Files.deleteIfExists(sock2); } } } diff --git a/test/jdk/java/nio/channels/unixdomain/policy3 b/test/jdk/java/nio/channels/unixdomain/policy3 index ccfe2ef15a7..89edb67117a 100644 --- a/test/jdk/java/nio/channels/unixdomain/policy3 +++ b/test/jdk/java/nio/channels/unixdomain/policy3 @@ -23,4 +23,6 @@ grant { // No permission permission java.io.FilePermission "sock", "delete"; + + permission java.lang.RuntimePermission "setSecurityManager"; }; -- GitLab From 40ae9937a01681bbb8ac4f01e7f7e3dada0c9086 Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Fri, 12 Feb 2021 13:12:02 +0000 Subject: [PATCH 040/367] 8261027: AArch64: Support for LSE atomics C++ HotSpot code Reviewed-by: adinn, simonis --- src/hotspot/cpu/aarch64/atomic_aarch64.hpp | 46 +++++ .../cpu/aarch64/macroAssembler_aarch64.cpp | 2 + .../cpu/aarch64/macroAssembler_aarch64.hpp | 2 + .../cpu/aarch64/stubGenerator_aarch64.cpp | 125 ++++++++++++- .../linux_aarch64/atomic_linux_aarch64.S | 96 ++++++++++ .../linux_aarch64/atomic_linux_aarch64.hpp | 168 ++++++++++++++---- 6 files changed, 405 insertions(+), 34 deletions(-) create mode 100644 src/hotspot/cpu/aarch64/atomic_aarch64.hpp create mode 100644 src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S diff --git a/src/hotspot/cpu/aarch64/atomic_aarch64.hpp b/src/hotspot/cpu/aarch64/atomic_aarch64.hpp new file mode 100644 index 00000000000..dc35fc40cab --- /dev/null +++ b/src/hotspot/cpu/aarch64/atomic_aarch64.hpp @@ -0,0 +1,46 @@ +/* Copyright (c) 2021, Red Hat Inc. 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef CPU_AARCH64_ATOMIC_AARCH64_HPP +#define CPU_AARCH64_ATOMIC_AARCH64_HPP + +// Atomic stub implementation. +// Default implementations are in atomic_linux_aarch64.S +// +// All stubs pass arguments the same way +// x0: src/dest address +// x1: arg1 +// x2: arg2 (optional) +// x3, x8, x9: scratch +typedef uint64_t (*aarch64_atomic_stub_t)(volatile void *ptr, uint64_t arg1, uint64_t arg2); + +// Pointers to stubs +extern aarch64_atomic_stub_t aarch64_atomic_fetch_add_4_impl; +extern aarch64_atomic_stub_t aarch64_atomic_fetch_add_8_impl; +extern aarch64_atomic_stub_t aarch64_atomic_xchg_4_impl; +extern aarch64_atomic_stub_t aarch64_atomic_xchg_8_impl; +extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_1_impl; +extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_4_impl; +extern aarch64_atomic_stub_t aarch64_atomic_cmpxchg_8_impl; + +#endif // CPU_AARCH64_ATOMIC_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index b742edb47dc..c47ec409fe0 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -2567,6 +2567,8 @@ void MacroAssembler::atomic_##OP(Register prev, Register newv, Register addr) { ATOMIC_XCHG(xchg, swp, ldxr, stxr, Assembler::xword) ATOMIC_XCHG(xchgw, swp, ldxrw, stxrw, Assembler::word) +ATOMIC_XCHG(xchgl, swpl, ldxr, stlxr, Assembler::xword) +ATOMIC_XCHG(xchglw, swpl, ldxrw, stlxrw, Assembler::word) ATOMIC_XCHG(xchgal, swpal, ldaxr, stlxr, Assembler::xword) ATOMIC_XCHG(xchgalw, swpal, ldaxrw, stlxrw, Assembler::word) diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index 4ffc97bb377..f4033a13d89 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -1039,6 +1039,8 @@ public: void atomic_xchg(Register prev, Register newv, Register addr); void atomic_xchgw(Register prev, Register newv, Register addr); + void atomic_xchgl(Register prev, Register newv, Register addr); + void atomic_xchglw(Register prev, Register newv, Register addr); void atomic_xchgal(Register prev, Register newv, Register addr); void atomic_xchgalw(Register prev, Register newv, Register addr); diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index 1cd6e171c6e..1d3ff1b2e69 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -26,6 +26,7 @@ #include "precompiled.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" +#include "atomic_aarch64.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/gc_globals.hpp" @@ -38,6 +39,7 @@ #include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" #include "prims/methodHandles.hpp" +#include "runtime/atomic.hpp" #include "runtime/frame.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/sharedRuntime.hpp" @@ -1361,7 +1363,7 @@ class StubGenerator: public StubCodeGenerator { // // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let // the hardware handle it. The two dwords within qwords that span - // cache line boundaries will still be loaded and stored atomicly. + // cache line boundaries will still be loaded and stored atomically. // // Side Effects: // disjoint_int_copy_entry is set to the no-overlap entry point @@ -1431,7 +1433,7 @@ class StubGenerator: public StubCodeGenerator { // // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let // the hardware handle it. The two dwords within qwords that span - // cache line boundaries will still be loaded and stored atomicly. + // cache line boundaries will still be loaded and stored atomically. // address generate_conjoint_copy(int size, bool aligned, bool is_oop, address nooverlap_target, address *entry, const char *name, @@ -1596,7 +1598,7 @@ class StubGenerator: public StubCodeGenerator { // // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let // the hardware handle it. The two dwords within qwords that span - // cache line boundaries will still be loaded and stored atomicly. + // cache line boundaries will still be loaded and stored atomically. // // Side Effects: // disjoint_int_copy_entry is set to the no-overlap entry point @@ -1620,7 +1622,7 @@ class StubGenerator: public StubCodeGenerator { // // If 'from' and/or 'to' are aligned on 4-byte boundaries, we let // the hardware handle it. The two dwords within qwords that span - // cache line boundaries will still be loaded and stored atomicly. + // cache line boundaries will still be loaded and stored atomically. // address generate_conjoint_int_copy(bool aligned, address nooverlap_target, address *entry, const char *name, @@ -5571,6 +5573,91 @@ class StubGenerator: public StubCodeGenerator { return start; } +#ifdef LINUX + // ARMv8.1 LSE versions of the atomic stubs used by Atomic::PlatformXX. + // + // If LSE is in use, generate LSE versions of all the stubs. The + // non-LSE versions are in atomic_aarch64.S. + void generate_atomic_entry_points() { + + if (! UseLSE) { + return; + } + + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "atomic entry points"); + + __ align(32); + aarch64_atomic_fetch_add_8_impl = (aarch64_atomic_stub_t)__ pc(); + { + Register prev = r2, addr = c_rarg0, incr = c_rarg1; + __ atomic_addal(prev, incr, addr); + __ mov(r0, prev); + __ ret(lr); + } + __ align(32); + aarch64_atomic_fetch_add_4_impl = (aarch64_atomic_stub_t)__ pc(); + { + Register prev = r2, addr = c_rarg0, incr = c_rarg1; + __ atomic_addalw(prev, incr, addr); + __ movw(r0, prev); + __ ret(lr); + } + __ align(32); + aarch64_atomic_xchg_4_impl = (aarch64_atomic_stub_t)__ pc(); + { + Register prev = r2, addr = c_rarg0, newv = c_rarg1; + __ atomic_xchglw(prev, newv, addr); + __ movw(r0, prev); + __ ret(lr); + } + __ align(32); + aarch64_atomic_xchg_8_impl = (aarch64_atomic_stub_t)__ pc(); + { + Register prev = r2, addr = c_rarg0, newv = c_rarg1; + __ atomic_xchgl(prev, newv, addr); + __ mov(r0, prev); + __ ret(lr); + } + __ align(32); + aarch64_atomic_cmpxchg_1_impl = (aarch64_atomic_stub_t)__ pc(); + { + Register prev = r3, ptr = c_rarg0, compare_val = c_rarg1, + exchange_val = c_rarg2; + __ cmpxchg(ptr, compare_val, exchange_val, + MacroAssembler::byte, + /*acquire*/false, /*release*/false, /*weak*/false, + prev); + __ movw(r0, prev); + __ ret(lr); + } + __ align(32); + aarch64_atomic_cmpxchg_4_impl = (aarch64_atomic_stub_t)__ pc(); + { + Register prev = r3, ptr = c_rarg0, compare_val = c_rarg1, + exchange_val = c_rarg2; + __ cmpxchg(ptr, compare_val, exchange_val, + MacroAssembler::word, + /*acquire*/false, /*release*/false, /*weak*/false, + prev); + __ movw(r0, prev); + __ ret(lr); + } + __ align(32); + aarch64_atomic_cmpxchg_8_impl = (aarch64_atomic_stub_t)__ pc(); + { + Register prev = r3, ptr = c_rarg0, compare_val = c_rarg1, + exchange_val = c_rarg2; + __ cmpxchg(ptr, compare_val, exchange_val, + MacroAssembler::xword, + /*acquire*/false, /*release*/false, /*weak*/false, + prev); + __ mov(r0, prev); + __ ret(lr); + } + } +#endif // LINUX + // Continuation point for throwing of implicit exceptions that are // not handled in the current activation. Fabricates an exception // oop and initiates normal exception dispatching in this @@ -6683,6 +6770,12 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32(); } +#ifdef LINUX + + generate_atomic_entry_points(); + +#endif // LINUX + StubRoutines::aarch64::set_completed(); } @@ -6703,3 +6796,27 @@ void StubGenerator_generate(CodeBuffer* code, bool all) { } StubGenerator g(code, all); } + + +#ifdef LINUX + +// Define pointers to atomic stubs and initialize them to point to the +// code in atomic_aarch64.S. + +#define DEFAULT_ATOMIC_OP(OPNAME, SIZE) \ + extern "C" uint64_t aarch64_atomic_ ## OPNAME ## _ ## SIZE ## _default_impl \ + (volatile void *ptr, uint64_t arg1, uint64_t arg2); \ + aarch64_atomic_stub_t aarch64_atomic_ ## OPNAME ## _ ## SIZE ## _impl \ + = aarch64_atomic_ ## OPNAME ## _ ## SIZE ## _default_impl; + +DEFAULT_ATOMIC_OP(fetch_add, 4) +DEFAULT_ATOMIC_OP(fetch_add, 8) +DEFAULT_ATOMIC_OP(xchg, 4) +DEFAULT_ATOMIC_OP(xchg, 8) +DEFAULT_ATOMIC_OP(cmpxchg, 1) +DEFAULT_ATOMIC_OP(cmpxchg, 4) +DEFAULT_ATOMIC_OP(cmpxchg, 8) + +#undef DEFAULT_ATOMIC_OP + +#endif // LINUX diff --git a/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S b/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S new file mode 100644 index 00000000000..512b51cc4cd --- /dev/null +++ b/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S @@ -0,0 +1,96 @@ +// Copyright (c) 2021, Red Hat Inc. 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. + +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// version 2 for more details (a copy is included in the LICENSE file that +// accompanied this code). + +// You should have received a copy of the GNU General Public License version +// 2 along with this work; if not, write to the Free Software Foundation, +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +// or visit www.oracle.com if you need additional information or have any +// questions. + + + + .text + + .globl aarch64_atomic_fetch_add_8_default_impl + .align 5 +aarch64_atomic_fetch_add_8_default_impl: +0: ldaxr x2, [x0] + add x8, x2, x1 + stlxr w9, x8, [x0] + cbnz w9, 0b + mov x0, x2 + ret + + .globl aarch64_atomic_fetch_add_4_default_impl + .align 5 +aarch64_atomic_fetch_add_4_default_impl: +0: ldaxr w2, [x0] + add w8, w2, w1 + stlxr w9, w8, [x0] + cbnz w9, 0b + mov w0, w2 + ret + + .globl aarch64_atomic_xchg_4_default_impl + .align 5 +aarch64_atomic_xchg_4_default_impl: +0: ldaxr w2, [x0] + stlxr w8, w1, [x0] + cbnz w8, 0b + mov w0, w2 + ret + + .globl aarch64_atomic_xchg_8_default_impl + .align 5 +aarch64_atomic_xchg_8_default_impl: +0: ldaxr x2, [x0] + stlxr w8, x1, [x0] + cbnz w8, 0b + mov x0, x2 + ret + + .globl aarch64_atomic_cmpxchg_1_default_impl + .align 5 +aarch64_atomic_cmpxchg_1_default_impl: +0: ldxrb w3, [x0] + eor w8, w3, w1 + tst x8, #0xff + b.ne 1f + stxrb w8, w2, [x0] + cbnz w8, 0b +1: mov w0, w3 + ret + + .globl aarch64_atomic_cmpxchg_4_default_impl + .align 5 +aarch64_atomic_cmpxchg_4_default_impl: +0: ldxr w3, [x0] + cmp w3, w1 + b.ne 1f + stxr w8, w2, [x0] + cbnz w8, 0b +1: mov w0, w3 + ret + + .globl aarch64_atomic_cmpxchg_8_default_impl + .align 5 +aarch64_atomic_cmpxchg_8_default_impl: +0: ldxr x3, [x0] + cmp x3, x1 + b.ne 1f + stxr w8, x2, [x0] + cbnz w8, 0b +1: mov x0, x3 + ret diff --git a/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp b/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp index 8e275a4173e..2767e33049e 100644 --- a/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp +++ b/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.hpp @@ -1,6 +1,6 @@ /* * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved. + * Copyright (c) 2014, 2021, Red Hat Inc. 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 @@ -26,58 +26,166 @@ #ifndef OS_CPU_LINUX_AARCH64_ATOMIC_LINUX_AARCH64_HPP #define OS_CPU_LINUX_AARCH64_ATOMIC_LINUX_AARCH64_HPP +#include "atomic_aarch64.hpp" #include "runtime/vm_version.hpp" // Implementation of class atomic + // Note that memory_order_conservative requires a full barrier after atomic stores. // See https://patchwork.kernel.org/patch/3575821/ +// Call one of the stubs from C++. This uses the C calling convention, +// but this asm definition is used in order only to clobber the +// registers we use. If we called the stubs via an ABI call we'd have +// to save X0 - X18 and most of the vectors. +// +// This really ought to be a template definition, but see GCC Bug +// 33661, template methods forget explicit local register asm +// vars. The problem is that register specifiers attached to local +// variables are ignored in any template function. +inline uint64_t bare_atomic_fastcall(address stub, volatile void *ptr, uint64_t arg1, uint64_t arg2 = 0) { + register uint64_t reg0 __asm__("x0") = (uint64_t)ptr; + register uint64_t reg1 __asm__("x1") = arg1; + register uint64_t reg2 __asm__("x2") = arg2; + register uint64_t reg3 __asm__("x3") = (uint64_t)stub; + register uint64_t result __asm__("x0"); + asm volatile(// "stp x29, x30, [sp, #-16]!;" + " blr %1;" + // " ldp x29, x30, [sp], #16 // regs %0, %1, %2, %3, %4" + : "=r"(result), "+r"(reg3), "+r"(reg2) + : "r"(reg1), "0"(reg0) : "x8", "x9", "x30", "cc", "memory"); + return result; +} + +template +inline D atomic_fastcall(F stub, volatile D *dest, T1 arg1) { + return (D)bare_atomic_fastcall(CAST_FROM_FN_PTR(address, stub), + dest, (uint64_t)arg1); +} + +template +inline D atomic_fastcall(F stub, volatile D *dest, T1 arg1, T2 arg2) { + return (D)bare_atomic_fastcall(CAST_FROM_FN_PTR(address, stub), + dest, (uint64_t)arg1, (uint64_t)arg2); +} + template struct Atomic::PlatformAdd { template - D add_and_fetch(D volatile* dest, I add_value, atomic_memory_order order) const { - D res = __atomic_add_fetch(dest, add_value, __ATOMIC_RELEASE); - FULL_MEM_BARRIER; - return res; - } + D fetch_and_add(D volatile* dest, I add_value, atomic_memory_order order) const; template - D fetch_and_add(D volatile* dest, I add_value, atomic_memory_order order) const { - return add_and_fetch(dest, add_value, order) - add_value; + D add_and_fetch(D volatile* dest, I add_value, atomic_memory_order order) const { + D value = fetch_and_add(dest, add_value, order) + add_value; + return value; } }; -template +template<> +template +inline D Atomic::PlatformAdd<4>::fetch_and_add(D volatile* dest, I add_value, + atomic_memory_order order) const { + STATIC_ASSERT(4 == sizeof(I)); + STATIC_ASSERT(4 == sizeof(D)); + D old_value + = atomic_fastcall(aarch64_atomic_fetch_add_4_impl, dest, add_value); + FULL_MEM_BARRIER; + return old_value; +} + +template<> +template +inline D Atomic::PlatformAdd<8>::fetch_and_add(D volatile* dest, I add_value, + atomic_memory_order order) const { + STATIC_ASSERT(8 == sizeof(I)); + STATIC_ASSERT(8 == sizeof(D)); + D old_value + = atomic_fastcall(aarch64_atomic_fetch_add_8_impl, dest, add_value); + FULL_MEM_BARRIER; + return old_value; +} + +template<> template -inline T Atomic::PlatformXchg::operator()(T volatile* dest, - T exchange_value, - atomic_memory_order order) const { - STATIC_ASSERT(byte_size == sizeof(T)); - T res = __atomic_exchange_n(dest, exchange_value, __ATOMIC_RELEASE); +inline T Atomic::PlatformXchg<4>::operator()(T volatile* dest, + T exchange_value, + atomic_memory_order order) const { + STATIC_ASSERT(4 == sizeof(T)); + T old_value = atomic_fastcall(aarch64_atomic_xchg_4_impl, dest, exchange_value); FULL_MEM_BARRIER; - return res; + return old_value; } -// __attribute__((unused)) on dest is to get rid of spurious GCC warnings. -template +template<> +template +inline T Atomic::PlatformXchg<8>::operator()(T volatile* dest, T exchange_value, + atomic_memory_order order) const { + STATIC_ASSERT(8 == sizeof(T)); + T old_value = atomic_fastcall(aarch64_atomic_xchg_8_impl, dest, exchange_value); + FULL_MEM_BARRIER; + return old_value; +} + +template<> template -inline T Atomic::PlatformCmpxchg::operator()(T volatile* dest __attribute__((unused)), - T compare_value, - T exchange_value, - atomic_memory_order order) const { - STATIC_ASSERT(byte_size == sizeof(T)); +inline T Atomic::PlatformCmpxchg<1>::operator()(T volatile* dest, + T compare_value, + T exchange_value, + atomic_memory_order order) const { + STATIC_ASSERT(1 == sizeof(T)); + aarch64_atomic_stub_t stub = aarch64_atomic_cmpxchg_1_impl; if (order == memory_order_relaxed) { - T value = compare_value; - __atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false, - __ATOMIC_RELAXED, __ATOMIC_RELAXED); - return value; + T old_value = atomic_fastcall(stub, dest, + compare_value, exchange_value); + return old_value; } else { - T value = compare_value; FULL_MEM_BARRIER; - __atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false, - __ATOMIC_RELAXED, __ATOMIC_RELAXED); + T old_value = atomic_fastcall(stub, dest, + compare_value, exchange_value); FULL_MEM_BARRIER; - return value; + return old_value; + } +} + +template<> +template +inline T Atomic::PlatformCmpxchg<4>::operator()(T volatile* dest, + T compare_value, + T exchange_value, + atomic_memory_order order) const { + STATIC_ASSERT(4 == sizeof(T)); + aarch64_atomic_stub_t stub = aarch64_atomic_cmpxchg_4_impl; + if (order == memory_order_relaxed) { + T old_value = atomic_fastcall(stub, dest, + compare_value, exchange_value); + return old_value; + } else { + FULL_MEM_BARRIER; + T old_value = atomic_fastcall(stub, dest, + compare_value, exchange_value); + FULL_MEM_BARRIER; + return old_value; + } +} + +template<> +template +inline T Atomic::PlatformCmpxchg<8>::operator()(T volatile* dest, + T compare_value, + T exchange_value, + atomic_memory_order order) const { + STATIC_ASSERT(8 == sizeof(T)); + aarch64_atomic_stub_t stub = aarch64_atomic_cmpxchg_8_impl; + if (order == memory_order_relaxed) { + T old_value = atomic_fastcall(stub, dest, + compare_value, exchange_value); + return old_value; + } else { + FULL_MEM_BARRIER; + T old_value = atomic_fastcall(stub, dest, + compare_value, exchange_value); + FULL_MEM_BARRIER; + return old_value; } } -- GitLab From 9f81ca8175a036027a3f5f19772c49bc4766411c Mon Sep 17 00:00:00 2001 From: Stefan Johansson Date: Fri, 12 Feb 2021 14:56:25 +0000 Subject: [PATCH 041/367] 8261230: GC tracing of page sizes are wrong in a few places Reviewed-by: ayang, stuefe --- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 2 +- .../share/gc/parallel/parMarkBitMap.cpp | 3 +- .../share/gc/shared/genCollectedHeap.cpp | 3 +- .../gc/g1/TestLargePageUseForAuxMemory.java | 45 +++++++++++++++++-- 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 8f33eac4443..2b97e7f7a1a 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1497,8 +1497,8 @@ G1RegionToSpaceMapper* G1CollectedHeap::create_aux_memory_mapper(const char* des os::trace_page_sizes_for_requested_size(description, size, - preferred_page_size, page_size, + preferred_page_size, rs.base(), rs.size()); diff --git a/src/hotspot/share/gc/parallel/parMarkBitMap.cpp b/src/hotspot/share/gc/parallel/parMarkBitMap.cpp index f26992f4120..d08762b2ca1 100644 --- a/src/hotspot/share/gc/parallel/parMarkBitMap.cpp +++ b/src/hotspot/share/gc/parallel/parMarkBitMap.cpp @@ -50,7 +50,8 @@ ParMarkBitMap::initialize(MemRegion covered_region) const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 : MAX2(page_sz, granularity); ReservedSpace rs(_reserved_byte_size, rs_align, rs_align > 0); - os::trace_page_sizes("Mark Bitmap", raw_bytes, raw_bytes, page_sz, + const size_t used_page_sz = ReservedSpace::actual_reserved_page_size(rs); + os::trace_page_sizes("Mark Bitmap", raw_bytes, raw_bytes, used_page_sz, rs.base(), rs.size()); MemTracker::record_virtual_memory_type((address)rs.base(), mtGC); diff --git a/src/hotspot/share/gc/shared/genCollectedHeap.cpp b/src/hotspot/share/gc/shared/genCollectedHeap.cpp index e498d54da11..a0b6d44637c 100644 --- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp +++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp @@ -172,11 +172,12 @@ ReservedHeapSpace GenCollectedHeap::allocate(size_t alignment) { SIZE_FORMAT, total_reserved, alignment); ReservedHeapSpace heap_rs = Universe::reserve_heap(total_reserved, alignment); + size_t used_page_size = ReservedSpace::actual_reserved_page_size(heap_rs); os::trace_page_sizes("Heap", MinHeapSize, total_reserved, - alignment, + used_page_size, heap_rs.base(), heap_rs.size()); diff --git a/test/hotspot/jtreg/gc/g1/TestLargePageUseForAuxMemory.java b/test/hotspot/jtreg/gc/g1/TestLargePageUseForAuxMemory.java index 67f4d0beeb2..685041921d3 100644 --- a/test/hotspot/jtreg/gc/g1/TestLargePageUseForAuxMemory.java +++ b/test/hotspot/jtreg/gc/g1/TestLargePageUseForAuxMemory.java @@ -49,9 +49,40 @@ public class TestLargePageUseForAuxMemory { static long smallPageSize; static long allocGranularity; + static boolean largePagesEnabled(OutputAnalyzer output) { + // The gc+init logging includes information about large pages. + String lp = output.firstMatch("Large Page Support: (\\w*)", 1); + return lp != null && lp.equals("Enabled"); + } + + static boolean largePagesAllocationFailure(OutputAnalyzer output, String pattern) { + // Check if there is a large page failure associated with the data structure + // being checked. In case of a large page allocation failure the output will + // include logs like this for the affected data structure: + // [0.048s][debug][gc,heap,coops] Reserve regular memory without large pages + // [0.048s][info ][pagesize ] Next Bitmap: ... page_size=4K ... + // + // The pattern passed in should match the second line. + String failureMatch = output.firstMatch("Reserve regular memory without large pages\\n.*" + pattern, 1); + if (failureMatch != null) { + return true; + } + return false; + } + static void checkSize(OutputAnalyzer output, long expectedSize, String pattern) { - String pageSizeStr = output.firstMatch(pattern, 1); + // First check the output for any large page allocation failure associated with + // the checked data structure. If we detect a failure then expect small pages. + if (largePagesAllocationFailure(output, pattern)) { + // This should only happen when we are expecting large pages + if (expectedSize == smallPageSize) { + throw new RuntimeException("Expected small page size when large page failure was detected"); + } + expectedSize = smallPageSize; + } + // Now check what page size is traced. + String pageSizeStr = output.firstMatch(pattern, 1); if (pageSizeStr == null) { output.reportDiagnosticSummary(); throw new RuntimeException("Match from '" + pattern + "' got 'null' expected: " + expectedSize); @@ -82,15 +113,21 @@ public class TestLargePageUseForAuxMemory { pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC", "-XX:G1HeapRegionSize=" + HEAP_REGION_SIZE, "-Xmx" + heapsize, - "-Xlog:pagesize", + "-Xlog:pagesize,gc+init,gc+heap+coops=debug", "-XX:+UseLargePages", "-XX:+IgnoreUnrecognizedVMOptions", // there is no ObjectAlignmentInBytes in 32 bit builds "-XX:ObjectAlignmentInBytes=8", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - checkSmallTables(output, (cardsShouldUseLargePages ? largePageSize : smallPageSize)); - checkBitmaps(output, (bitmapShouldUseLargePages ? largePageSize : smallPageSize)); + // Only expect large page size if large pages are enabled. + if (largePagesEnabled(output)) { + checkSmallTables(output, (cardsShouldUseLargePages ? largePageSize : smallPageSize)); + checkBitmaps(output, (bitmapShouldUseLargePages ? largePageSize : smallPageSize)); + } else { + checkSmallTables(output, smallPageSize); + checkBitmaps(output, smallPageSize); + } output.shouldHaveExitValue(0); // Test with large page disabled. -- GitLab From 59b8d595d2fcc564f18f27ec306c135b7e4e46b3 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Fri, 12 Feb 2021 14:57:01 +0000 Subject: [PATCH 042/367] 8261481: Cannot read Kerberos settings in dynamic store on macOS Big Sur Reviewed-by: mullan --- .../share/classes/sun/security/krb5/Config.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/Config.java b/src/java.security.jgss/share/classes/sun/security/krb5/Config.java index b3254bf7a57..c575a70fa33 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/Config.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/Config.java @@ -167,17 +167,16 @@ public class Config { String osVersion = GetPropertyAction.privilegedGetProperty("os.version"); String[] fragments = osVersion.split("\\."); - - // sanity check the "10." part of the version - if (!fragments[0].equals("10")) return false; if (fragments.length < 2) return false; - // check if Mac OS X 10.7(.y) + // check if Mac OS X 10.7(.y) or higher try { + int majorVers = Integer.parseInt(fragments[0]); int minorVers = Integer.parseInt(fragments[1]); - if (minorVers >= 7) return true; + if (majorVers > 10) return true; + if (majorVers == 10 && minorVers >= 7) return true; } catch (NumberFormatException e) { - // was not an integer + // were not integers } return false; -- GitLab From b670efd896a2905b6842b8199261aa2f3d7c12b9 Mon Sep 17 00:00:00 2001 From: Anton Kozlov Date: Fri, 12 Feb 2021 15:11:21 +0000 Subject: [PATCH 043/367] 8261072: AArch64: Fix MacroAssembler::get_thread convention Reviewed-by: burban, aph --- src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index c47ec409fe0..3bcdcf97f0e 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -5268,10 +5268,14 @@ void MacroAssembler::char_array_compress(Register src, Register dst, Register le // by the call to JavaThread::aarch64_get_thread_helper() or, indeed, // the call setup code. // -// aarch64_get_thread_helper() clobbers only r0, r1, and flags. +// On Linux, aarch64_get_thread_helper() clobbers only r0, r1, and flags. +// On other systems, the helper is a usual C function. // void MacroAssembler::get_thread(Register dst) { - RegSet saved_regs = RegSet::range(r0, r1) + lr - dst; + RegSet saved_regs = + LINUX_ONLY(RegSet::range(r0, r1) + lr - dst) + NOT_LINUX (RegSet::range(r0, r17) + lr - dst); + push(saved_regs, sp); mov(lr, CAST_FROM_FN_PTR(address, JavaThread::aarch64_get_thread_helper)); -- GitLab From c0e805a4750a499fc199908bc1330a50cf2b980d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Fri, 12 Feb 2021 15:44:15 +0000 Subject: [PATCH 044/367] 8261654: Missing license header in Signatures.java Reviewed-by: jjg --- .../doclets/formats/html/Signatures.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java index 0a51ec1e666..dafd39440c9 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java @@ -1,3 +1,28 @@ +/* + * Copyright (c) 2020, 2021, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + package jdk.javadoc.internal.doclets.formats.html; import jdk.javadoc.doclet.DocletEnvironment; -- GitLab From 6475d4774ffdd2b505a96329d819cca2b4bbece5 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Fri, 12 Feb 2021 15:46:37 +0000 Subject: [PATCH 045/367] 8261655: [PPC64] Build broken after JDK-8260941 Reviewed-by: shade, clanger --- .../cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp index a4c2afce55f..8337317e3f2 100644 --- a/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp @@ -43,6 +43,8 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, Register preserve) { + CardTableBarrierSet* ctbs = barrier_set_cast(BarrierSet::barrier_set()); + CardTable* ct = ctbs->card_table(); assert_different_registers(addr, count, R0); Label Lskip_loop, Lstore_loop; -- GitLab From 350303d4f0c71f77fa784a92d13522a380e3b2fe Mon Sep 17 00:00:00 2001 From: Ian Graves Date: Fri, 12 Feb 2021 16:06:39 +0000 Subject: [PATCH 046/367] 8260221: java.util.Formatter throws wrong exception for mismatched flags in %% conversion Reviewed-by: smarks --- src/java.base/share/classes/java/util/Formatter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/util/Formatter.java b/src/java.base/share/classes/java/util/Formatter.java index e5934b28e78..c4dc4c0b85d 100644 --- a/src/java.base/share/classes/java/util/Formatter.java +++ b/src/java.base/share/classes/java/util/Formatter.java @@ -1832,7 +1832,7 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter; * *

    The {@code '-'} flag defined for General * conversions applies. If any other flags are provided, then a - * {@link FormatFlagsConversionMismatchException} will be thrown. + * {@link IllegalFormatFlagsException } will be thrown. * *

    The precision is not applicable. If the precision is specified an * {@link IllegalFormatPrecisionException} will be thrown. -- GitLab From 3aa1b4c72c289093a6d5894322978ba02acf5ef1 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 12 Feb 2021 16:16:44 +0000 Subject: [PATCH 047/367] 8261623: reference to javac internals in Extern class Reviewed-by: hannesw --- .../internal/doclets/toolkit/WorkArounds.java | 12 ++++++++++++ .../internal/doclets/toolkit/util/Extern.java | 14 +------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java index 33ed2e9798a..60afb6859e4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java @@ -198,6 +198,18 @@ public class WorkArounds { return elementUtils.getTypeElement(className); } + + // TODO: The following should be replaced by a new method such as Elements.isAutomaticModule + // see JDK-8261625 + public boolean isAutomaticModule(ModuleElement me) { + if (me == null) { + return false; + } else { + ModuleSymbol msym = (ModuleSymbol) me; + return (msym.flags() & Flags.AUTOMATIC_MODULE) != 0; + } + } + // TODO: need to re-implement this using j.l.m. correctly!, this has // implications on testInterface, the note here is that javac's supertype // does the right thing returning Parameters in scope. diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java index 88231ea8e5f..1b6607e3dbe 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Extern.java @@ -47,8 +47,6 @@ import javax.tools.Diagnostic; import javax.tools.Diagnostic.Kind; import javax.tools.DocumentationTool; -import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.code.Symbol.ModuleSymbol; import jdk.javadoc.doclet.Reporter; import jdk.javadoc.internal.doclets.toolkit.AbstractDoclet; import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration; @@ -575,7 +573,7 @@ public class Extern { return DocletConstants.DEFAULT_ELEMENT_NAME; } else if (moduleName == null) { // suppress the warning message in the case of automatic modules - if (!isAutomaticModule(me) && issueWarning) { + if (!configuration.workArounds.isAutomaticModule(me) && issueWarning) { configuration.getReporter().print(Kind.WARNING, resources.getText("doclet.linkMismatch_ModuleLinkedtoPackage", path)); } @@ -586,16 +584,6 @@ public class Extern { return moduleName == null ? DocletConstants.DEFAULT_ELEMENT_NAME : moduleName; } - // The following should be replaced by a new method such as Elements.isAutomaticModule - private boolean isAutomaticModule(ModuleElement me) { - if (me == null) { - return false; - } else { - ModuleSymbol msym = (ModuleSymbol) me; - return (msym.flags() & Flags.AUTOMATIC_MODULE) != 0; - } - } - public boolean isUrl (String urlCandidate) { try { new URL(urlCandidate); -- GitLab From 33fcd325f6d865b391712e9f415ba9daace4167d Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Fri, 12 Feb 2021 16:17:16 +0000 Subject: [PATCH 048/367] 8261659: JDK-8261027 causes a Tier1 validate-source failure Reviewed-by: iignatyev, bpb --- src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S b/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S index 512b51cc4cd..72969b1df63 100644 --- a/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S +++ b/src/hotspot/os_cpu/linux_aarch64/atomic_linux_aarch64.S @@ -1,20 +1,20 @@ // Copyright (c) 2021, Red Hat Inc. 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. - +// // This code is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // version 2 for more details (a copy is included in the LICENSE file that // accompanied this code). - +// // You should have received a copy of the GNU General Public License version // 2 along with this work; if not, write to the Free Software Foundation, // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - +// // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA // or visit www.oracle.com if you need additional information or have any // questions. -- GitLab From 66757750a2adf0739d0f5bf98a3f50a123b7adcf Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Fri, 12 Feb 2021 16:42:13 +0000 Subject: [PATCH 049/367] 8253702: BigSur version number reported as 10.16, should be 11.nn Reviewed-by: bpb, kcr --- .../macosx/native/libjava/java_props_macosx.c | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/java.base/macosx/native/libjava/java_props_macosx.c b/src/java.base/macosx/native/libjava/java_props_macosx.c index 321f7583b26..2189c1f94e3 100644 --- a/src/java.base/macosx/native/libjava/java_props_macosx.c +++ b/src/java.base/macosx/native/libjava/java_props_macosx.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2021, 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 @@ -247,15 +247,35 @@ void setOSNameAndVersion(java_props_t *sprops) { [invoke getReturnValue:&osVer]; NSString *nsVerStr; - if (osVer.patchVersion == 0) { // Omit trailing ".0" - nsVerStr = [NSString stringWithFormat:@"%ld.%ld", - (long)osVer.majorVersion, (long)osVer.minorVersion]; + // Copy out the char* if running on version other than 10.16 Mac OS (10.16 == 11.x) + // or explicitly requesting version compatibility + if (!((long)osVer.majorVersion == 10 && (long)osVer.minorVersion >= 16) || + (getenv("SYSTEM_VERSION_COMPAT") != NULL)) { + if (osVer.patchVersion == 0) { // Omit trailing ".0" + nsVerStr = [NSString stringWithFormat:@"%ld.%ld", + (long)osVer.majorVersion, (long)osVer.minorVersion]; + } else { + nsVerStr = [NSString stringWithFormat:@"%ld.%ld.%ld", + (long)osVer.majorVersion, (long)osVer.minorVersion, (long)osVer.patchVersion]; + } + // Copy out the char* + osVersionCStr = strdup([nsVerStr UTF8String]); } else { - nsVerStr = [NSString stringWithFormat:@"%ld.%ld.%ld", - (long)osVer.majorVersion, (long)osVer.minorVersion, (long)osVer.patchVersion]; + // Version 10.16, without explicit env setting of SYSTEM_VERSION_COMPAT + // AKA 11.x; compute the version number from the letter in the ProductBuildVersion + NSDictionary *version = [NSDictionary dictionaryWithContentsOfFile : + @"/System/Library/CoreServices/SystemVersion.plist"]; + if (version != NULL) { + NSString *nsBuildVerStr = [version objectForKey : @"ProductBuildVersion"]; + if (nsBuildVerStr != NULL && nsBuildVerStr.length >= 3) { + int letter = [nsBuildVerStr characterAtIndex:2]; + if (letter >= 'B' && letter <= 'Z') { + int vers = letter - 'A' - 1; + asprintf(&osVersionCStr, "11.%d", vers); + } + } + } } - // Copy out the char* - osVersionCStr = strdup([nsVerStr UTF8String]); } // Fallback if running on pre-10.9 Mac OS if (osVersionCStr == NULL) { -- GitLab From 28163a9e9840249e04384ce4e795418bd3715481 Mon Sep 17 00:00:00 2001 From: Vladimir Kempik Date: Fri, 12 Feb 2021 17:10:21 +0000 Subject: [PATCH 050/367] 8261652: Remove some dead comments from os_bsd_x86 Reviewed-by: dcubed --- src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp index d1462df5fce..595c1b0f775 100644 --- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp +++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp @@ -64,7 +64,6 @@ # include # include # include -# include # include # include # include @@ -391,16 +390,6 @@ enum { bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info, ucontext_t* uc, JavaThread* thread) { - -/* - NOTE: does not seem to work on bsd. - if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) { - // can't decode this kind of signal - info = NULL; - } else { - assert(sig == info->si_signo, "bad siginfo"); - } -*/ // decide if this trap can be handled by a stub address stub = NULL; -- GitLab From a305743cfa2f67ded62c1dd972b107d5579de97b Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Fri, 12 Feb 2021 17:34:29 +0000 Subject: [PATCH 051/367] 8261660: AArch64: Race condition in stub code generation for LSE Atomics Reviewed-by: dcubed, adinn --- src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index 1d3ff1b2e69..0f9218e592f 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -6772,7 +6772,9 @@ class StubGenerator: public StubCodeGenerator { #ifdef LINUX +#if 0 // JDK-8261660: disabled for now. generate_atomic_entry_points(); +#endif #endif // LINUX -- GitLab From 3dc6f52a89e4baab1a5501880824f8d1a68e6356 Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Fri, 12 Feb 2021 17:35:25 +0000 Subject: [PATCH 052/367] 8261160: Add a deserialization JFR event Co-authored-by: Sean Coffey Co-authored-by: Chris Hegarty Reviewed-by: coffeys, rriggs, dfuchs, egahlin --- .../classes/java/io/ObjectInputStream.java | 41 +- .../internal/event/DeserializationEvent.java | 42 ++ .../jdk/jfr/events/DeserializationEvent.java | 67 +++ .../jfr/internal/instrument/JDKEvents.java | 12 +- src/jdk.jfr/share/conf/jfr/default.jfc | 5 + src/jdk.jfr/share/conf/jfr/profile.jfc | 5 + .../serialFilter/GlobalFilterTest.java | 14 +- .../event/io/TestDeserializationEvent.java | 437 ++++++++++++++++++ .../metadata/TestDefaultConfigurations.java | 3 +- .../jfr/event/metadata/TestEventMetadata.java | 6 +- .../event/runtime/TestActiveSettingEvent.java | 3 +- test/lib/jdk/test/lib/jfr/EventNames.java | 2 + 12 files changed, 615 insertions(+), 22 deletions(-) create mode 100644 src/java.base/share/classes/jdk/internal/event/DeserializationEvent.java create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/events/DeserializationEvent.java create mode 100644 test/jdk/jdk/jfr/event/io/TestDeserializationEvent.java diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java index 03d3aa8dc45..931a829df73 100644 --- a/src/java.base/share/classes/java/io/ObjectInputStream.java +++ b/src/java.base/share/classes/java/io/ObjectInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2021, 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 @@ -48,6 +48,7 @@ import java.util.concurrent.ConcurrentMap; import static java.io.ObjectStreamClass.processQueue; import jdk.internal.access.SharedSecrets; +import jdk.internal.event.DeserializationEvent; import jdk.internal.misc.Unsafe; import sun.reflect.misc.ReflectUtil; import sun.security.action.GetBooleanAction; @@ -1323,9 +1324,12 @@ public class ObjectInputStream } /** - * Invoke the serialization filter if non-null. + * Invokes the serialization filter if non-null. + * * If the filter rejects or an exception is thrown, throws InvalidClassException. * + * Logs and/or commits a {@code DeserializationEvent}, if configured. + * * @param clazz the class; may be null * @param arrayLength the array length requested; use {@code -1} if not creating an array * @throws InvalidClassException if it rejected by the filter or @@ -1333,11 +1337,12 @@ public class ObjectInputStream */ private void filterCheck(Class clazz, int arrayLength) throws InvalidClassException { + // Info about the stream is not available if overridden by subclass, return 0 + long bytesRead = (bin == null) ? 0 : bin.getBytesRead(); + RuntimeException ex = null; + ObjectInputFilter.Status status = null; + if (serialFilter != null) { - RuntimeException ex = null; - ObjectInputFilter.Status status; - // Info about the stream is not available if overridden by subclass, return 0 - long bytesRead = (bin == null) ? 0 : bin.getBytesRead(); try { status = serialFilter.checkInput(new FilterValues(clazz, arrayLength, totalObjectRefs, depth, bytesRead)); @@ -1355,12 +1360,24 @@ public class ObjectInputStream status, clazz, arrayLength, totalObjectRefs, depth, bytesRead, Objects.toString(ex, "n/a")); } - if (status == null || - status == ObjectInputFilter.Status.REJECTED) { - InvalidClassException ice = new InvalidClassException("filter status: " + status); - ice.initCause(ex); - throw ice; - } + } + DeserializationEvent event = new DeserializationEvent(); + if (event.shouldCommit()) { + event.filterConfigured = serialFilter != null; + event.filterStatus = status != null ? status.name() : null; + event.type = clazz; + event.arrayLength = arrayLength; + event.objectReferences = totalObjectRefs; + event.depth = depth; + event.bytesRead = bytesRead; + event.exceptionType = ex != null ? ex.getClass() : null; + event.exceptionMessage = ex != null ? ex.getMessage() : null; + event.commit(); + } + if (serialFilter != null && (status == null || status == ObjectInputFilter.Status.REJECTED)) { + InvalidClassException ice = new InvalidClassException("filter status: " + status); + ice.initCause(ex); + throw ice; } } diff --git a/src/java.base/share/classes/jdk/internal/event/DeserializationEvent.java b/src/java.base/share/classes/jdk/internal/event/DeserializationEvent.java new file mode 100644 index 00000000000..0caf61318fd --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/event/DeserializationEvent.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.event; + +/** + * Event details relating to deserialization. + */ + +public final class DeserializationEvent extends Event { + public boolean filterConfigured; + public String filterStatus; + public Class type; + public int arrayLength; + public long objectReferences; + public long depth; + public long bytesRead; + public Class exceptionType; + public String exceptionMessage; +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/DeserializationEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/DeserializationEvent.java new file mode 100644 index 00000000000..7e89aa894a3 --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/DeserializationEvent.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.events; + +import jdk.jfr.Category; +import jdk.jfr.Description; +import jdk.jfr.Label; +import jdk.jfr.Name; +import jdk.jfr.internal.MirrorEvent; + +@Category({"Java Development Kit", "Serialization"}) +@Label("Deserialization") +@Name("jdk.Deserialization") +@Description("Results of deserialiation and ObjectInputFilter checks") +@MirrorEvent(className = "jdk.internal.event.DeserializationEvent") +public final class DeserializationEvent extends AbstractJDKEvent { + + @Label("Filter Configured") + public boolean filterConfigured; + + @Label("Filter Status") + public String filterStatus; + + @Label ("Type") + public Class type; + + @Label ("Array Length") + public int arrayLength; + + @Label ("Object References") + public long objectReferences; + + @Label ("Depth") + public long depth; + + @Label ("Bytes Read") + public long bytesRead; + + @Label ("Exception Type") + public Class exceptionType; + + @Label ("Exception Message") + public String exceptionMessage; +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java index 82a2383c43f..50b67c51d53 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 @@ -38,6 +38,7 @@ import jdk.jfr.events.ExceptionThrownEvent; import jdk.jfr.events.FileForceEvent; import jdk.jfr.events.FileReadEvent; import jdk.jfr.events.FileWriteEvent; +import jdk.jfr.events.DeserializationEvent; import jdk.jfr.events.ProcessStartEvent; import jdk.jfr.events.SecurityPropertyModificationEvent; import jdk.jfr.events.SocketReadEvent; @@ -55,11 +56,12 @@ import jdk.jfr.internal.SecuritySupport; public final class JDKEvents { private static final Class[] mirrorEventClasses = { + DeserializationEvent.class, + ProcessStartEvent.class, SecurityPropertyModificationEvent.class, TLSHandshakeEvent.class, X509CertificateEvent.class, - X509ValidationEvent.class, - ProcessStartEvent.class + X509ValidationEvent.class }; private static final Class[] eventClasses = { @@ -73,11 +75,13 @@ public final class JDKEvents { ErrorThrownEvent.class, ActiveSettingEvent.class, ActiveRecordingEvent.class, + jdk.internal.event.DeserializationEvent.class, + jdk.internal.event.ProcessStartEvent.class, jdk.internal.event.SecurityPropertyModificationEvent.class, jdk.internal.event.TLSHandshakeEvent.class, jdk.internal.event.X509CertificateEvent.class, jdk.internal.event.X509ValidationEvent.class, - jdk.internal.event.ProcessStartEvent.class, + DirectBufferStatisticsEvent.class }; diff --git a/src/jdk.jfr/share/conf/jfr/default.jfc b/src/jdk.jfr/share/conf/jfr/default.jfc index 49e148c4393..d70a292609a 100644 --- a/src/jdk.jfr/share/conf/jfr/default.jfc +++ b/src/jdk.jfr/share/conf/jfr/default.jfc @@ -665,6 +665,11 @@ 20 ms + + false + true + + false true diff --git a/src/jdk.jfr/share/conf/jfr/profile.jfc b/src/jdk.jfr/share/conf/jfr/profile.jfc index 5374f5b4e55..1ded1577adc 100644 --- a/src/jdk.jfr/share/conf/jfr/profile.jfc +++ b/src/jdk.jfr/share/conf/jfr/profile.jfc @@ -665,6 +665,11 @@ 10 ms + + false + true + + false true diff --git a/test/jdk/java/io/Serializable/serialFilter/GlobalFilterTest.java b/test/jdk/java/io/Serializable/serialFilter/GlobalFilterTest.java index 1e679242890..6ebf35726d0 100644 --- a/test/jdk/java/io/Serializable/serialFilter/GlobalFilterTest.java +++ b/test/jdk/java/io/Serializable/serialFilter/GlobalFilterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 @@ -53,6 +53,18 @@ import org.testng.annotations.DataProvider; * * @summary Test Global Filters */ + +/* @test + * @bug 8261160 + * @summary Add a deserialization JFR event + * @build GlobalFilterTest SerialFilterTest + * @requires vm.hasJFR + * @run testng/othervm/policy=security.policy + * -XX:StartFlightRecording=name=DeserializationEvent,dumponexit=true + * -Djava.security.properties=${test.src}/java.security-extra1 + * -Djava.security.debug=properties GlobalFilterTest + */ + @Test public class GlobalFilterTest { private static final String serialPropName = "jdk.serialFilter"; diff --git a/test/jdk/jdk/jfr/event/io/TestDeserializationEvent.java b/test/jdk/jdk/jfr/event/io/TestDeserializationEvent.java new file mode 100644 index 00000000000..c2b250c3e00 --- /dev/null +++ b/test/jdk/jdk/jfr/event/io/TestDeserializationEvent.java @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.event.io; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InvalidClassException; +import java.io.ObjectInputFilter.Status; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedClass; +import jdk.jfr.consumer.RecordedEvent; +import jdk.test.lib.jfr.EventNames; +import jdk.test.lib.jfr.Events; +import jdk.test.lib.serial.SerialObjectBuilder; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; +import static java.lang.System.out; +import static org.testng.Assert.*; + +/* + * @test + * @bug 8261160 + * @summary Add a deserialization JFR event + * @key jfr + * @requires vm.hasJFR + * @library /test/lib + * @run testng/othervm jdk.jfr.event.io.TestDeserializationEvent + */ +public class TestDeserializationEvent { + + public record R() implements Serializable { } + + @DataProvider(name = "scenarios") + public Object[][] scenarios() throws Exception { + byte[] ba1 = serialize(new R()); + byte[] ba2 = serialize(new int[] { 56, 67, 58, 59, 60 }); + byte[] ba3 = serialize(new R[] { new R(), new R() }); + byte[] ba4 = serialize(new char[][] { new char[] {'a', 'b'}, new char[] {'c'} }); + + // data provider columns- 1:id, 2:deserialize-operation, 3:expected-event-checkers + return new Object[][] { + { 1, // single stream object, R + (Runnable)() -> deserialize(ba1), + List.of( + Set.of( + assertFilterStatus(null), + assertType(R.class), + assertArrayLength(-1), + assertObjectReferences(1), + assertDepth(1), + assertHasBytesRead(), + assertExceptionType(null), + assertExceptionMessage(null))) }, + { 2, // primitive int array + (Runnable)() -> deserialize(ba2), + List.of( + Set.of( // TC_CLASS, for array class int[] + assertType(int[].class), + assertArrayLength(-1)), + Set.of( // TC_ARRAY, actual array + assertType(int[].class), + assertArrayLength(5))) }, + { 3, // reference array, R + (Runnable)() -> deserialize(ba3), + List.of( + Set.of( // TC_CLASS, for array class R[] + assertType(R[].class), + assertArrayLength(-1)), + Set.of( // TC_ARRAY, actual array + assertType(R[].class), + assertArrayLength(2)), + Set.of( // TC_CLASS, for R + assertType(R.class), + assertArrayLength(-1)), + Set.of( // TC_REFERENCE, for TC_CLASS relating second stream obj + assertType(null), + assertArrayLength(-1))) }, + { 4, // multi-dimensional prim char array + (Runnable)() -> deserialize(ba4), + List.of( + Set.of( // TC_CLASS, for array class char[][] + assertType(char[][].class), + assertArrayLength(-1), + assertDepth(1)), + Set.of( // TC_ARRAY, actual char[][] array + assertType(char[][].class), + assertArrayLength(2), + assertDepth(1)), + Set.of( // TC_CLASS, for array class char[] + assertType(char[].class), + assertArrayLength(-1), + assertDepth(2)), + Set.of( // TC_ARRAY, first char[] array + assertType(char[].class), + assertArrayLength(2), + assertDepth(2)), + Set.of( // TC_REFERENCE, for TC_CLASS relating to second stream array + assertType(null), + assertArrayLength(-1), + assertDepth(2)), + Set.of( // TC_ARRAY, second char[] array + assertType(char[].class), + assertArrayLength(1), + assertDepth(2))) } + }; + } + + @Test(dataProvider = "scenarios") + public void test(int id, + Runnable thunk, + List>> expectedValuesChecker) + throws IOException + { + try (Recording recording = new Recording()) { + recording.enable(EventNames.Deserialization); + recording.start(); + thunk.run(); + recording.stop(); + List events = Events.fromRecording(recording); + assertEquals(events.size(), expectedValuesChecker.size()); + assertEventList(events, expectedValuesChecker); + } + } + + static final Class ICE = InvalidClassException.class; + + @DataProvider(name = "filterDisallowedValues") + public Object[][] filterDisallowedValues() { + return new Object[][] { + { Status.REJECTED, "REJECTED" }, + { null, null } + }; + } + + @Test(dataProvider = "filterDisallowedValues") + public void testFilterDisallow(Status filterStatus, + String expectedValue) + throws Exception + { + try (Recording recording = new Recording(); + var bais = new ByteArrayInputStream(serialize(new R())); + var ois = new ObjectInputStream(bais)) { + ois.setObjectInputFilter(fv -> filterStatus); + recording.enable(EventNames.Deserialization); + recording.start(); + assertThrows(ICE, () -> ois.readObject()); + recording.stop(); + List events = Events.fromRecording(recording); + assertEquals(events.size(), 1); + assertEquals(events.get(0).getEventType().getName(), "jdk.Deserialization"); + assertFilterConfigured(true).accept(events.get(0)); + assertFilterStatus(expectedValue).accept(events.get(0)); + } + } + + @DataProvider(name = "filterAllowedValues") + public Object[][] filterAllowedValues() { + return new Object[][] { + { Status.ALLOWED, "ALLOWED" }, + { Status.UNDECIDED, "UNDECIDED" }, + }; + } + + @Test(dataProvider = "filterAllowedValues") + public void testFilterAllowed(Status filterStatus, + String expectedValue) throws Exception { + try (Recording recording = new Recording(); + var bais = new ByteArrayInputStream(serialize(new R())); + var ois = new ObjectInputStream(bais)) { + ois.setObjectInputFilter(fv -> filterStatus); + recording.enable(EventNames.Deserialization); + recording.start(); + ois.readObject(); + recording.stop(); + List events = Events.fromRecording(recording); + assertEquals(events.size(), 1); + assertEquals(events.get(0).getEventType().getName(), "jdk.Deserialization"); + assertFilterConfigured(true).accept(events.get(0)); + assertFilterStatus(expectedValue).accept(events.get(0)); + } + } + + static class XYZException extends RuntimeException { + XYZException(String msg) { super(msg); } + } + + @Test + public void testException() throws Exception { + try (Recording recording = new Recording(); + var bais = new ByteArrayInputStream(serialize(new R())); + var ois = new ObjectInputStream(bais)) { + ois.setObjectInputFilter(fv -> { throw new XYZException("I am a bad filter!!!"); }); + recording.enable(EventNames.Deserialization); + recording.start(); + assertThrows(ICE, () -> ois.readObject()); + recording.stop(); + List events = Events.fromRecording(recording); + assertEquals(events.size(), 1); + assertEquals(events.get(0).getEventType().getName(), "jdk.Deserialization"); + assertFilterConfigured(true).accept(events.get(0)); + assertExceptionType(XYZException.class).accept(events.get(0)); + assertExceptionMessage("I am a bad filter!!!").accept(events.get(0)); + } + } + + static void assertEventList(List actualEvents, + List>> expectedValuesChecker) { + int found = 0; + for (RecordedEvent recordedEvent : actualEvents) { + assertEquals(recordedEvent.getEventType().getName(), "jdk.Deserialization"); + out.println("Checking recorded event:" + recordedEvent); + Set> checkers = expectedValuesChecker.get(found); + for (Consumer checker : checkers) { + out.println(" checking:" + checker); + checker.accept(recordedEvent); + } + assertFilterConfigured(false).accept(recordedEvent); // no filter expected + assertExceptionType(null).accept(recordedEvent); // no exception type expected + assertExceptionMessage(null).accept(recordedEvent); // no exception message expected + found++; + } + assertEquals(found, expectedValuesChecker.size()); + } + + static Consumer assertFilterConfigured(boolean expectedValue) { + return new Consumer<>() { + @Override public void accept(RecordedEvent recordedEvent) { + assertTrue(recordedEvent.hasField("filterConfigured")); + assertEquals((boolean)recordedEvent.getValue("filterConfigured"), expectedValue); + } + @Override public String toString() { + return "assertFilterConfigured, expectedValue=" + expectedValue; + } + }; + } + + static Consumer assertFilterStatus(String expectedValue) { + return new Consumer<>() { + @Override public void accept(RecordedEvent recordedEvent) { + assertTrue(recordedEvent.hasField("filterStatus")); + assertEquals(recordedEvent.getValue("filterStatus"), expectedValue); + } + @Override public String toString() { + return "assertFilterStatus, expectedValue=" + expectedValue; + } + }; + } + + static Consumer assertType(Class expectedValue) { + return new Consumer<>() { + @Override public void accept(RecordedEvent recordedEvent) { + assertTrue(recordedEvent.hasField("type")); + assertClassOrNull(expectedValue, recordedEvent, "type"); + } + @Override public String toString() { + return "assertType, expectedValue=" + expectedValue; + } + }; + } + + static Consumer assertArrayLength(int expectedValue) { + return new Consumer<>() { + @Override public void accept(RecordedEvent recordedEvent) { + assertTrue(recordedEvent.hasField("arrayLength")); + assertEquals((int)recordedEvent.getValue("arrayLength"), expectedValue); + } + @Override public String toString() { + return "assertArrayLength, expectedValue=" + expectedValue; + } + }; + } + + static Consumer assertObjectReferences(long expectedValue) { + return new Consumer<>() { + @Override public void accept(RecordedEvent recordedEvent) { + assertTrue(recordedEvent.hasField("objectReferences")); + assertEquals((long)recordedEvent.getValue("objectReferences"), expectedValue); + } + @Override public String toString() { + return "assertObjectReferences, expectedValue=" + expectedValue; + } + }; + } + + static Consumer assertDepth(long expectedValue) { + return new Consumer<>() { + @Override public void accept(RecordedEvent recordedEvent) { + assertTrue(recordedEvent.hasField("depth")); + assertEquals((long)recordedEvent.getValue("depth"), expectedValue); + } + @Override public String toString() { + return "assertDepth, expectedValue=" + expectedValue; + } + }; + } + + static Consumer assertHasBytesRead() { + return new Consumer<>() { + @Override public void accept(RecordedEvent recordedEvent) { + assertTrue(recordedEvent.hasField("bytesRead")); + } + @Override public String toString() { + return "assertHasBytesRead,"; + } + }; + } + + static Consumer assertBytesRead(long expectedValue) { + return new Consumer<>() { + @Override public void accept(RecordedEvent recordedEvent) { + assertHasBytesRead().accept(recordedEvent); + assertEquals((long)recordedEvent.getValue("bytesRead"), expectedValue); + } + @Override public String toString() { + return "assertBytesRead, expectedValue=" + expectedValue; + } + }; + } + + static Consumer assertExceptionType(Class expectedValue) { + return new Consumer<>() { + @Override public void accept(RecordedEvent recordedEvent) { + assertTrue(recordedEvent.hasField("exceptionType")); + assertClassOrNull(expectedValue, recordedEvent, "exceptionType"); + } + @Override public String toString() { + return "assertExceptionType, expectedValue=" + expectedValue; + } + }; + } + + static Consumer assertExceptionMessage(String expectedValue) { + return new Consumer<>() { + @Override public void accept(RecordedEvent recordedEvent) { + assertTrue(recordedEvent.hasField("exceptionMessage")); + assertEquals(recordedEvent.getValue("exceptionMessage"), expectedValue); + } + @Override public String toString() { + return "assertExceptionMessage, expectedValue=" + expectedValue; + } + }; + } + + static void assertClassOrNull(Class expectedValue, + RecordedEvent recordedEvent, + String valueName) { + if (expectedValue == null && recordedEvent.getValue(valueName) == null) + return; + + if (recordedEvent.getValue(valueName) instanceof RecordedClass recordedClass) + assertEquals(recordedClass.getName(), expectedValue.getName()); + else + fail("Expected RecordedClass, got:" + recordedEvent.getValue(valueName).getClass()); + } + + static byte[] serialize(T obj) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(obj); + oos.close(); + return baos.toByteArray(); + } + + @SuppressWarnings("unchecked") + static T deserialize(byte[] streamBytes) { + try { + ByteArrayInputStream bais = new ByteArrayInputStream(streamBytes); + ObjectInputStream ois = new ObjectInputStream(bais); + return (T) ois.readObject(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + // --- + static volatile boolean initializedFoo; // false + // Do not inadvertently initialize this class, Foo. + static class Foo implements Serializable { + static { TestDeserializationEvent.initializedFoo = true; } + } + + /** + * Checks that the creation and recording of the Deserialization event does + * not inadvertently trigger initialization of the class of the stream + * object, when deserialization is rejected by the filter. + */ + @Test + public void testRejectedClassNotInitialized() throws Exception { + byte[] bytes = SerialObjectBuilder.newBuilder("Foo").build(); + assertFalse(initializedFoo); // sanity + + try (Recording recording = new Recording(); + var bais = new ByteArrayInputStream(bytes); + var ois = new ObjectInputStream(bais)) { + ois.setObjectInputFilter(fv -> Status.REJECTED); + recording.enable(EventNames.Deserialization); + recording.start(); + assertThrows(ICE, () -> ois.readObject()); + recording.stop(); + List events = Events.fromRecording(recording); + assertEquals(events.size(), 1); + assertEquals(events.get(0).getEventType().getName(), "jdk.Deserialization"); + assertFilterConfigured(true).accept(events.get(0)); + assertFilterStatus("REJECTED").accept(events.get(0)); + assertFalse(initializedFoo); + assertType(Foo.class); + } + } +} diff --git a/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java b/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java index 162864c97e9..126358db3e1 100644 --- a/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java +++ b/test/jdk/jdk/jfr/event/metadata/TestDefaultConfigurations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, 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 @@ -178,6 +178,7 @@ public class TestDefaultConfigurations { insertSetting(doc, EventNames.X509Certificate, "threshold", "0 ns"); insertSetting(doc, EventNames.X509Validation, "threshold", "0 ns"); insertSetting(doc, EventNames.ProcessStart, "threshold", "0 ns"); + insertSetting(doc, EventNames.Deserialization, "threshold", "0 ns"); return doc; } diff --git a/test/jdk/jdk/jfr/event/metadata/TestEventMetadata.java b/test/jdk/jdk/jfr/event/metadata/TestEventMetadata.java index f6652d7352f..c129df76359 100644 --- a/test/jdk/jdk/jfr/event/metadata/TestEventMetadata.java +++ b/test/jdk/jdk/jfr/event/metadata/TestEventMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021, 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 @@ -212,9 +212,9 @@ public class TestEventMetadata { String lowerCased = name.toLowerCase(); Asserts.assertFalse(lowerCased.contains("info") && !lowerCased.contains("information"), "Use 'information' instead 'info' in name"); Asserts.assertFalse(lowerCased.contains("alloc") && !lowerCased.contains("alloca"), "Use 'allocation' instead 'alloc' in name"); - Asserts.assertFalse(lowerCased.contains("config") && !lowerCased.contains("configuration"), "Use 'configuration' instead of 'config' in name"); + Asserts.assertFalse(lowerCased.contains("config") && !(lowerCased.contains("configuration") || lowerCased.contains("filterconfigured")), "Use 'configuration' instead of 'config' in name"); Asserts.assertFalse(lowerCased.contains("evac") && !lowerCased.contains("evacu"), "Use 'evacuation' instead of 'evac' in name"); - Asserts.assertFalse(lowerCased.contains("stat") && !(lowerCased.contains("state") ||lowerCased.contains("statistic")) , "Use 'statistics' instead of 'stat' in name"); + Asserts.assertFalse(lowerCased.contains("stat") && !(lowerCased.contains("state") ||lowerCased.contains("statistic") ||lowerCased.contains("filterstatus")) , "Use 'statistics' instead of 'stat' in name"); Asserts.assertFalse(name.contains("ID") , "Use 'id' or 'Id' instead of 'ID' in name"); } } diff --git a/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java b/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java index 35e0e0b4b55..0022be43d1b 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -206,6 +206,7 @@ public final class TestActiveSettingEvent { settingValues.put(EventNames.X509Certificate + "#threshold", "0 ns"); settingValues.put(EventNames.X509Validation + "#threshold", "0 ns"); settingValues.put(EventNames.ProcessStart + "#threshold", "0 ns"); + settingValues.put(EventNames.Deserialization + "#threshold", "0 ns"); try (Recording recording = new Recording(c)) { Map eventTypes = new HashMap<>(); diff --git a/test/lib/jdk/test/lib/jfr/EventNames.java b/test/lib/jdk/test/lib/jfr/EventNames.java index 59d6ff73ce4..b4fd3652551 100644 --- a/test/lib/jdk/test/lib/jfr/EventNames.java +++ b/test/lib/jdk/test/lib/jfr/EventNames.java @@ -199,6 +199,8 @@ public class EventNames { public final static String X509Validation = PREFIX + "X509Validation"; public final static String SecurityProperty = PREFIX + "SecurityPropertyModification"; public final static String DirectBufferStatistics = PREFIX + "DirectBufferStatistics"; + public final static String Deserialization = PREFIX + "Deserialization"; + // Flight Recorder public final static String DumpReason = PREFIX + "DumpReason"; -- GitLab From 06170b7cbf6129274747b4406562184802d4ff07 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Fri, 12 Feb 2021 17:45:47 +0000 Subject: [PATCH 053/367] 8261662: Rename compute_loader_lock_object Reviewed-by: dcubed, stuefe --- src/hotspot/share/classfile/systemDictionary.cpp | 10 +++++----- src/hotspot/share/classfile/systemDictionary.hpp | 2 +- src/hotspot/share/classfile/systemDictionaryShared.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index 7318400b0e5..81c7f52820a 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -185,7 +185,7 @@ bool SystemDictionary::is_platform_class_loader(oop class_loader) { return (class_loader->klass() == vmClasses::jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass()); } -Handle SystemDictionary::compute_loader_lock_object(Handle class_loader) { +Handle SystemDictionary::get_loader_lock_or_null(Handle class_loader) { // If class_loader is NULL or parallelCapable, the JVM doesn't acquire a lock while loading. if (is_parallelCapable(class_loader)) { return Handle(); @@ -692,7 +692,7 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, // the define. // ParallelCapable Classloaders and the bootstrap classloader // do not acquire lock here. - Handle lockObject = compute_loader_lock_object(class_loader); + Handle lockObject = get_loader_lock_or_null(class_loader); ObjectLocker ol(lockObject, THREAD); // Check again (after locking) if the class already exists in SystemDictionary @@ -1051,7 +1051,7 @@ InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* class_name, // Classloaders that support parallelism, e.g. bootstrap classloader, // do not acquire lock here - Handle lockObject = compute_loader_lock_object(class_loader); + Handle lockObject = get_loader_lock_or_null(class_loader); ObjectLocker ol(lockObject, THREAD); // Parse the stream and create a klass. @@ -1342,7 +1342,7 @@ InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik, ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader()); { HandleMark hm(THREAD); - Handle lockObject = compute_loader_lock_object(class_loader); + Handle lockObject = get_loader_lock_or_null(class_loader); ObjectLocker ol(lockObject, THREAD); // prohibited package check assumes all classes loaded from archive call // restore_unshareable_info which calls ik->set_package() @@ -1544,7 +1544,7 @@ void SystemDictionary::define_instance_class(InstanceKlass* k, Handle class_load // hole with systemDictionary updates and check_constraints if (!is_parallelCapable(class_loader)) { assert(ObjectSynchronizer::current_thread_holds_lock(THREAD->as_Java_thread(), - compute_loader_lock_object(class_loader)), + get_loader_lock_or_null(class_loader)), "define called without lock"); } diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index 2ef0e9b9b5b..20b4ed2f9df 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -387,7 +387,7 @@ protected: static InstanceKlass* load_shared_boot_class(Symbol* class_name, PackageEntry* pkg_entry, TRAPS); - static Handle compute_loader_lock_object(Handle class_loader); + static Handle get_loader_lock_or_null(Handle class_loader); static InstanceKlass* find_or_define_instance_class(Symbol* class_name, Handle class_loader, InstanceKlass* k, TRAPS); diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index f45f7027529..8050a4dea6a 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -1013,7 +1013,7 @@ InstanceKlass* SystemDictionaryShared::find_or_load_shared_class( // Note: currently, find_or_load_shared_class is called only from // JVM_FindLoadedClass and used for PlatformClassLoader and AppClassLoader, // which are parallel-capable loaders, so a lock here is NOT taken. - assert(compute_loader_lock_object(class_loader) == NULL, "ObjectLocker not required"); + assert(get_loader_lock_or_null(class_loader) == NULL, "ObjectLocker not required"); { MutexLocker mu(THREAD, SystemDictionary_lock); InstanceKlass* check = dictionary->find_class(d_hash, name); -- GitLab From f0d9829b68b136d0a6bdba7dac6f34ad2c229dd1 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Fri, 12 Feb 2021 18:42:07 +0000 Subject: [PATCH 054/367] 8261533: Java_sun_font_CFont_getCascadeList leaks memory according to Xcode Reviewed-by: serb --- .../macosx/native/libawt_lwawt/font/AWTFont.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m b/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m index 8ca4183ffd9..0f27514b910 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m @@ -544,6 +544,7 @@ JNIEXPORT void JNICALL Java_sun_font_CFont_getCascadeList (JNIEnv *env, jclass cls, jlong awtFontPtr, jobject arrayListOfString) { +JNI_COCOA_ENTER(env); jclass alc = (*env)->FindClass(env, "java/util/ArrayList"); if (alc == NULL) return; jmethodID addMID = (*env)->GetMethodID(env, alc, "add", "(Ljava/lang/Object;)Z"); @@ -553,13 +554,15 @@ Java_sun_font_CFont_getCascadeList AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr); NSFont* nsFont = awtFont->fFont; CTFontRef font = (CTFontRef)nsFont; - CFStringRef base = CTFontCopyFullName(font); CFArrayRef codes = CFLocaleCopyISOLanguageCodes(); #ifdef DEBUG + CFStringRef base = CTFontCopyFullName(font); NSLog(@"BaseFont is : %@", (NSString*)base); + CFRelease(base); #endif CFArrayRef fds = CTFontCopyDefaultCascadeListForLanguages(font, codes); + CFRelease(codes); CFIndex cnt = CFArrayGetCount(fds); for (i=0; iCallBooleanMethod(env, arrayListOfString, addMID, jFontName); if ((*env)->ExceptionOccurred(env)) { + CFRelease(fds); return; } (*env)->DeleteLocalRef(env, jFontName); } + CFRelease(fds); +JNI_COCOA_EXIT(env); } -- GitLab From dc46aa85c6e16cb904d1c40a4577b5e48c56a3d4 Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Fri, 12 Feb 2021 20:58:22 +0000 Subject: [PATCH 055/367] 8261534: Test sun/security/pkcs11/KeyAgreement/IllegalPackageAccess.java fails on platforms where no nsslib artifacts are defined Reviewed-by: mbaesken --- .../sun/security/pkcs11/KeyAgreement/IllegalPackageAccess.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/sun/security/pkcs11/KeyAgreement/IllegalPackageAccess.java b/test/jdk/sun/security/pkcs11/KeyAgreement/IllegalPackageAccess.java index f8448dd0713..9490108597c 100644 --- a/test/jdk/sun/security/pkcs11/KeyAgreement/IllegalPackageAccess.java +++ b/test/jdk/sun/security/pkcs11/KeyAgreement/IllegalPackageAccess.java @@ -71,6 +71,7 @@ public class IllegalPackageAccess extends PKCS11Test { @Override public void main(Provider p) throws Exception { + Policy.setPolicy(null); Policy.setPolicy(new MyPolicy()); System.setSecurityManager(new SecurityManager()); -- GitLab From e29c560a11c4cbc261bdd04db5d24170fb9f12b6 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Fri, 12 Feb 2021 22:01:43 +0000 Subject: [PATCH 056/367] 8247514: Improve clhsdb 'findpc' ability to determine what an address points to by improving PointerFinder and PointerLocation classes Reviewed-by: ysuenaga, kevinw --- .../classes/sun/jvm/hotspot/oops/Method.java | 5 +- .../sun/jvm/hotspot/runtime/JavaThread.java | 4 +- .../jvm/hotspot/utilities/PointerFinder.java | 66 ++++++++- .../hotspot/utilities/PointerLocation.java | 126 ++++++++++++---- .../jtreg/serviceability/sa/ClhsdbFindPC.java | 137 +++++++++++++++--- 5 files changed, 284 insertions(+), 54 deletions(-) diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Method.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Method.java index 8afb1f19767..a0c678b22f9 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Method.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Method.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, 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 @@ -267,7 +267,8 @@ public class Method extends Metadata { } public void printValueOn(PrintStream tty) { - tty.print("Method " + getName().asString() + getSignature().asString() + "@" + getAddress()); + tty.print("Method " + getMethodHolder().getName().asString() + "." + + getName().asString() + getSignature().asString() + "@" + getAddress()); } public void iterateFields(MetadataVisitor visitor) { diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java index aafd48a89b8..c830ac8d384 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, 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 @@ -467,7 +467,7 @@ public class JavaThread extends Thread { return fr; } - private Address lastSPDbg() { + public Address lastSPDbg() { return access.getLastSP(addr); } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java index 498482305cd..d34d0f4e908 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, 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 @@ -26,10 +26,13 @@ package sun.jvm.hotspot.utilities; import sun.jvm.hotspot.code.*; import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.gc.shared.*; import sun.jvm.hotspot.interpreter.*; -import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.memory.*; +import sun.jvm.hotspot.oops.Metadata; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.WrongTypeException; /** This class, only intended for use in the debugging system, provides the functionality of find() in the VM. */ @@ -37,7 +40,60 @@ import sun.jvm.hotspot.memory.*; public class PointerFinder { public static PointerLocation find(Address a) { PointerLocation loc = new PointerLocation(a); + Threads threads = VM.getVM().getThreads(); + + // Check if address is a pointer to a Metadata object. + try { + loc.metadata = Metadata.instantiateWrapperFor(a); + return loc; + } catch (Exception e) { + // Just ignore. This just means we aren't dealing with a Metadata pointer. + } + + // Check if address is some other C++ type that we can deduce + loc.ctype = VM.getVM().getTypeDataBase().guessTypeForAddress(a); + if (loc.ctype == null && VM.getVM().isSharingEnabled()) { + // Check if the value falls in the _md_region + try { + Address loc1 = a.getAddressAt(0); + FileMapInfo cdsFileMapInfo = VM.getVM().getFileMapInfo(); + if (cdsFileMapInfo.inCopiedVtableSpace(loc1)) { + loc.ctype = cdsFileMapInfo.getTypeForVptrAddress(loc1); + } + } catch (AddressException | WrongTypeException e) { + // This can happen if "a" or "loc1" is a bad address. Just ignore. + } + } + if (loc.ctype != null) { + return loc; + } + + // Check if address is in the stack of a JavaThread + for (int i = 0; i < threads.getNumberOfThreads(); i++) { + JavaThread t = threads.getJavaThreadAt(i); + Address stackBase = t.getStackBase(); + if (stackBase != null) { + Long stackSize = t.getStackSize(); + Address stackEnd = stackBase.addOffsetTo(-stackSize); + if (a.lessThanOrEqual(stackBase) && a.greaterThan(stackEnd)) { + loc.stackThread = t; + return loc; + } + } + } + // Check if address is a native (C++) symbol + JVMDebugger dbg = VM.getVM().getDebugger(); + CDebugger cdbg = dbg.getCDebugger(); + if (cdbg != null) { + loc.loadObject = cdbg.loadObjectContainingPC(a); + if (loc.loadObject != null) { + loc.nativeSymbol = loc.loadObject.closestSymbolToPC(a); + return loc; + } + } + + // Check if address is in the java heap. CollectedHeap heap = VM.getVM().getUniverse().heap(); if (heap instanceof GenCollectedHeap) { GenCollectedHeap genheap = (GenCollectedHeap) heap; @@ -50,13 +106,12 @@ public class PointerFinder { } } - if (Assert.ASSERTS_ENABLED) { + if (Assert.ASSERTS_ENABLED) { Assert.that(loc.gen != null, "Should have found this in a generation"); } if (VM.getVM().getUseTLAB()) { // Try to find thread containing it - Threads threads = VM.getVM().getThreads(); for (int i = 0; i < threads.getNumberOfThreads(); i++) { JavaThread t = threads.getJavaThreadAt(i); ThreadLocalAllocBuffer tlab = t.tlab(); @@ -78,6 +133,7 @@ public class PointerFinder { } } + // Check if address is in the interpreter Interpreter interp = VM.getVM().getInterpreter(); if (interp.contains(a)) { loc.inInterpreter = true; @@ -85,6 +141,7 @@ public class PointerFinder { return loc; } + // Check if address is in the code cache if (!VM.getVM().isCore()) { CodeCache c = VM.getVM().getCodeCache(); if (c.contains(a)) { @@ -127,7 +184,6 @@ public class PointerFinder { return loc; } // Look in thread-local handles - Threads threads = VM.getVM().getThreads(); for (int i = 0; i < threads.getNumberOfThreads(); i++) { JavaThread t = threads.getJavaThreadAt(i); JNIHandleBlock handleBlock = t.activeHandles(); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java index 992a93885a8..aa2da619b46 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, 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 @@ -27,10 +27,13 @@ package sun.jvm.hotspot.utilities; import java.io.*; import sun.jvm.hotspot.code.*; import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.gc.shared.*; import sun.jvm.hotspot.interpreter.*; -import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.memory.*; +import sun.jvm.hotspot.oops.Metadata; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.types.Type; /** This class attempts to describe possible locations of pointers in the VM. */ @@ -45,6 +48,13 @@ public class PointerLocation { Address addr; + Metadata metadata; + Type ctype; + JavaThread stackThread; + + LoadObject loadObject; + ClosestSymbol nativeSymbol; + CollectedHeap heap; Generation gen; @@ -80,6 +90,22 @@ public class PointerLocation { this.addr = addr; } + public boolean isMetadata() { + return metadata != null; + } + + public boolean isCtype() { + return ctype != null; + } + + public boolean isInJavaStack() { + return stackThread != null; + } + + public boolean isNativeSymbol() { + return loadObject != null; + } + public boolean isInHeap() { return (heap != null || (gen != null)); } @@ -175,8 +201,9 @@ public class PointerLocation { } public boolean isUnknown() { - return (!(isInHeap() || isInInterpreter() || isInCodeCache() || - isInStrongGlobalJNIHandles() || isInWeakGlobalJNIHandles() || isInLocalJNIHandleBlock())); + return (!(isMetadata() || isCtype() || isInJavaStack() || isNativeSymbol() || isInHeap() || + isInInterpreter() || isInCodeCache() || isInStrongGlobalJNIHandles() || + isInWeakGlobalJNIHandles() || isInLocalJNIHandleBlock())); } public String toString() { @@ -186,24 +213,66 @@ public class PointerLocation { } public void print() { - printOn(System.out); + printOn(System.out, true, true); + } + + public void print(boolean printAddress, boolean verbose) { + printOn(System.out, printAddress, verbose); } public void printOn(PrintStream tty) { - tty.print("Address "); - if (addr == null) { - tty.print("0x0"); - } else { - tty.print(addr.toString()); + printOn(tty, true, true); + } + + public void printOn(PrintStream tty, boolean printAddress, boolean verbose) { + if (printAddress) { + tty.print("Address "); + if (addr == null) { + tty.print("0x0"); + } else { + tty.print(addr.toString()); + } + tty.print(": "); } - tty.print(": "); - if (isInHeap()) { + if (isMetadata()) { + metadata.printValueOn(tty); // does not include "\n" + tty.println(); + } else if (isCtype()) { + tty.println("Is of type " + ctype.getName()); + } else if (isInJavaStack()) { + if (verbose) { + tty.format("In java stack [%s,%s,%s] for thread %s:\n ", + stackThread.getStackBase(), stackThread.lastSPDbg(), + stackThread.getStackBase().addOffsetTo(-stackThread.getStackSize()), + stackThread); + stackThread.printThreadInfoOn(tty); // includes "\n" + } else { + tty.format("In java stack for thread \"%s\" %s\n", stackThread.getThreadName(), stackThread); + } + } else if (isNativeSymbol()) { + CDebugger cdbg = VM.getVM().getDebugger().getCDebugger(); + long diff; + if (nativeSymbol != null) { + String name = nativeSymbol.getName(); + if (cdbg.canDemangle()) { + name = cdbg.demangle(name); + } + tty.print(name); + diff = nativeSymbol.getOffset(); + } else { + tty.print(loadObject.getName()); + diff = addr.minus(loadObject.getBase()); + } + if (diff != 0L) { + tty.print(" + 0x" + Long.toHexString(diff)); + } + tty.println(); + } else if (isInHeap()) { if (isInTLAB()) { - tty.print("In thread-local allocation buffer for thread \"" + - getTLABThread().getThreadName() + "\" ("); - getTLABThread().printThreadIDOn(tty); + tty.print("In thread-local allocation buffer for thread ("); + getTLABThread().printThreadInfoOn(tty); tty.print(") "); - getTLAB().printOn(tty); + getTLAB().printOn(tty); // includes "\n" } else { if (isInNewGen()) { tty.print("In new generation "); @@ -213,13 +282,16 @@ public class PointerLocation { tty.print("In unknown section of Java heap"); } if (getGeneration() != null) { - getGeneration().printOn(tty); + getGeneration().printOn(tty); // does not include "\n" } + tty.println(); } } else if (isInInterpreter()) { - tty.println("In interpreter codelet \"" + interpreterCodelet.getDescription() + "\""); - interpreterCodelet.printOn(tty); + tty.print("In interpreter codelet: "); + interpreterCodelet.printOn(tty); // includes "\n" } else if (isInCodeCache()) { + // TODO: print the type of CodeBlob. See "look for known code blobs" comment + // in PStack.java for example code. CodeBlob b = getCodeBlob(); tty.print("In "); if (isInBlobCode()) { @@ -235,28 +307,32 @@ public class PointerLocation { tty.print("unknown location"); } tty.print(" in "); - b.printOn(tty); + if (verbose) { + b.printOn(tty); // includes "\n" + } else { + tty.println(b.toString()); + } // FIXME: add more detail } else if (isInStrongGlobalJNIHandles()) { - tty.print("In JNI strong global"); + tty.println("In JNI strong global"); } else if (isInWeakGlobalJNIHandles()) { - tty.print("In JNI weak global"); + tty.println("In JNI weak global"); } else if (isInLocalJNIHandleBlock()) { tty.print("In thread-local"); tty.print(" JNI handle block (" + handleBlock.top() + " handle slots present)"); if (handleThread.isJavaThread()) { tty.print(" for JavaThread "); - ((JavaThread) handleThread).printThreadIDOn(tty); + ((JavaThread) handleThread).printThreadIDOn(tty); // includes "\n" } else { - tty.print(" for a non-Java Thread"); + tty.println(" for a non-Java Thread"); } } else { // This must be last if (Assert.ASSERTS_ENABLED) { Assert.that(isUnknown(), "Should have unknown location"); } - tty.print("In unknown location"); + tty.println("In unknown location"); } } } diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java index 6b10d800a8c..34906370425 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java @@ -27,6 +27,7 @@ import java.util.Map; import java.util.ArrayList; import jdk.test.lib.apps.LingeredApp; +import jdk.test.lib.Platform; import jdk.test.lib.util.CoreUtils; import jtreg.SkippedException; @@ -75,12 +76,18 @@ import jtreg.SkippedException; */ public class ClhsdbFindPC { + static LingeredApp theApp = null; + static String coreFileName = null; + static ClhsdbLauncher test = null; private static void testFindPC(boolean withXcomp, boolean withCore) throws Exception { - LingeredApp theApp = null; - String coreFileName = null; try { - ClhsdbLauncher test = new ClhsdbLauncher(); + String segvAddress = null; + List cmds = null; + String cmdStr = null; + Map> expStrMap = null; + + test = new ClhsdbLauncher(); theApp = new LingeredAppWithTrivialMain(); theApp.setForceCrash(withCore); @@ -97,24 +104,38 @@ public class ClhsdbFindPC { } System.out.println("with pid " + theApp.getPid()); - // Get the core file name if we are debugging a core instead of live process if (withCore) { - coreFileName = CoreUtils.getCoreFileLocation(theApp.getOutput().getStdout(), theApp.getPid()); - } + String crashOutput = theApp.getOutput().getStdout(); + // Get the core file name if we are debugging a core instead of live process + coreFileName = CoreUtils.getCoreFileLocation(crashOutput, theApp.getPid()); + // Get the SEGV Address from the following line: + // # SIGSEGV (0xb) at pc=0x00007f20a897f7f4, pid=8561, tid=8562 + String[] parts = crashOutput.split(" pc="); + String[] tokens = parts[1].split(","); + segvAddress = tokens[0]; - // Run 'jstack -v' command to get the findpc address - List cmds = List.of("jstack -v"); - String output; - if (withCore) { - output = test.runOnCore(coreFileName, cmds, null, null); - } else { - output = test.run(theApp.getPid(), cmds, null, null); + // Test the 'findpc' command passing in the SEGV address + cmds = new ArrayList(); + cmdStr = "findpc " + segvAddress; + cmds.add(cmdStr); + expStrMap = new HashMap<>(); + if (Platform.isOSX()) { + // OSX will only find addresses in JVM libraries, not user or system libraries + expStrMap.put(cmdStr, List.of("In unknown location")); + } else { // symbol lookups not supported with OSX live process + expStrMap.put(cmdStr, List.of("Java_jdk_test_lib_apps_LingeredApp_crash")); + } + runTest(withCore, cmds, expStrMap); } + // Run 'jstack -v' command to get the pc and other useful values + cmds = List.of("jstack -v"); + String jStackOutput = runTest(withCore, cmds, null); + // Extract pc address from the following line: // - LingeredAppWithTrivialMain.main(java.lang.String[]) @bci=1, line=33, pc=0x00007ff18ff519f0, ... String pcAddress = null; - String[] parts = output.split("LingeredAppWithTrivialMain.main"); + String[] parts = jStackOutput.split("LingeredAppWithTrivialMain.main"); String[] tokens = parts[1].split(" "); for (String token : tokens) { if (token.contains("pc")) { @@ -128,11 +149,11 @@ public class ClhsdbFindPC { throw new RuntimeException("Cannot find LingeredAppWithTrivialMain.main pc in output"); } - // Test the 'findpc' command passing in the pc obtained from above + // Test the 'findpc' command passing in the pc obtained from jstack above cmds = new ArrayList(); - String cmdStr = "findpc " + pcAddress; + cmdStr = "findpc " + pcAddress; cmds.add(cmdStr); - Map> expStrMap = new HashMap<>(); + expStrMap = new HashMap<>(); if (withXcomp) { expStrMap.put(cmdStr, List.of( "In code in NMethod for LingeredAppWithTrivialMain.main", @@ -143,12 +164,78 @@ public class ClhsdbFindPC { expStrMap.put(cmdStr, List.of( "In interpreter codelet")); } + runTest(withCore, cmds, expStrMap); - if (withCore) { - test.runOnCore(coreFileName, cmds, expStrMap, null); + // Run findpc on a Method*. We can find one in the jstack output. For example: + // - LingeredAppWithTrivialMain.main(java.lang.String[]) @bci=1, line=33, pc=..., Method*=0x0000008041000208 ... + // This is testing the PointerFinder support for C++ MetaData types. + parts = jStackOutput.split("LingeredAppWithTrivialMain.main"); + parts = parts[1].split("Method\\*="); + parts = parts[1].split(" "); + String methodAddr = parts[0]; + cmdStr = "findpc " + methodAddr; + cmds = List.of(cmdStr); + expStrMap = new HashMap<>(); + expStrMap.put(cmdStr, List.of("Method ", + "LingeredAppWithTrivialMain.main", + methodAddr)); + runTest(withCore, cmds, expStrMap); + + // Run findpc on a JavaThread*. We can find one in the jstack output. + // The tid for a thread is it's JavaThread*. For example: + // "main" #1 prio=5 tid=0x00000080263398f0 nid=0x277e0 ... + // This is testing the PointerFinder support for all C++ types other than MetaData types. + parts = jStackOutput.split("tid="); + parts = parts[1].split(" "); + String tid = parts[0]; // address of the JavaThread + cmdStr = "findpc " + tid; + cmds = List.of(cmdStr); + expStrMap = new HashMap<>(); + expStrMap.put(cmdStr, List.of("Is of type JavaThread")); + runTest(withCore, cmds, expStrMap); + + // Run findpc on a java stack address. We can find one in the jstack output. + // "main" #1 prio=5 tid=... nid=0x277e0 waiting on condition [0x0000008025aef000] + // The stack address is the last word between the brackets. + // This is testing the PointerFinder support for thread stack addresses. + parts = jStackOutput.split("tid="); + parts = parts[1].split(" \\["); + parts = parts[1].split("\\]"); + String stackAddress = parts[0]; // address of the thread's stack + cmdStr = "findpc " + stackAddress; + cmds = List.of(cmdStr); + expStrMap = new HashMap<>(); + expStrMap.put(cmdStr, List.of("In java stack")); + runTest(withCore, cmds, expStrMap); + + // Run 'examine ' using a thread's tid as the address. The + // examine output will be the of the form: + // : + // Where is the word stored at . also happens to + // be the vtable address. We then run findpc on this vtable address. + // This tests PointerFinder support for native C++ symbols. + cmds = List.of("examine " + tid); + String examineOutput = runTest(withCore, cmds, null); + // Extract . + parts = examineOutput.split(tid + ": "); + String value = parts[1]; + // Use findpc on . The output should look something like: + // Address 0x00007fed86f610b8: vtable for JavaThread + 0x10 + cmdStr = "findpc " + value; + cmds = List.of(cmdStr); + expStrMap = new HashMap<>(); + if (Platform.isWindows()) { + expStrMap.put(cmdStr, List.of("jvm.+JavaThread")); + } else if (Platform.isOSX()) { + if (withCore) { + expStrMap.put(cmdStr, List.of("__ZTV10JavaThread")); + } else { // symbol lookups not supported with OSX live process + expStrMap.put(cmdStr, List.of("In unknown location")); + } } else { - test.run(theApp.getPid(), cmds, expStrMap, null); + expStrMap.put(cmdStr, List.of("vtable for JavaThread")); } + runTest(withCore, cmds, expStrMap); } catch (SkippedException se) { throw se; } catch (Exception ex) { @@ -160,6 +247,16 @@ public class ClhsdbFindPC { } } + private static String runTest(boolean withCore, List cmds, Map> expStrMap) + throws Exception + { + if (withCore) { + return test.runOnCore(coreFileName, cmds, expStrMap, null); + } else { + return test.run(theApp.getPid(), cmds, expStrMap, null); + } + } + public static void main(String[] args) throws Exception { boolean withXcomp = Boolean.parseBoolean(args[0]); boolean withCore = Boolean.parseBoolean(args[1]); -- GitLab From 735757f1e0ec9d05eb4c6f4d680b34de96f83700 Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Fri, 12 Feb 2021 22:41:08 +0000 Subject: [PATCH 057/367] 8261661: gc/stress/TestReclaimStringsLeaksMemory.java fails because Reserved memory size is too big Co-authored-by: Albert Mingkun Yang Reviewed-by: ayang, kbarrett --- .../jtreg/gc/stress/TestReclaimStringsLeaksMemory.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/gc/stress/TestReclaimStringsLeaksMemory.java b/test/hotspot/jtreg/gc/stress/TestReclaimStringsLeaksMemory.java index 85d13bb2f46..aac4e3d02c9 100644 --- a/test/hotspot/jtreg/gc/stress/TestReclaimStringsLeaksMemory.java +++ b/test/hotspot/jtreg/gc/stress/TestReclaimStringsLeaksMemory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, 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 @@ -48,9 +48,9 @@ import jdk.test.lib.process.ProcessTools; public class TestReclaimStringsLeaksMemory { - // The amount of memory in kB reserved in the "Symbol" category that indicates a memory leak for + // The amount of memory in B reserved in the "Symbol" category that indicates a memory leak for // this test. - public static final int ReservedThreshold = 70000; + public static final int ReservedThreshold = 70000000; public static void main(String[] args) throws Exception { ArrayList baseargs = new ArrayList<>(Arrays.asList("-Xms256M", @@ -77,7 +77,7 @@ public class TestReclaimStringsLeaksMemory { } int reserved = Integer.parseInt(m.group(1)); - Asserts.assertLT(reserved, ReservedThreshold, "Reserved memory size is " + reserved + "KB which is greater than or equal to " + ReservedThreshold + "KB indicating a memory leak"); + Asserts.assertLT(reserved, ReservedThreshold, "Reserved memory size is " + reserved + "B which is greater than or equal to " + ReservedThreshold + "B indicating a memory leak"); output.shouldHaveExitValue(0); } -- GitLab From 849390a11e4dd4001a4f8bf75250eef942d9da18 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Sat, 13 Feb 2021 02:14:32 +0000 Subject: [PATCH 058/367] 8260401: StackOverflowError on open WindowsPreferences Reviewed-by: bpb --- .../windows/classes/java/util/prefs/WindowsPreferences.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java.prefs/windows/classes/java/util/prefs/WindowsPreferences.java b/src/java.prefs/windows/classes/java/util/prefs/WindowsPreferences.java index 157c33c2bbe..e955d84779d 100644 --- a/src/java.prefs/windows/classes/java/util/prefs/WindowsPreferences.java +++ b/src/java.prefs/windows/classes/java/util/prefs/WindowsPreferences.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, 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 @@ -432,7 +432,7 @@ class WindowsPreferences extends AbstractPreferences { if (result[ERROR_CODE] != ERROR_SUCCESS) { logger().warning("Could not create windows registry node " + byteArrayToString(windowsAbsolutePath()) + - " at root 0x" + Long.toHexString(rootNativeHandle()) + + " at root 0x" + Long.toHexString(parentNativeHandle) + ". Windows RegCreateKeyEx(...) returned error code " + result[ERROR_CODE] + "."); isBackingStoreAvailable = false; @@ -458,7 +458,7 @@ class WindowsPreferences extends AbstractPreferences { if (result[ERROR_CODE] != ERROR_SUCCESS) { logger().warning("Could not open/create prefs root node " + byteArrayToString(windowsAbsolutePath()) + - " at root 0x" + Long.toHexString(rootNativeHandle()) + + " at root 0x" + Long.toHexString(rootNativeHandle) + ". Windows RegCreateKeyEx(...) returned error code " + result[ERROR_CODE] + "."); isBackingStoreAvailable = false; -- GitLab From 95d73129ce5074d3510710e7e238761a9af9ef3a Mon Sep 17 00:00:00 2001 From: Hui Shi Date: Sat, 13 Feb 2021 02:47:33 +0000 Subject: [PATCH 059/367] 8261585: Restore HandleArea used in Deoptimization::uncommon_trap Reviewed-by: coleenp, jiefu --- src/hotspot/share/runtime/deoptimization.cpp | 1 + .../uncommontrap/UncommonTrapLeak.java | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/uncommontrap/UncommonTrapLeak.java diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index 470d41ff694..e0a04aa4c48 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -2465,6 +2465,7 @@ Deoptimization::UnrollBlock* Deoptimization::uncommon_trap(JavaThread* thread, j // This enters VM and may safepoint uncommon_trap_inner(thread, trap_request); } + HandleMark hm(thread); return fetch_unroll_info_helper(thread, exec_mode); } diff --git a/test/hotspot/jtreg/compiler/uncommontrap/UncommonTrapLeak.java b/test/hotspot/jtreg/compiler/uncommontrap/UncommonTrapLeak.java new file mode 100644 index 00000000000..5593f502614 --- /dev/null +++ b/test/hotspot/jtreg/compiler/uncommontrap/UncommonTrapLeak.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.ref.WeakReference; + +/* + * @test + * @bug 8260473 + * @summary Handle leak might cause object not collected as expected + * + * @run main/othervm -XX:-Inline -XX:-TieredCompilation -XX:CompileCommand=compileonly,UncommonTrapLeak.foo + * -XX:CompileThreshold=100 -XX:-BackgroundCompilation UncommonTrapLeak + * + * @author Hui Shi + */ +public class UncommonTrapLeak { + static WeakReference ref = null; + static int val = 0; + public static void main(String args[]) { + for (int i = 0; i < 300; i++) { + val++; + foo(i); + System.gc(); + if (ref.get() != null) { + throw new RuntimeException("Failed: referent not collected after trap " + ref.get()); + } + if (i % 100 == 0) { + System.out.println(i); + } + } + } + + static void foo(int i) { + Object o = new Object(); + ref = new WeakReference(o); + if (val == 200) { + // trigger Deoptimization::uncommon_trap + if (o instanceof UncommonTrapLeak) { + } + } + } +} + -- GitLab From 235da6aa048a9c5b3a702bdd9ab54017f14f097b Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Sat, 13 Feb 2021 07:13:22 +0000 Subject: [PATCH 060/367] 8261672: Reduce inclusion of classLoaderData.hpp Reviewed-by: lfoltan, coleenp --- .../gc/shared/barrierSetAssembler_aarch64.cpp | 3 +- .../ppc/gc/shared/barrierSetAssembler_ppc.cpp | 1 + .../x86/gc/shared/barrierSetAssembler_x86.cpp | 3 +- src/hotspot/os/aix/os_aix.cpp | 1 - src/hotspot/os/bsd/os_bsd.cpp | 1 - src/hotspot/os/windows/os_windows.cpp | 1 - src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp | 1 - src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp | 1 - src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp | 1 - .../os_cpu/linux_aarch64/os_linux_aarch64.cpp | 1 - src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp | 1 - src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp | 1 - .../os_cpu/linux_s390/os_linux_s390.cpp | 1 - src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp | 1 - .../os_cpu/linux_zero/os_linux_zero.cpp | 1 - .../windows_aarch64/os_windows_aarch64.cpp | 1 - .../os_cpu/windows_x86/os_windows_x86.cpp | 1 - src/hotspot/share/asm/codeBuffer.cpp | 1 + src/hotspot/share/ci/ciMethodData.cpp | 3 +- .../share/classfile/javaAssertions.hpp | 3 +- .../share/classfile/loaderConstraints.cpp | 3 +- src/hotspot/share/classfile/moduleEntry.cpp | 7 +++- src/hotspot/share/classfile/moduleEntry.hpp | 10 ++--- src/hotspot/share/classfile/packageEntry.cpp | 1 + .../share/classfile/resolutionErrors.cpp | 1 + src/hotspot/share/classfile/symbolTable.cpp | 1 + .../classfile/systemDictionaryShared.hpp | 1 + src/hotspot/share/code/compiledIC.cpp | 1 + src/hotspot/share/code/compiledMethod.cpp | 2 + src/hotspot/share/code/nmethod.cpp | 1 + src/hotspot/share/compiler/compileTask.cpp | 1 + .../share/gc/g1/g1FullGCMarker.inline.hpp | 3 +- .../parallel/psCompactionManager.inline.hpp | 3 +- src/hotspot/share/gc/shared/collectedHeap.cpp | 1 + .../share/gc/shared/gcVMOperations.cpp | 2 +- .../share/gc/shared/genOopClosures.inline.hpp | 3 +- src/hotspot/share/gc/z/zCollectedHeap.cpp | 3 +- src/hotspot/share/jvmci/metadataHandles.cpp | 3 +- src/hotspot/share/memory/filemap.hpp | 4 +- src/hotspot/share/oops/compiledICHolder.hpp | 13 +----- .../share/oops/compiledICHolder.inline.hpp | 42 +++++++++++++++++++ src/hotspot/share/oops/instanceKlass.hpp | 1 - src/hotspot/share/oops/klass.hpp | 19 +++------ src/hotspot/share/oops/klass.inline.hpp | 22 +++++++++- src/hotspot/share/oops/methodData.cpp | 1 + src/hotspot/share/oops/methodData.hpp | 3 +- src/hotspot/share/oops/objArrayKlass.hpp | 5 ++- src/hotspot/share/oops/typeArrayKlass.hpp | 5 ++- src/hotspot/share/opto/runtime.cpp | 1 + src/hotspot/share/prims/jni.cpp | 1 - src/hotspot/share/prims/jvmtiEnvBase.hpp | 3 +- src/hotspot/share/prims/jvmtiImpl.cpp | 1 + .../share/runtime/flags/jvmFlagAccess.cpp | 3 +- src/hotspot/share/runtime/java.cpp | 1 - src/hotspot/share/runtime/os.cpp | 1 - src/hotspot/share/runtime/sharedRuntime.cpp | 1 + src/hotspot/share/services/attachListener.hpp | 3 +- src/hotspot/share/services/runtimeService.cpp | 3 +- src/hotspot/share/services/threadService.cpp | 1 + 59 files changed, 135 insertions(+), 74 deletions(-) create mode 100644 src/hotspot/share/oops/compiledICHolder.inline.hpp diff --git a/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp index 2841e68cf56..777448c6a8c 100644 --- a/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, 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 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/barrierSetNMethod.hpp" diff --git a/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp b/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp index cc78b019153..800b34e4ba7 100644 --- a/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp @@ -26,6 +26,7 @@ #include "nativeInst_ppc.hpp" #include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" +#include "classfile/classLoaderData.hpp" #include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/barrierSetNMethod.hpp" #include "interpreter/interp_masm.hpp" diff --git a/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp index 274cc1a8702..6e820f98689 100644 --- a/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, 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 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.hpp" #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetAssembler.hpp" #include "gc/shared/barrierSetNMethod.hpp" diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index a976e4f6b94..92ab7dae99b 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -29,7 +29,6 @@ // no precompiled headers #include "jvm.h" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index 627b995dfed..a11ceac93c1 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -24,7 +24,6 @@ // no precompiled headers #include "jvm.h" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 53dd2d99f15..15ce223bd37 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -27,7 +27,6 @@ // no precompiled headers #include "jvm.h" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" diff --git a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp index 07f1f8be755..d3482e32f21 100644 --- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp +++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp @@ -27,7 +27,6 @@ #include "jvm.h" #include "assembler_ppc.hpp" #include "asm/assembler.inline.hpp" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" diff --git a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp index 595c1b0f775..e7252b5653e 100644 --- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp +++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp @@ -25,7 +25,6 @@ // no precompiled headers #include "jvm.h" #include "asm/macroAssembler.hpp" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" diff --git a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp index 8bca69035b7..18125f1c16c 100644 --- a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp +++ b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp @@ -31,7 +31,6 @@ // no precompiled headers #include "jvm.h" #include "assembler_zero.inline.hpp" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" diff --git a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp index a785369a8dd..13702ba1c23 100644 --- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp @@ -26,7 +26,6 @@ // no precompiled headers #include "jvm.h" #include "asm/macroAssembler.hpp" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" diff --git a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp index 12eb0f543ce..064c1fba16b 100644 --- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp +++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp @@ -25,7 +25,6 @@ // no precompiled headers #include "jvm.h" #include "assembler_arm.inline.hpp" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" diff --git a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp index 0e390ab3f28..5edb303b68b 100644 --- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp +++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp @@ -27,7 +27,6 @@ #include "jvm.h" #include "assembler_ppc.hpp" #include "asm/assembler.inline.hpp" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" diff --git a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp index cd370d2f7a3..53b017d2217 100644 --- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp +++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp @@ -28,7 +28,6 @@ // no precompiled headers #include "jvm.h" #include "asm/assembler.inline.hpp" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/icBuffer.hpp" #include "code/nativeInst.hpp" diff --git a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp index ed603aa641e..dcd2f566a16 100644 --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp +++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp @@ -25,7 +25,6 @@ // no precompiled headers #include "jvm.h" #include "asm/macroAssembler.hpp" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" diff --git a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp index e38b7d351ae..ac57da78a25 100644 --- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp +++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp @@ -26,7 +26,6 @@ // no precompiled headers #include "jvm.h" #include "assembler_zero.inline.hpp" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" diff --git a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp index 6422eb406e0..94a96fc05af 100644 --- a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp +++ b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp @@ -25,7 +25,6 @@ #include "precompiled.hpp" #include "jvm.h" #include "asm/macroAssembler.hpp" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" diff --git a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp index 2e18762cf63..764780db4e1 100644 --- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp +++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp @@ -25,7 +25,6 @@ // no precompiled headers #include "jvm.h" #include "asm/macroAssembler.hpp" -#include "classfile/classLoader.hpp" #include "classfile/vmSymbols.hpp" #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index 7558c9c8572..7d76c8ae751 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -27,6 +27,7 @@ #include "code/oopRecorder.inline.hpp" #include "compiler/disassembler.hpp" #include "logging/log.hpp" +#include "oops/klass.inline.hpp" #include "oops/methodData.hpp" #include "oops/oop.inline.hpp" #include "runtime/icache.hpp" diff --git a/src/hotspot/share/ci/ciMethodData.cpp b/src/hotspot/share/ci/ciMethodData.cpp index 8e177980a7a..8f61ce744dc 100644 --- a/src/hotspot/share/ci/ciMethodData.cpp +++ b/src/hotspot/share/ci/ciMethodData.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2021, 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 @@ -30,6 +30,7 @@ #include "compiler/compiler_globals.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" +#include "oops/klass.inline.hpp" #include "runtime/deoptimization.hpp" #include "utilities/copy.hpp" diff --git a/src/hotspot/share/classfile/javaAssertions.hpp b/src/hotspot/share/classfile/javaAssertions.hpp index b2fa038b24a..58d03eacd48 100644 --- a/src/hotspot/share/classfile/javaAssertions.hpp +++ b/src/hotspot/share/classfile/javaAssertions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, 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 @@ -27,6 +27,7 @@ #include "oops/objArrayOop.hpp" #include "oops/typeArrayOop.hpp" +#include "runtime/handles.hpp" #include "utilities/exceptions.hpp" #include "utilities/ostream.hpp" diff --git a/src/hotspot/share/classfile/loaderConstraints.cpp b/src/hotspot/share/classfile/loaderConstraints.cpp index d0bf7052821..3caaddb3cb2 100644 --- a/src/hotspot/share/classfile/loaderConstraints.cpp +++ b/src/hotspot/share/classfile/loaderConstraints.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -29,6 +29,7 @@ #include "classfile/loaderConstraints.hpp" #include "logging/log.hpp" #include "memory/resourceArea.hpp" +#include "oops/klass.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/safepoint.hpp" diff --git a/src/hotspot/share/classfile/moduleEntry.cpp b/src/hotspot/share/classfile/moduleEntry.cpp index 08c97c9e7a7..9477e37439e 100644 --- a/src/hotspot/share/classfile/moduleEntry.cpp +++ b/src/hotspot/share/classfile/moduleEntry.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 @@ -368,6 +368,11 @@ ModuleEntryTable::~ModuleEntryTable() { assert(new_entry_free_list() == NULL, "entry present on ModuleEntryTable's free list"); } +void ModuleEntry::set_loader_data(ClassLoaderData* cld) { + assert(!cld->has_class_mirror_holder(), "Unexpected has_class_mirror_holder cld"); + _loader_data = cld; +} + #if INCLUDE_CDS_JAVA_HEAP typedef ResourceHashtable< const ModuleEntry*, diff --git a/src/hotspot/share/classfile/moduleEntry.hpp b/src/hotspot/share/classfile/moduleEntry.hpp index c86904bc823..959fcac74e3 100644 --- a/src/hotspot/share/classfile/moduleEntry.hpp +++ b/src/hotspot/share/classfile/moduleEntry.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2021, 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 @@ -26,7 +26,6 @@ #define SHARE_CLASSFILE_MODULEENTRY_HPP #include "jni.h" -#include "classfile/classLoaderData.hpp" #include "oops/oopHandle.hpp" #include "oops/symbol.hpp" #include "runtime/mutexLocker.hpp" @@ -46,6 +45,7 @@ #define JAVA_BASE_NAME_LEN 9 template class Array; +class ClassLoaderData; class MetaspaceClosure; class ModuleClosure; @@ -112,11 +112,7 @@ public: void set_shared_protection_domain(ClassLoaderData *loader_data, Handle pd); ClassLoaderData* loader_data() const { return _loader_data; } - - void set_loader_data(ClassLoaderData* cld) { - assert(!cld->has_class_mirror_holder(), "Unexpected has_class_mirror_holder cld"); - _loader_data = cld; - } + void set_loader_data(ClassLoaderData* cld); Symbol* version() const { return _version; } void set_version(Symbol* version); diff --git a/src/hotspot/share/classfile/packageEntry.cpp b/src/hotspot/share/classfile/packageEntry.cpp index 8e5c826dbad..8beb89c595a 100644 --- a/src/hotspot/share/classfile/packageEntry.cpp +++ b/src/hotspot/share/classfile/packageEntry.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.hpp" #include "classfile/moduleEntry.hpp" #include "classfile/packageEntry.hpp" #include "classfile/vmSymbols.hpp" diff --git a/src/hotspot/share/classfile/resolutionErrors.cpp b/src/hotspot/share/classfile/resolutionErrors.cpp index d248a5e55ec..47eca140606 100644 --- a/src/hotspot/share/classfile/resolutionErrors.cpp +++ b/src/hotspot/share/classfile/resolutionErrors.cpp @@ -27,6 +27,7 @@ #include "memory/allocation.hpp" #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" +#include "oops/klass.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/safepoint.hpp" diff --git a/src/hotspot/share/classfile/symbolTable.cpp b/src/hotspot/share/classfile/symbolTable.cpp index 776a74a2706..a0d7b12d9ab 100644 --- a/src/hotspot/share/classfile/symbolTable.cpp +++ b/src/hotspot/share/classfile/symbolTable.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" +#include "classfile/classLoaderData.hpp" #include "classfile/compactHashtable.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" diff --git a/src/hotspot/share/classfile/systemDictionaryShared.hpp b/src/hotspot/share/classfile/systemDictionaryShared.hpp index db02009b880..37f3d9a33a4 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.hpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP #define SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP +#include "classfile/classLoaderData.hpp" #include "classfile/packageEntry.hpp" #include "classfile/systemDictionary.hpp" #include "memory/filemap.hpp" diff --git a/src/hotspot/share/code/compiledIC.cpp b/src/hotspot/share/code/compiledIC.cpp index 848cc98a4c2..f326ccc738d 100644 --- a/src/hotspot/share/code/compiledIC.cpp +++ b/src/hotspot/share/code/compiledIC.cpp @@ -35,6 +35,7 @@ #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" +#include "oops/klass.inline.hpp" #include "oops/method.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" diff --git a/src/hotspot/share/code/compiledMethod.cpp b/src/hotspot/share/code/compiledMethod.cpp index 0d6ffe789c5..74c38880742 100644 --- a/src/hotspot/share/code/compiledMethod.cpp +++ b/src/hotspot/share/code/compiledMethod.cpp @@ -36,6 +36,8 @@ #include "logging/log.hpp" #include "logging/logTag.hpp" #include "memory/resourceArea.hpp" +#include "oops/compiledICHolder.inline.hpp" +#include "oops/klass.inline.hpp" #include "oops/methodData.hpp" #include "oops/method.inline.hpp" #include "prims/methodHandles.hpp" diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 0711c399e82..57cb798b3f3 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -46,6 +46,7 @@ #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/access.inline.hpp" +#include "oops/klass.inline.hpp" #include "oops/method.inline.hpp" #include "oops/methodData.hpp" #include "oops/oop.inline.hpp" diff --git a/src/hotspot/share/compiler/compileTask.cpp b/src/hotspot/share/compiler/compileTask.cpp index c56ebdb888b..d610d8bdcf8 100644 --- a/src/hotspot/share/compiler/compileTask.cpp +++ b/src/hotspot/share/compiler/compileTask.cpp @@ -31,6 +31,7 @@ #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/resourceArea.hpp" +#include "oops/klass.inline.hpp" #include "runtime/handles.inline.hpp" #include "runtime/jniHandles.hpp" diff --git a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp index 75d8f656305..75592996898 100644 --- a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2021, 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 @@ -25,6 +25,7 @@ #ifndef SHARE_GC_G1_G1FULLGCMARKER_INLINE_HPP #define SHARE_GC_G1_G1FULLGCMARKER_INLINE_HPP +#include "classfile/classLoaderData.hpp" #include "classfile/javaClasses.inline.hpp" #include "gc/g1/g1Allocator.inline.hpp" #include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp" diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp index 03ce090a4f4..a0df3dade2a 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2021, 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 @@ -25,6 +25,7 @@ #ifndef SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_INLINE_HPP #define SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_INLINE_HPP +#include "classfile/classLoaderData.hpp" #include "classfile/javaClasses.inline.hpp" #include "gc/parallel/parMarkBitMap.hpp" #include "gc/parallel/psCompactionManager.hpp" diff --git a/src/hotspot/share/gc/shared/collectedHeap.cpp b/src/hotspot/share/gc/shared/collectedHeap.cpp index 105d64ba2f1..c62304e2217 100644 --- a/src/hotspot/share/gc/shared/collectedHeap.cpp +++ b/src/hotspot/share/gc/shared/collectedHeap.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.hpp" #include "classfile/vmClasses.hpp" #include "gc/shared/allocTracer.hpp" #include "gc/shared/barrierSet.hpp" diff --git a/src/hotspot/share/gc/shared/gcVMOperations.cpp b/src/hotspot/share/gc/shared/gcVMOperations.cpp index a8a4084990e..f73974981c9 100644 --- a/src/hotspot/share/gc/shared/gcVMOperations.cpp +++ b/src/hotspot/share/gc/shared/gcVMOperations.cpp @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "classfile/classLoader.hpp" +#include "classfile/classLoaderData.hpp" #include "classfile/javaClasses.hpp" #include "gc/shared/allocTracer.hpp" #include "gc/shared/gcId.hpp" diff --git a/src/hotspot/share/gc/shared/genOopClosures.inline.hpp b/src/hotspot/share/gc/shared/genOopClosures.inline.hpp index da85dd1db42..0b547e6dcff 100644 --- a/src/hotspot/share/gc/shared/genOopClosures.inline.hpp +++ b/src/hotspot/share/gc/shared/genOopClosures.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2021, 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 @@ -25,6 +25,7 @@ #ifndef SHARE_GC_SHARED_GENOOPCLOSURES_INLINE_HPP #define SHARE_GC_SHARED_GENOOPCLOSURES_INLINE_HPP +#include "classfile/classLoaderData.hpp" #include "gc/shared/cardTableRS.hpp" #include "gc/shared/genCollectedHeap.hpp" #include "gc/shared/genOopClosures.hpp" diff --git a/src/hotspot/share/gc/z/zCollectedHeap.cpp b/src/hotspot/share/gc/z/zCollectedHeap.cpp index f07d4b4c7aa..24bd1e31816 100644 --- a/src/hotspot/share/gc/z/zCollectedHeap.cpp +++ b/src/hotspot/share/gc/z/zCollectedHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021, 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 @@ -22,6 +22,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.hpp" #include "gc/shared/gcHeapSummary.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/z/zCollectedHeap.hpp" diff --git a/src/hotspot/share/jvmci/metadataHandles.cpp b/src/hotspot/share/jvmci/metadataHandles.cpp index da1ad7b61a0..bcf66721f52 100644 --- a/src/hotspot/share/jvmci/metadataHandles.cpp +++ b/src/hotspot/share/jvmci/metadataHandles.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, 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 @@ -22,6 +22,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.hpp" #include "jvmci/metadataHandles.hpp" #include "runtime/atomic.hpp" diff --git a/src/hotspot/share/memory/filemap.hpp b/src/hotspot/share/memory/filemap.hpp index 7b00b1b5878..de05861a5a1 100644 --- a/src/hotspot/share/memory/filemap.hpp +++ b/src/hotspot/share/memory/filemap.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_MEMORY_FILEMAP_HPP #define SHARE_MEMORY_FILEMAP_HPP -#include "classfile/classLoader.hpp" #include "include/cds.h" #include "memory/metaspaceShared.hpp" #include "memory/metaspace.hpp" @@ -44,6 +43,9 @@ static const int JVM_IDENT_MAX = 256; class CHeapBitMap; +class ClassFileStream; +class ClassLoaderData; +class ClassPathEntry; class outputStream; class SharedClassPathEntry { diff --git a/src/hotspot/share/oops/compiledICHolder.hpp b/src/hotspot/share/oops/compiledICHolder.hpp index a1932cba56c..b3d0c8715bf 100644 --- a/src/hotspot/share/oops/compiledICHolder.hpp +++ b/src/hotspot/share/oops/compiledICHolder.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2021, 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 @@ -71,16 +71,7 @@ class CompiledICHolder : public CHeapObj { CompiledICHolder* next() { return _next; } void set_next(CompiledICHolder* n) { _next = n; } - inline bool is_loader_alive() { - Klass* k = _is_metadata_method ? ((Method*)_holder_metadata)->method_holder() : (Klass*)_holder_metadata; - if (!k->is_loader_alive()) { - return false; - } - if (!_holder_klass->is_loader_alive()) { - return false; - } - return true; - } + inline bool is_loader_alive(); // Verify void verify_on(outputStream* st); diff --git a/src/hotspot/share/oops/compiledICHolder.inline.hpp b/src/hotspot/share/oops/compiledICHolder.inline.hpp new file mode 100644 index 00000000000..4a5531531f0 --- /dev/null +++ b/src/hotspot/share/oops/compiledICHolder.inline.hpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_OOPS_COMPILEDICHOLDER_INLINE_HPP +#define SHARE_OOPS_COMPILEDICHOLDER_INLINE_HPP + +#include "oops/compiledICHolder.hpp" +#include "oops/klass.inline.hpp" + +inline bool CompiledICHolder::is_loader_alive() { + Klass* k = _is_metadata_method ? ((Method*)_holder_metadata)->method_holder() : (Klass*)_holder_metadata; + if (!k->is_loader_alive()) { + return false; + } + if (!_holder_klass->is_loader_alive()) { + return false; + } + return true; +} + +#endif // SHARE_OOPS_COMPILEDICHOLDER_INLINE_HPP diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index 2b038ed4322..220ec9b1b29 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_OOPS_INSTANCEKLASS_HPP #define SHARE_OOPS_INSTANCEKLASS_HPP -#include "classfile/classLoaderData.hpp" #include "memory/referenceType.hpp" #include "oops/annotations.hpp" #include "oops/constMethod.hpp" diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index 6449eda3778..cfed2823f11 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, 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 @@ -25,7 +25,6 @@ #ifndef SHARE_OOPS_KLASS_HPP #define SHARE_OOPS_KLASS_HPP -#include "classfile/classLoaderData.hpp" #include "memory/iterator.hpp" #include "memory/memRegion.hpp" #include "oops/markWord.hpp" @@ -67,6 +66,7 @@ const uint KLASS_ID_COUNT = 6; // Forward declarations. template class Array; template class GrowableArray; +class ClassLoaderData; class fieldDescriptor; class klassVtable; class ModuleEntry; @@ -508,11 +508,7 @@ protected: oop class_loader() const; - // This loads the klass's holder as a phantom. This is useful when a weak Klass - // pointer has been "peeked" and then must be kept alive before it may - // be used safely. All uses of klass_holder need to apply the appropriate barriers, - // except during GC. - oop klass_holder() const { return class_loader_data()->holder_phantom(); } + inline oop klass_holder() const; protected: virtual Klass* array_klass_impl(bool or_null, int rank, TRAPS); @@ -635,11 +631,11 @@ protected: void set_is_shared() { _access_flags.set_is_shared_class(); } bool is_hidden() const { return access_flags().is_hidden_class(); } void set_is_hidden() { _access_flags.set_is_hidden_class(); } - bool is_non_strong_hidden() const { return access_flags().is_hidden_class() && - class_loader_data()->has_class_mirror_holder(); } bool is_value_based() { return _access_flags.is_value_based_class(); } void set_is_value_based() { _access_flags.set_is_value_based_class(); } + inline bool is_non_strong_hidden() const; + bool is_cloneable() const; void set_is_cloneable(); @@ -672,10 +668,7 @@ protected: virtual void metaspace_pointers_do(MetaspaceClosure* iter); virtual MetaspaceObj::Type type() const { return ClassType; } - // Iff the class loader (or mirror for unsafe anonymous classes) is alive the - // Klass is considered alive. This is safe to call before the CLD is marked as - // unloading, and hence during concurrent class unloading. - bool is_loader_alive() const { return class_loader_data()->is_alive(); } + inline bool is_loader_alive() const; void clean_subklass(); diff --git a/src/hotspot/share/oops/klass.inline.hpp b/src/hotspot/share/oops/klass.inline.hpp index df4e8ded400..6842363577c 100644 --- a/src/hotspot/share/oops/klass.inline.hpp +++ b/src/hotspot/share/oops/klass.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -29,6 +29,26 @@ #include "oops/klass.hpp" #include "oops/markWord.hpp" +// This loads the klass's holder as a phantom. This is useful when a weak Klass +// pointer has been "peeked" and then must be kept alive before it may +// be used safely. All uses of klass_holder need to apply the appropriate barriers, +// except during GC. +inline oop Klass::klass_holder() const { + return class_loader_data()->holder_phantom(); +} + +inline bool Klass::is_non_strong_hidden() const { + return access_flags().is_hidden_class() && + class_loader_data()->has_class_mirror_holder(); +} + +// Iff the class loader (or mirror for unsafe anonymous classes) is alive the +// Klass is considered alive. This is safe to call before the CLD is marked as +// unloading, and hence during concurrent class unloading. +inline bool Klass::is_loader_alive() const { + return class_loader_data()->is_alive(); +} + inline void Klass::set_prototype_header(markWord header) { assert(!header.has_bias_pattern() || is_instance_klass(), "biased locking currently only supported for Java instances"); _prototype_header = header; diff --git a/src/hotspot/share/oops/methodData.cpp b/src/hotspot/share/oops/methodData.cpp index 54aa8ec0a4e..1aa89934562 100644 --- a/src/hotspot/share/oops/methodData.cpp +++ b/src/hotspot/share/oops/methodData.cpp @@ -32,6 +32,7 @@ #include "interpreter/linkResolver.hpp" #include "memory/metaspaceClosure.hpp" #include "memory/resourceArea.hpp" +#include "oops/klass.inline.hpp" #include "oops/methodData.inline.hpp" #include "prims/jvmtiRedefineClasses.hpp" #include "runtime/arguments.hpp" diff --git a/src/hotspot/share/oops/methodData.hpp b/src/hotspot/share/oops/methodData.hpp index a02362b01f8..a33b118334e 100644 --- a/src/hotspot/share/oops/methodData.hpp +++ b/src/hotspot/share/oops/methodData.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, 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 @@ -30,6 +30,7 @@ #include "oops/method.hpp" #include "oops/oop.hpp" #include "runtime/atomic.hpp" +#include "runtime/mutex.hpp" #include "utilities/align.hpp" #include "utilities/copy.hpp" diff --git a/src/hotspot/share/oops/objArrayKlass.hpp b/src/hotspot/share/oops/objArrayKlass.hpp index e2feb61f4e9..6ed8ae6f760 100644 --- a/src/hotspot/share/oops/objArrayKlass.hpp +++ b/src/hotspot/share/oops/objArrayKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, 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 @@ -25,10 +25,11 @@ #ifndef SHARE_OOPS_OBJARRAYKLASS_HPP #define SHARE_OOPS_OBJARRAYKLASS_HPP -#include "classfile/classLoaderData.hpp" #include "oops/arrayKlass.hpp" #include "utilities/macros.hpp" +class ClassLoaderData; + // ObjArrayKlass is the klass for objArrays class ObjArrayKlass : public ArrayKlass { diff --git a/src/hotspot/share/oops/typeArrayKlass.hpp b/src/hotspot/share/oops/typeArrayKlass.hpp index 436d369f340..0c57c8a375f 100644 --- a/src/hotspot/share/oops/typeArrayKlass.hpp +++ b/src/hotspot/share/oops/typeArrayKlass.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, 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 @@ -25,9 +25,10 @@ #ifndef SHARE_OOPS_TYPEARRAYKLASS_HPP #define SHARE_OOPS_TYPEARRAYKLASS_HPP -#include "classfile/classLoaderData.hpp" #include "oops/arrayKlass.hpp" +class ClassLoaderData; + // A TypeArrayKlass is the klass of a typeArray // It contains the type and size of the elements diff --git a/src/hotspot/share/opto/runtime.cpp b/src/hotspot/share/opto/runtime.cpp index f5cec6b7d05..5017efdb17f 100644 --- a/src/hotspot/share/opto/runtime.cpp +++ b/src/hotspot/share/opto/runtime.cpp @@ -47,6 +47,7 @@ #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "oops/objArrayKlass.hpp" +#include "oops/klass.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/typeArrayOop.inline.hpp" #include "opto/ad.hpp" diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp index 917e0bff389..3f3731c29bb 100644 --- a/src/hotspot/share/prims/jni.cpp +++ b/src/hotspot/share/prims/jni.cpp @@ -29,7 +29,6 @@ #include "ci/ciReplay.hpp" #include "classfile/altHashing.hpp" #include "classfile/classFileStream.hpp" -#include "classfile/classLoader.hpp" #include "classfile/javaClasses.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/javaThreadStatus.hpp" diff --git a/src/hotspot/share/prims/jvmtiEnvBase.hpp b/src/hotspot/share/prims/jvmtiEnvBase.hpp index fa516fe568a..68399ed6a14 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.hpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -25,7 +25,6 @@ #ifndef SHARE_PRIMS_JVMTIENVBASE_HPP #define SHARE_PRIMS_JVMTIENVBASE_HPP -#include "classfile/classLoader.hpp" #include "prims/jvmtiEnvThreadState.hpp" #include "prims/jvmtiEventController.hpp" #include "prims/jvmtiThreadState.hpp" diff --git a/src/hotspot/share/prims/jvmtiImpl.cpp b/src/hotspot/share/prims/jvmtiImpl.cpp index a034eac3a17..6fcf47cee6e 100644 --- a/src/hotspot/share/prims/jvmtiImpl.cpp +++ b/src/hotspot/share/prims/jvmtiImpl.cpp @@ -34,6 +34,7 @@ #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" +#include "oops/klass.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/oopHandle.inline.hpp" #include "prims/jvmtiAgentThread.hpp" diff --git a/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp b/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp index 4695aab8fa4..34c9b949049 100644 --- a/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp +++ b/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, 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 @@ -29,6 +29,7 @@ #include "runtime/flags/jvmFlagAccess.hpp" #include "runtime/flags/jvmFlagLimit.hpp" #include "runtime/flags/jvmFlagConstraintsRuntime.hpp" +#include "runtime/os.hpp" #include "utilities/macros.hpp" #include "utilities/ostream.hpp" diff --git a/src/hotspot/share/runtime/java.cpp b/src/hotspot/share/runtime/java.cpp index cd322887017..4d22edef1c4 100644 --- a/src/hotspot/share/runtime/java.cpp +++ b/src/hotspot/share/runtime/java.cpp @@ -25,7 +25,6 @@ #include "precompiled.hpp" #include "jvm.h" #include "aot/aotLoader.hpp" -#include "classfile/classLoader.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/javaClasses.hpp" #include "classfile/stringTable.hpp" diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index 798d36f0981..44c7cb14b2b 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -24,7 +24,6 @@ #include "precompiled.hpp" #include "jvm.h" -#include "classfile/classLoader.hpp" #include "classfile/javaClasses.hpp" #include "classfile/moduleEntry.hpp" #include "classfile/systemDictionary.hpp" diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index 5b6950f0152..5e23228615e 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -48,6 +48,7 @@ #include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" +#include "oops/compiledICHolder.inline.hpp" #include "oops/klass.hpp" #include "oops/method.inline.hpp" #include "oops/objArrayKlass.hpp" diff --git a/src/hotspot/share/services/attachListener.hpp b/src/hotspot/share/services/attachListener.hpp index 251b9766735..d80f2be9511 100644 --- a/src/hotspot/share/services/attachListener.hpp +++ b/src/hotspot/share/services/attachListener.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, 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 @@ -27,6 +27,7 @@ #include "memory/allocation.hpp" #include "runtime/atomic.hpp" +#include "runtime/globals.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/share/services/runtimeService.cpp b/src/hotspot/share/services/runtimeService.cpp index be2108a86c7..d2e8d058a98 100644 --- a/src/hotspot/share/services/runtimeService.cpp +++ b/src/hotspot/share/services/runtimeService.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -23,7 +23,6 @@ */ #include "precompiled.hpp" -#include "classfile/classLoader.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "runtime/vm_version.hpp" diff --git a/src/hotspot/share/services/threadService.cpp b/src/hotspot/share/services/threadService.cpp index ee08ac41606..c0476bba8f2 100644 --- a/src/hotspot/share/services/threadService.cpp +++ b/src/hotspot/share/services/threadService.cpp @@ -33,6 +33,7 @@ #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/instanceKlass.hpp" +#include "oops/klass.inline.hpp" #include "oops/objArrayKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" -- GitLab From d9744f6536076144ff09c4e788a892bdc3d4bacb Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Mon, 15 Feb 2021 06:37:39 +0000 Subject: [PATCH 061/367] 8261608: Move common CDS archive building code to archiveBuilder.cpp Reviewed-by: coleenp, ccheung --- .../share/classfile/compactHashtable.cpp | 11 +- .../share/classfile/compactHashtable.hpp | 6 +- src/hotspot/share/classfile/klassFactory.cpp | 1 - src/hotspot/share/classfile/moduleEntry.cpp | 7 +- src/hotspot/share/classfile/packageEntry.cpp | 5 +- src/hotspot/share/classfile/stringTable.cpp | 4 +- src/hotspot/share/classfile/symbolTable.cpp | 4 +- .../classfile/systemDictionaryShared.cpp | 4 +- src/hotspot/share/memory/allocation.cpp | 4 +- src/hotspot/share/memory/archiveBuilder.cpp | 291 ++++++++++++---- src/hotspot/share/memory/archiveBuilder.hpp | 100 +++++- src/hotspot/share/memory/archiveUtils.cpp | 62 +++- src/hotspot/share/memory/archiveUtils.hpp | 24 +- src/hotspot/share/memory/arena.cpp | 1 - src/hotspot/share/memory/cppVtables.cpp | 7 +- src/hotspot/share/memory/dumpAllocStats.cpp | 24 +- src/hotspot/share/memory/dumpAllocStats.hpp | 13 +- src/hotspot/share/memory/dynamicArchive.cpp | 84 +---- src/hotspot/share/memory/heapShared.cpp | 8 +- .../printMetaspaceInfoKlassClosure.cpp | 1 - src/hotspot/share/memory/metaspaceShared.cpp | 314 +++--------------- src/hotspot/share/memory/metaspaceShared.hpp | 104 +----- .../share/memory/metaspaceShared.inline.hpp | 39 --- src/hotspot/share/oops/array.hpp | 4 +- src/hotspot/share/oops/constantPool.cpp | 1 - src/hotspot/share/oops/cpCache.cpp | 1 - src/hotspot/share/oops/klass.cpp | 1 - src/hotspot/share/runtime/sharedRuntime.cpp | 1 - src/hotspot/share/runtime/synchronizer.cpp | 1 - .../runtime/cds/appcds/LotsOfClasses.java | 2 +- .../dynamicArchive/DynamicLotsOfClasses.java | 8 +- 31 files changed, 501 insertions(+), 636 deletions(-) delete mode 100644 src/hotspot/share/memory/metaspaceShared.inline.hpp diff --git a/src/hotspot/share/classfile/compactHashtable.cpp b/src/hotspot/share/classfile/compactHashtable.cpp index 9780f0bfbf3..808de7c7fb2 100644 --- a/src/hotspot/share/classfile/compactHashtable.cpp +++ b/src/hotspot/share/classfile/compactHashtable.cpp @@ -27,10 +27,9 @@ #include "classfile/compactHashtable.hpp" #include "classfile/javaClasses.hpp" #include "logging/logMessage.hpp" -#include "memory/dynamicArchive.hpp" +#include "memory/archiveBuilder.hpp" #include "memory/heapShared.inline.hpp" #include "memory/metadataFactory.hpp" -#include "memory/metaspaceShared.hpp" #include "runtime/arguments.hpp" #include "runtime/globals.hpp" #include "runtime/vmThread.hpp" @@ -74,11 +73,11 @@ CompactHashtableWriter::~CompactHashtableWriter() { size_t CompactHashtableWriter::estimate_size(int num_entries) { int num_buckets = calculate_num_buckets(num_entries); - size_t bucket_bytes = MetaspaceShared::ro_array_bytesize(num_buckets + 1); + size_t bucket_bytes = ArchiveBuilder::ro_array_bytesize(num_buckets + 1); // In worst case, we have no VALUE_ONLY_BUCKET_TYPE, so each entry takes 2 slots int entries_space = 2 * num_entries; - size_t entry_bytes = MetaspaceShared::ro_array_bytesize(entries_space); + size_t entry_bytes = ArchiveBuilder::ro_array_bytesize(entries_space); return bucket_bytes + entry_bytes @@ -109,8 +108,8 @@ void CompactHashtableWriter::allocate_table() { "Too many entries."); } - _compact_buckets = MetaspaceShared::new_ro_array(_num_buckets + 1); - _compact_entries = MetaspaceShared::new_ro_array(entries_space); + _compact_buckets = ArchiveBuilder::new_ro_array(_num_buckets + 1); + _compact_entries = ArchiveBuilder::new_ro_array(entries_space); _stats->bucket_count = _num_buckets; _stats->bucket_bytes = align_up(_compact_buckets->size() * BytesPerWord, diff --git a/src/hotspot/share/classfile/compactHashtable.hpp b/src/hotspot/share/classfile/compactHashtable.hpp index 4b27058b59d..a5127576a8d 100644 --- a/src/hotspot/share/classfile/compactHashtable.hpp +++ b/src/hotspot/share/classfile/compactHashtable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, 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 @@ -48,6 +48,10 @@ public: int hashentry_bytes; int bucket_count; int bucket_bytes; + + CompactHashtableStats() : + hashentry_count(0), hashentry_bytes(0), + bucket_count(0), bucket_bytes(0) {} }; #if INCLUDE_CDS diff --git a/src/hotspot/share/classfile/klassFactory.cpp b/src/hotspot/share/classfile/klassFactory.cpp index cc12c1c7a07..e3f41ee0b45 100644 --- a/src/hotspot/share/classfile/klassFactory.cpp +++ b/src/hotspot/share/classfile/klassFactory.cpp @@ -31,7 +31,6 @@ #include "classfile/classLoadInfo.hpp" #include "classfile/klassFactory.hpp" #include "memory/filemap.hpp" -#include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "prims/jvmtiEnvBase.hpp" #include "prims/jvmtiRedefineClasses.hpp" diff --git a/src/hotspot/share/classfile/moduleEntry.cpp b/src/hotspot/share/classfile/moduleEntry.cpp index 9477e37439e..7d9c9001b40 100644 --- a/src/hotspot/share/classfile/moduleEntry.cpp +++ b/src/hotspot/share/classfile/moduleEntry.cpp @@ -33,7 +33,6 @@ #include "memory/archiveUtils.hpp" #include "memory/filemap.hpp" #include "memory/heapShared.hpp" -#include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/oopHandle.inline.hpp" @@ -385,7 +384,7 @@ static ArchivedModuleEntries* _archive_modules_entries = NULL; ModuleEntry* ModuleEntry::allocate_archived_entry() const { assert(is_named(), "unnamed packages/modules are not archived"); - ModuleEntry* archived_entry = (ModuleEntry*)MetaspaceShared::read_write_space_alloc(sizeof(ModuleEntry)); + ModuleEntry* archived_entry = (ModuleEntry*)ArchiveBuilder::rw_region_alloc(sizeof(ModuleEntry)); memcpy((void*)archived_entry, (void*)this, sizeof(ModuleEntry)); if (_archive_modules_entries == NULL) { @@ -410,7 +409,7 @@ Array* ModuleEntry::write_growable_array(GrowableArray* archived_array = NULL; int length = (array == NULL) ? 0 : array->length(); if (length > 0) { - archived_array = MetaspaceShared::new_ro_array(length); + archived_array = ArchiveBuilder::new_ro_array(length); for (int i = 0; i < length; i++) { ModuleEntry* archived_entry = get_archived_entry(array->at(i)); archived_array->at_put(i, archived_entry); @@ -518,7 +517,7 @@ void ModuleEntryTable::iterate_symbols(MetaspaceClosure* closure) { } Array* ModuleEntryTable::allocate_archived_entries() { - Array* archived_modules = MetaspaceShared::new_rw_array(number_of_entries()); + Array* archived_modules = ArchiveBuilder::new_rw_array(number_of_entries()); int n = 0; for (int i = 0; i < table_size(); ++i) { for (ModuleEntry* m = bucket(i); m != NULL; m = m->next()) { diff --git a/src/hotspot/share/classfile/packageEntry.cpp b/src/hotspot/share/classfile/packageEntry.cpp index 8beb89c595a..b32a6a51102 100644 --- a/src/hotspot/share/classfile/packageEntry.cpp +++ b/src/hotspot/share/classfile/packageEntry.cpp @@ -30,7 +30,6 @@ #include "logging/log.hpp" #include "memory/archiveBuilder.hpp" #include "memory/archiveUtils.hpp" -#include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "oops/array.hpp" #include "oops/symbol.hpp" @@ -209,7 +208,7 @@ static ArchivedPackageEntries* _archived_packages_entries = NULL; PackageEntry* PackageEntry::allocate_archived_entry() const { assert(!in_unnamed_module(), "unnamed packages/modules are not archived"); - PackageEntry* archived_entry = (PackageEntry*)MetaspaceShared::read_write_space_alloc(sizeof(PackageEntry)); + PackageEntry* archived_entry = (PackageEntry*)ArchiveBuilder::rw_region_alloc(sizeof(PackageEntry)); memcpy((void*)archived_entry, (void*)this, sizeof(PackageEntry)); if (_archived_packages_entries == NULL) { @@ -279,7 +278,7 @@ Array* PackageEntryTable::allocate_archived_entries() { } } - Array* archived_packages = MetaspaceShared::new_rw_array(n); + Array* archived_packages = ArchiveBuilder::new_rw_array(n); for (n = 0, i = 0; i < table_size(); ++i) { for (PackageEntry* p = bucket(i); p != NULL; p = p->next()) { if (p->module()->name() != NULL) { diff --git a/src/hotspot/share/classfile/stringTable.cpp b/src/hotspot/share/classfile/stringTable.cpp index 6c2f61a26c7..8fe73d6759c 100644 --- a/src/hotspot/share/classfile/stringTable.cpp +++ b/src/hotspot/share/classfile/stringTable.cpp @@ -34,7 +34,7 @@ #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" -#include "memory/filemap.hpp" +#include "memory/archiveBuilder.hpp" #include "memory/heapShared.inline.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" @@ -760,7 +760,7 @@ void StringTable::write_to_archive(const DumpedInternedStrings* dumped_interned_ assert(HeapShared::is_heap_object_archiving_allowed(), "must be"); _shared_table.reset(); - CompactHashtableWriter writer(_items_count, &MetaspaceShared::stats()->string); + CompactHashtableWriter writer(_items_count, ArchiveBuilder::string_stats()); // Copy the interned strings into the "string space" within the java heap CopyToArchive copier(&writer); diff --git a/src/hotspot/share/classfile/symbolTable.cpp b/src/hotspot/share/classfile/symbolTable.cpp index a0d7b12d9ab..26f3c6ad379 100644 --- a/src/hotspot/share/classfile/symbolTable.cpp +++ b/src/hotspot/share/classfile/symbolTable.cpp @@ -32,7 +32,6 @@ #include "memory/archiveBuilder.hpp" #include "memory/dynamicArchive.hpp" #include "memory/metaspaceClosure.hpp" -#include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" @@ -602,8 +601,7 @@ size_t SymbolTable::estimate_size_for_archive() { } void SymbolTable::write_to_archive(GrowableArray* symbols) { - CompactHashtableWriter writer(int(_items_count), - &MetaspaceShared::stats()->symbol); + CompactHashtableWriter writer(int(_items_count), ArchiveBuilder::symbol_stats()); copy_shared_symbol_table(symbols, &writer); if (!DynamicDumpSharedSpaces) { _shared_table.reset(); diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index 8050a4dea6a..643e67d16e0 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -2038,7 +2038,7 @@ public: log_info(cds,dynamic)("Archiving hidden %s", info._proxy_klasses->at(0)->external_name()); size_t byte_size = sizeof(RunTimeLambdaProxyClassInfo); RunTimeLambdaProxyClassInfo* runtime_info = - (RunTimeLambdaProxyClassInfo*)MetaspaceShared::read_only_space_alloc(byte_size); + (RunTimeLambdaProxyClassInfo*)ArchiveBuilder::ro_region_alloc(byte_size); runtime_info->init(key, info); unsigned int hash = runtime_info->hash(); u4 delta = _builder->any_to_offset_u4((void*)runtime_info); @@ -2086,7 +2086,7 @@ public: if (!info.is_excluded() && info.is_builtin() == _is_builtin) { size_t byte_size = RunTimeSharedClassInfo::byte_size(info._klass, info.num_verifier_constraints(), info.num_loader_constraints()); RunTimeSharedClassInfo* record; - record = (RunTimeSharedClassInfo*)MetaspaceShared::read_only_space_alloc(byte_size); + record = (RunTimeSharedClassInfo*)ArchiveBuilder::ro_region_alloc(byte_size); record->init(info); unsigned int hash; diff --git a/src/hotspot/share/memory/allocation.cpp b/src/hotspot/share/memory/allocation.cpp index a4c55edac87..c3024bcb372 100644 --- a/src/hotspot/share/memory/allocation.cpp +++ b/src/hotspot/share/memory/allocation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, 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 @@ -26,7 +26,7 @@ #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "memory/arena.hpp" -#include "memory/metaspaceShared.hpp" +#include "memory/metaspace.hpp" #include "memory/resourceArea.hpp" #include "runtime/os.hpp" #include "runtime/task.hpp" diff --git a/src/hotspot/share/memory/archiveBuilder.cpp b/src/hotspot/share/memory/archiveBuilder.cpp index a4361c4ddea..77da41abd96 100644 --- a/src/hotspot/share/memory/archiveBuilder.cpp +++ b/src/hotspot/share/memory/archiveBuilder.cpp @@ -27,6 +27,7 @@ #include "classfile/symbolTable.hpp" #include "classfile/systemDictionaryShared.hpp" #include "classfile/vmClasses.hpp" +#include "interpreter/abstractInterpreter.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/allStatic.hpp" @@ -44,6 +45,7 @@ #include "runtime/thread.hpp" #include "utilities/align.hpp" #include "utilities/bitMap.inline.hpp" +#include "utilities/formatBuffer.hpp" #include "utilities/hashtable.inline.hpp" ArchiveBuilder* ArchiveBuilder::_current = NULL; @@ -69,7 +71,7 @@ class AdapterToTrampoline : public ResourceHashtable< static AdapterToTrampoline* _adapter_to_trampoline = NULL; ArchiveBuilder::OtherROAllocMark::~OtherROAllocMark() { - char* newtop = ArchiveBuilder::current()->_ro_region->top(); + char* newtop = ArchiveBuilder::current()->_ro_region.top(); ArchiveBuilder::alloc_stats()->record_other_type(int(newtop - _oldtop), true); } @@ -159,37 +161,40 @@ void ArchiveBuilder::SourceObjList::relocate(int i, ArchiveBuilder* builder) { _ptrmap.iterate(&relocator, start, end); } -ArchiveBuilder::ArchiveBuilder(DumpRegion* mc_region, DumpRegion* rw_region, DumpRegion* ro_region) - : _rw_src_objs(), _ro_src_objs(), _src_obj_table(INITIAL_TABLE_SIZE) { - assert(_current == NULL, "must be"); - _current = this; - +ArchiveBuilder::ArchiveBuilder() : + _current_dump_space(NULL), + _buffer_bottom(NULL), + _last_verified_top(NULL), + _num_dump_regions_used(0), + _other_region_used_bytes(0), + _requested_static_archive_bottom(NULL), + _requested_static_archive_top(NULL), + _requested_dynamic_archive_bottom(NULL), + _requested_dynamic_archive_top(NULL), + _mapped_static_archive_bottom(NULL), + _mapped_static_archive_top(NULL), + _buffer_to_requested_delta(0), + _mc_region("mc", MAX_SHARED_DELTA), + _rw_region("rw", MAX_SHARED_DELTA), + _ro_region("ro", MAX_SHARED_DELTA), + _rw_src_objs(), + _ro_src_objs(), + _src_obj_table(INITIAL_TABLE_SIZE), + _num_instance_klasses(0), + _num_obj_array_klasses(0), + _num_type_array_klasses(0), + _total_closed_heap_region_size(0), + _total_open_heap_region_size(0), + _estimated_metaspaceobj_bytes(0), + _estimated_hashtable_bytes(0), + _estimated_trampoline_bytes(0) +{ _klasses = new (ResourceObj::C_HEAP, mtClassShared) GrowableArray(4 * K, mtClassShared); _symbols = new (ResourceObj::C_HEAP, mtClassShared) GrowableArray(256 * K, mtClassShared); _special_refs = new (ResourceObj::C_HEAP, mtClassShared) GrowableArray(24 * K, mtClassShared); - _num_instance_klasses = 0; - _num_obj_array_klasses = 0; - _num_type_array_klasses = 0; - _alloc_stats = new (ResourceObj::C_HEAP, mtClassShared) DumpAllocStats; - - _mc_region = mc_region; - _rw_region = rw_region; - _ro_region = ro_region; - - _num_dump_regions_used = 0; - - _estimated_metaspaceobj_bytes = 0; - _estimated_hashtable_bytes = 0; - _estimated_trampoline_bytes = 0; - - _requested_static_archive_bottom = NULL; - _requested_static_archive_top = NULL; - _mapped_static_archive_bottom = NULL; - _mapped_static_archive_top = NULL; - _requested_dynamic_archive_bottom = NULL; - _requested_dynamic_archive_top = NULL; - _buffer_to_requested_delta = 0; + assert(_current == NULL, "must be"); + _current = this; } ArchiveBuilder::~ArchiveBuilder() { @@ -205,7 +210,10 @@ ArchiveBuilder::~ArchiveBuilder() { delete _klasses; delete _symbols; delete _special_refs; - delete _alloc_stats; +} + +bool ArchiveBuilder::is_dumping_full_module_graph() { + return DumpSharedSpaces && MetaspaceShared::use_full_module_graph(); } class GatherKlassesAndSymbols : public UniqueMetaspaceClosure { @@ -261,7 +269,7 @@ void ArchiveBuilder::gather_klasses_and_symbols() { GatherKlassesAndSymbols doit(this); iterate_roots(&doit, /*is_relocating_pointers=*/false); #if INCLUDE_CDS_JAVA_HEAP - if (DumpSharedSpaces && MetaspaceShared::use_full_module_graph()) { + if (is_dumping_full_module_graph()) { ClassLoaderDataShared::iterate_symbols(&doit); } #endif @@ -335,7 +343,7 @@ size_t ArchiveBuilder::estimate_archive_size() { size_t dictionary_est = SystemDictionaryShared::estimate_size_for_archive(); _estimated_hashtable_bytes = symbol_table_est + dictionary_est; - _estimated_trampoline_bytes = allocate_method_trampoline_info(); + _estimated_trampoline_bytes = collect_method_trampolines(); size_t total = 0; @@ -366,18 +374,18 @@ address ArchiveBuilder::reserve_buffer() { // buffer_bottom is the lowest address of the 3 core regions (mc, rw, ro) when // we are copying the class metadata into the buffer. address buffer_bottom = (address)rs.base(); - log_info(cds)("Reserved output buffer space at : " PTR_FORMAT " [" SIZE_FORMAT " bytes]", + log_info(cds)("Reserved output buffer space at " PTR_FORMAT " [" SIZE_FORMAT " bytes]", p2i(buffer_bottom), buffer_size); - MetaspaceShared::set_shared_rs(rs); + _shared_rs = rs; - MetaspaceShared::init_shared_dump_space(_mc_region); _buffer_bottom = buffer_bottom; _last_verified_top = buffer_bottom; - _current_dump_space = _mc_region; + _current_dump_space = &_mc_region; _num_dump_regions_used = 1; _other_region_used_bytes = 0; + _current_dump_space->init(&_shared_rs, &_shared_vs); - ArchivePtrMarker::initialize(&_ptrmap, (address*)_mc_region->base(), (address*)_mc_region->top()); + ArchivePtrMarker::initialize(&_ptrmap, &_shared_vs); // The bottom of the static archive should be mapped at this address by default. _requested_static_archive_bottom = (address)MetaspaceShared::requested_base_address(); @@ -520,6 +528,7 @@ void ArchiveBuilder::remember_embedded_pointer_in_copied_obj(MetaspaceClosure::R void ArchiveBuilder::gather_source_objs() { ResourceMark rm; log_info(cds)("Gathering all archivable objects ... "); + gather_klasses_and_symbols(); GatherSortedSourceObjs doit(this); iterate_sorted_roots(&doit, /*is_relocating_pointers=*/false); doit.finish(); @@ -565,16 +574,61 @@ ArchiveBuilder::FollowMode ArchiveBuilder::get_follow_mode(MetaspaceClosure::Ref } } +void ArchiveBuilder::start_dump_space(DumpRegion* next) { + address bottom = _last_verified_top; + address top = (address)(current_dump_space()->top()); + _other_region_used_bytes += size_t(top - bottom); + + current_dump_space()->pack(next); + _current_dump_space = next; + _num_dump_regions_used ++; + + _last_verified_top = (address)(current_dump_space()->top()); +} + +void ArchiveBuilder::verify_estimate_size(size_t estimate, const char* which) { + address bottom = _last_verified_top; + address top = (address)(current_dump_space()->top()); + size_t used = size_t(top - bottom) + _other_region_used_bytes; + int diff = int(estimate) - int(used); + + log_info(cds)("%s estimate = " SIZE_FORMAT " used = " SIZE_FORMAT "; diff = %d bytes", which, estimate, used, diff); + assert(diff >= 0, "Estimate is too small"); + + _last_verified_top = top; + _other_region_used_bytes = 0; +} + void ArchiveBuilder::dump_rw_region() { ResourceMark rm; log_info(cds)("Allocating RW objects ... "); - make_shallow_copies(_rw_region, &_rw_src_objs); + start_dump_space(&_rw_region); + make_shallow_copies(&_rw_region, &_rw_src_objs); + +#if INCLUDE_CDS_JAVA_HEAP + if (is_dumping_full_module_graph()) { + // Archive the ModuleEntry's and PackageEntry's of the 3 built-in loaders + char* start = rw_region()->top(); + ClassLoaderDataShared::allocate_archived_tables(); + alloc_stats()->record_modules(rw_region()->top() - start, /*read_only*/false); + } +#endif } void ArchiveBuilder::dump_ro_region() { ResourceMark rm; log_info(cds)("Allocating RO objects ... "); - make_shallow_copies(_ro_region, &_ro_src_objs); + + start_dump_space(&_ro_region); + make_shallow_copies(&_ro_region, &_ro_src_objs); + +#if INCLUDE_CDS_JAVA_HEAP + if (is_dumping_full_module_graph()) { + char* start = ro_region()->top(); + ClassLoaderDataShared::init_archived_tables(); + alloc_stats()->record_modules(ro_region()->top() - start, /*read_only*/true); + } +#endif } void ArchiveBuilder::make_shallow_copies(DumpRegion *dump_region, @@ -619,7 +673,7 @@ void ArchiveBuilder::make_shallow_copy(DumpRegion *dump_region, SourceObjInfo* s log_trace(cds)("Copy: " PTR_FORMAT " ==> " PTR_FORMAT " %d", p2i(src), p2i(dest), bytes); src_info->set_dumped_addr((address)dest); - _alloc_stats->record(ref->msotype(), int(newtop - oldtop), src_info->read_only()); + _alloc_stats.record(ref->msotype(), int(newtop - oldtop), src_info->read_only()); } address ArchiveBuilder::get_dumped_addr(address src_obj) const { @@ -821,6 +875,8 @@ class RelocateBufferToRequested : public BitMapClosure { void ArchiveBuilder::relocate_to_requested() { + ro_region()->pack(); + size_t my_archive_size = buffer_top() - buffer_bottom(); if (DumpSharedSpaces) { @@ -989,9 +1045,9 @@ public: write_header(mapinfo); write_data(header, header_end, 0); - DumpRegion* mc_region = builder->_mc_region; - DumpRegion* rw_region = builder->_rw_region; - DumpRegion* ro_region = builder->_ro_region; + DumpRegion* mc_region = &builder->_mc_region; + DumpRegion* rw_region = &builder->_rw_region; + DumpRegion* ro_region = &builder->_ro_region; address mc = address(mc_region->base()); address mc_end = address(mc_region->end()); @@ -1019,18 +1075,8 @@ public: } }; -void ArchiveBuilder::write_cds_map_to_log(FileMapInfo* mapinfo, - GrowableArray *closed_heap_regions, - GrowableArray *open_heap_regions, - char* bitmap, size_t bitmap_size_in_bytes) { - if (log_is_enabled(Info, cds, map)) { - CDSMapLogger::write(this, mapinfo, closed_heap_regions, open_heap_regions, - bitmap, bitmap_size_in_bytes); - } -} - -void ArchiveBuilder::print_stats(int ro_all, int rw_all, int mc_all) { - _alloc_stats->print_stats(ro_all, rw_all, mc_all); +void ArchiveBuilder::print_stats() { + _alloc_stats.print_stats(int(_ro_region.used()), int(_rw_region.used()), int(_mc_region.used())); } void ArchiveBuilder::clean_up_src_obj_table() { @@ -1038,6 +1084,20 @@ void ArchiveBuilder::clean_up_src_obj_table() { _src_obj_table.iterate(&cleaner); } +void ArchiveBuilder::init_mc_region() { + if (DumpSharedSpaces) { // these are needed only for static archive + // We don't want any valid object to be at the very bottom of the archive. + // See ArchivePtrMarker::mark_pointer(). + mc_region()->allocate(16); + + size_t trampoline_size = SharedRuntime::trampoline_size(); + size_t buf_size = (size_t)AbstractInterpreter::number_of_method_entries * trampoline_size; + MetaspaceShared::set_i2i_entry_code_buffers((address)mc_region()->allocate(buf_size)); + } + + allocate_method_trampolines(); +} + void ArchiveBuilder::allocate_method_trampolines_for(InstanceKlass* ik) { if (ik->methods() != NULL) { for (int j = 0; j < ik->methods()->length(); j++) { @@ -1048,9 +1108,9 @@ void ArchiveBuilder::allocate_method_trampolines_for(InstanceKlass* ik) { MethodTrampolineInfo* info = _adapter_to_trampoline->get(ent); if (info->c2i_entry_trampoline() == NULL) { info->set_c2i_entry_trampoline( - (address)MetaspaceShared::misc_code_space_alloc(SharedRuntime::trampoline_size())); + (address)mc_region()->allocate(SharedRuntime::trampoline_size())); info->set_adapter_trampoline( - (AdapterHandlerEntry**)MetaspaceShared::misc_code_space_alloc(sizeof(AdapterHandlerEntry*))); + (AdapterHandlerEntry**)mc_region()->allocate(sizeof(AdapterHandlerEntry*))); } } } @@ -1069,7 +1129,7 @@ void ArchiveBuilder::allocate_method_trampolines() { // Allocate MethodTrampolineInfo for all Methods that will be archived. Also // return the total number of bytes needed by the method trampolines in the MC // region. -size_t ArchiveBuilder::allocate_method_trampoline_info() { +size_t ArchiveBuilder::collect_method_trampolines() { size_t total = 0; size_t each_method_bytes = align_up(SharedRuntime::trampoline_size(), BytesPerWord) + @@ -1124,6 +1184,123 @@ void ArchiveBuilder::update_method_trampolines() { } } +void ArchiveBuilder::write_archive(FileMapInfo* mapinfo, + GrowableArray* closed_heap_regions, + GrowableArray* open_heap_regions, + GrowableArray* closed_heap_oopmaps, + GrowableArray* open_heap_oopmaps) { + // Make sure NUM_CDS_REGIONS (exported in cds.h) agrees with + // MetaspaceShared::n_regions (internal to hotspot). + assert(NUM_CDS_REGIONS == MetaspaceShared::n_regions, "sanity"); + + // mc contains the trampoline code for method entries, which are patched at run time, + // so it needs to be read/write. + write_region(mapinfo, MetaspaceShared::mc, &_mc_region, /*read_only=*/false,/*allow_exec=*/true); + write_region(mapinfo, MetaspaceShared::rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false); + write_region(mapinfo, MetaspaceShared::ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false); + + size_t bitmap_size_in_bytes; + char* bitmap = mapinfo->write_bitmap_region(ArchivePtrMarker::ptrmap(), closed_heap_oopmaps, open_heap_oopmaps, + bitmap_size_in_bytes); + + if (closed_heap_regions != NULL) { + _total_closed_heap_region_size = mapinfo->write_archive_heap_regions( + closed_heap_regions, + closed_heap_oopmaps, + MetaspaceShared::first_closed_archive_heap_region, + MetaspaceShared::max_closed_archive_heap_region); + _total_open_heap_region_size = mapinfo->write_archive_heap_regions( + open_heap_regions, + open_heap_oopmaps, + MetaspaceShared::first_open_archive_heap_region, + MetaspaceShared::max_open_archive_heap_region); + } + + print_region_stats(mapinfo, closed_heap_regions, open_heap_regions); + + mapinfo->set_requested_base((char*)MetaspaceShared::requested_base_address()); + mapinfo->set_header_crc(mapinfo->compute_header_crc()); + mapinfo->write_header(); + mapinfo->close(); + + if (log_is_enabled(Info, cds)) { + print_stats(); + } + + if (log_is_enabled(Info, cds, map)) { + CDSMapLogger::write(this, mapinfo, closed_heap_regions, open_heap_regions, + bitmap, bitmap_size_in_bytes); + } + FREE_C_HEAP_ARRAY(char, bitmap); +} + +void ArchiveBuilder::write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region, bool read_only, bool allow_exec) { + mapinfo->write_region(region_idx, dump_region->base(), dump_region->used(), read_only, allow_exec); +} + +void ArchiveBuilder::print_region_stats(FileMapInfo *mapinfo, + GrowableArray* closed_heap_regions, + GrowableArray* open_heap_regions) { + // Print statistics of all the regions + const size_t bitmap_used = mapinfo->space_at(MetaspaceShared::bm)->used(); + const size_t bitmap_reserved = mapinfo->space_at(MetaspaceShared::bm)->used_aligned(); + const size_t total_reserved = _ro_region.reserved() + _rw_region.reserved() + + _mc_region.reserved() + + bitmap_reserved + + _total_closed_heap_region_size + + _total_open_heap_region_size; + const size_t total_bytes = _ro_region.used() + _rw_region.used() + + _mc_region.used() + + bitmap_used + + _total_closed_heap_region_size + + _total_open_heap_region_size; + const double total_u_perc = percent_of(total_bytes, total_reserved); + + _mc_region.print(total_reserved); + _rw_region.print(total_reserved); + _ro_region.print(total_reserved); + + print_bitmap_region_stats(bitmap_used, total_reserved); + + if (closed_heap_regions != NULL) { + print_heap_region_stats(closed_heap_regions, "ca", total_reserved); + print_heap_region_stats(open_heap_regions, "oa", total_reserved); + } + + log_debug(cds)("total : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]", + total_bytes, total_reserved, total_u_perc); +} + +void ArchiveBuilder::print_bitmap_region_stats(size_t size, size_t total_size) { + log_debug(cds)("bm space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used]", + size, size/double(total_size)*100.0, size); +} + +void ArchiveBuilder::print_heap_region_stats(GrowableArray *heap_mem, + const char *name, size_t total_size) { + int arr_len = heap_mem == NULL ? 0 : heap_mem->length(); + for (int i = 0; i < arr_len; i++) { + char* start = (char*)heap_mem->at(i).start(); + size_t size = heap_mem->at(i).byte_size(); + char* top = start + size; + log_debug(cds)("%s%d space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used] at " INTPTR_FORMAT, + name, i, size, size/double(total_size)*100.0, size, p2i(start)); + } +} + +void ArchiveBuilder::report_out_of_space(const char* name, size_t needed_bytes) { + // This is highly unlikely to happen on 64-bits because we have reserved a 4GB space. + // On 32-bit we reserve only 256MB so you could run out of space with 100,000 classes + // or so. + _mc_region.print_out_of_space_msg(name, needed_bytes); + _rw_region.print_out_of_space_msg(name, needed_bytes); + _ro_region.print_out_of_space_msg(name, needed_bytes); + + vm_exit_during_initialization(err_msg("Unable to allocate from '%s' region", name), + "Please reduce the number of shared classes."); +} + + #ifndef PRODUCT void ArchiveBuilder::assert_is_vm_thread() { assert(Thread::current()->is_VM_thread(), "ArchiveBuilder should be used only inside the VMThread"); diff --git a/src/hotspot/share/memory/archiveBuilder.hpp b/src/hotspot/share/memory/archiveBuilder.hpp index 0859b6a14b1..d4c6f5228b5 100644 --- a/src/hotspot/share/memory/archiveBuilder.hpp +++ b/src/hotspot/share/memory/archiveBuilder.hpp @@ -26,7 +26,9 @@ #define SHARE_MEMORY_ARCHIVEBUILDER_HPP #include "memory/archiveUtils.hpp" +#include "memory/dumpAllocStats.hpp" #include "memory/metaspaceClosure.hpp" +#include "oops/array.hpp" #include "oops/klass.hpp" #include "runtime/os.hpp" #include "utilities/bitMap.hpp" @@ -34,13 +36,17 @@ #include "utilities/hashtable.hpp" #include "utilities/resourceHash.hpp" +struct ArchiveHeapOopmapInfo; class CHeapBitMap; -class DumpAllocStats; class FileMapInfo; class Klass; class MemRegion; class Symbol; +// Metaspace::allocate() requires that all blocks must be aligned with KlassAlignmentInBytes. +// We enforce the same alignment rule in blocks allocated from the shared space. +const int SharedSpaceObjectAlignment = KlassAlignmentInBytes; + // Overview of CDS archive creation (for both static and dynamic dump): // // [1] Load all classes (static dump: from the classlist, dynamic dump: as part of app execution) @@ -186,9 +192,12 @@ private: static const int INITIAL_TABLE_SIZE = 15889; static const int MAX_TABLE_SIZE = 1000000; - DumpRegion* _mc_region; - DumpRegion* _rw_region; - DumpRegion* _ro_region; + ReservedSpace _shared_rs; + VirtualSpace _shared_vs; + + DumpRegion _mc_region; + DumpRegion _rw_region; + DumpRegion _ro_region; CHeapBitMap _ptrmap; // bitmap used by ArchivePtrMarker SourceObjList _rw_src_objs; // objs to put in rw region @@ -202,7 +211,16 @@ private: int _num_instance_klasses; int _num_obj_array_klasses; int _num_type_array_klasses; - DumpAllocStats* _alloc_stats; + DumpAllocStats _alloc_stats; + size_t _total_closed_heap_region_size; + size_t _total_open_heap_region_size; + + void print_region_stats(FileMapInfo *map_info, + GrowableArray* closed_heap_regions, + GrowableArray* open_heap_regions); + void print_bitmap_region_stats(size_t size, size_t total_size); + void print_heap_region_stats(GrowableArray *heap_mem, + const char *name, size_t total_size); // For global access. static ArchiveBuilder* _current; @@ -215,12 +233,13 @@ public: char* _oldtop; public: OtherROAllocMark() { - _oldtop = _current->_ro_region->top(); + _oldtop = _current->_ro_region.top(); } ~OtherROAllocMark(); }; private: + bool is_dumping_full_module_graph(); FollowMode get_follow_mode(MetaspaceClosure::Ref *ref); void iterate_sorted_roots(MetaspaceClosure* it, bool is_relocating_pointers); @@ -254,8 +273,10 @@ protected: return os::vm_allocation_granularity(); } + void start_dump_space(DumpRegion* next); + void verify_estimate_size(size_t estimate, const char* which); + public: - void set_current_dump_space(DumpRegion* r) { _current_dump_space = r; } address reserve_buffer(); address buffer_bottom() const { return _buffer_bottom; } @@ -317,7 +338,7 @@ public: static void assert_is_vm_thread() PRODUCT_RETURN; public: - ArchiveBuilder(DumpRegion* mc_region, DumpRegion* rw_region, DumpRegion* ro_region); + ArchiveBuilder(); ~ArchiveBuilder(); void gather_klasses_and_symbols(); @@ -327,6 +348,43 @@ public: void add_special_ref(MetaspaceClosure::SpecialRef type, address src_obj, size_t field_offset); void remember_embedded_pointer_in_copied_obj(MetaspaceClosure::Ref* enclosing_ref, MetaspaceClosure::Ref* ref); + DumpRegion* mc_region() { return &_mc_region; } + DumpRegion* rw_region() { return &_rw_region; } + DumpRegion* ro_region() { return &_ro_region; } + + static char* mc_region_alloc(size_t num_bytes) { + return current()->mc_region()->allocate(num_bytes); + } + static char* rw_region_alloc(size_t num_bytes) { + return current()->rw_region()->allocate(num_bytes); + } + static char* ro_region_alloc(size_t num_bytes) { + return current()->ro_region()->allocate(num_bytes); + } + + template + static Array* new_ro_array(int length) { + size_t byte_size = Array::byte_sizeof(length, sizeof(T)); + Array* array = (Array*)ro_region_alloc(byte_size); + array->initialize(length); + return array; + } + + template + static Array* new_rw_array(int length) { + size_t byte_size = Array::byte_sizeof(length, sizeof(T)); + Array* array = (Array*)rw_region_alloc(byte_size); + array->initialize(length); + return array; + } + + template + static size_t ro_array_bytesize(int length) { + size_t byte_size = Array::byte_sizeof(length, sizeof(T)); + return align_up(byte_size, SharedSpaceObjectAlignment); + } + + void init_mc_region(); void dump_rw_region(); void dump_ro_region(); void relocate_metaspaceobj_embedded_pointers(); @@ -334,10 +392,13 @@ public: void relocate_vm_classes(); void make_klasses_shareable(); void relocate_to_requested(); - void write_cds_map_to_log(FileMapInfo* mapinfo, - GrowableArray *closed_heap_regions, - GrowableArray *open_heap_regions, - char* bitmap, size_t bitmap_size_in_bytes); + void write_archive(FileMapInfo* mapinfo, + GrowableArray* closed_heap_regions, + GrowableArray* open_heap_regions, + GrowableArray* closed_heap_oopmaps, + GrowableArray* open_heap_oopmaps); + void write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region, + bool read_only, bool allow_exec); address get_dumped_addr(address src_obj) const; @@ -356,7 +417,15 @@ public: } static DumpAllocStats* alloc_stats() { - return current()->_alloc_stats; + return &(current()->_alloc_stats); + } + + static CompactHashtableStats* symbol_stats() { + return alloc_stats()->symbol_stats(); + } + + static CompactHashtableStats* string_stats() { + return alloc_stats()->string_stats(); } void relocate_klass_ptr(oop o); @@ -371,12 +440,13 @@ public: return (Symbol*)current()->get_dumped_addr((address)orig_symbol); } - void print_stats(int ro_all, int rw_all, int mc_all); + void print_stats(); + void report_out_of_space(const char* name, size_t needed_bytes); // Method trampolines related functions + size_t collect_method_trampolines(); void allocate_method_trampolines(); void allocate_method_trampolines_for(InstanceKlass* ik); - size_t allocate_method_trampoline_info(); void update_method_trampolines(); }; diff --git a/src/hotspot/share/memory/archiveUtils.cpp b/src/hotspot/share/memory/archiveUtils.cpp index 5a3bb5cf461..3195144bed6 100644 --- a/src/hotspot/share/memory/archiveUtils.cpp +++ b/src/hotspot/share/memory/archiveUtils.cpp @@ -40,14 +40,13 @@ #include "utilities/bitMap.inline.hpp" CHeapBitMap* ArchivePtrMarker::_ptrmap = NULL; -address* ArchivePtrMarker::_ptr_base; -address* ArchivePtrMarker::_ptr_end; +VirtualSpace* ArchivePtrMarker::_vs; + bool ArchivePtrMarker::_compacted; -void ArchivePtrMarker::initialize(CHeapBitMap* ptrmap, address* ptr_base, address* ptr_end) { +void ArchivePtrMarker::initialize(CHeapBitMap* ptrmap, VirtualSpace* vs) { assert(_ptrmap == NULL, "initialize only once"); - _ptr_base = ptr_base; - _ptr_end = ptr_end; + _vs = vs; _compacted = false; _ptrmap = ptrmap; @@ -66,17 +65,17 @@ void ArchivePtrMarker::mark_pointer(address* ptr_loc) { assert(_ptrmap != NULL, "not initialized"); assert(!_compacted, "cannot mark anymore"); - if (_ptr_base <= ptr_loc && ptr_loc < _ptr_end) { + if (ptr_base() <= ptr_loc && ptr_loc < ptr_end()) { address value = *ptr_loc; // We don't want any pointer that points to very bottom of the archive, otherwise when // MetaspaceShared::default_base_address()==0, we can't distinguish between a pointer // to nothing (NULL) vs a pointer to an objects that happens to be at the very bottom // of the archive. - assert(value != (address)_ptr_base, "don't point to the bottom of the archive"); + assert(value != (address)ptr_base(), "don't point to the bottom of the archive"); if (value != NULL) { assert(uintx(ptr_loc) % sizeof(intptr_t) == 0, "pointers must be stored in aligned addresses"); - size_t idx = ptr_loc - _ptr_base; + size_t idx = ptr_loc - ptr_base(); if (_ptrmap->size() <= idx) { _ptrmap->resize((idx + 1) * 2); } @@ -91,9 +90,9 @@ void ArchivePtrMarker::clear_pointer(address* ptr_loc) { assert(_ptrmap != NULL, "not initialized"); assert(!_compacted, "cannot clear anymore"); - assert(_ptr_base <= ptr_loc && ptr_loc < _ptr_end, "must be"); + assert(ptr_base() <= ptr_loc && ptr_loc < ptr_end(), "must be"); assert(uintx(ptr_loc) % sizeof(intptr_t) == 0, "pointers must be stored in aligned addresses"); - size_t idx = ptr_loc - _ptr_base; + size_t idx = ptr_loc - ptr_base(); assert(idx < _ptrmap->size(), "cannot clear pointers that have not been marked"); _ptrmap->clear_bit(idx); //tty->print_cr("Clearing pointer [" PTR_FORMAT "] -> " PTR_FORMAT " @ " SIZE_FORMAT_W(5), p2i(ptr_loc), p2i(*ptr_loc), idx); @@ -132,7 +131,7 @@ public: void ArchivePtrMarker::compact(address relocatable_base, address relocatable_end) { assert(!_compacted, "cannot compact again"); - ArchivePtrBitmapCleaner cleaner(_ptrmap, _ptr_base, relocatable_base, relocatable_end); + ArchivePtrBitmapCleaner cleaner(_ptrmap, ptr_base(), relocatable_base, relocatable_end); _ptrmap->iterate(&cleaner); compact(cleaner.max_non_null_offset()); } @@ -147,16 +146,16 @@ char* DumpRegion::expand_top_to(char* newtop) { assert(is_allocatable(), "must be initialized and not packed"); assert(newtop >= _top, "must not grow backwards"); if (newtop > _end) { - MetaspaceShared::report_out_of_space(_name, newtop - _top); + ArchiveBuilder::current()->report_out_of_space(_name, newtop - _top); ShouldNotReachHere(); } - MetaspaceShared::commit_to(_rs, _vs, newtop); + commit_to(newtop); _top = newtop; - if (_rs == MetaspaceShared::shared_rs()) { + if (_max_delta > 0) { uintx delta = ArchiveBuilder::current()->buffer_to_offset((address)(newtop-1)); - if (delta > ArchiveBuilder::MAX_SHARED_DELTA) { + if (delta > _max_delta) { // This is just a sanity check and should not appear in any real world usage. This // happens only if you allocate more than 2GB of shared objects and would require // millions of shared classes. @@ -168,6 +167,39 @@ char* DumpRegion::expand_top_to(char* newtop) { return _top; } +void DumpRegion::commit_to(char* newtop) { + Arguments::assert_is_dumping_archive(); + char* base = _rs->base(); + size_t need_committed_size = newtop - base; + size_t has_committed_size = _vs->committed_size(); + if (need_committed_size < has_committed_size) { + return; + } + + size_t min_bytes = need_committed_size - has_committed_size; + size_t preferred_bytes = 1 * M; + size_t uncommitted = _vs->reserved_size() - has_committed_size; + + size_t commit = MAX2(min_bytes, preferred_bytes); + commit = MIN2(commit, uncommitted); + assert(commit <= uncommitted, "sanity"); + + if (!_vs->expand_by(commit, false)) { + vm_exit_during_initialization(err_msg("Failed to expand shared space to " SIZE_FORMAT " bytes", + need_committed_size)); + } + + const char* which; + if (_rs->base() == (char*)MetaspaceShared::symbol_rs_base()) { + which = "symbol"; + } else { + which = "shared"; + } + log_debug(cds)("Expanding %s spaces by " SIZE_FORMAT_W(7) " bytes [total " SIZE_FORMAT_W(9) " bytes ending at %p]", + which, commit, _vs->actual_committed_size(), _vs->high()); +} + + char* DumpRegion::allocate(size_t num_bytes) { char* p = (char*)align_up(_top, (size_t)SharedSpaceObjectAlignment); char* newtop = p + align_up(num_bytes, (size_t)SharedSpaceObjectAlignment); diff --git a/src/hotspot/share/memory/archiveUtils.hpp b/src/hotspot/share/memory/archiveUtils.hpp index d61f974135d..4121b955e43 100644 --- a/src/hotspot/share/memory/archiveUtils.hpp +++ b/src/hotspot/share/memory/archiveUtils.hpp @@ -27,6 +27,7 @@ #include "logging/log.hpp" #include "memory/iterator.hpp" +#include "memory/virtualspace.hpp" #include "runtime/arguments.hpp" #include "utilities/bitMap.hpp" @@ -39,15 +40,18 @@ class VirtualSpace; // mark_pointer(/*ptr_loc=*/&k->_name). It's required that (_prt_base <= ptr_loc < _ptr_end). _ptr_base is // fixed, but _ptr_end can be expanded as more objects are dumped. class ArchivePtrMarker : AllStatic { - static CHeapBitMap* _ptrmap; - static address* _ptr_base; - static address* _ptr_end; + static CHeapBitMap* _ptrmap; + static VirtualSpace* _vs; // Once _ptrmap is compacted, we don't allow bit marking anymore. This is to // avoid unintentional copy operations after the bitmap has been finalized and written. static bool _compacted; + + static address* ptr_base() { return (address*)_vs->low(); } // committed lower bound (inclusive) + static address* ptr_end() { return (address*)_vs->high(); } // committed upper bound (exclusive) + public: - static void initialize(CHeapBitMap* ptrmap, address* ptr_base, address* ptr_end); + static void initialize(CHeapBitMap* ptrmap, VirtualSpace* vs); static void mark_pointer(address* ptr_loc); static void clear_pointer(address* ptr_loc); static void compact(address relocatable_base, address relocatable_end); @@ -64,11 +68,6 @@ public: mark_pointer(ptr_loc); } - static void expand_ptr_end(address *new_ptr_end) { - assert(_ptr_end <= new_ptr_end, "must be"); - _ptr_end = new_ptr_end; - } - static CHeapBitMap* ptrmap() { return _ptrmap; } @@ -128,12 +127,17 @@ private: char* _base; char* _top; char* _end; + uintx _max_delta; bool _is_packed; ReservedSpace* _rs; VirtualSpace* _vs; + void commit_to(char* newtop); + public: - DumpRegion(const char* name) : _name(name), _base(NULL), _top(NULL), _end(NULL), _is_packed(false) {} + DumpRegion(const char* name, uintx max_delta = 0) + : _name(name), _base(NULL), _top(NULL), _end(NULL), + _max_delta(max_delta), _is_packed(false) {} char* expand_top_to(char* newtop); char* allocate(size_t num_bytes); diff --git a/src/hotspot/share/memory/arena.cpp b/src/hotspot/share/memory/arena.cpp index e7939d6f29e..8388f68c359 100644 --- a/src/hotspot/share/memory/arena.cpp +++ b/src/hotspot/share/memory/arena.cpp @@ -25,7 +25,6 @@ #include "precompiled.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" -#include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "runtime/os.hpp" #include "runtime/task.hpp" diff --git a/src/hotspot/share/memory/cppVtables.cpp b/src/hotspot/share/memory/cppVtables.cpp index 617c4f4c8ef..a4179bbb81c 100644 --- a/src/hotspot/share/memory/cppVtables.cpp +++ b/src/hotspot/share/memory/cppVtables.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, 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 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "logging/log.hpp" #include "memory/archiveUtils.hpp" +#include "memory/archiveBuilder.hpp" #include "memory/cppVtables.hpp" #include "memory/metaspaceShared.hpp" #include "oops/instanceClassLoaderKlass.hpp" @@ -100,7 +101,7 @@ template CppVtableInfo* CppVtableCloner::allocate_and_initialize(const char* name) { int n = get_vtable_length(name); CppVtableInfo* info = - (CppVtableInfo*)MetaspaceShared::misc_code_dump_space()->allocate(CppVtableInfo::byte_size(n)); + (CppVtableInfo*)ArchiveBuilder::current()->mc_region()->allocate(CppVtableInfo::byte_size(n)); info->set_vtable_size(n); initialize(name, info); return info; @@ -214,7 +215,7 @@ CppVtableInfo** CppVtables::_index = NULL; char* CppVtables::dumptime_init() { assert(DumpSharedSpaces, "must"); size_t vtptrs_bytes = _num_cloned_vtable_kinds * sizeof(CppVtableInfo*); - _index = (CppVtableInfo**)MetaspaceShared::misc_code_dump_space()->allocate(vtptrs_bytes); + _index = (CppVtableInfo**)ArchiveBuilder::current()->mc_region()->allocate(vtptrs_bytes); CPP_VTABLE_TYPES_DO(ALLOCATE_AND_INITIALIZE_VTABLE); diff --git a/src/hotspot/share/memory/dumpAllocStats.cpp b/src/hotspot/share/memory/dumpAllocStats.cpp index 23264ca11bf..1628943f968 100644 --- a/src/hotspot/share/memory/dumpAllocStats.cpp +++ b/src/hotspot/share/memory/dumpAllocStats.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, 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 @@ -26,25 +26,21 @@ #include "logging/log.hpp" #include "logging/logMessage.hpp" #include "memory/dumpAllocStats.hpp" -#include "memory/metaspaceShared.hpp" void DumpAllocStats::print_stats(int ro_all, int rw_all, int mc_all) { - // Calculate size of data that was not allocated by Metaspace::allocate() - MetaspaceSharedStats *stats = MetaspaceShared::stats(); - // symbols - _counts[RO][SymbolHashentryType] = stats->symbol.hashentry_count; - _bytes [RO][SymbolHashentryType] = stats->symbol.hashentry_bytes; + _counts[RO][SymbolHashentryType] = _symbol_stats.hashentry_count; + _bytes [RO][SymbolHashentryType] = _symbol_stats.hashentry_bytes; - _counts[RO][SymbolBucketType] = stats->symbol.bucket_count; - _bytes [RO][SymbolBucketType] = stats->symbol.bucket_bytes; + _counts[RO][SymbolBucketType] = _symbol_stats.bucket_count; + _bytes [RO][SymbolBucketType] = _symbol_stats.bucket_bytes; // strings - _counts[RO][StringHashentryType] = stats->string.hashentry_count; - _bytes [RO][StringHashentryType] = stats->string.hashentry_bytes; + _counts[RO][StringHashentryType] = _string_stats.hashentry_count; + _bytes [RO][StringHashentryType] = _string_stats.hashentry_bytes; - _counts[RO][StringBucketType] = stats->string.bucket_count; - _bytes [RO][StringBucketType] = stats->string.bucket_bytes; + _counts[RO][StringBucketType] = _string_stats.bucket_count; + _bytes [RO][StringBucketType] = _string_stats.bucket_bytes; // TODO: count things like dictionary, vtable, etc _bytes[RW][OtherType] += mc_all; @@ -70,7 +66,7 @@ void DumpAllocStats::print_stats(int ro_all, int rw_all, int mc_all) { LogMessage(cds) msg; - msg.debug("Detailed metadata info (excluding st regions; rw stats include mc regions):"); + msg.debug("Detailed metadata info (excluding heap regions; rw stats include mc regions):"); msg.debug("%s", hdr); msg.debug("%s", sep); for (int type = 0; type < int(_number_of_types); type ++) { diff --git a/src/hotspot/share/memory/dumpAllocStats.hpp b/src/hotspot/share/memory/dumpAllocStats.hpp index bb1e20b1191..fcffa2c07bb 100644 --- a/src/hotspot/share/memory/dumpAllocStats.hpp +++ b/src/hotspot/share/memory/dumpAllocStats.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, 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 @@ -26,6 +26,7 @@ #define SHARE_MEMORY_DUMPALLOCSTATS_HPP #include "memory/allocation.hpp" +#include "classfile/compactHashtable.hpp" // This is for dumping detailed statistics for the allocations // in the shared spaces. @@ -57,17 +58,23 @@ public: } } -public: - enum { RO = 0, RW = 1 }; + CompactHashtableStats _symbol_stats; + CompactHashtableStats _string_stats; int _counts[2][_number_of_types]; int _bytes [2][_number_of_types]; +public: + enum { RO = 0, RW = 1 }; + DumpAllocStats() { memset(_counts, 0, sizeof(_counts)); memset(_bytes, 0, sizeof(_bytes)); }; + CompactHashtableStats* symbol_stats() { return &_symbol_stats; } + CompactHashtableStats* string_stats() { return &_string_stats; } + void record(MetaspaceObj::Type type, int byte_size, bool read_only) { assert(int(type) >= 0 && type < MetaspaceObj::_number_of_types, "sanity"); int which = (read_only) ? RO : RW; diff --git a/src/hotspot/share/memory/dynamicArchive.cpp b/src/hotspot/share/memory/dynamicArchive.cpp index dc23c869de5..6d1bebfbb31 100644 --- a/src/hotspot/share/memory/dynamicArchive.cpp +++ b/src/hotspot/share/memory/dynamicArchive.cpp @@ -92,35 +92,7 @@ public: void write_archive(char* serialized_data); public: - DynamicArchiveBuilder() : ArchiveBuilder(MetaspaceShared::misc_code_dump_space(), - MetaspaceShared::read_write_dump_space(), - MetaspaceShared::read_only_dump_space()) { - } - - void start_dump_space(DumpRegion* next) { - address bottom = _last_verified_top; - address top = (address)(current_dump_space()->top()); - _other_region_used_bytes += size_t(top - bottom); - - MetaspaceShared::pack_dump_space(current_dump_space(), next, MetaspaceShared::shared_rs()); - _current_dump_space = next; - _num_dump_regions_used ++; - - _last_verified_top = (address)(current_dump_space()->top()); - } - - void verify_estimate_size(size_t estimate, const char* which) { - address bottom = _last_verified_top; - address top = (address)(current_dump_space()->top()); - size_t used = size_t(top - bottom) + _other_region_used_bytes; - int diff = int(estimate) - int(used); - - log_info(cds)("%s estimate = " SIZE_FORMAT " used = " SIZE_FORMAT "; diff = %d bytes", which, estimate, used, diff); - assert(diff >= 0, "Estimate is too small"); - - _last_verified_top = top; - _other_region_used_bytes = 0; - } + DynamicArchiveBuilder() : ArchiveBuilder() { } // Do this before and after the archive dump to see if any corruption // is caused by dynamic dumping. @@ -140,27 +112,16 @@ public: DEBUG_ONLY(SystemDictionaryShared::NoClassLoadingMark nclm); SystemDictionaryShared::check_excluded_classes(); - gather_klasses_and_symbols(); - - // mc space starts ... - reserve_buffer(); init_header(); + gather_source_objs(); + reserve_buffer(); - allocate_method_trampolines(); + init_mc_region(); verify_estimate_size(_estimated_trampoline_bytes, "Trampolines"); - gather_source_objs(); - // rw space starts ... - start_dump_space(MetaspaceShared::read_write_dump_space()); - log_info(cds, dynamic)("Copying %d klasses and %d symbols", klasses()->length(), symbols()->length()); - dump_rw_region(); - - // ro space starts ... - DumpRegion* ro_space = MetaspaceShared::read_only_dump_space(); - start_dump_space(ro_space); dump_ro_region(); relocate_metaspaceobj_embedded_pointers(); relocate_roots(); @@ -173,12 +134,14 @@ public: // Note that these tables still point to the *original* objects, so // they would need to call DynamicArchive::original_to_target() to // get the correct addresses. - assert(current_dump_space() == ro_space, "Must be RO space"); + assert(current_dump_space() == ro_region(), "Must be RO space"); SymbolTable::write_to_archive(symbols()); + + ArchiveBuilder::OtherROAllocMark mark; SystemDictionaryShared::write_to_archive(false); - serialized_data = ro_space->top(); - WriteClosure wc(ro_space); + serialized_data = ro_region()->top(); + WriteClosure wc(ro_region()); SymbolTable::serialize_shared_table_header(&wc, false); SystemDictionaryShared::serialize_dictionary_headers(&wc, false); } @@ -333,9 +296,6 @@ void DynamicArchiveBuilder::remark_pointers_for_instance_klass(InstanceKlass* k, } void DynamicArchiveBuilder::write_archive(char* serialized_data) { - int num_klasses = klasses()->length(); - int num_symbols = symbols()->length(); - Array* table = FileMapInfo::saved_shared_path_table().table(); SharedPathTable runtime_table(table, FileMapInfo::shared_path_table().size()); _header->set_shared_path_table(runtime_table); @@ -344,19 +304,8 @@ void DynamicArchiveBuilder::write_archive(char* serialized_data) { FileMapInfo* dynamic_info = FileMapInfo::dynamic_info(); assert(dynamic_info != NULL, "Sanity"); - // Now write the archived data including the file offsets. - const char* archive_name = Arguments::GetSharedDynamicArchivePath(); - dynamic_info->open_for_write(archive_name); - size_t bitmap_size_in_bytes; - char* bitmap = MetaspaceShared::write_core_archive_regions(dynamic_info, NULL, NULL, bitmap_size_in_bytes); - dynamic_info->set_requested_base((char*)MetaspaceShared::requested_base_address()); - dynamic_info->set_header_crc(dynamic_info->compute_header_crc()); - dynamic_info->write_header(); - dynamic_info->close(); - - write_cds_map_to_log(dynamic_info, NULL, NULL, - bitmap, bitmap_size_in_bytes); - FREE_C_HEAP_ARRAY(char, bitmap); + dynamic_info->open_for_write(Arguments::GetSharedDynamicArchivePath()); + ArchiveBuilder::write_archive(dynamic_info, NULL, NULL, NULL, NULL); address base = _requested_dynamic_archive_bottom; address top = _requested_dynamic_archive_top; @@ -366,13 +315,13 @@ void DynamicArchiveBuilder::write_archive(char* serialized_data) { " [" SIZE_FORMAT " bytes header, " SIZE_FORMAT " bytes total]", p2i(base), p2i(top), _header->header_size(), file_size); - log_info(cds, dynamic)("%d klasses; %d symbols", num_klasses, num_symbols); + log_info(cds, dynamic)("%d klasses; %d symbols", klasses()->length(), symbols()->length()); } class VM_PopulateDynamicDumpSharedSpace: public VM_GC_Sync_Operation { - DynamicArchiveBuilder* _builder; + DynamicArchiveBuilder builder; public: - VM_PopulateDynamicDumpSharedSpace(DynamicArchiveBuilder* builder) : VM_GC_Sync_Operation(), _builder(builder) {} + VM_PopulateDynamicDumpSharedSpace() : VM_GC_Sync_Operation() {} VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; } void doit() { ResourceMark rm; @@ -386,7 +335,7 @@ public: } FileMapInfo::check_nonempty_dir_in_shared_path_table(); - _builder->doit(); + builder.doit(); } }; @@ -397,8 +346,7 @@ void DynamicArchive::dump() { return; } - DynamicArchiveBuilder builder; - VM_PopulateDynamicDumpSharedSpace op(&builder); + VM_PopulateDynamicDumpSharedSpace op; VMThread::execute(&op); } diff --git a/src/hotspot/share/memory/heapShared.cpp b/src/hotspot/share/memory/heapShared.cpp index 3fd2c228079..b2471029c64 100644 --- a/src/hotspot/share/memory/heapShared.cpp +++ b/src/hotspot/share/memory/heapShared.cpp @@ -298,7 +298,7 @@ oop HeapShared::archive_heap_object(oop obj) { } void HeapShared::archive_klass_objects() { - GrowableArray* klasses = MetaspaceShared::collected_klasses(); + GrowableArray* klasses = ArchiveBuilder::current()->klasses(); assert(klasses != NULL, "sanity"); for (int i = 0; i < klasses->length(); i++) { Klass* k = ArchiveBuilder::get_relocated_klass(klasses->at(i)); @@ -573,7 +573,7 @@ void ArchivedKlassSubGraphInfoRecord::init(KlassSubGraphInfo* info) { int num_entry_fields = entry_fields->length(); assert(num_entry_fields % 2 == 0, "sanity"); _entry_field_records = - MetaspaceShared::new_ro_array(num_entry_fields); + ArchiveBuilder::new_ro_array(num_entry_fields); for (int i = 0 ; i < num_entry_fields; i++) { _entry_field_records->at_put(i, entry_fields->at(i)); } @@ -584,7 +584,7 @@ void ArchivedKlassSubGraphInfoRecord::init(KlassSubGraphInfo* info) { if (subgraph_object_klasses != NULL) { int num_subgraphs_klasses = subgraph_object_klasses->length(); _subgraph_object_klasses = - MetaspaceShared::new_ro_array(num_subgraphs_klasses); + ArchiveBuilder::new_ro_array(num_subgraphs_klasses); for (int i = 0; i < num_subgraphs_klasses; i++) { Klass* subgraph_k = subgraph_object_klasses->at(i); if (log_is_enabled(Info, cds, heap)) { @@ -610,7 +610,7 @@ struct CopyKlassSubGraphInfoToArchive : StackObj { bool do_entry(Klass* klass, KlassSubGraphInfo& info) { if (info.subgraph_object_klasses() != NULL || info.subgraph_entry_fields() != NULL) { ArchivedKlassSubGraphInfoRecord* record = - (ArchivedKlassSubGraphInfoRecord*)MetaspaceShared::read_only_space_alloc(sizeof(ArchivedKlassSubGraphInfoRecord)); + (ArchivedKlassSubGraphInfoRecord*)ArchiveBuilder::ro_region_alloc(sizeof(ArchivedKlassSubGraphInfoRecord)); record->init(&info); unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary((address)klass); diff --git a/src/hotspot/share/memory/metaspace/printMetaspaceInfoKlassClosure.cpp b/src/hotspot/share/memory/metaspace/printMetaspaceInfoKlassClosure.cpp index b100bf957c0..f852a5782ef 100644 --- a/src/hotspot/share/memory/metaspace/printMetaspaceInfoKlassClosure.cpp +++ b/src/hotspot/share/memory/metaspace/printMetaspaceInfoKlassClosure.cpp @@ -24,7 +24,6 @@ */ #include "precompiled.hpp" #include "memory/metaspace/printMetaspaceInfoKlassClosure.hpp" -#include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "oops/klass.hpp" #include "oops/reflectionAccessorImplKlassHelper.hpp" diff --git a/src/hotspot/share/memory/metaspaceShared.cpp b/src/hotspot/share/memory/metaspaceShared.cpp index 9bc8bfc7742..3cbd9583b46 100644 --- a/src/hotspot/share/memory/metaspaceShared.cpp +++ b/src/hotspot/share/memory/metaspaceShared.cpp @@ -40,18 +40,15 @@ #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "gc/shared/gcVMOperations.hpp" -#include "interpreter/abstractInterpreter.hpp" #include "interpreter/bytecodeStream.hpp" #include "interpreter/bytecodes.hpp" #include "logging/log.hpp" #include "logging/logMessage.hpp" #include "memory/archiveBuilder.hpp" -#include "memory/archiveUtils.inline.hpp" #include "memory/cppVtables.hpp" #include "memory/dumpAllocStats.hpp" -#include "memory/dynamicArchive.hpp" #include "memory/filemap.hpp" -#include "memory/heapShared.inline.hpp" +#include "memory/heapShared.hpp" #include "memory/metaspace.hpp" #include "memory/metaspaceClosure.hpp" #include "memory/metaspaceShared.hpp" @@ -75,16 +72,12 @@ #include "utilities/bitMap.inline.hpp" #include "utilities/ostream.hpp" #include "utilities/defaultStream.hpp" -#include "utilities/hashtable.inline.hpp" #if INCLUDE_G1GC #include "gc/g1/g1CollectedHeap.inline.hpp" #endif -ReservedSpace MetaspaceShared::_shared_rs; -VirtualSpace MetaspaceShared::_shared_vs; ReservedSpace MetaspaceShared::_symbol_rs; VirtualSpace MetaspaceShared::_symbol_vs; -MetaspaceSharedStats MetaspaceShared::_stats; bool MetaspaceShared::_has_error_classes; bool MetaspaceShared::_archive_loading_failed = false; bool MetaspaceShared::_remapped_readwrite = false; @@ -105,63 +98,30 @@ bool MetaspaceShared::_use_full_module_graph = true; // oa0 - open archive heap space #0 // oa1 - open archive heap space #1 (may be empty) // -// The mc, rw, and ro regions are linearly allocated, starting from -// SharedBaseAddress, in the order of mc->rw->ro. The size of these 3 regions -// are page-aligned, and there's no gap between any consecutive regions. +// bm - bitmap for relocating the above 7 regions. +// +// The mc, rw, and ro regions are linearly allocated, in the order of mc->rw->ro. +// These regions are aligned with MetaspaceShared::reserved_space_alignment(). // // These 3 regions are populated in the following steps: -// [1] All classes are loaded in MetaspaceShared::preload_classes(). All metadata are -// temporarily allocated outside of the shared regions. Only the method entry -// trampolines are written into the mc region. -// [2] C++ vtables are copied into the mc region. +// [0] All classes are loaded in MetaspaceShared::preload_classes(). All metadata are +// temporarily allocated outside of the shared regions. +// [1] We enter a safepoint and allocate a buffer for the mc/rw/ro regions. +// [2] C++ vtables and method trampolines are copied into the mc region. // [3] ArchiveBuilder copies RW metadata into the rw region. // [4] ArchiveBuilder copies RO metadata into the ro region. // [5] SymbolTable, StringTable, SystemDictionary, and a few other read-only data // are copied into the ro region as read-only tables. // -// The s0/s1 and oa0/oa1 regions are populated inside HeapShared::archive_java_heap_objects. -// Their layout is independent of the other 4 regions. - -static DumpRegion _mc_region("mc"), _ro_region("ro"), _rw_region("rw"), _symbol_region("symbols"); -static size_t _total_closed_archive_region_size = 0, _total_open_archive_region_size = 0; +// The ca0/ca1 and oa0/oa1 regions are populated inside HeapShared::archive_java_heap_objects. +// Their layout is independent of the mc/rw/ro regions. -void MetaspaceShared::init_shared_dump_space(DumpRegion* first_space) { - first_space->init(&_shared_rs, &_shared_vs); -} - -DumpRegion* MetaspaceShared::misc_code_dump_space() { - return &_mc_region; -} - -DumpRegion* MetaspaceShared::read_write_dump_space() { - return &_rw_region; -} - -DumpRegion* MetaspaceShared::read_only_dump_space() { - return &_ro_region; -} - -void MetaspaceShared::pack_dump_space(DumpRegion* current, DumpRegion* next, - ReservedSpace* rs) { - current->pack(next); -} +static DumpRegion _symbol_region("symbols"); char* MetaspaceShared::symbol_space_alloc(size_t num_bytes) { return _symbol_region.allocate(num_bytes); } -char* MetaspaceShared::misc_code_space_alloc(size_t num_bytes) { - return _mc_region.allocate(num_bytes); -} - -char* MetaspaceShared::read_only_space_alloc(size_t num_bytes) { - return _ro_region.allocate(num_bytes); -} - -char* MetaspaceShared::read_write_space_alloc(size_t num_bytes) { - return _rw_region.allocate(num_bytes); -} - size_t MetaspaceShared::reserved_space_alignment() { return os::vm_allocation_granularity(); } static bool shared_base_valid(char* shared_base) { @@ -316,39 +276,6 @@ void MetaspaceShared::read_extra_data(const char* filename, TRAPS) { } } -void MetaspaceShared::commit_to(ReservedSpace* rs, VirtualSpace* vs, char* newtop) { - Arguments::assert_is_dumping_archive(); - char* base = rs->base(); - size_t need_committed_size = newtop - base; - size_t has_committed_size = vs->committed_size(); - if (need_committed_size < has_committed_size) { - return; - } - - size_t min_bytes = need_committed_size - has_committed_size; - size_t preferred_bytes = 1 * M; - size_t uncommitted = vs->reserved_size() - has_committed_size; - - size_t commit =MAX2(min_bytes, preferred_bytes); - commit = MIN2(commit, uncommitted); - assert(commit <= uncommitted, "sanity"); - - bool result = vs->expand_by(commit, false); - if (rs == &_shared_rs) { - ArchivePtrMarker::expand_ptr_end((address*)vs->high()); - } - - if (!result) { - vm_exit_during_initialization(err_msg("Failed to expand shared space to " SIZE_FORMAT " bytes", - need_committed_size)); - } - - assert(rs == &_shared_rs || rs == &_symbol_rs, "must be"); - const char* which = (rs == &_shared_rs) ? "shared" : "symbol"; - log_debug(cds)("Expanding %s spaces by " SIZE_FORMAT_W(7) " bytes [total " SIZE_FORMAT_W(9) " bytes ending at %p]", - which, commit, vs->actual_committed_size(), vs->high()); -} - // Read/write a data stream for restoring/preserving metadata pointers and // miscellaneous data from/to the shared archive file. @@ -395,14 +322,10 @@ void MetaspaceShared::serialize(SerializeClosure* soc) { soc->do_tag(666); } -void MetaspaceShared::init_misc_code_space() { - // We don't want any valid object to be at the very bottom of the archive. - // See ArchivePtrMarker::mark_pointer(). - MetaspaceShared::misc_code_space_alloc(16); - - size_t trampoline_size = SharedRuntime::trampoline_size(); - size_t buf_size = (size_t)AbstractInterpreter::number_of_method_entries * trampoline_size; - _i2i_entry_code_buffers = (address)misc_code_space_alloc(buf_size); +void MetaspaceShared::set_i2i_entry_code_buffers(address b) { + assert(DumpSharedSpaces, "must be"); + assert(_i2i_entry_code_buffers == NULL, "initialize only once"); + _i2i_entry_code_buffers = b; } address MetaspaceShared::i2i_entry_code_buffers() { @@ -411,14 +334,6 @@ address MetaspaceShared::i2i_entry_code_buffers() { return _i2i_entry_code_buffers; } -// Global object for holding classes that have been loaded. Since this -// is run at a safepoint just before exit, this is the entire set of classes. -static GrowableArray* _global_klass_objects; - -GrowableArray* MetaspaceShared::collected_klasses() { - return _global_klass_objects; -} - static void rewrite_nofast_bytecode(const methodHandle& method) { BytecodeStream bcs(method); while (!bcs.is_last_bytecode()) { @@ -459,7 +374,7 @@ private: GrowableArray *_closed_archive_heap_oopmaps; GrowableArray *_open_archive_heap_oopmaps; - void dump_java_heap_objects() NOT_CDS_JAVA_HEAP_RETURN; + void dump_java_heap_objects(GrowableArray* klasses) NOT_CDS_JAVA_HEAP_RETURN; void dump_archive_heap_oopmaps() NOT_CDS_JAVA_HEAP_RETURN; void dump_archive_heap_oopmaps(GrowableArray* regions, GrowableArray* oopmaps); @@ -468,10 +383,6 @@ private: SymbolTable::write_to_archive(symbols); } char* dump_read_only_tables(); - void print_region_stats(FileMapInfo* map_info); - void print_bitmap_region_stats(size_t size, size_t total_size); - void print_heap_region_stats(GrowableArray *heap_mem, - const char *name, size_t total_size); public: @@ -488,8 +399,7 @@ public: class StaticArchiveBuilder : public ArchiveBuilder { public: - StaticArchiveBuilder(DumpRegion* mc_region, DumpRegion* rw_region, DumpRegion* ro_region) - : ArchiveBuilder(mc_region, rw_region, ro_region) {} + StaticArchiveBuilder() : ArchiveBuilder() {} virtual void iterate_roots(MetaspaceClosure* it, bool is_relocating_pointers) { FileMapInfo::metaspace_pointers_do(it, false); @@ -516,8 +426,9 @@ char* VM_PopulateDumpSharedSpace::dump_read_only_tables() { SystemDictionaryShared::write_to_archive(); // Write the other data to the output array. - char* start = _ro_region.top(); - WriteClosure wc(&_ro_region); + DumpRegion* ro_region = ArchiveBuilder::current()->ro_region(); + char* start = ro_region->top(); + WriteClosure wc(ro_region); MetaspaceShared::serialize(&wc); // Write the bitmaps for patching the archive heap regions @@ -557,50 +468,21 @@ void VM_PopulateDumpSharedSpace::doit() { // that so we don't have to walk the SystemDictionary again. SystemDictionaryShared::check_excluded_classes(); - StaticArchiveBuilder builder(&_mc_region, &_rw_region, &_ro_region); - builder.gather_klasses_and_symbols(); - builder.reserve_buffer(); - _global_klass_objects = builder.klasses(); - + StaticArchiveBuilder builder; builder.gather_source_objs(); + builder.reserve_buffer(); - MetaspaceShared::init_misc_code_space(); - builder.allocate_method_trampoline_info(); - builder.allocate_method_trampolines(); - + builder.init_mc_region(); char* cloned_vtables = CppVtables::dumptime_init(); - { - _mc_region.pack(&_rw_region); - builder.set_current_dump_space(&_rw_region); - builder.dump_rw_region(); -#if INCLUDE_CDS_JAVA_HEAP - if (MetaspaceShared::use_full_module_graph()) { - // Archive the ModuleEntry's and PackageEntry's of the 3 built-in loaders - char* start = _rw_region.top(); - ClassLoaderDataShared::allocate_archived_tables(); - ArchiveBuilder::alloc_stats()->record_modules(_rw_region.top() - start, /*read_only*/false); - } -#endif - } - { - _rw_region.pack(&_ro_region); - builder.set_current_dump_space(&_ro_region); - builder.dump_ro_region(); -#if INCLUDE_CDS_JAVA_HEAP - if (MetaspaceShared::use_full_module_graph()) { - char* start = _ro_region.top(); - ClassLoaderDataShared::init_archived_tables(); - ArchiveBuilder::alloc_stats()->record_modules(_ro_region.top() - start, /*read_only*/true); - } -#endif - } + builder.dump_rw_region(); + builder.dump_ro_region(); builder.relocate_metaspaceobj_embedded_pointers(); // Dump supported java heap objects _closed_archive_heap_regions = NULL; _open_archive_heap_regions = NULL; - dump_java_heap_objects(); + dump_java_heap_objects(builder.klasses()); builder.relocate_roots(); dump_shared_symbol_table(builder.symbols()); @@ -614,7 +496,6 @@ void VM_PopulateDumpSharedSpace::doit() { builder.make_klasses_shareable(); char* serialized_data = dump_read_only_tables(); - _ro_region.pack(); SystemDictionaryShared::adjust_lambda_proxy_class_dictionary(); @@ -626,42 +507,18 @@ void VM_PopulateDumpSharedSpace::doit() { // without runtime relocation. builder.relocate_to_requested(); - // Create and write the archive file that maps the shared spaces. - + // Write the archive file FileMapInfo* mapinfo = new FileMapInfo(true); mapinfo->populate_header(os::vm_allocation_granularity()); mapinfo->set_serialized_data(serialized_data); mapinfo->set_cloned_vtables(cloned_vtables); mapinfo->set_i2i_entry_code_buffers(MetaspaceShared::i2i_entry_code_buffers()); mapinfo->open_for_write(); - size_t bitmap_size_in_bytes; - char* bitmap = MetaspaceShared::write_core_archive_regions(mapinfo, _closed_archive_heap_oopmaps, - _open_archive_heap_oopmaps, - bitmap_size_in_bytes); - _total_closed_archive_region_size = mapinfo->write_archive_heap_regions( - _closed_archive_heap_regions, - _closed_archive_heap_oopmaps, - MetaspaceShared::first_closed_archive_heap_region, - MetaspaceShared::max_closed_archive_heap_region); - _total_open_archive_region_size = mapinfo->write_archive_heap_regions( - _open_archive_heap_regions, - _open_archive_heap_oopmaps, - MetaspaceShared::first_open_archive_heap_region, - MetaspaceShared::max_open_archive_heap_region); - - mapinfo->set_requested_base((char*)MetaspaceShared::requested_base_address()); - mapinfo->set_header_crc(mapinfo->compute_header_crc()); - mapinfo->write_header(); - print_region_stats(mapinfo); - mapinfo->close(); - - builder.write_cds_map_to_log(mapinfo, _closed_archive_heap_regions, _open_archive_heap_regions, - bitmap, bitmap_size_in_bytes); - FREE_C_HEAP_ARRAY(char, bitmap); - - if (log_is_enabled(Info, cds)) { - builder.print_stats(int(_ro_region.used()), int(_rw_region.used()), int(_mc_region.used())); - } + builder.write_archive(mapinfo, + _closed_archive_heap_regions, + _open_archive_heap_regions, + _closed_archive_heap_oopmaps, + _open_archive_heap_oopmaps); if (PrintSystemDictionaryAtExit) { SystemDictionary::print(); @@ -678,73 +535,6 @@ void VM_PopulateDumpSharedSpace::doit() { vm_direct_exit(0); } -void VM_PopulateDumpSharedSpace::print_region_stats(FileMapInfo *map_info) { - // Print statistics of all the regions - const size_t bitmap_used = map_info->space_at(MetaspaceShared::bm)->used(); - const size_t bitmap_reserved = map_info->space_at(MetaspaceShared::bm)->used_aligned(); - const size_t total_reserved = _ro_region.reserved() + _rw_region.reserved() + - _mc_region.reserved() + - bitmap_reserved + - _total_closed_archive_region_size + - _total_open_archive_region_size; - const size_t total_bytes = _ro_region.used() + _rw_region.used() + - _mc_region.used() + - bitmap_used + - _total_closed_archive_region_size + - _total_open_archive_region_size; - const double total_u_perc = percent_of(total_bytes, total_reserved); - - _mc_region.print(total_reserved); - _rw_region.print(total_reserved); - _ro_region.print(total_reserved); - print_bitmap_region_stats(bitmap_used, total_reserved); - print_heap_region_stats(_closed_archive_heap_regions, "ca", total_reserved); - print_heap_region_stats(_open_archive_heap_regions, "oa", total_reserved); - - log_debug(cds)("total : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]", - total_bytes, total_reserved, total_u_perc); -} - -void VM_PopulateDumpSharedSpace::print_bitmap_region_stats(size_t size, size_t total_size) { - log_debug(cds)("bm space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used]", - size, size/double(total_size)*100.0, size); -} - -void VM_PopulateDumpSharedSpace::print_heap_region_stats(GrowableArray *heap_mem, - const char *name, size_t total_size) { - int arr_len = heap_mem == NULL ? 0 : heap_mem->length(); - for (int i = 0; i < arr_len; i++) { - char* start = (char*)heap_mem->at(i).start(); - size_t size = heap_mem->at(i).byte_size(); - char* top = start + size; - log_debug(cds)("%s%d space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [100.0%% used] at " INTPTR_FORMAT, - name, i, size, size/double(total_size)*100.0, size, p2i(start)); - - } -} - -char* MetaspaceShared::write_core_archive_regions(FileMapInfo* mapinfo, - GrowableArray* closed_oopmaps, - GrowableArray* open_oopmaps, - size_t& bitmap_size_in_bytes) { - // Make sure NUM_CDS_REGIONS (exported in cds.h) agrees with - // MetaspaceShared::n_regions (internal to hotspot). - assert(NUM_CDS_REGIONS == MetaspaceShared::n_regions, "sanity"); - - // mc contains the trampoline code for method entries, which are patched at run time, - // so it needs to be read/write. - write_region(mapinfo, mc, &_mc_region, /*read_only=*/false,/*allow_exec=*/true); - write_region(mapinfo, rw, &_rw_region, /*read_only=*/false,/*allow_exec=*/false); - write_region(mapinfo, ro, &_ro_region, /*read_only=*/true, /*allow_exec=*/false); - - return mapinfo->write_bitmap_region(ArchivePtrMarker::ptrmap(), closed_oopmaps, open_oopmaps, - bitmap_size_in_bytes); -} - -void MetaspaceShared::write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region, bool read_only, bool allow_exec) { - mapinfo->write_region(region_idx, dump_region->base(), dump_region->used(), read_only, allow_exec); -} - static GrowableArray* _loaded_cld = NULL; class CollectCLDClosure : public CLDClosure { @@ -987,7 +777,7 @@ bool MetaspaceShared::try_link_class(InstanceKlass* ik, TRAPS) { } #if INCLUDE_CDS_JAVA_HEAP -void VM_PopulateDumpSharedSpace::dump_java_heap_objects() { +void VM_PopulateDumpSharedSpace::dump_java_heap_objects(GrowableArray* klasses) { if(!HeapShared::is_heap_object_archiving_allowed()) { log_info(cds)( "Archived java heap is not supported as UseG1GC, " @@ -999,8 +789,8 @@ void VM_PopulateDumpSharedSpace::dump_java_heap_objects() { } // Find all the interned strings that should be dumped. int i; - for (i = 0; i < _global_klass_objects->length(); i++) { - Klass* k = _global_klass_objects->at(i); + for (i = 0; i < klasses->length(); i++) { + Klass* k = klasses->at(i); if (k->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(k); ik->constants()->add_dumped_interned_strings(); @@ -1640,18 +1430,6 @@ bool MetaspaceShared::remap_shared_readonly_as_readwrite() { return true; } -void MetaspaceShared::report_out_of_space(const char* name, size_t needed_bytes) { - // This is highly unlikely to happen on 64-bits because we have reserved a 4GB space. - // On 32-bit we reserve only 256MB so you could run out of space with 100,000 classes - // or so. - _mc_region.print_out_of_space_msg(name, needed_bytes); - _rw_region.print_out_of_space_msg(name, needed_bytes); - _ro_region.print_out_of_space_msg(name, needed_bytes); - - vm_exit_during_initialization(err_msg("Unable to allocate from '%s' region", name), - "Please reduce the number of shared classes."); -} - bool MetaspaceShared::use_full_module_graph() { #if INCLUDE_CDS_JAVA_HEAP if (ClassLoaderDataShared::is_full_module_graph_loaded()) { @@ -1669,24 +1447,16 @@ bool MetaspaceShared::use_full_module_graph() { } void MetaspaceShared::print_on(outputStream* st) { - if (UseSharedSpaces || DumpSharedSpaces) { + if (UseSharedSpaces) { st->print("CDS archive(s) mapped at: "); - address base; - address top; - if (UseSharedSpaces) { // Runtime - base = (address)MetaspaceObj::shared_metaspace_base(); - address static_top = (address)_shared_metaspace_static_top; - top = (address)MetaspaceObj::shared_metaspace_top(); - st->print("[" PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "), ", p2i(base), p2i(static_top), p2i(top)); - } else if (DumpSharedSpaces) { // Dump Time - base = (address)_shared_rs.base(); - top = (address)_shared_rs.end(); - st->print("[" PTR_FORMAT "-" PTR_FORMAT "), ", p2i(base), p2i(top)); - } + address base = (address)MetaspaceObj::shared_metaspace_base(); + address static_top = (address)_shared_metaspace_static_top; + address top = (address)MetaspaceObj::shared_metaspace_top(); + st->print("[" PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "), ", p2i(base), p2i(static_top), p2i(top)); st->print("size " SIZE_FORMAT ", ", top - base); st->print("SharedBaseAddress: " PTR_FORMAT ", ArchiveRelocationMode: %d.", SharedBaseAddress, (int)ArchiveRelocationMode); } else { - st->print("CDS disabled."); + st->print("CDS archive(s) not mapped"); } st->cr(); } diff --git a/src/hotspot/share/memory/metaspaceShared.hpp b/src/hotspot/share/memory/metaspaceShared.hpp index 215a7f2a37c..89fd06c9df5 100644 --- a/src/hotspot/share/memory/metaspaceShared.hpp +++ b/src/hotspot/share/memory/metaspaceShared.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_MEMORY_METASPACESHARED_HPP #define SHARE_MEMORY_METASPACESHARED_HPP -#include "classfile/compactHashtable.hpp" #include "memory/allocation.hpp" #include "memory/memRegion.hpp" #include "memory/virtualspace.hpp" @@ -33,15 +32,10 @@ #include "utilities/macros.hpp" #include "utilities/resourceHash.hpp" -// Metaspace::allocate() requires that all blocks must be aligned with KlassAlignmentInBytes. -// We enforce the same alignment rule in blocks allocated from the shared space. -const int SharedSpaceObjectAlignment = KlassAlignmentInBytes; - -class outputStream; -class CHeapBitMap; class FileMapInfo; -class DumpRegion; -struct ArchiveHeapOopmapInfo; +class outputStream; + +template class GrowableArray; enum MapArchiveResult { MAP_ARCHIVE_SUCCESS, @@ -49,32 +43,14 @@ enum MapArchiveResult { MAP_ARCHIVE_OTHER_FAILURE }; -class MetaspaceSharedStats { -public: - MetaspaceSharedStats() { - memset(this, 0, sizeof(*this)); - } - CompactHashtableStats symbol; - CompactHashtableStats string; -}; - // Class Data Sharing Support class MetaspaceShared : AllStatic { - - // CDS support - - // Note: _shared_rs and _symbol_rs are only used at dump time. - static ReservedSpace _shared_rs; - static VirtualSpace _shared_vs; - static ReservedSpace _symbol_rs; - static VirtualSpace _symbol_vs; - static int _max_alignment; - static MetaspaceSharedStats _stats; + static ReservedSpace _symbol_rs; // used only during -Xshare:dump + static VirtualSpace _symbol_vs; // used only during -Xshare:dump static bool _has_error_classes; static bool _archive_loading_failed; static bool _remapped_readwrite; static address _i2i_entry_code_buffers; - static size_t _core_spaces_size; static void* _shared_metaspace_static_top; static intx _relocation_delta; static char* _requested_base_address; @@ -107,22 +83,10 @@ class MetaspaceShared : AllStatic { static int preload_classes(const char * class_list_path, TRAPS) NOT_CDS_RETURN_(0); - static GrowableArray* collected_klasses(); - - static ReservedSpace* shared_rs() { - CDS_ONLY(return &_shared_rs); - NOT_CDS(return NULL); - } - static Symbol* symbol_rs_base() { return (Symbol*)_symbol_rs.base(); } - static void set_shared_rs(ReservedSpace rs) { - CDS_ONLY(_shared_rs = rs); - } - - static void commit_to(ReservedSpace* rs, VirtualSpace* vs, char* newtop) NOT_CDS_RETURN; static void initialize_for_static_dump() NOT_CDS_RETURN; static void initialize_runtime_shared_and_meta_spaces() NOT_CDS_RETURN; static void post_initialize(TRAPS) NOT_CDS_RETURN; @@ -132,10 +96,6 @@ class MetaspaceShared : AllStatic { static void set_archive_loading_failed() { _archive_loading_failed = true; } - static bool is_in_output_space(void* ptr) { - assert(DumpSharedSpaces, "must be"); - return shared_rs()->contains(ptr); - } static bool map_shared_spaces(FileMapInfo* mapinfo) NOT_CDS_RETURN_(false); static void initialize_shared_spaces() NOT_CDS_RETURN; @@ -161,12 +121,6 @@ class MetaspaceShared : AllStatic { static void serialize(SerializeClosure* sc) NOT_CDS_RETURN; - static MetaspaceSharedStats* stats() { - return &_stats; - } - - static void report_out_of_space(const char* name, size_t needed_bytes); - // JVM/TI RedefineClasses() support: // Remap the shared readonly space to shared readwrite, private if // sharing is enabled. Simply returns true if sharing is not enabled @@ -184,50 +138,15 @@ class MetaspaceShared : AllStatic { #if INCLUDE_CDS static size_t reserved_space_alignment(); - static void init_shared_dump_space(DumpRegion* first_space); - static DumpRegion* misc_code_dump_space(); - static DumpRegion* read_write_dump_space(); - static DumpRegion* read_only_dump_space(); - static void pack_dump_space(DumpRegion* current, DumpRegion* next, - ReservedSpace* rs); - static void rewrite_nofast_bytecodes_and_calculate_fingerprints(Thread* thread, InstanceKlass* ik); #endif // Allocate a block of memory from the temporary "symbol" region. static char* symbol_space_alloc(size_t num_bytes); - // Allocate a block of memory from the "mc" or "ro" regions. - static char* misc_code_space_alloc(size_t num_bytes); - static char* read_only_space_alloc(size_t num_bytes); - static char* read_write_space_alloc(size_t num_bytes); - - template - static Array* new_ro_array(int length) { - size_t byte_size = Array::byte_sizeof(length, sizeof(T)); - Array* array = (Array*)read_only_space_alloc(byte_size); - array->initialize(length); - return array; - } - - template - static Array* new_rw_array(int length) { - size_t byte_size = Array::byte_sizeof(length, sizeof(T)); - Array* array = (Array*)read_write_space_alloc(byte_size); - array->initialize(length); - return array; - } - - template - static size_t ro_array_bytesize(int length) { - size_t byte_size = Array::byte_sizeof(length, sizeof(T)); - return align_up(byte_size, SharedSpaceObjectAlignment); - } - static void init_misc_code_space(); static address i2i_entry_code_buffers(); - - static void initialize_ptr_marker(CHeapBitMap* ptrmap); + static void set_i2i_entry_code_buffers(address b); // This is the base address as specified by -XX:SharedBaseAddress during -Xshare:dump. // Both the base/top archives are written using this as their base address. @@ -254,13 +173,6 @@ class MetaspaceShared : AllStatic { return is_windows; } - // Returns the bitmap region which is allocated from C heap. - // Caller must free it with FREE_C_HEAP_ARRAY() - static char* write_core_archive_regions(FileMapInfo* mapinfo, - GrowableArray* closed_oopmaps, - GrowableArray* open_oopmaps, - size_t& bitmap_size_in_bytes); - // Can we skip some expensive operations related to modules? static bool use_optimized_module_handling() { return NOT_CDS(false) CDS_ONLY(_use_optimized_module_handling); } static void disable_optimized_module_handling() { _use_optimized_module_handling = false; } @@ -270,10 +182,6 @@ class MetaspaceShared : AllStatic { static void disable_full_module_graph() { _use_full_module_graph = false; } private: -#if INCLUDE_CDS - static void write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region, - bool read_only, bool allow_exec); -#endif static void read_extra_data(const char* filename, TRAPS) NOT_CDS_RETURN; static FileMapInfo* open_static_archive(); static FileMapInfo* open_dynamic_archive(); diff --git a/src/hotspot/share/memory/metaspaceShared.inline.hpp b/src/hotspot/share/memory/metaspaceShared.inline.hpp deleted file mode 100644 index 2f6f6bdc630..00000000000 --- a/src/hotspot/share/memory/metaspaceShared.inline.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2018, 2019, 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. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_MEMORY_METASPACESHARED_INLINE_HPP -#define SHARE_MEMORY_METASPACESHARED_INLINE_HPP - -#include "memory/metaspaceShared.hpp" -#if INCLUDE_G1GC -#include "gc/g1/g1Allocator.inline.hpp" -#endif - -#if INCLUDE_CDS_JAVA_HEAP -bool MetaspaceShared::is_archive_object(oop p) { - return (p == NULL) ? false : G1ArchiveAllocator::is_archive_object(p); -} -#endif - -#endif // SHARE_MEMORY_METASPACESHARED_INLINE_HPP diff --git a/src/hotspot/share/oops/array.hpp b/src/hotspot/share/oops/array.hpp index f383564ac84..589ac22d33e 100644 --- a/src/hotspot/share/oops/array.hpp +++ b/src/hotspot/share/oops/array.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2021, 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 @@ -35,8 +35,8 @@ template class Array: public MetaspaceObj { + friend class ArchiveBuilder; friend class MetadataFactory; - friend class MetaspaceShared; friend class VMStructs; friend class JVMCIVMStructs; friend class MethodHandleCompiler; // special case diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index 1dc0404c701..efbcb0e5ee1 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -39,7 +39,6 @@ #include "memory/heapShared.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" -#include "memory/metaspaceShared.hpp" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp index 35a159919ce..fc3fc1a72ed 100644 --- a/src/hotspot/share/oops/cpCache.cpp +++ b/src/hotspot/share/oops/cpCache.cpp @@ -36,7 +36,6 @@ #include "memory/heapShared.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" -#include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "oops/access.inline.hpp" #include "oops/compressedOops.hpp" diff --git a/src/hotspot/share/oops/klass.cpp b/src/hotspot/share/oops/klass.cpp index 143172dfa24..cb62cb5cd39 100644 --- a/src/hotspot/share/oops/klass.cpp +++ b/src/hotspot/share/oops/klass.cpp @@ -38,7 +38,6 @@ #include "memory/heapShared.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" -#include "memory/metaspaceShared.hpp" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index 5e23228615e..bea1bf644ab 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -45,7 +45,6 @@ #include "interpreter/interpreterRuntime.hpp" #include "jfr/jfrEvents.hpp" #include "logging/log.hpp" -#include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "oops/compiledICHolder.inline.hpp" diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp index 815b5bfdfbe..3f3e4a6dd81 100644 --- a/src/hotspot/share/runtime/synchronizer.cpp +++ b/src/hotspot/share/runtime/synchronizer.cpp @@ -28,7 +28,6 @@ #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" -#include "memory/metaspaceShared.hpp" #include "memory/padded.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" diff --git a/test/hotspot/jtreg/runtime/cds/appcds/LotsOfClasses.java b/test/hotspot/jtreg/runtime/cds/appcds/LotsOfClasses.java index 9372e7aeed1..0f71c1ba389 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/LotsOfClasses.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/LotsOfClasses.java @@ -49,7 +49,7 @@ public class LotsOfClasses { opts.addSuffix("-Xlog:hashtables"); opts.addSuffix("-Xmx500m"); opts.addSuffix("-Xlog:gc+region+cds"); - opts.addSuffix("-Xlog:gc+region=trace"); + opts.addSuffix("-Xlog:cds=debug"); // test detailed metadata info printing CDSTestUtils.createArchiveAndCheck(opts); } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicLotsOfClasses.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicLotsOfClasses.java index 26c7b52515e..202d00f889c 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicLotsOfClasses.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicLotsOfClasses.java @@ -75,12 +75,12 @@ public class DynamicLotsOfClasses extends DynamicArchiveTestBase { "ALL-SYSTEM", "-Xlog:hashtables", "-Xmx500m", - "-Xlog:cds,cds+dynamic", + "-Xlog:cds=debug", // test detailed metadata info printing + "-Xlog:cds+dynamic=info", bootClassPath, "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", "-cp", appJar, mainClass, classList) - .assertNormalExit(output -> { - output.shouldContain("Written dynamic archive 0x"); - }); + .assertNormalExit("Written dynamic archive 0x", + "Detailed metadata info"); } } -- GitLab From 7c9315916970fc9a46ff5c4eda0f1baad4dc1dbb Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 15 Feb 2021 08:41:28 +0000 Subject: [PATCH 062/367] 8261503: Shenandoah: reconsider verifier memory ordering Reviewed-by: zgu --- .../share/gc/shenandoah/shenandoahVerifier.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp index 3eb2bbc78c9..b7ab52e2bbb 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp @@ -160,7 +160,7 @@ private: // skip break; case ShenandoahVerifier::_verify_liveness_complete: - Atomic::add(&_ld[obj_reg->index()], (uint) obj->size()); + Atomic::add(&_ld[obj_reg->index()], (uint) obj->size(), memory_order_relaxed); // fallthrough for fast failure for un-live regions: case ShenandoahVerifier::_verify_liveness_conservative: check(ShenandoahAsserts::_safe_oop, obj, obj_reg->has_live(), @@ -483,7 +483,7 @@ public: } } - Atomic::add(&_processed, processed); + Atomic::add(&_processed, processed, memory_order_relaxed); } }; @@ -512,7 +512,7 @@ public: _processed(0) {}; size_t processed() { - return _processed; + return Atomic::load(&_processed); } virtual void work(uint worker_id) { @@ -522,7 +522,7 @@ public: _options); while (true) { - size_t v = Atomic::fetch_and_add(&_claimed, 1u); + size_t v = Atomic::fetch_and_add(&_claimed, 1u, memory_order_relaxed); if (v < _heap->num_regions()) { ShenandoahHeapRegion* r = _heap->get_region(v); if (!r->is_humongous() && !r->is_trash()) { @@ -542,7 +542,7 @@ public: if (_heap->complete_marking_context()->is_marked((oop)obj)) { verify_and_follow(obj, stack, cl, &processed); } - Atomic::add(&_processed, processed); + Atomic::add(&_processed, processed, memory_order_relaxed); } virtual void work_regular(ShenandoahHeapRegion *r, ShenandoahVerifierStack &stack, ShenandoahVerifyOopClosure &cl) { @@ -575,7 +575,7 @@ public: } } - Atomic::add(&_processed, processed); + Atomic::add(&_processed, processed, memory_order_relaxed); } void verify_and_follow(HeapWord *addr, ShenandoahVerifierStack &stack, ShenandoahVerifyOopClosure &cl, size_t *processed) { @@ -747,12 +747,12 @@ void ShenandoahVerifier::verify_at_safepoint(const char *label, if (r->is_humongous()) { // For humongous objects, test if start region is marked live, and if so, // all humongous regions in that chain have live data equal to their "used". - juint start_live = Atomic::load_acquire(&ld[r->humongous_start_region()->index()]); + juint start_live = Atomic::load(&ld[r->humongous_start_region()->index()]); if (start_live > 0) { verf_live = (juint)(r->used() / HeapWordSize); } } else { - verf_live = Atomic::load_acquire(&ld[r->index()]); + verf_live = Atomic::load(&ld[r->index()]); } size_t reg_live = r->get_live_data_words(); -- GitLab From 4642730b057bfa37df740fc8d9e17bfb60e53447 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 15 Feb 2021 08:42:28 +0000 Subject: [PATCH 063/367] 8261496: Shenandoah: reconsider pacing updates memory ordering Reviewed-by: zgu --- src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp | 4 ++-- src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp | 6 +++--- src/hotspot/share/gc/shenandoah/shenandoahPacer.inline.hpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp index 1a3030e1d24..4483488739d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp @@ -100,7 +100,7 @@ void ShenandoahControlThread::run_service() { bool implicit_gc_requested = _gc_requested.is_set() && !is_explicit_gc(_requested_gc_cause); // This control loop iteration have seen this much allocations. - size_t allocs_seen = Atomic::xchg(&_allocs_seen, (size_t)0); + size_t allocs_seen = Atomic::xchg(&_allocs_seen, (size_t)0, memory_order_relaxed); // Check if we have seen a new target for soft max heap size. bool soft_max_changed = check_soft_max_changed(); @@ -595,7 +595,7 @@ void ShenandoahControlThread::notify_heap_changed() { void ShenandoahControlThread::pacing_notify_alloc(size_t words) { assert(ShenandoahPacing, "should only call when pacing is enabled"); - Atomic::add(&_allocs_seen, words); + Atomic::add(&_allocs_seen, words, memory_order_relaxed); } void ShenandoahControlThread::set_forced_counters_update(bool value) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp index d8866ebd6dd..745d6d88c87 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp @@ -179,7 +179,7 @@ size_t ShenandoahPacer::update_and_get_progress_history() { void ShenandoahPacer::restart_with(size_t non_taxable_bytes, double tax_rate) { size_t initial = (size_t)(non_taxable_bytes * tax_rate) >> LogHeapWordSize; STATIC_ASSERT(sizeof(size_t) <= sizeof(intptr_t)); - Atomic::xchg(&_budget, (intptr_t)initial); + Atomic::xchg(&_budget, (intptr_t)initial, memory_order_relaxed); Atomic::store(&_tax_rate, tax_rate); Atomic::inc(&_epoch); @@ -201,14 +201,14 @@ bool ShenandoahPacer::claim_for_alloc(size_t words, bool force) { return false; } new_val = cur - tax; - } while (Atomic::cmpxchg(&_budget, cur, new_val) != cur); + } while (Atomic::cmpxchg(&_budget, cur, new_val, memory_order_relaxed) != cur); return true; } void ShenandoahPacer::unpace_for_alloc(intptr_t epoch, size_t words) { assert(ShenandoahPacing, "Only be here when pacing is enabled"); - if (_epoch != epoch) { + if (Atomic::load(&_epoch) != epoch) { // Stale ticket, no need to unpace. return; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPacer.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahPacer.inline.hpp index c416d85234f..783755a4320 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.inline.hpp @@ -53,13 +53,13 @@ inline void ShenandoahPacer::report_internal(size_t words) { inline void ShenandoahPacer::report_progress_internal(size_t words) { assert(ShenandoahPacing, "Only be here when pacing is enabled"); STATIC_ASSERT(sizeof(size_t) <= sizeof(intptr_t)); - Atomic::add(&_progress, (intptr_t)words); + Atomic::add(&_progress, (intptr_t)words, memory_order_relaxed); } inline void ShenandoahPacer::add_budget(size_t words) { STATIC_ASSERT(sizeof(size_t) <= sizeof(intptr_t)); intptr_t inc = (intptr_t) words; - intptr_t new_budget = Atomic::add(&_budget, inc); + intptr_t new_budget = Atomic::add(&_budget, inc, memory_order_relaxed); // Was the budget replenished beyond zero? Then all pacing claims // are satisfied, notify the waiters. Avoid taking any locks here, -- GitLab From 745c0b9140d12a727b7ce1b2c0499c4be0a1dd96 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 15 Feb 2021 08:43:05 +0000 Subject: [PATCH 064/367] 8261493: Shenandoah: reconsider bitmap access memory ordering Reviewed-by: rkennke, zgu --- .../gc/shenandoah/shenandoahMarkBitMap.hpp | 2 -- .../shenandoahMarkBitMap.inline.hpp | 20 ++++--------------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.hpp index a37523f8197..a71cad75bae 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.hpp @@ -82,8 +82,6 @@ private: return map() + to_words_align_down(bit); } - static inline const bm_word_t load_word_ordered(const volatile bm_word_t* const addr, atomic_memory_order memory_order); - bool at(idx_t index) const { verify_index(index); return (*word_addr(index) & bit_mask(index)) != 0; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.inline.hpp index b9e0bb61f54..9dd3f729899 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkBitMap.inline.hpp @@ -46,7 +46,7 @@ inline bool ShenandoahMarkBitMap::mark_strong(HeapWord* heap_addr, bool& was_upg volatile bm_word_t* const addr = word_addr(bit); const bm_word_t mask = bit_mask(bit); const bm_word_t mask_weak = (bm_word_t)1 << (bit_in_word(bit) + 1); - bm_word_t old_val = load_word_ordered(addr, memory_order_conservative); + bm_word_t old_val = Atomic::load(addr); do { const bm_word_t new_val = old_val | mask; @@ -54,7 +54,7 @@ inline bool ShenandoahMarkBitMap::mark_strong(HeapWord* heap_addr, bool& was_upg assert(!was_upgraded, "Should be false already"); return false; // Someone else beat us to it. } - const bm_word_t cur_val = Atomic::cmpxchg(addr, old_val, new_val, memory_order_conservative); + const bm_word_t cur_val = Atomic::cmpxchg(addr, old_val, new_val, memory_order_relaxed); if (cur_val == old_val) { was_upgraded = (cur_val & mask_weak) != 0; return true; // Success. @@ -71,7 +71,7 @@ inline bool ShenandoahMarkBitMap::mark_weak(HeapWord* heap_addr) { volatile bm_word_t* const addr = word_addr(bit); const bm_word_t mask_weak = (bm_word_t)1 << (bit_in_word(bit) + 1); const bm_word_t mask_strong = (bm_word_t)1 << bit_in_word(bit); - bm_word_t old_val = load_word_ordered(addr, memory_order_conservative); + bm_word_t old_val = Atomic::load(addr); do { if ((old_val & mask_strong) != 0) { @@ -81,7 +81,7 @@ inline bool ShenandoahMarkBitMap::mark_weak(HeapWord* heap_addr) { if (new_val == old_val) { return false; // Someone else beat us to it. } - const bm_word_t cur_val = Atomic::cmpxchg(addr, old_val, new_val, memory_order_conservative); + const bm_word_t cur_val = Atomic::cmpxchg(addr, old_val, new_val, memory_order_relaxed); if (cur_val == old_val) { return true; // Success. } @@ -107,18 +107,6 @@ inline bool ShenandoahMarkBitMap::is_marked(HeapWord* addr) const { return (*word_addr(index) & mask) != 0; } -inline const ShenandoahMarkBitMap::bm_word_t ShenandoahMarkBitMap::load_word_ordered(const volatile bm_word_t* const addr, atomic_memory_order memory_order) { - if (memory_order == memory_order_relaxed || memory_order == memory_order_release) { - return Atomic::load(addr); - } else { - assert(memory_order == memory_order_acq_rel || - memory_order == memory_order_acquire || - memory_order == memory_order_conservative, - "unexpected memory ordering"); - return Atomic::load_acquire(addr); - } -} - template inline ShenandoahMarkBitMap::idx_t ShenandoahMarkBitMap::get_next_bit_impl(idx_t l_index, idx_t r_index) const { STATIC_ASSERT(flip == find_ones_flip || flip == find_zeros_flip); -- GitLab From df0897ea5763bd9312a1bbc050f941194b369d1f Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 15 Feb 2021 08:43:42 +0000 Subject: [PATCH 065/367] 8261504: Shenandoah: reconsider ShenandoahJavaThreadsIterator::claim memory ordering Reviewed-by: zgu --- src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp index 9aa10d17d32..91d5a278e1e 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp @@ -46,7 +46,7 @@ ShenandoahJavaThreadsIterator::ShenandoahJavaThreadsIterator(ShenandoahPhaseTimi } uint ShenandoahJavaThreadsIterator::claim() { - return Atomic::fetch_and_add(&_claimed, _stride); + return Atomic::fetch_and_add(&_claimed, _stride, memory_order_relaxed); } void ShenandoahJavaThreadsIterator::threads_do(ThreadClosure* cl, uint worker_id) { -- GitLab From c6eedda89e32e18f6274238dd6d3f14c2de8679d Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 15 Feb 2021 08:44:20 +0000 Subject: [PATCH 066/367] 8261500: Shenandoah: reconsider region live data memory ordering Reviewed-by: zgu --- .../share/gc/shenandoah/shenandoahHeapRegion.inline.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp index c02c00b7d4f..461aa30fcbe 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp @@ -80,7 +80,7 @@ inline void ShenandoahHeapRegion::increase_live_data_gc_words(size_t s) { } inline void ShenandoahHeapRegion::internal_increase_live_data(size_t s) { - size_t new_live_data = Atomic::add(&_live_data, s); + size_t new_live_data = Atomic::add(&_live_data, s, memory_order_relaxed); #ifdef ASSERT size_t live_bytes = new_live_data * HeapWordSize; size_t used_bytes = used(); @@ -90,11 +90,11 @@ inline void ShenandoahHeapRegion::internal_increase_live_data(size_t s) { } inline void ShenandoahHeapRegion::clear_live_data() { - Atomic::release_store_fence(&_live_data, (size_t)0); + Atomic::store(&_live_data, (size_t)0); } inline size_t ShenandoahHeapRegion::get_live_data_words() const { - return Atomic::load_acquire(&_live_data); + return Atomic::load(&_live_data); } inline size_t ShenandoahHeapRegion::get_live_data_bytes() const { -- GitLab From 3882fda83bebf4a8c8100fd59c37f04610491ce7 Mon Sep 17 00:00:00 2001 From: Leo Korinth Date: Mon, 15 Feb 2021 08:52:47 +0000 Subject: [PATCH 067/367] 8260414: Remove unused set_single_threaded_mode() method in task executor Reviewed-by: kbarrett, ayang --- src/hotspot/share/gc/shared/referenceProcessor.cpp | 5 ----- src/hotspot/share/gc/shared/referenceProcessor.hpp | 5 +---- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/hotspot/share/gc/shared/referenceProcessor.cpp b/src/hotspot/share/gc/shared/referenceProcessor.cpp index e2fed87ffb3..1779bdfabca 100644 --- a/src/hotspot/share/gc/shared/referenceProcessor.cpp +++ b/src/hotspot/share/gc/shared/referenceProcessor.cpp @@ -245,11 +245,6 @@ ReferenceProcessorStats ReferenceProcessor::process_discovered_references( process_phantom_refs(is_alive, keep_alive, complete_gc, task_executor, phase_times); } - if (task_executor != NULL) { - // Record the work done by the parallel workers. - task_executor->set_single_threaded_mode(); - } - phase_times->set_total_time_ms((os::elapsedTime() - start_time) * 1000); return stats; diff --git a/src/hotspot/share/gc/shared/referenceProcessor.hpp b/src/hotspot/share/gc/shared/referenceProcessor.hpp index 695bdf49053..1af26228dff 100644 --- a/src/hotspot/share/gc/shared/referenceProcessor.hpp +++ b/src/hotspot/share/gc/shared/referenceProcessor.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2021, 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 @@ -633,9 +633,6 @@ public: // Executes a task using worker threads. virtual void execute(ProcessTask& task, uint ergo_workers) = 0; - - // Switch to single threaded mode. - virtual void set_single_threaded_mode() { }; }; // Abstract reference processing task to execute. -- GitLab From 2e610f53c1db775cb0a65879d89273451e3366b7 Mon Sep 17 00:00:00 2001 From: Stanimir Stamenkov Date: Mon, 15 Feb 2021 16:16:50 +0000 Subject: [PATCH 068/367] 8260687: Inherited font size is smaller than expected when using StyleSheet to add styles Co-authored-by: Alexey Ivanov Reviewed-by: psadhukhan, aivanov, kizune --- .../javax/swing/text/html/StyleSheet.java | 7 +- .../8260687/BodyInheritedFontSize.java | 169 ++++++++++++++++++ .../html/StyleSheet/TestWrongCSSFontSize.java | 48 +++-- 3 files changed, 211 insertions(+), 13 deletions(-) create mode 100644 test/jdk/javax/swing/text/html/StyleSheet/8260687/BodyInheritedFontSize.java diff --git a/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java b/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java index ee2946b5938..3352e0e79f8 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/StyleSheet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021, 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 @@ -2813,7 +2813,10 @@ public class StyleSheet extends StyleContext { ((StyleConstants)key); if (cssKey != null) { Object value = doGetAttribute(cssKey); - if (value instanceof CSS.CssValue) { + if (value instanceof CSS.FontSize) { + return ((CSS.FontSize)value) + .getValue(this, StyleSheet.this); + } else if (value instanceof CSS.CssValue) { return ((CSS.CssValue)value).toStyleConstants ((StyleConstants)key, host); } diff --git a/test/jdk/javax/swing/text/html/StyleSheet/8260687/BodyInheritedFontSize.java b/test/jdk/javax/swing/text/html/StyleSheet/8260687/BodyInheritedFontSize.java new file mode 100644 index 00000000000..50030df2082 --- /dev/null +++ b/test/jdk/javax/swing/text/html/StyleSheet/8260687/BodyInheritedFontSize.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2021, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; +import javax.swing.text.AbstractDocument.AbstractElement; +import javax.swing.text.Document; +import javax.swing.text.GlyphView; +import javax.swing.text.View; +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.StyleSheet; + +/* + * @test + * @bug 8260687 + * @summary Tests inherited font-size is the same as explicitly specified + * @run main BodyInheritedFontSize + */ +public class BodyInheritedFontSize { + private static final String HTML_TEXT = """ + + +

    100% from body

    +

    16pt inherited from body

    +

    16pt paragraph

    + + + """; + + private static JEditorPane createEditorPane(boolean w3cUnits, boolean showFrame) { + JEditorPane htmlPane = new JEditorPane(); + htmlPane.setEditable(false); + + if (w3cUnits) { + htmlPane.putClientProperty(JEditorPane.W3C_LENGTH_UNITS, Boolean.TRUE); + } + + HTMLEditorKit kit = new HTMLEditorKit(); + htmlPane.setEditorKit(kit); + + StyleSheet styleSheet = kit.getStyleSheet(); + styleSheet.addRule("body { font-family: sans-serif; font-size: 16pt; }"); + + Document doc = kit.createDefaultDocument(); + htmlPane.setDocument(doc); + htmlPane.setText(HTML_TEXT); + + if (showFrame) { + JFrame frame = new JFrame("HtmlFontSizeGUITest: " + + (w3cUnits ? "w3c" : "std")); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.add(new JScrollPane(htmlPane), BorderLayout.CENTER); + frame.setLocationRelativeTo(null); + frame.pack(); + frame.setVisible(true); + } + + // Ignore the result but perform layout + htmlPane.getPreferredSize(); + + return htmlPane; + } + + public static void main(String[] args) throws Exception { + final List argsList = Arrays.asList(args); + final boolean showFrame = toShowFrame(argsList); + final boolean debugPrint = toDebugPrint(argsList); + + final List exceptions = new ArrayList<>(2); + SwingUtilities.invokeAndWait(() -> { + for (boolean w3cUnits : new boolean[] {true, false}) { + JEditorPane htmlPane = createEditorPane(w3cUnits, showFrame); + try { + checkFontSize(htmlPane, w3cUnits, debugPrint); + } catch (Exception e) { + exceptions.add(e); + } + } + }); + if (exceptions.size() > 0) { + exceptions.forEach(System.err::println); + throw new RuntimeException( + "Test failed: " + exceptions.get(0).getMessage(), + exceptions.get(0)); + } + } + + private static boolean toShowFrame(final List argsList) { + return argsList.contains("-show"); + } + + private static boolean toDebugPrint(final List argsList) { + return argsList.contains("-print"); + } + + private static void checkFontSize(JEditorPane htmlPane, + boolean w3cUnits, + boolean debugPrint) { + final View rootView = htmlPane.getUI().getRootView(htmlPane); + final View boxView = rootView.getView(0); + final View bodyView = boxView.getView(1); + + int fontSizePercentage = getViewFontSize(bodyView.getView(0), debugPrint); + int fontSizeInherited = getViewFontSize(bodyView.getView(1), debugPrint); + int fontSizeExplicit = getViewFontSize(bodyView.getView(2), debugPrint); + if (debugPrint) { + System.out.println("w3cUnits: " + w3cUnits + "\n" + + "Percentage: " + fontSizePercentage + "\n" + + "Inherited: " + fontSizeInherited + "\n" + + "Explicit: " + fontSizeExplicit + "\n"); + } + if (fontSizeInherited != fontSizeExplicit + || fontSizePercentage != fontSizeExplicit) { + throw new RuntimeException("The font size is different with " + + (w3cUnits ? "w3cUnits" : "stdUnits") + ": " + + "Percentage: " + fontSizePercentage + " vs. " + + "Inherited: " + fontSizeInherited + " vs. " + + "Explicit: " + fontSizeExplicit); + } + } + + private static int getViewFontSize(View paragraphView, boolean debugPrint) { + GlyphView inlineView = findFirstTextRun(paragraphView); + int fontSize = inlineView.getFont().getSize(); + if (debugPrint) { + ((AbstractElement) inlineView.getElement()).dump(System.out, 1); + } + return fontSize; + } + + private static GlyphView findFirstTextRun(View view) { + if (view instanceof GlyphView) { + return (GlyphView) view; + } + for (int i = 0; i < view.getViewCount(); i++) { + GlyphView textRun = findFirstTextRun(view.getView(i)); + if (textRun != null) { + return textRun; + } + } + return null; + } +} diff --git a/test/jdk/javax/swing/text/html/StyleSheet/TestWrongCSSFontSize.java b/test/jdk/javax/swing/text/html/StyleSheet/TestWrongCSSFontSize.java index b1fadc2d621..4c289cdcf2b 100644 --- a/test/jdk/javax/swing/text/html/StyleSheet/TestWrongCSSFontSize.java +++ b/test/jdk/javax/swing/text/html/StyleSheet/TestWrongCSSFontSize.java @@ -26,6 +26,7 @@ import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import javax.imageio.ImageIO; @@ -39,10 +40,11 @@ import javax.swing.text.View; * @bug 8257664 * @summary Tests inherited font-size with parent percentage specification. * @run main TestWrongCSSFontSize + * @run main TestWrongCSSFontSize -w3cUnits */ public class TestWrongCSSFontSize { - private static String text = + private static final String TEXT = "