From 73cefe1c8becf5022e6895988dcc678018ad8beb Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Wed, 19 Jun 2024 04:00:37 +0000 Subject: [PATCH 01/61] 8334258: Compiler erronousely allows access to instance variable in argument expression of a constructor invocation Reviewed-by: jpai Backport-of: e227c7e37d4de0656f013f3a936b1acfa56cc2e0 --- .../com/sun/tools/javac/comp/Resolve.java | 23 +++++++++++-------- .../SuperInit/EarlyAssignmentNoPreview1.java | 21 +++++++++++++++++ .../SuperInit/EarlyAssignmentNoPreview1.out | 2 ++ .../SuperInit/EarlyAssignmentNoPreview2.java | 21 +++++++++++++++++ .../SuperInit/EarlyAssignmentNoPreview2.out | 2 ++ .../SuperInit/EarlyAssignmentNoPreview3.java | 21 +++++++++++++++++ .../SuperInit/EarlyAssignmentNoPreview3.out | 2 ++ 7 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview1.java create mode 100644 test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview1.out create mode 100644 test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview2.java create mode 100644 test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview2.out create mode 100644 test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview3.java create mode 100644 test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview3.out diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index ac8374a9a55..5b60a7383aa 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, 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 @@ -100,6 +100,7 @@ public class Resolve { DeferredAttr deferredAttr; Check chk; Infer infer; + Preview preview; ClassFinder finder; ModuleFinder moduleFinder; Types types; @@ -135,7 +136,7 @@ protected Resolve(Context context) { moduleFinder = ModuleFinder.instance(context); types = Types.instance(context); diags = JCDiagnostic.Factory.instance(context); - Preview preview = Preview.instance(context); + preview = Preview.instance(context); Source source = Source.instance(context); Options options = Options.instance(context); compactMethodDiags = options.isSet(Option.XDIAGS, "compact") || @@ -1480,10 +1481,11 @@ else throw new FatalError( /** Find unqualified variable or field with given name. * Synthetic fields always skipped. + * @param pos The position to use for error reporting. * @param env The current environment. * @param name The name of the variable or field. */ - Symbol findVar(Env env, Name name) { + Symbol findVar(DiagnosticPosition pos, Env env, Name name) { Symbol bestSoFar = varNotFound; Env env1 = env; boolean staticOnly = false; @@ -1508,7 +1510,7 @@ Symbol findVar(Env env, Name name) { (sym.flags() & STATIC) == 0) { if (staticOnly) return new StaticError(sym); - if (env1.info.ctorPrologue && !isAllowedEarlyReference(env1, (VarSymbol)sym)) + if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) return new RefBeforeCtorCalledError(sym); } return sym; @@ -2421,15 +2423,15 @@ Symbol findType(Env env, Name name) { * (a subset of VAL, TYP, PCK). */ Symbol findIdent(DiagnosticPosition pos, Env env, Name name, KindSelector kind) { - return checkNonExistentType(checkRestrictedType(pos, findIdentInternal(env, name, kind), name)); + return checkNonExistentType(checkRestrictedType(pos, findIdentInternal(pos, env, name, kind), name)); } - Symbol findIdentInternal(Env env, Name name, KindSelector kind) { + Symbol findIdentInternal(DiagnosticPosition pos, Env env, Name name, KindSelector kind) { Symbol bestSoFar = typeNotFound; Symbol sym; if (kind.contains(KindSelector.VAL)) { - sym = findVar(env, name); + sym = findVar(pos, env, name); if (sym.exists()) return sym; else bestSoFar = bestOf(bestSoFar, sym); } @@ -3776,7 +3778,7 @@ Symbol resolveSelf(DiagnosticPosition pos, if (sym != null) { if (staticOnly) sym = new StaticError(sym); - else if (env1.info.ctorPrologue && !isAllowedEarlyReference(env1, (VarSymbol)sym)) + else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) sym = new RefBeforeCtorCalledError(sym); return accessBase(sym, pos, env.enclClass.sym.type, name, true); @@ -3845,7 +3847,7 @@ private List pruneInterfaces(Type t) { * We also don't verify that the field has no initializer, which is required. * To catch those cases, we rely on similar logic in Attr.checkAssignable(). */ - private boolean isAllowedEarlyReference(Env env, VarSymbol v) { + private boolean isAllowedEarlyReference(DiagnosticPosition pos, Env env, VarSymbol v) { // Check assumptions Assert.check(env.info.ctorPrologue); @@ -3867,6 +3869,9 @@ private boolean isAllowedEarlyReference(Env env, VarSymbol v) { if (isEarlyReference(env, base, v) && v.owner != env.enclClass.sym) return false; + // The flexible constructors feature must be enabled + preview.checkSourceLevel(pos, Feature.FLEXIBLE_CONSTRUCTORS); + // OK return true; } diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview1.java b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview1.java new file mode 100644 index 00000000000..abb6bacbc8f --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview1.java @@ -0,0 +1,21 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8334258 + * @summary Disallow early assignment if FLEXIBLE_CONSTRUCTORS preview feature is not enabled + * @compile/fail/ref=EarlyAssignmentNoPreview1.out -XDrawDiagnostics EarlyAssignmentNoPreview1.java + */ +public class EarlyAssignmentNoPreview1 { + + Runnable r; + + public EarlyAssignmentNoPreview1() { + this(r = () -> System.out.println("hello")); + } + + public EarlyAssignmentNoPreview1(Runnable r) { + } + + public static void main(String[] args) { + new EarlyAssignmentNoPreview1(); + } +} diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview1.out b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview1.out new file mode 100644 index 00000000000..6c5afbbd12b --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview1.out @@ -0,0 +1,2 @@ +EarlyAssignmentNoPreview1.java:12:14: compiler.err.preview.feature.disabled: (compiler.misc.feature.flexible.constructors) +1 error diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview2.java b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview2.java new file mode 100644 index 00000000000..3c33734f42a --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview2.java @@ -0,0 +1,21 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8334258 + * @summary Disallow early assignment if FLEXIBLE_CONSTRUCTORS preview feature is not enabled + * @compile/fail/ref=EarlyAssignmentNoPreview2.out -XDrawDiagnostics EarlyAssignmentNoPreview2.java + */ +public class EarlyAssignmentNoPreview2 { + + Runnable r; + + public EarlyAssignmentNoPreview2() { + this(this.r = () -> System.out.println("hello")); + } + + public EarlyAssignmentNoPreview2(Runnable r) { + } + + public static void main(String[] args) { + new EarlyAssignmentNoPreview2(); + } +} diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview2.out b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview2.out new file mode 100644 index 00000000000..38fb885684e --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview2.out @@ -0,0 +1,2 @@ +EarlyAssignmentNoPreview2.java:12:14: compiler.err.preview.feature.disabled: (compiler.misc.feature.flexible.constructors) +1 error diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview3.java b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview3.java new file mode 100644 index 00000000000..f6269f2cb1f --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview3.java @@ -0,0 +1,21 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8334258 + * @summary Disallow early assignment if FLEXIBLE_CONSTRUCTORS preview feature is not enabled + * @compile/fail/ref=EarlyAssignmentNoPreview3.out -XDrawDiagnostics EarlyAssignmentNoPreview3.java + */ +public class EarlyAssignmentNoPreview3 { + + Runnable r; + + public EarlyAssignmentNoPreview3() { + this(EarlyAssignmentNoPreview3.this.r = () -> System.out.println("hello")); + } + + public EarlyAssignmentNoPreview3(Runnable r) { + } + + public static void main(String[] args) { + new EarlyAssignmentNoPreview3(); + } +} diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview3.out b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview3.out new file mode 100644 index 00000000000..def9f4f3722 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignmentNoPreview3.out @@ -0,0 +1,2 @@ +EarlyAssignmentNoPreview3.java:12:39: compiler.err.preview.feature.disabled: (compiler.misc.feature.flexible.constructors) +1 error From 0a07c23f20ef3d1d745197f275303f5d34c44bda Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Wed, 19 Jun 2024 04:00:58 +0000 Subject: [PATCH 02/61] 8334043: VerifyError when inner class is accessed in prologue Reviewed-by: jpai Backport-of: e1fc5b44104e667a5458379e179caba2b0d2321d --- .../classes/com/sun/tools/javac/comp/Resolve.java | 15 ++++++++++++++- .../tools/javac/SuperInit/EarlyAssignments.java | 11 +++++++++++ .../tools/javac/SuperInit/EarlyAssignments.out | 3 ++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index 5b60a7383aa..079a0bc5c6a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -3863,7 +3863,20 @@ private boolean isAllowedEarlyReference(DiagnosticPosition pos, Env // Get the symbol's qualifier, if any JCExpression lhs = TreeInfo.skipParens(assign.lhs); - JCExpression base = lhs instanceof JCFieldAccess select ? select.selected : null; + JCExpression base; + switch (lhs.getTag()) { + case IDENT: + base = null; + break; + case SELECT: + JCFieldAccess select = (JCFieldAccess)lhs; + base = select.selected; + if (!TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base)) + return false; + break; + default: + return false; + } // If an early reference, the field must not be declared in a superclass if (isEarlyReference(env, base, v) && v.owner != env.enclClass.sym) diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignments.java b/test/langtools/tools/javac/SuperInit/EarlyAssignments.java index 89a13ccf0ff..c3cad5d7016 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyAssignments.java +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignments.java @@ -158,4 +158,15 @@ public Inner7() { super(); } } + + public static class Inner8 { + class Inner8a { + int x; + } + + public Inner8() { + this.new Inner8a().x = 1; // FAIL - illegal early access + super(); + } + } } diff --git a/test/langtools/tools/javac/SuperInit/EarlyAssignments.out b/test/langtools/tools/javac/SuperInit/EarlyAssignments.out index 81b4f20b505..38182c2d312 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyAssignments.out +++ b/test/langtools/tools/javac/SuperInit/EarlyAssignments.out @@ -23,6 +23,7 @@ EarlyAssignments.java:134:17: compiler.err.cant.ref.before.ctor.called: super EarlyAssignments.java:139:23: compiler.err.cant.ref.before.ctor.called: this EarlyAssignments.java:148:13: compiler.err.cant.assign.initialized.before.ctor.called: x EarlyAssignments.java:157:13: compiler.err.cant.assign.val.to.var: final, x +EarlyAssignments.java:168:13: compiler.err.cant.ref.before.ctor.called: this - compiler.note.preview.filename: EarlyAssignments.java, DEFAULT - compiler.note.preview.recompile -25 errors +26 errors From b7fbcee15437cb18692c9957254861ca7fae3dba Mon Sep 17 00:00:00 2001 From: Richard Reingruber Date: Thu, 20 Jun 2024 07:09:24 +0000 Subject: [PATCH 03/61] 8334402: ProblemList test/hotspot/jtreg/compiler/c2/TestMergeStores.java on big endian platforms Reviewed-by: kvn --- test/hotspot/jtreg/ProblemList.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index 7df34e4443d..c1b7551f7d5 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -64,6 +64,8 @@ compiler/rtm/locking/TestUseRTMXendForLockBusy.java 8183263 generic-x64,generic- compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java 8183263 generic-x64,generic-i586 compiler/c2/Test8004741.java 8235801 generic-all +compiler/c2/TestMergeStores.java#id0 8331311 generic-ppc64,linux-s390x +compiler/c2/TestMergeStores.java#id1 8331311 generic-ppc64,linux-s390x compiler/c2/irTests/TestDuplicateBackedge.java 8318904 generic-all compiler/codecache/jmx/PoolsIndependenceTest.java 8264632 macosx-all From 5ce4c8109d25c0008c38fab5ad2ed5168098e315 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Thu, 20 Jun 2024 13:55:55 +0000 Subject: [PATCH 04/61] 8304732: jdk/jfr/api/consumer/recordingstream/TestStop.java failed again with "Expected outer stream to have 3 events" Reviewed-by: mgronlun Backport-of: 856931d01f14b1c665c04e05d5637b8237c56988 --- .../classes/jdk/jfr/internal/HiddenWait.java | 32 +++++++++++++ .../share/classes/jdk/jfr/internal/JVM.java | 13 ++--- .../classes/jdk/jfr/internal/JVMSupport.java | 8 +--- .../jdk/jfr/internal/MetadataRepository.java | 23 +++++++-- .../consumer/AbstractEventStream.java | 6 +-- .../consumer/EventDirectoryStream.java | 44 ++++++++++------- .../internal/consumer/EventFileStream.java | 4 +- .../internal/management/StreamBarrier.java | 15 ++++-- .../classes/jdk/jfr/internal/util/Utils.java | 6 ++- .../consumer/recordingstream/TestStop.java | 47 +++++++++++-------- 10 files changed, 136 insertions(+), 62 deletions(-) create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/internal/HiddenWait.java diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/HiddenWait.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/HiddenWait.java new file mode 100644 index 00000000000..26505990332 --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/HiddenWait.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024, 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.internal; + +/** + * The HiddenWait class is used to exclude jdk.JavaMonitorWait events + * from being generated when Object.wait() is called on an object of this type. + */ +public final class HiddenWait { +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java index 02edfd1e5ab..2e600c8c029 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,14 +41,10 @@ public final class JVM { static final long RESERVED_CLASS_ID_LIMIT = 500; - private static class ChunkRotationMonitor {} - /* * The JVM uses the chunk rotation monitor to notify Java that a rotation is warranted. - * The monitor type is used to exclude jdk.JavaMonitorWait events from being generated - * when Object.wait() is called on this monitor. */ - public static final Object CHUNK_ROTATION_MONITOR = new ChunkRotationMonitor(); + public static final Object CHUNK_ROTATION_MONITOR = new HiddenWait(); private static volatile boolean nativeOK; @@ -174,6 +170,11 @@ private static class ChunkRotationMonitor {} */ public static native long getTicksFrequency(); + /** + * Returns the same clock that sets the start time of a chunk (in nanos). + */ + public static native long nanosNow(); + /** * Write message to log. Should swallow null or empty message, and be able * to handle any Java character and not crash with very large message diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java index 036d49e6e0e..345d2fdcc8d 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, 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 @@ -119,11 +119,7 @@ private static void awaitUniqueTimestamp() { lastTimestamp = time; return; } - try { - Thread.sleep(0, 100); - } catch (InterruptedException iex) { - // ignore - } + Utils.takeNap(1); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java index 7031718cb28..75be70a0d1d 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java @@ -64,6 +64,8 @@ public final class MetadataRepository { private boolean unregistered; private long lastUnloaded = -1; + private long lastMillis; + public MetadataRepository() { initializeJVMEventTypes(); } @@ -313,11 +315,12 @@ synchronized Instant setOutput(String filename) { if (staleMetadata) { storeDescriptorInJVM(); } + // Each chunk needs a unique timestamp. If two chunks get the same + // timestamp, the parser may stop prematurely at an earlier chunk. + // The resolution needs to be measured in milliseconds as this + // is what RecordingInfo:getStopTime() returns. + awaitEpochMilliShift(); JVM.setOutput(filename); - // Each chunk needs a unique start timestamp and - // if the clock resolution is low, two chunks may - // get the same timestamp. Utils.getChunkStartNanos() - // ensures the timestamp is unique for the next chunk long chunkStart = JVMSupport.getChunkStartNanos(); if (filename != null) { RepositoryFiles.notifyNewFile(); @@ -332,6 +335,18 @@ synchronized Instant setOutput(String filename) { return Utils.epochNanosToInstant(chunkStart); } + private void awaitEpochMilliShift() { + while (true) { + long nanos = JVM.nanosNow(); + long millis = Utils.epochNanosToInstant(nanos).toEpochMilli(); + if (millis != lastMillis) { + lastMillis = millis; + return; + } + Utils.takeNap(1); + } + } + private void unregisterUnloaded() { long unloaded = JVM.getUnloadedEventClassCount(); if (this.lastUnloaded != unloaded) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/AbstractEventStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/AbstractEventStream.java index e3b43635e33..cdfc8f017a6 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/AbstractEventStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/AbstractEventStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, 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 @@ -205,7 +205,7 @@ public final void awaitTermination(Duration timeout) throws InterruptedException protected abstract void process() throws IOException; - protected abstract boolean isRecording(); + protected abstract boolean isRecordingStream(); protected final void closeParser() { parserState.close(); @@ -249,7 +249,7 @@ private void startInternal(long startNanos) { if (streamConfiguration.started) { throw new IllegalStateException("Event stream can only be started once"); } - if (isRecording() && streamConfiguration.startTime == null) { + if (isRecordingStream() && streamConfiguration.startTime == null) { streamConfiguration.setStartNanos(startNanos); } streamConfiguration.setStarted(true); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventDirectoryStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventDirectoryStream.java index 3ed1c4c8d35..bc9aa7987c3 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventDirectoryStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventDirectoryStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, 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,9 +33,11 @@ import java.util.Comparator; import java.util.List; import java.util.Objects; +import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import jdk.jfr.Configuration; +import jdk.jfr.RecordingState; import jdk.jfr.consumer.RecordedEvent; import jdk.jfr.internal.JVM; import jdk.jfr.internal.LogLevel; @@ -59,6 +61,7 @@ public final class EventDirectoryStream extends AbstractEventStream { private final FileAccess fileAccess; private final PlatformRecording recording; private final StreamBarrier barrier = new StreamBarrier(); + private final AtomicLong streamId = new AtomicLong(); private ChunkParser currentParser; private long currentChunkStartNanos; private RecordedEvent[] sortedCache; @@ -80,6 +83,8 @@ public EventDirectoryStream( } this.fileAccess = Objects.requireNonNull(fileAccess); this.repositoryFiles = new RepositoryFiles(fileAccess, p, allowSubDirectories); + this.streamId.incrementAndGet(); + Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, "Stream " + streamId + " started."); } @Override @@ -137,13 +142,14 @@ protected void processRecursionSafe() throws IOException { Dispatcher lastDisp = null; Dispatcher disp = dispatcher(); Path path; - boolean validStartTime = isRecording() || disp.startTime != null; + boolean validStartTime = isRecordingStream() || disp.startTime != null; if (validStartTime) { path = repositoryFiles.firstPath(disp.startNanos, true); } else { path = repositoryFiles.lastPath(true); } if (path == null) { // closed + logStreamEnd("no first chunk file found."); return; } currentChunkStartNanos = repositoryFiles.getTimestamp(path); @@ -168,7 +174,10 @@ protected void processRecursionSafe() throws IOException { processUnordered(disp); } currentParser.resetCache(); - if (currentParser.getLastFlush() > filterEnd) { + long lastFlush = currentParser.getLastFlush(); + if (lastFlush > filterEnd) { + logStreamEnd("end time at " + filterEnd + + "ns (epoch), parser at " + lastFlush + "ns (epoch)."); return; } } @@ -177,20 +186,25 @@ protected void processRecursionSafe() throws IOException { barrier.check(); // block if recording is being stopped if (barrier.getStreamEnd() <= endMillis) { + String msg = "stopped at " + barrier.getStreamEnd() + "ms (epoch), "; + msg += "parser at " + endMillis + "ms (epoch), " + endNanos + "ns (epoch)"; + logStreamEnd(msg); return; } - if (!barrier.hasStreamEnd() && isLastChunk()) { - // Recording was stopped/closed externally, and no more data to process. - return; + if (isRecordingStream()) { + if (recording.getState() == RecordingState.STOPPED && !barrier.used()) { + logStreamEnd("recording stopped externally."); + return; + } } if (repositoryFiles.hasFixedPath() && currentParser.isFinalChunk()) { - // JVM process exited/crashed, or repository migrated to an unknown location + logStreamEnd("JVM process exited/crashed, or repository migrated to an unknown location."); return; } if (isClosed()) { - // Stream was closed + logStreamEnd("stream closed."); return; } long durationNanos = currentParser.getChunkDuration(); @@ -205,7 +219,8 @@ protected void processRecursionSafe() throws IOException { } path = repositoryFiles.nextPath(currentChunkStartNanos + durationNanos, true); if (path == null) { - return; // stream closed + logStreamEnd("no more chunk files found."); + return; } currentChunkStartNanos = repositoryFiles.getTimestamp(path); input.setFile(path); @@ -217,15 +232,12 @@ protected void processRecursionSafe() throws IOException { } } - - private boolean isLastChunk() { - if (!isRecording()) { - return false; - } - return recording.getFinalChunkStartNanos() >= currentParser.getStartNanos(); + private void logStreamEnd(String text) { + String msg = "Stream " + streamId + " ended, " + text; + Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, msg); } - protected boolean isRecording() { + protected boolean isRecordingStream() { return recording != null; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventFileStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventFileStream.java index 9ecaf2a6075..f03e8d8acb4 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventFileStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/EventFileStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, 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 @@ -73,7 +73,7 @@ public void close() { } @Override - protected boolean isRecording() { + protected boolean isRecordingStream() { return false; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/StreamBarrier.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/StreamBarrier.java index ed94a908d47..0b3132da217 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/StreamBarrier.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/StreamBarrier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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,6 +41,7 @@ public final class StreamBarrier implements Closeable { private boolean activated = false; + private boolean used = false; private long end = Long.MAX_VALUE; // Blocks thread until barrier is deactivated @@ -62,12 +63,9 @@ public synchronized long getStreamEnd() { return end; } - public synchronized boolean hasStreamEnd() { - return end != Long.MAX_VALUE; - } - public synchronized void activate() { activated = true; + used = true; } @Override @@ -75,4 +73,11 @@ public synchronized void close() throws IOException { activated = false; this.notifyAll(); } + + /** + * Returns {@code true) if barrier is, or has been, in active state, {@code false) otherwise. + */ + public synchronized boolean used() { + return used; + } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java index 0049662e9a1..5e04a25fe7d 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/Utils.java @@ -48,6 +48,7 @@ import jdk.jfr.Event; import jdk.jfr.EventType; import jdk.jfr.RecordingState; +import jdk.jfr.internal.HiddenWait; import jdk.jfr.internal.LogLevel; import jdk.jfr.internal.LogTag; import jdk.jfr.internal.Logger; @@ -351,8 +352,11 @@ private static boolean isSupportedType(Class type) { } public static void takeNap(long millis) { + HiddenWait hiddenWait = new HiddenWait(); try { - Thread.sleep(millis); + synchronized(hiddenWait) { + hiddenWait.wait(millis); + } } catch (InterruptedException e) { // ok } diff --git a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStop.java b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStop.java index 58dcbbcbe20..36bbaa3c557 100644 --- a/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStop.java +++ b/test/jdk/jdk/jfr/api/consumer/recordingstream/TestStop.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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,7 +41,7 @@ * @requires vm.hasJFR * @library /test/lib /test/jdk * @build jdk.jfr.api.consumer.recordingstream.EventProducer - * @run main/othervm jdk.jfr.api.consumer.recordingstream.TestStop + * @run main/othervm -Xlog:system+parser+jfr=info jdk.jfr.api.consumer.recordingstream.TestStop */ public class TestStop { static class StopEvent extends Event { @@ -139,41 +139,50 @@ private static void testNestedStop() throws Exception { Path fileInner = Path.of("inner.jfr"); inner.dump(fileInner); outer.dump(fileOuter); - System.out.println("Outer dump:"); var dumpOuter = RecordingFile.readAllEvents(fileOuter); - for (RecordedEvent e : dumpOuter) { - System.out.println(eventToText(e)); - } - System.out.println("Inner dump:"); var dumpInner = RecordingFile.readAllEvents(fileInner); - for (RecordedEvent e : dumpInner) { - System.out.println(eventToText(e)); - } - System.out.println(); - System.out.println("Outer stream:"); - for (String s : outerStream) { - System.out.println(s); - } - System.out.println("Inner stream:"); - for (String s : innerStream) { - System.out.println(s); - } + if (dumpOuter.size() != 3) { + log(outerStream, innerStream, dumpOuter, dumpInner); throw new AssertionError("Expected outer dump to have 3 events"); } if (outerStream.size() != 3) { + log(outerStream, innerStream, dumpOuter, dumpInner); throw new AssertionError("Expected outer stream to have 3 events"); } if (dumpInner.size() != 1) { + log(outerStream, innerStream, dumpOuter, dumpInner); throw new AssertionError("Expected inner dump to have 1 event"); } if (innerStream.size() != 1) { + log(outerStream, innerStream, dumpOuter, dumpInner); throw new AssertionError("Expected inner stream to have 1 event"); } } } } + private static void log(List outerStream, List innerStream, List dumpOuter, + List dumpInner) { + System.out.println("Outer dump:"); + for (RecordedEvent e : dumpOuter) { + System.out.println(eventToText(e)); + } + System.out.println("Inner dump:"); + for (RecordedEvent e : dumpInner) { + System.out.println(eventToText(e)); + } + System.out.println(); + System.out.println("Outer stream:"); + for (String s : outerStream) { + System.out.println(s); + } + System.out.println("Inner stream:"); + for (String s : innerStream) { + System.out.println(s); + } + } + private static String eventToText(RecordedEvent event) { Instant timestamp = event.getEndTime(); long s = timestamp.getEpochSecond(); From c82ec31109ed960c0453a6656b6ef0a6da065694 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Thu, 20 Jun 2024 18:02:13 +0000 Subject: [PATCH 05/61] 8334488: Improve error for illegal early access from nested class Reviewed-by: mcimadamore Backport-of: 7b3a96d57023e8a7cf495e2d7c551976f0e5656b --- .../classes/com/sun/tools/javac/comp/Attr.java | 3 +-- .../classes/com/sun/tools/javac/comp/Enter.java | 1 + .../AnonymousInSuperCallNegTest.out | 2 +- .../tools/javac/LocalClassCtorPrologue.out | 2 +- .../EarlyInnerAccessErrorMessageTest.java | 16 ++++++++++++++++ .../EarlyInnerAccessErrorMessageTest.out | 4 ++++ .../tools/javac/SuperInit/EarlyLocalClass.out | 2 +- 7 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.java create mode 100644 test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.out diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 533541bd108..08c37fc5aa4 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -950,7 +950,6 @@ public void visitClassDef(JCClassDecl tree) { Optional.ofNullable(env.info.attributionMode.isSpeculative ? argumentAttr.withLocalCacheContext() : null); boolean ctorProloguePrev = env.info.ctorPrologue; - env.info.ctorPrologue = false; try { // Local and anonymous classes have not been entered yet, so we need to // do it now. @@ -995,7 +994,7 @@ public void visitMethodDef(JCMethodDecl tree) { Lint lint = env.info.lint.augment(m); Lint prevLint = chk.setLint(lint); boolean ctorProloguePrev = env.info.ctorPrologue; - env.info.ctorPrologue = false; + Assert.check(!env.info.ctorPrologue); MethodSymbol prevMethod = chk.setMethod(m); try { deferredLintHandler.flush(tree.pos(), lint); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java index 7478ef1c907..926be3b6e26 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java @@ -209,6 +209,7 @@ public Env classEnv(JCClassDecl tree, Env env) { localEnv.info.lint = null; // leave this to be filled in by Attr, // when annotations have been processed localEnv.info.isAnonymousDiamond = TreeInfo.isDiamond(env.tree); + localEnv.info.ctorPrologue = false; return localEnv; } diff --git a/test/langtools/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out b/test/langtools/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out index 140521689a0..c04b45bce1e 100644 --- a/test/langtools/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out +++ b/test/langtools/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out @@ -1,2 +1,2 @@ -AnonymousInSuperCallNegTest.java:23:49: compiler.err.no.encl.instance.of.type.in.scope: AnonymousInSuperCallNegTest.JavacBug +AnonymousInSuperCallNegTest.java:23:49: compiler.err.cant.ref.before.ctor.called: x 1 error diff --git a/test/langtools/tools/javac/LocalClassCtorPrologue.out b/test/langtools/tools/javac/LocalClassCtorPrologue.out index f1a999af491..65f3418825d 100644 --- a/test/langtools/tools/javac/LocalClassCtorPrologue.out +++ b/test/langtools/tools/javac/LocalClassCtorPrologue.out @@ -1,4 +1,4 @@ -LocalClassCtorPrologue.java:16:17: compiler.err.no.encl.instance.of.type.in.scope: LocalClassCtorPrologue +LocalClassCtorPrologue.java:16:17: compiler.err.cant.ref.before.ctor.called: x - compiler.note.preview.filename: LocalClassCtorPrologue.java, DEFAULT - compiler.note.preview.recompile 1 error diff --git a/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.java b/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.java new file mode 100644 index 00000000000..a8ee3a2aea5 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8334488 + * @summary Verify the error message generated for early access from inner class + * @compile/fail/ref=EarlyInnerAccessErrorMessageTest.out -XDrawDiagnostics EarlyInnerAccessErrorMessageTest.java + * @enablePreview + */ +public class EarlyInnerAccessErrorMessageTest { + int x; + EarlyInnerAccessErrorMessageTest() { + class Inner { + { System.out.println(x); } + } + super(); + } +} diff --git a/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.out b/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.out new file mode 100644 index 00000000000..a8d690a4c23 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.out @@ -0,0 +1,4 @@ +EarlyInnerAccessErrorMessageTest.java:12:34: compiler.err.cant.ref.before.ctor.called: x +- compiler.note.preview.filename: EarlyInnerAccessErrorMessageTest.java, DEFAULT +- compiler.note.preview.recompile +1 error diff --git a/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out b/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out index 390b68ea2c9..ee01f9c403d 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out +++ b/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out @@ -1,4 +1,4 @@ -EarlyLocalClass.java:12:32: compiler.err.no.encl.instance.of.type.in.scope: EarlyLocalClass +EarlyLocalClass.java:12:32: compiler.err.cant.ref.before.ctor.called: this - compiler.note.preview.filename: EarlyLocalClass.java, DEFAULT - compiler.note.preview.recompile 1 error From dac518fa08680f21791ee714593a68b0c8c80dde Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Fri, 21 Jun 2024 10:09:14 +0000 Subject: [PATCH 06/61] 8333344: JMX attaching of Subject does not work when security manager not allowed Reviewed-by: dfuchs Backport-of: bcf4bb4882e06d8c52f6eb4e9c4e027ba0622c5f --- src/java.base/share/classes/module-info.java | 1 + .../remote/rmi/RMIConnectionImpl.java | 91 ++++++++++++++----- .../remote/internal/ServerNotifForwarder.java | 5 +- .../MBeanServerFileAccessController.java | 22 +++-- .../javax/management/monitor/Monitor.java | 36 ++++++-- .../management/monitor/StartStopTest.java | 10 +- .../management/monitor/ThreadPoolAccTest.java | 14 ++- test/jdk/javax/management/monitor/all.policy | 3 + .../NotificationAccessControllerTest.java | 2 + .../notif/NotificationEmissionTest.java | 4 +- .../NonJMXPrincipalsTest.java | 1 + .../PasswordAccessFileTest.java | 2 + .../passwordAuthenticator/RMIAltAuthTest.java | 3 + .../RMIPasswdAuthTest.java | 3 + .../passwordAuthenticator/SimpleStandard.java | 6 +- .../security/AuthorizationTest.java | 6 ++ .../jmxremote/bootstrap/RmiBootstrapTest.java | 2 + 17 files changed, 162 insertions(+), 49 deletions(-) create mode 100644 test/jdk/javax/management/monitor/all.policy diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index a8b0a0c992c..52c1029dd3d 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -165,6 +165,7 @@ java.desktop, java.logging, java.management, + java.management.rmi, java.naming, java.rmi, jdk.charsets, diff --git a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java index 289bc8f3822..047863d34ef 100644 --- a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +++ b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java @@ -46,6 +46,7 @@ import javax.management.remote.JMXServerErrorException; import javax.management.remote.NotificationResult; import javax.security.auth.Subject; +import jdk.internal.access.SharedSecrets; import sun.reflect.misc.ReflectUtil; import static javax.management.remote.rmi.RMIConnector.Util.cast; @@ -108,14 +109,19 @@ public RMIConnectionImpl(RMIServerImpl rmiServer, this.rmiServer = rmiServer; this.connectionId = connectionId; this.defaultClassLoader = defaultClassLoader; - this.subject = subject; + if (subject == null) { this.acc = null; } else { // An authenticated Subject was provided. // Subject Delegation has been removed. - this.acc = JMXSubjectDomainCombiner.getContext(subject); + if (SharedSecrets.getJavaLangAccess().allowSecurityManager()) { + // SM is allowed. Will use ACC created with Subject: + this.acc = JMXSubjectDomainCombiner.getContext(subject); + } else { + this.acc = null; + } } this.mbeanServer = rmiServer.getMBeanServer(); @@ -1292,10 +1298,21 @@ public NotificationResult run() { return getServerNotifFwd().fetchNotifs(csn, t, mn); } }; - if (acc == null) - return action.run(); - else - return AccessController.doPrivileged(action, acc); + if (!SharedSecrets.getJavaLangAccess().allowSecurityManager()) { + // Modern case + if (subject == null) { + return action.run(); + } else { + return Subject.doAs(subject, action); + } + } else { + // SM permitted + if (acc == null) { + return action.run(); // No Subject or ACC + } else { + return AccessController.doPrivileged(action, acc); + } + } } finally { serverCommunicatorAdmin.rspOutgoing(); } @@ -1411,16 +1428,36 @@ private Object doPrivilegedOperation(final int operation, serverCommunicatorAdmin.reqIncoming(); try { PrivilegedOperation op = new PrivilegedOperation(operation, params); - if (acc == null) { - try { - return op.run(); - } catch (Exception e) { - if (e instanceof RuntimeException) - throw (RuntimeException) e; - throw new PrivilegedActionException(e); + if (!SharedSecrets.getJavaLangAccess().allowSecurityManager()) { + // Modern case + if (subject == null) { + try { + return op.run(); + } catch (Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } else { + throw new PrivilegedActionException(e); + } + } + } else { + return Subject.doAs(subject, op); } } else { - return AccessController.doPrivileged(op, acc); + // SM permitted + if (acc == null) { + try { + return op.run(); + } catch (Exception e) { + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } else { + throw new PrivilegedActionException(e); + } + } + } else { + return AccessController.doPrivileged(op, acc); + } } } catch (Error e) { throw new JMXServerErrorException(e.toString(),e); @@ -1585,15 +1622,25 @@ private T unwrap(final MarshalledObject mo, } try { final ClassLoader old = AccessController.doPrivileged(new SetCcl(cl)); - try{ - if (acc != null) { - return AccessController.doPrivileged( - (PrivilegedExceptionAction) () -> - wrappedClass.cast(mo.get()), acc); - }else{ - return wrappedClass.cast(mo.get()); + try { + if (!SharedSecrets.getJavaLangAccess().allowSecurityManager()) { + // Modern case + if (subject != null) { + return Subject.doAs(subject, (PrivilegedExceptionAction) () -> wrappedClass.cast(mo.get())); + } else { + return wrappedClass.cast(mo.get()); + } + } else { + // SM permitted + if (acc != null) { + return AccessController.doPrivileged( + (PrivilegedExceptionAction) () -> + wrappedClass.cast(mo.get()), acc); + } else { + return wrappedClass.cast(mo.get()); + } } - }finally{ + } finally { AccessController.doPrivileged(new SetCcl(old)); } } catch (PrivilegedActionException pe) { diff --git a/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java b/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java index e04a375c998..7ea1e485869 100644 --- a/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java +++ b/src/java.management/share/classes/com/sun/jmx/remote/internal/ServerNotifForwarder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, 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 @@ -343,10 +343,9 @@ public void terminate() { //---------------- // PRIVATE METHODS //---------------- - @SuppressWarnings("removal") private Subject getSubject() { - return Subject.getSubject(AccessController.getContext()); + return Subject.current(); } private void checkState() throws IOException { diff --git a/src/java.management/share/classes/com/sun/jmx/remote/security/MBeanServerFileAccessController.java b/src/java.management/share/classes/com/sun/jmx/remote/security/MBeanServerFileAccessController.java index d694d9cce31..bc14b6ad3f2 100644 --- a/src/java.management/share/classes/com/sun/jmx/remote/security/MBeanServerFileAccessController.java +++ b/src/java.management/share/classes/com/sun/jmx/remote/security/MBeanServerFileAccessController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, 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 @@ -42,6 +42,7 @@ import javax.management.MBeanServer; import javax.management.ObjectName; import javax.security.auth.Subject; +import jdk.internal.access.SharedSecrets; /** *

An object of this class implements the MBeanServerAccessController @@ -300,16 +301,19 @@ private static Properties propertiesFromFile(String fname) } } + @SuppressWarnings("removal") private synchronized void checkAccess(AccessType requiredAccess, String arg) { - @SuppressWarnings("removal") - final AccessControlContext acc = AccessController.getContext(); - @SuppressWarnings("removal") - final Subject s = - AccessController.doPrivileged(new PrivilegedAction<>() { - public Subject run() { - return Subject.getSubject(acc); - } + Subject s = null; + if (!SharedSecrets.getJavaLangAccess().allowSecurityManager()) { + s = Subject.current(); + } else { + final AccessControlContext acc = AccessController.getContext(); + s = AccessController.doPrivileged(new PrivilegedAction<>() { + public Subject run() { + return Subject.getSubject(acc); + } }); + } if (s == null) return; /* security has not been enabled */ final Set principals = s.getPrincipals(); String newPropertyValue = null; diff --git a/src/java.management/share/classes/javax/management/monitor/Monitor.java b/src/java.management/share/classes/javax/management/monitor/Monitor.java index aa6ec14ab63..2ccb96b8db6 100644 --- a/src/java.management/share/classes/javax/management/monitor/Monitor.java +++ b/src/java.management/share/classes/javax/management/monitor/Monitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, 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 @@ -60,6 +60,8 @@ import javax.management.NotificationBroadcasterSupport; import javax.management.ObjectName; import javax.management.ReflectionException; +import javax.security.auth.Subject; +import jdk.internal.access.SharedSecrets; import static javax.management.monitor.MonitorNotification.*; /** @@ -169,8 +171,9 @@ public final synchronized void setDerivedGaugeTimeStamp( new CopyOnWriteArrayList<>(); /** - * AccessControlContext of the Monitor.start() caller. + * Subject and possibly AccessControlContext of the Monitor.start() caller. */ + private volatile Subject subject; @SuppressWarnings("removal") private static final AccessControlContext noPermissionsACC = new AccessControlContext( @@ -713,10 +716,14 @@ void doStart() { // cleanupIsComplexTypeAttribute(); - // Cache the AccessControlContext of the Monitor.start() caller. + // Cache the Subject or AccessControlContext of the Monitor.start() caller. // The monitor tasks will be executed within this context. // - acc = AccessController.getContext(); + if (!SharedSecrets.getJavaLangAccess().allowSecurityManager()) { + subject = Subject.current(); + } else { + acc = AccessController.getContext(); + } // Start the scheduler. // @@ -747,8 +754,9 @@ void doStop() { // cleanupFutures(); - // Reset the AccessControlContext. + // Reset the Subject and AccessControlContext. // + subject = null; acc = noPermissionsACC; // Reset the complex type attribute information @@ -1512,9 +1520,11 @@ public Future submit() { @SuppressWarnings("removal") public void run() { final ScheduledFuture sf; + final Subject s; final AccessControlContext ac; synchronized (Monitor.this) { sf = Monitor.this.schedulerFuture; + s = Monitor.this.subject; ac = Monitor.this.acc; } PrivilegedAction action = new PrivilegedAction<>() { @@ -1531,10 +1541,20 @@ public Void run() { return null; } }; - if (ac == null) { - throw new SecurityException("AccessControlContext cannot be null"); + if (!SharedSecrets.getJavaLangAccess().allowSecurityManager()) { + // No SecurityManager permitted: + if (s == null) { + action.run(); + } else { + Subject.doAs(s, action); + } + } else { + if (ac == null) { + throw new SecurityException("AccessControlContext cannot be null"); + } + // ACC means SM is permitted. + AccessController.doPrivileged(action, ac); } - AccessController.doPrivileged(action, ac); synchronized (Monitor.this) { if (Monitor.this.isActive() && Monitor.this.schedulerFuture == sf) { diff --git a/test/jdk/javax/management/monitor/StartStopTest.java b/test/jdk/javax/management/monitor/StartStopTest.java index 8e5490aeaae..4779f40cdc7 100644 --- a/test/jdk/javax/management/monitor/StartStopTest.java +++ b/test/jdk/javax/management/monitor/StartStopTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, 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 @@ -32,9 +32,17 @@ * * @run clean StartStopTest * @run build StartStopTest + * * @run main/othervm/timeout=300 StartStopTest 1 * @run main/othervm/timeout=300 StartStopTest 2 * @run main/othervm/timeout=300 StartStopTest 3 + * @run main/othervm/timeout=300 -Djava.security.manager=allow StartStopTest 1 + * @run main/othervm/timeout=300 -Djava.security.manager=allow StartStopTest 2 + * @run main/othervm/timeout=300 -Djava.security.manager=allow StartStopTest 3 + * @run main/othervm/timeout=300/policy=all.policy StartStopTest 1 + * @run main/othervm/timeout=300/policy=all.policy StartStopTest 2 + * @run main/othervm/timeout=300/policy=all.policy StartStopTest 3 + * * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=5 StartStopTest 1 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=5 StartStopTest 2 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=5 StartStopTest 3 diff --git a/test/jdk/javax/management/monitor/ThreadPoolAccTest.java b/test/jdk/javax/management/monitor/ThreadPoolAccTest.java index 542fa9c657c..508cefddf94 100644 --- a/test/jdk/javax/management/monitor/ThreadPoolAccTest.java +++ b/test/jdk/javax/management/monitor/ThreadPoolAccTest.java @@ -30,13 +30,19 @@ * * @run clean ThreadPoolAccTest * @run build ThreadPoolAccTest + * + * @run main/othervm ThreadPoolAccTest * @run main/othervm -Djava.security.manager=allow ThreadPoolAccTest + * @run main/othervm -Djava.security.manager=allow -DThreadPoolAccTest.useGetSubjectACC=true ThreadPoolAccTest + * @run main/othervm/policy=all.policy ThreadPoolAccTest + * @run main/othervm/policy=all.policy -DThreadPoolAccTest.useGetSubjectACC=true ThreadPoolAccTest */ import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Date; import java.util.Set; +import java.util.concurrent.Callable; import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import javax.management.ObjectName; @@ -67,7 +73,9 @@ public String getString() { return ""; } private void setPrincipal() { - Subject subject = Subject.getSubject(AccessController.getContext()); + // Use Subject.current() unless test Property is set. + Subject subject = Boolean.getBoolean("ThreadPoolAccTest.useGetSubjectACC") ? + Subject.getSubject(AccessController.getContext()) : Subject.current(); Set principals = subject.getPrincipals(JMXPrincipal.class); principal = principals.iterator().next().getName(); } @@ -136,7 +144,9 @@ public Void run() { return null; } }; - Subject.doAs(subject, action); + // Subject.doAs(subject, action); + Callable c = (Callable) () -> action.run(); + Subject.callAs(subject, c); } sleep(500); // wait for getX method to be called, which calls setPrincipal diff --git a/test/jdk/javax/management/monitor/all.policy b/test/jdk/javax/management/monitor/all.policy new file mode 100644 index 00000000000..cb9dbed32cc --- /dev/null +++ b/test/jdk/javax/management/monitor/all.policy @@ -0,0 +1,3 @@ +grant { + permission java.security.AllPermission; +}; diff --git a/test/jdk/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java b/test/jdk/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java index 352faea27d1..57db8588ed3 100644 --- a/test/jdk/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java +++ b/test/jdk/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java @@ -30,6 +30,8 @@ * java.management/com.sun.jmx.remote.security * @run clean NotificationAccessControllerTest * @run build NotificationAccessControllerTest + * + * @run main/othervm NotificationAccessControllerTest * @run main/othervm -Djava.security.manager=allow NotificationAccessControllerTest */ diff --git a/test/jdk/javax/management/remote/mandatory/notif/NotificationEmissionTest.java b/test/jdk/javax/management/remote/mandatory/notif/NotificationEmissionTest.java index a4c57005853..e57636c87f6 100644 --- a/test/jdk/javax/management/remote/mandatory/notif/NotificationEmissionTest.java +++ b/test/jdk/javax/management/remote/mandatory/notif/NotificationEmissionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, 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 @@ -31,7 +31,9 @@ * * @run clean NotificationEmissionTest * @run build NotificationEmissionTest + * * @run main NotificationEmissionTest 1 + * @run main/othervm -Djava.security.manager=allow NotificationEmissionTest 1 * @run main/othervm -Djava.security.manager=allow NotificationEmissionTest 2 * @run main/othervm -Djava.security.manager=allow NotificationEmissionTest 3 * @run main/othervm -Djava.security.manager=allow NotificationEmissionTest 4 diff --git a/test/jdk/javax/management/remote/mandatory/passwordAccessFile/NonJMXPrincipalsTest.java b/test/jdk/javax/management/remote/mandatory/passwordAccessFile/NonJMXPrincipalsTest.java index f9e04a373f6..796507eeff3 100644 --- a/test/jdk/javax/management/remote/mandatory/passwordAccessFile/NonJMXPrincipalsTest.java +++ b/test/jdk/javax/management/remote/mandatory/passwordAccessFile/NonJMXPrincipalsTest.java @@ -30,6 +30,7 @@ * * @run clean NonJMXPrincipalsTest SimpleStandard SimpleStandardMBean * @run build NonJMXPrincipalsTest SimpleStandard SimpleStandardMBean + * @run main/othervm NonJMXPrincipalsTest * @run main/othervm -Djava.security.manager=allow NonJMXPrincipalsTest */ diff --git a/test/jdk/javax/management/remote/mandatory/passwordAccessFile/PasswordAccessFileTest.java b/test/jdk/javax/management/remote/mandatory/passwordAccessFile/PasswordAccessFileTest.java index d073553d3f5..ae3ec697b39 100644 --- a/test/jdk/javax/management/remote/mandatory/passwordAccessFile/PasswordAccessFileTest.java +++ b/test/jdk/javax/management/remote/mandatory/passwordAccessFile/PasswordAccessFileTest.java @@ -30,6 +30,8 @@ * * @run clean PasswordAccessFileTest SimpleStandard SimpleStandardMBean * @run build PasswordAccessFileTest SimpleStandard SimpleStandardMBean + * + * @run main/othervm PasswordAccessFileTest * @run main/othervm -Djava.security.manager=allow PasswordAccessFileTest */ diff --git a/test/jdk/javax/management/remote/mandatory/passwordAuthenticator/RMIAltAuthTest.java b/test/jdk/javax/management/remote/mandatory/passwordAuthenticator/RMIAltAuthTest.java index e86f9cc8f1a..13d94a87920 100644 --- a/test/jdk/javax/management/remote/mandatory/passwordAuthenticator/RMIAltAuthTest.java +++ b/test/jdk/javax/management/remote/mandatory/passwordAuthenticator/RMIAltAuthTest.java @@ -30,7 +30,10 @@ * java.management/com.sun.jmx.remote.security * @run clean RMIAltAuthTest * @run build RMIAltAuthTest SimpleStandard SimpleStandardMBean + * + * @run main/othervm RMIAltAuthTest * @run main/othervm -Djava.security.manager=allow RMIAltAuthTest + * @run main/othervm -Djava.security.manager=allow -DSimpleStandard.useGetSubjectACC=true RMIAltAuthTest */ import java.io.File; diff --git a/test/jdk/javax/management/remote/mandatory/passwordAuthenticator/RMIPasswdAuthTest.java b/test/jdk/javax/management/remote/mandatory/passwordAuthenticator/RMIPasswdAuthTest.java index 87384e070cd..8897d34c4e8 100644 --- a/test/jdk/javax/management/remote/mandatory/passwordAuthenticator/RMIPasswdAuthTest.java +++ b/test/jdk/javax/management/remote/mandatory/passwordAuthenticator/RMIPasswdAuthTest.java @@ -30,7 +30,10 @@ * java.management/com.sun.jmx.remote.security * @run clean RMIPasswdAuthTest * @run build RMIPasswdAuthTest SimpleStandard SimpleStandardMBean + * + * @run main/othervm RMIPasswdAuthTest * @run main/othervm -Djava.security.manager=allow RMIPasswdAuthTest + * @run main/othervm -Djava.security.manager=allow -DSimpleStandard.useGetSubjectACC=true RMIPasswdAuthTest */ import java.io.File; diff --git a/test/jdk/javax/management/remote/mandatory/passwordAuthenticator/SimpleStandard.java b/test/jdk/javax/management/remote/mandatory/passwordAuthenticator/SimpleStandard.java index bc503b3e291..b5657498365 100644 --- a/test/jdk/javax/management/remote/mandatory/passwordAuthenticator/SimpleStandard.java +++ b/test/jdk/javax/management/remote/mandatory/passwordAuthenticator/SimpleStandard.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, 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 @@ -152,8 +152,8 @@ public int getNbResets() { * type JMXPrincipal and refers to the "monitorRole" identity. */ private void checkSubject() { - AccessControlContext acc = AccessController.getContext(); - Subject subject = Subject.getSubject(acc); + Subject subject = Boolean.getBoolean("SimpleStandard.useGetSubjectACC") ? + Subject.getSubject(AccessController.getContext()) : Subject.current(); Set principals = subject.getPrincipals(); Principal principal = (Principal) principals.iterator().next(); if (!(principal instanceof JMXPrincipal)) diff --git a/test/jdk/javax/management/security/AuthorizationTest.java b/test/jdk/javax/management/security/AuthorizationTest.java index 2c48dbffb56..cdb412e139b 100644 --- a/test/jdk/javax/management/security/AuthorizationTest.java +++ b/test/jdk/javax/management/security/AuthorizationTest.java @@ -29,9 +29,15 @@ * @modules java.management.rmi * @library /test/lib * @compile Simple.java + * + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException + * @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException + * * @run main/othervm/timeout=300 -Djava.security.manager=allow -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials * @run main/othervm/timeout=300 -Djava.security.manager=allow -DDEBUG_STANDARD -Dusername=username2 -Dpassword=password2 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedSetException -expectedInvokeException * @run main/othervm/timeout=300 -Djava.security.manager=allow -DDEBUG_STANDARD -Dusername=username6 -Dpassword=password6 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException + * * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username3 -Dpassword=password3 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedGetException * @run main/othervm/timeout=300/policy=java.policy.authorization -DDEBUG_STANDARD -Dusername=username5 -Dpassword=password5 AuthorizationTest -server -mapType x.password.file -populate -client -mapType credentials -expectedCreateException -expectedGetException -expectedSetException -expectedInvokeException diff --git a/test/jdk/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java b/test/jdk/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java index 770b642088a..09e32174c74 100644 --- a/test/jdk/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java +++ b/test/jdk/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java @@ -61,6 +61,7 @@ * * @library /test/lib * + * @run main/othervm/timeout=300 RmiBootstrapTest .*_test.*.in * @run main/othervm/timeout=300 -Djava.security.manager=allow RmiBootstrapTest .*_test.*.in * */ @@ -72,6 +73,7 @@ * * @library /test/lib * + * @run main/othervm/timeout=300 RmiBootstrapTest .*_ssltest.*.in * @run main/othervm/timeout=300 -Djava.security.manager=allow RmiBootstrapTest .*_ssltest.*.in * */ From e89e237417c7617f419d4031ec4934d13c29a41f Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Fri, 21 Jun 2024 16:39:18 +0000 Subject: [PATCH 07/61] 8334333: MissingResourceCauseTestRun.java fails if run by root Reviewed-by: naoto Backport-of: 053d14918c0519ea20c8d182291938a79813c33b --- .../Control/MissingResourceCauseTestRun.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test/jdk/java/util/ResourceBundle/Control/MissingResourceCauseTestRun.java b/test/jdk/java/util/ResourceBundle/Control/MissingResourceCauseTestRun.java index 30cd81757df..66a60f11ad4 100644 --- a/test/jdk/java/util/ResourceBundle/Control/MissingResourceCauseTestRun.java +++ b/test/jdk/java/util/ResourceBundle/Control/MissingResourceCauseTestRun.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, 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 4354216 8213127 + * @bug 4354216 8213127 8334333 * @summary Test for the cause support when throwing a * MissingResourceBundle. (This test exists under * ResourceBundle/Control because bad resource bundle data can be @@ -32,6 +32,7 @@ * @build jdk.test.lib.JDKToolLauncher * jdk.test.lib.Utils * jdk.test.lib.process.ProcessTools + * jdk.test.lib.Platform * MissingResourceCauseTest * NonResourceBundle * PrivateConstructorRB @@ -50,9 +51,14 @@ import jdk.test.lib.JDKToolLauncher; import jdk.test.lib.Utils; import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.Platform; +import jtreg.SkippedException; public class MissingResourceCauseTestRun { public static void main(String[] args) throws Throwable { + if (Platform.isRoot() && !Platform.isWindows()) { + throw new SkippedException("Unable to create an unreadable properties file."); + } Path path = Paths.get("UnreadableRB.properties"); Files.deleteIfExists(path); try { @@ -98,7 +104,7 @@ private static void runCmd() throws Throwable { } private static void deleteFile(Path path) throws Throwable { - if(path.toFile().exists()) { + if (path.toFile().exists()) { ProcessTools.executeCommand("chmod", "666", path.toString()) .outputTo(System.out) .errorTo(System.out) From d7c03274e9fe7fe5bd760ab2ce54808d920ce7f5 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Fri, 21 Jun 2024 22:33:23 +0000 Subject: [PATCH 08/61] 8333854: IllegalAccessError with proxies after JDK-8332457 Reviewed-by: asotona Backport-of: 30a7bdc43ae2ca40e4fae99a4e4fd83158cbba5e --- .../java/lang/reflect/ProxyGenerator.java | 247 ++++++++++++------ .../Proxy/NonPublicMethodTypeTest.java | 59 +++++ 2 files changed, 229 insertions(+), 77 deletions(-) create mode 100644 test/jdk/java/lang/reflect/Proxy/NonPublicMethodTypeTest.java diff --git a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java index 776f5df4e5a..24dde98b08a 100644 --- a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java +++ b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java @@ -39,7 +39,6 @@ import java.util.ListIterator; import java.util.Map; import java.util.Objects; -import jdk.internal.constant.ConstantUtils; import jdk.internal.constant.MethodTypeDescImpl; import jdk.internal.constant.ReferenceClassDescImpl; import sun.security.action.GetBooleanAction; @@ -47,10 +46,7 @@ import static java.lang.classfile.ClassFile.*; import java.lang.classfile.attribute.StackMapFrameInfo; import java.lang.classfile.attribute.StackMapTableAttribute; -import java.lang.constant.ConstantDescs; import static java.lang.constant.ConstantDescs.*; -import java.lang.constant.DirectMethodHandleDesc; -import java.lang.constant.DynamicConstantDesc; /** * ProxyGenerator contains the code to generate a dynamic proxy class @@ -65,7 +61,10 @@ final class ProxyGenerator { ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS); private static final ClassDesc + CD_ClassLoader = ReferenceClassDescImpl.ofValidated("Ljava/lang/ClassLoader;"), CD_Class_array = ReferenceClassDescImpl.ofValidated("[Ljava/lang/Class;"), + CD_ClassNotFoundException = ReferenceClassDescImpl.ofValidated("Ljava/lang/ClassNotFoundException;"), + CD_NoClassDefFoundError = ReferenceClassDescImpl.ofValidated("Ljava/lang/NoClassDefFoundError;"), CD_IllegalAccessException = ReferenceClassDescImpl.ofValidated("Ljava/lang/IllegalAccessException;"), CD_InvocationHandler = ReferenceClassDescImpl.ofValidated("Ljava/lang/reflect/InvocationHandler;"), CD_Method = ReferenceClassDescImpl.ofValidated("Ljava/lang/reflect/Method;"), @@ -81,8 +80,9 @@ final class ProxyGenerator { MTD_void_String = MethodTypeDescImpl.ofValidated(CD_void, CD_String), MTD_void_Throwable = MethodTypeDescImpl.ofValidated(CD_void, CD_Throwable), MTD_Class = MethodTypeDescImpl.ofValidated(CD_Class), - MTD_Class_array = MethodTypeDescImpl.ofValidated(CD_Class_array), - MTD_Method_String_Class_array = MethodTypeDescImpl.ofValidated(CD_Method, ConstantDescs.CD_String, CD_Class_array), + MTD_Class_String_boolean_ClassLoader = MethodTypeDescImpl.ofValidated(CD_Class, CD_String, CD_boolean, CD_ClassLoader), + MTD_ClassLoader = MethodTypeDescImpl.ofValidated(CD_ClassLoader), + MTD_Method_String_Class_array = MethodTypeDescImpl.ofValidated(CD_Method, CD_String, CD_Class_array), MTD_MethodHandles$Lookup = MethodTypeDescImpl.ofValidated(CD_MethodHandles_Lookup), MTD_MethodHandles$Lookup_MethodHandles$Lookup = MethodTypeDescImpl.ofValidated(CD_MethodHandles_Lookup, CD_MethodHandles_Lookup), MTD_Object_Object_Method_ObjectArray = MethodTypeDescImpl.ofValidated(CD_Object, CD_Object, CD_Method, CD_Object_array), @@ -107,34 +107,33 @@ final class ProxyGenerator { "jdk.proxy.ProxyGenerator.saveGeneratedFiles")); /* Preloaded ProxyMethod objects for methods in java.lang.Object */ - private static final ProxyMethod HASH_CODE_METHOD; - private static final ProxyMethod EQUALS_METHOD; - private static final ProxyMethod TO_STRING_METHOD; + private static final Method OBJECT_HASH_CODE_METHOD; + private static final Method OBJECT_EQUALS_METHOD; + private static final Method OBJECT_TO_STRING_METHOD; static { try { - HASH_CODE_METHOD = new ProxyMethod(Object.class.getMethod("hashCode")); - EQUALS_METHOD = new ProxyMethod(Object.class.getMethod("equals", Object.class)); - TO_STRING_METHOD = new ProxyMethod(Object.class.getMethod("toString")); + OBJECT_HASH_CODE_METHOD = Object.class.getMethod("hashCode"); + OBJECT_EQUALS_METHOD = Object.class.getMethod("equals", Object.class); + OBJECT_TO_STRING_METHOD = Object.class.getMethod("toString"); } catch (NoSuchMethodException e) { throw new NoSuchMethodError(e.getMessage()); } } private final ConstantPoolBuilder cp; - private final List throwableStack; + private final List classLoaderLocal, throwableStack; private final NameAndTypeEntry exInit; - private final ClassEntry object, proxy, ute; + private final ClassEntry objectCE, proxyCE, uteCE, classCE; private final FieldRefEntry handlerField; - private final InterfaceMethodRefEntry invoke; - private final MethodRefEntry uteInit; - private final DirectMethodHandleDesc bsm; + private final InterfaceMethodRefEntry invocationHandlerInvoke; + private final MethodRefEntry uteInit, classGetMethod, classForName, throwableGetMessage; /** - * Name of proxy class + * ClassEntry for this proxy class */ - private ClassEntry classEntry; + private final ClassEntry thisClassCE; /** * Proxy interfaces @@ -153,6 +152,12 @@ final class ProxyGenerator { */ private final Map> proxyMethods = new LinkedHashMap<>(); + /** + * Ordinal of next ProxyMethod object added to proxyMethods. + * Indexes are reserved for hashcode(0), equals(1), toString(2). + */ + private int proxyMethodCount = 3; + /** * Construct a ProxyGenerator to generate a proxy class with the * specified name and for the given interfaces. @@ -163,18 +168,23 @@ final class ProxyGenerator { private ProxyGenerator(ClassLoader loader, String className, List> interfaces, int accessFlags) { this.cp = ConstantPoolBuilder.of(); - this.classEntry = cp.classEntry(ReferenceClassDescImpl.ofValidatedBinaryName(className)); + this.thisClassCE = cp.classEntry(ReferenceClassDescImpl.ofValidatedBinaryName(className)); this.interfaces = interfaces; this.accessFlags = accessFlags; - this.throwableStack = List.of(StackMapFrameInfo.ObjectVerificationTypeInfo.of(cp.classEntry(CD_Throwable))); + var throwable = cp.classEntry(CD_Throwable); + this.classLoaderLocal = List.of(StackMapFrameInfo.ObjectVerificationTypeInfo.of(cp.classEntry(CD_ClassLoader))); + this.throwableStack = List.of(StackMapFrameInfo.ObjectVerificationTypeInfo.of(throwable)); this.exInit = cp.nameAndTypeEntry(INIT_NAME, MTD_void_String); - this.object = cp.classEntry(CD_Object); - this.proxy = cp.classEntry(CD_Proxy); - this.handlerField = cp.fieldRefEntry(proxy, cp.nameAndTypeEntry(NAME_HANDLER_FIELD, CD_InvocationHandler)); - this.invoke = cp.interfaceMethodRefEntry(CD_InvocationHandler, "invoke", MTD_Object_Object_Method_ObjectArray); - this.ute = cp.classEntry(CD_UndeclaredThrowableException); - this.uteInit = cp.methodRefEntry(ute, cp.nameAndTypeEntry(INIT_NAME, MTD_void_Throwable)); - this.bsm = ConstantDescs.ofConstantBootstrap(classEntry.asSymbol(), "$getMethod", CD_Method, CD_Class, CD_String, CD_MethodType); + this.objectCE = cp.classEntry(CD_Object); + this.proxyCE = cp.classEntry(CD_Proxy); + this.classCE = cp.classEntry(CD_Class); + this.handlerField = cp.fieldRefEntry(proxyCE, cp.nameAndTypeEntry(NAME_HANDLER_FIELD, CD_InvocationHandler)); + this.invocationHandlerInvoke = cp.interfaceMethodRefEntry(CD_InvocationHandler, "invoke", MTD_Object_Object_Method_ObjectArray); + this.uteCE = cp.classEntry(CD_UndeclaredThrowableException); + this.uteInit = cp.methodRefEntry(uteCE, cp.nameAndTypeEntry(INIT_NAME, MTD_void_Throwable)); + this.classGetMethod = cp.methodRefEntry(classCE, cp.nameAndTypeEntry("getMethod", MTD_Method_String_Class_array)); + this.classForName = cp.methodRefEntry(classCE, cp.nameAndTypeEntry("forName", MTD_Class_String_boolean_ClassLoader)); + this.throwableGetMessage = cp.methodRefEntry(throwable, cp.nameAndTypeEntry("getMessage", MTD_String)); } /** @@ -441,9 +451,9 @@ private byte[] generateClassFile() { * java.lang.Object take precedence over duplicate methods in the * proxy interfaces. */ - addProxyMethod(HASH_CODE_METHOD); - addProxyMethod(EQUALS_METHOD); - addProxyMethod(TO_STRING_METHOD); + addProxyMethod(new ProxyMethod(OBJECT_HASH_CODE_METHOD, "m0")); + addProxyMethod(new ProxyMethod(OBJECT_EQUALS_METHOD, "m1")); + addProxyMethod(new ProxyMethod(OBJECT_TO_STRING_METHOD, "m2")); /* * Accumulate all of the methods from the proxy interfaces. @@ -464,20 +474,23 @@ private byte[] generateClassFile() { checkReturnTypes(sigmethods); } - return CF_CONTEXT.build(classEntry, cp, clb -> { - clb.withSuperclass(proxy); + return CF_CONTEXT.build(thisClassCE, cp, clb -> { + clb.withSuperclass(proxyCE); clb.withFlags(accessFlags); clb.withInterfaces(toClassEntries(cp, interfaces)); generateConstructor(clb); for (List sigmethods : proxyMethods.values()) { for (ProxyMethod pm : sigmethods) { + // add static field for the Method object + clb.withField(pm.methodFieldName, CD_Method, ACC_PRIVATE | ACC_STATIC | ACC_FINAL); + // Generate code for proxy method - pm.generateMethod(this, clb); + pm.generateMethod(clb); } } - generateBootstrapMethod(clb); + generateStaticInitializer(clb); generateLookupAccessor(clb); }); } @@ -520,7 +533,7 @@ private void addProxyMethod(Method m, Class fromClass) { } } sigmethods.add(new ProxyMethod(m, sig, m.getSharedParameterTypes(), returnType, - exceptionTypes, fromClass)); + exceptionTypes, fromClass, "m" + proxyMethodCount++)); } /** @@ -542,32 +555,56 @@ private void generateConstructor(ClassBuilder clb) { clb.withMethodBody(INIT_NAME, MTD_void_InvocationHandler, ACC_PUBLIC, cob -> cob .aload(0) .aload(1) - .invokespecial(cp.methodRefEntry(proxy, cp.nameAndTypeEntry(INIT_NAME, MTD_void_InvocationHandler))) + .invokespecial(cp.methodRefEntry(proxyCE, + cp.nameAndTypeEntry(INIT_NAME, MTD_void_InvocationHandler))) .return_()); } /** - * Generate CONDY bootstrap method for the proxy class to retrieve {@link Method} instances. + * Generate the class initializer. + * Discussion: Currently, for Proxy to work with SecurityManager, + * we rely on the parameter classes of the methods to be computed + * from Proxy instead of via user code paths like bootstrap method + * lazy evaluation. That might change if we can pass in the live + * Method objects directly.. */ - private void generateBootstrapMethod(ClassBuilder clb) { - clb.withMethodBody(bsm.methodName(), bsm.invocationType(), ClassFile.ACC_PRIVATE | ClassFile.ACC_STATIC, cob -> { - cob.aload(3) //interface Class - .aload(4) //interface method name String - .aload(5) //interface MethodType - .invokevirtual(CD_MethodType, "parameterArray", MTD_Class_array) - .invokevirtual(ConstantDescs.CD_Class, "getMethod", MTD_Method_String_Class_array) - .areturn(); - Label failLabel = cob.newBoundLabel(); - ClassEntry nsme = cp.classEntry(CD_NoSuchMethodError); - cob.exceptionCatch(cob.startLabel(), failLabel, failLabel, CD_NoSuchMethodException) - .new_(nsme) + private void generateStaticInitializer(ClassBuilder clb) { + clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> { + // Put ClassLoader at local variable index 0, used by + // Class.forName(String, boolean, ClassLoader) calls + cob.ldc(thisClassCE) + .invokevirtual(cp.methodRefEntry(classCE, + cp.nameAndTypeEntry("getClassLoader", MTD_ClassLoader))) + .astore(0); + var ts = cob.newBoundLabel(); + for (List sigmethods : proxyMethods.values()) { + for (ProxyMethod pm : sigmethods) { + pm.codeFieldInitialization(cob); + } + } + cob.return_(); + var c1 = cob.newBoundLabel(); + var nsmError = cp.classEntry(CD_NoSuchMethodError); + cob.exceptionCatch(ts, c1, c1, CD_NoSuchMethodException) + .new_(nsmError) + .dup_x1() + .swap() + .invokevirtual(throwableGetMessage) + .invokespecial(cp.methodRefEntry(nsmError, exInit)) + .athrow(); + var c2 = cob.newBoundLabel(); + var ncdfError = cp.classEntry(CD_NoClassDefFoundError); + cob.exceptionCatch(ts, c1, c2, CD_ClassNotFoundException) + .new_(ncdfError) .dup_x1() .swap() - .invokevirtual(cp.methodRefEntry(CD_Throwable, "getMessage", MTD_String)) - .invokespecial(cp.methodRefEntry(nsme, exInit)) - .athrow() - .with(StackMapTableAttribute.of(List.of( - StackMapFrameInfo.of(failLabel, List.of(), throwableStack)))); + .invokevirtual(throwableGetMessage) + .invokespecial(cp.methodRefEntry(ncdfError, exInit)) + .athrow(); + cob.with(StackMapTableAttribute.of(List.of( + StackMapFrameInfo.of(c1, classLoaderLocal, throwableStack), + StackMapFrameInfo.of(c2, classLoaderLocal, throwableStack)))); + }); } @@ -587,7 +624,7 @@ private void generateLookupAccessor(ClassBuilder clb) { ClassEntry iae = cp.classEntry(CD_IllegalAccessException); cob.aload(cob.parameterSlot(0)) .invokevirtual(cp.methodRefEntry(mhl, cp.nameAndTypeEntry("lookupClass", MTD_Class))) - .ldc(proxy) + .ldc(proxyCE) .if_acmpne(failLabel) .aload(cob.parameterSlot(0)) .invokevirtual(cp.methodRefEntry(mhl, cp.nameAndTypeEntry("hasFullPrivilegeAccess", MTD_boolean))) @@ -613,24 +650,29 @@ private void generateLookupAccessor(ClassBuilder clb) { * being generated: a method whose implementation will encode and * dispatch invocations to the proxy instance's invocation handler. */ - private static class ProxyMethod { + private class ProxyMethod { private final Method method; private final String shortSignature; private final Class fromClass; private final Class[] parameterTypes; private final Class returnType; + private final String methodFieldName; private Class[] exceptionTypes; + private final FieldRefEntry methodField; private ProxyMethod(Method method, String sig, Class[] parameterTypes, Class returnType, Class[] exceptionTypes, - Class fromClass) { + Class fromClass, String methodFieldName) { this.method = method; this.shortSignature = sig; this.parameterTypes = parameterTypes; this.returnType = returnType; this.exceptionTypes = exceptionTypes; this.fromClass = fromClass; + this.methodFieldName = methodFieldName; + this.methodField = cp.fieldRefEntry(thisClassCE, + cp.nameAndTypeEntry(methodFieldName, CD_Method)); } /** @@ -639,17 +681,16 @@ private ProxyMethod(Method method, String sig, Class[] parameterTypes, * @param method The method for which to create a proxy * @param methodFieldName the fieldName to generate */ - private ProxyMethod(Method method) { + private ProxyMethod(Method method, String methodFieldName) { this(method, method.toShortSignature(), method.getSharedParameterTypes(), method.getReturnType(), - method.getSharedExceptionTypes(), method.getDeclaringClass()); + method.getSharedExceptionTypes(), method.getDeclaringClass(), methodFieldName); } /** * Generate this method, including the code and exception table entry. */ - private void generateMethod(ProxyGenerator pg, ClassBuilder clb) { - var cp = pg.cp; + private void generateMethod(ClassBuilder clb) { var pTypes = new ClassDesc[parameterTypes.length]; for (int i = 0; i < pTypes.length; i++) { pTypes[i] = toClassDesc(parameterTypes[i]); @@ -661,17 +702,14 @@ private void generateMethod(ProxyGenerator pg, ClassBuilder clb) { clb.withMethod(method.getName(), desc, accessFlags, mb -> mb.with(ExceptionsAttribute.of(toClassEntries(cp, List.of(exceptionTypes)))) .withCode(cob -> { - cob.aload(0) - .getfield(pg.handlerField) - .aload(0) - .ldc(DynamicConstantDesc.of(pg.bsm, - toClassDesc(fromClass), - method.getName(), - desc)); + cob.aload(cob.receiverSlot()) + .getfield(handlerField) + .aload(cob.receiverSlot()) + .getstatic(methodField); if (parameterTypes.length > 0) { // Create an array and fill with the parameters converting primitives to wrappers cob.loadConstant(parameterTypes.length) - .anewarray(pg.object); + .anewarray(objectCE); for (int i = 0; i < parameterTypes.length; i++) { cob.dup() .loadConstant(i); @@ -682,7 +720,7 @@ private void generateMethod(ProxyGenerator pg, ClassBuilder clb) { cob.aconst_null(); } - cob.invokeinterface(pg.invoke); + cob.invokeinterface(invocationHandlerInvoke); if (returnType == void.class) { cob.pop() @@ -698,14 +736,14 @@ private void generateMethod(ProxyGenerator pg, ClassBuilder clb) { cob.athrow(); // just rethrow the exception var c2 = cob.newBoundLabel(); cob.exceptionCatchAll(cob.startLabel(), c1, c2) - .new_(pg.ute) + .new_(uteCE) .dup_x1() .swap() - .invokespecial(pg.uteInit) + .invokespecial(uteInit) .athrow() .with(StackMapTableAttribute.of(List.of( - StackMapFrameInfo.of(c1, List.of(), pg.throwableStack), - StackMapFrameInfo.of(c2, List.of(), pg.throwableStack)))); + StackMapFrameInfo.of(c1, List.of(), throwableStack), + StackMapFrameInfo.of(c2, List.of(), throwableStack)))); } })); } @@ -720,7 +758,7 @@ private void codeWrapArgument(CodeBuilder cob, Class type, int slot) { if (type.isPrimitive()) { cob.loadLocal(TypeKind.from(type).asLoadable(), slot); PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type); - cob.invokestatic(prim.wrapperMethodRef(cob.constantPool())); + cob.invokestatic(prim.wrapperMethodRef(cp)); } else { cob.aload(slot); } @@ -736,7 +774,7 @@ private void codeUnwrapReturnValue(CodeBuilder cob, Class type) { PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type); cob.checkcast(prim.wrapperClass) - .invokevirtual(prim.unwrapMethodRef(cob.constantPool())) + .invokevirtual(prim.unwrapMethodRef(cp)) .return_(TypeKind.from(type).asLoadable()); } else { cob.checkcast(toClassDesc(type)) @@ -744,6 +782,57 @@ private void codeUnwrapReturnValue(CodeBuilder cob, Class type) { } } + /** + * Generate code for initializing the static field that stores + * the Method object for this proxy method. A class loader is + * anticipated at local variable index 0. + * The generated code must be run in an AccessController.doPrivileged + * block if a SecurityManager is present, as otherwise the code + * cannot pass {@code null} ClassLoader to forName. + */ + private void codeFieldInitialization(CodeBuilder cob) { + var cp = cob.constantPool(); + codeClassForName(cob, fromClass); + + cob.ldc(method.getName()) + .loadConstant(parameterTypes.length) + .anewarray(classCE); + + // Construct an array with the parameter types mapping primitives to Wrapper types + for (int i = 0; i < parameterTypes.length; i++) { + cob.dup() + .loadConstant(i); + if (parameterTypes[i].isPrimitive()) { + PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(parameterTypes[i]); + cob.getstatic(prim.typeFieldRef(cp)); + } else { + codeClassForName(cob, parameterTypes[i]); + } + cob.aastore(); + } + // lookup the method + cob.invokevirtual(classGetMethod) + .putstatic(methodField); + } + + /* + * =============== Code Generation Utility Methods =============== + */ + + /** + * Generate code to invoke the Class.forName with the name of the given + * class to get its Class object at runtime. The code is written to + * the supplied stream. Note that the code generated by this method + * may cause the checked ClassNotFoundException to be thrown. A class + * loader is anticipated at local variable index 0. + */ + private void codeClassForName(CodeBuilder cob, Class cl) { + cob.ldc(cl.getName()) + .iconst_0() // false + .aload(0)// classLoader + .invokestatic(classForName); + } + @Override public String toString() { return method.toShortString(); @@ -810,5 +899,9 @@ public MethodRefEntry wrapperMethodRef(ConstantPoolBuilder cp) { public MethodRefEntry unwrapMethodRef(ConstantPoolBuilder cp) { return cp.methodRefEntry(wrapperClass, unwrapMethodName, unwrapMethodType); } + + public FieldRefEntry typeFieldRef(ConstantPoolBuilder cp) { + return cp.fieldRefEntry(wrapperClass, "TYPE", CD_Class); + } } } diff --git a/test/jdk/java/lang/reflect/Proxy/NonPublicMethodTypeTest.java b/test/jdk/java/lang/reflect/Proxy/NonPublicMethodTypeTest.java new file mode 100644 index 00000000000..8919dc2f0b2 --- /dev/null +++ b/test/jdk/java/lang/reflect/Proxy/NonPublicMethodTypeTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024, 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 8333854 + * @summary Test invoking a method in a proxy interface with package-private + * classes or interfaces in its method type + * @run junit NonPublicMethodTypeTest + */ + +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Proxy; + +import static org.junit.jupiter.api.Assertions.assertNotSame; + +public final class NonPublicMethodTypeTest { + interface NonPublicWorker { + void work(); + } + + public interface PublicWorkable { + void accept(NonPublicWorker worker); + } + + @Test + public void test() { + PublicWorkable proxy = (PublicWorkable) Proxy.newProxyInstance( + NonPublicMethodTypeTest.class.getClassLoader(), + new Class[] {PublicWorkable.class}, + (_, _, _) -> null); + assertNotSame(NonPublicWorker.class.getPackage(), + proxy.getClass().getPackage(), + "Proxy class should not be able to access method parameter " + + "NonPublic type's package"); + proxy.accept(() -> {}); // Call should not fail + } +} From ac628742b85e3e054dd19b184fb9835404310866 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Sun, 23 Jun 2024 16:43:27 +0000 Subject: [PATCH 09/61] 8334441: Mark tests in jdk_security_infra group as manual Reviewed-by: clanger Backport-of: 6753acf73792d536793351e0c89843c274a30f0c --- test/jdk/ProblemList.txt | 2 - test/jdk/TEST.groups | 5 +- .../certification/CAInterop.java | 268 +++++++++--------- .../certification/CertignaCA.java | 6 +- .../certification/DTrustCA.java | 6 +- .../certification/DigicertCSRootG5.java | 6 +- .../certification/EmSignRootG2CA.java | 6 +- .../certification/HaricaCA.java | 6 +- .../certification/LuxTrustCA.java | 6 +- .../javax/net/ssl/HttpsURLConnectionTest.java | 2 +- 10 files changed, 158 insertions(+), 155 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 4ea08fa2bbc..546f95b0054 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -620,8 +620,6 @@ javax/net/ssl/SSLSession/CertMsgCheck.java 8326705 generic- sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java 8316183,8333317 generic-all -security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#teliasonerarootcav1 8333640 generic-all - ############################################################################ # jdk_sound diff --git a/test/jdk/TEST.groups b/test/jdk/TEST.groups index fa868699aab..0a8d2748465 100644 --- a/test/jdk/TEST.groups +++ b/test/jdk/TEST.groups @@ -251,6 +251,8 @@ jdk_security = \ :jdk_security3 \ :jdk_security4 +# Tests in this group are manual as they depend on external infra +# and may fail with external reasons, for instance - change in CA test portal. jdk_security_infra = \ security/infra @@ -618,6 +620,7 @@ jdk_core_manual_no_input = \ javax/xml/jaxp/datatype/8033980/GregorianCalAndDurSerDataUtil.java jdk_security_manual_no_input = \ + :jdk_security_infra \ com/sun/crypto/provider/Cipher/DES/PerformanceTest.java \ com/sun/crypto/provider/Cipher/AEAD/GCMIncrementByte4.java \ com/sun/crypto/provider/Cipher/AEAD/GCMIncrementDirect4.java \ @@ -661,4 +664,4 @@ jdk_containers_extended = \ jdk_core_no_security = \ :jdk_core \ - -:jdk_security \ No newline at end of file + -:jdk_security diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java index 9f071bc1450..889926077a9 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java @@ -27,12 +27,12 @@ * @summary Interoperability tests with Actalis CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp * CAInterop actalisauthenticationrootca OCSP - * @run main/othervm/timeout=180 -Djava.security.debug=certpath,ocsp + * @run main/othervm/manual/timeout=180 -Djava.security.debug=certpath,ocsp * -Dcom.sun.security.ocsp.useget=false * CAInterop actalisauthenticationrootca OCSP - * @run main/othervm/timeout=180 -Djava.security.debug=certpath,ocsp + * @run main/othervm/manual/timeout=180 -Djava.security.debug=certpath,ocsp * CAInterop actalisauthenticationrootca CRL */ @@ -42,9 +42,9 @@ * @summary Interoperability tests with Amazon's CA1 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca1 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca1 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca1 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop amazonrootca1 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca1 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop amazonrootca1 CRL */ /* @@ -53,9 +53,9 @@ * @summary Interoperability tests with Amazon's CA2 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca2 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca2 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca2 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop amazonrootca2 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca2 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop amazonrootca2 CRL */ /* @@ -64,9 +64,9 @@ * @summary Interoperability tests with Amazon's CA3 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca3 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca3 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca3 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop amazonrootca3 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca3 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop amazonrootca3 CRL */ /* @@ -75,9 +75,9 @@ * @summary Interoperability tests with Amazon's CA4 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop amazonrootca4 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca4 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop amazonrootca4 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop amazonrootca4 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop amazonrootca4 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop amazonrootca4 CRL */ /* @@ -86,9 +86,9 @@ * @summary Interoperability tests with Buypass Class 2 CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass2ca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop buypassclass2ca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass2ca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop buypassclass2ca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop buypassclass2ca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop buypassclass2ca CRL */ /* @@ -97,9 +97,9 @@ * @summary Interoperability tests with Buypass Class 3 CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass3ca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop buypassclass3ca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop buypassclass3ca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop buypassclass3ca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop buypassclass3ca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop buypassclass3ca CRL */ /* @@ -108,9 +108,9 @@ * @summary Interoperability tests with Comodo RSA CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop comodorsaca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop comodorsaca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop comodorsaca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop comodorsaca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop comodorsaca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop comodorsaca CRL */ /* @@ -119,9 +119,9 @@ * @summary Interoperability tests with Comodo ECC CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop comodoeccca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop comodoeccca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop comodoeccca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop comodoeccca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop comodoeccca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop comodoeccca CRL */ /* @@ -130,9 +130,9 @@ * @summary Interoperability tests with Comodo userTrust RSA CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop usertrustrsaca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop usertrustrsaca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop usertrustrsaca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop usertrustrsaca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop usertrustrsaca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop usertrustrsaca CRL */ /* @@ -141,9 +141,9 @@ * @summary Interoperability tests with Comodo userTrust ECC CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop usertrusteccca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop usertrusteccca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop usertrusteccca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop usertrusteccca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop usertrusteccca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop usertrusteccca CRL */ /* @@ -152,8 +152,8 @@ * @summary Interoperability tests with Let's Encrypt ISRG Root X1 CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop letsencryptisrgx1 DEFAULT - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop letsencryptisrgx1 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop letsencryptisrgx1 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop letsencryptisrgx1 DEFAULT */ /* @@ -162,8 +162,8 @@ * @summary Interoperability tests with Let's Encrypt ISRG Root X2 CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop letsencryptisrgx2 DEFAULT - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop letsencryptisrgx2 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop letsencryptisrgx2 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop letsencryptisrgx2 DEFAULT */ /* @@ -172,9 +172,9 @@ * @summary Interoperability tests with GlobalSign R6 CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsignrootcar6 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsignrootcar6 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop globalsignrootcar6 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop globalsignrootcar6 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsignrootcar6 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop globalsignrootcar6 CRL */ /* @@ -183,9 +183,9 @@ * @summary Interoperability tests with Entrust CAs * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop entrustrootcaec1 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop entrustrootcaec1 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop entrustrootcaec1 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop entrustrootcaec1 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop entrustrootcaec1 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop entrustrootcaec1 CRL */ /* @@ -194,9 +194,9 @@ * @summary Interoperability tests with Entrust CAs * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop entrustrootcag4 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop entrustrootcag4 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop entrustrootcag4 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop entrustrootcag4 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop entrustrootcag4 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop entrustrootcag4 CRL */ /* @@ -205,9 +205,9 @@ * @summary Interoperability tests with GoDaddy CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop godaddyrootg2ca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop godaddyrootg2ca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop godaddyrootg2ca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop godaddyrootg2ca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop godaddyrootg2ca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop godaddyrootg2ca CRL */ /* @@ -216,9 +216,9 @@ * @summary Interoperability tests with Starfield CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop starfieldrootg2ca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop starfieldrootg2ca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop starfieldrootg2ca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop starfieldrootg2ca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop starfieldrootg2ca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop starfieldrootg2ca CRL */ /* @@ -227,8 +227,8 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsigneccrootcar4 DEFAULT - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsigneccrootcar4 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop globalsigneccrootcar4 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsigneccrootcar4 DEFAULT */ /* @@ -237,8 +237,8 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar1 DEFAULT - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootcar1 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar1 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootcar1 DEFAULT */ /* @@ -247,8 +247,8 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar2 DEFAULT - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootcar2 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop gtsrootcar2 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootcar2 DEFAULT */ /* @@ -257,8 +257,8 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar3 DEFAULT - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootecccar3 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar3 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootecccar3 DEFAULT */ /* @@ -267,8 +267,8 @@ * @summary Interoperability tests with Google's GlobalSign R4 and GTS Root certificates * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootecccar4 DEFAULT - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar4 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop gtsrootecccar4 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop gtsrootecccar4 DEFAULT */ /* @@ -277,9 +277,9 @@ * @summary Interoperability tests with Microsoft TLS root CAs * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop microsoftecc2017 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop microsoftecc2017 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop microsoftecc2017 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop microsoftecc2017 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop microsoftecc2017 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop microsoftecc2017 CRL */ /* @@ -288,9 +288,9 @@ * @summary Interoperability tests with Microsoft TLS root CAs * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop microsoftrsa2017 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop microsoftrsa2017 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop microsoftrsa2017 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop microsoftrsa2017 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop microsoftrsa2017 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop microsoftrsa2017 CRL */ /* @@ -299,9 +299,9 @@ * @summary Interoperability tests with QuoVadis Root CA1 G3 CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca1g3 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop quovadisrootca1g3 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca1g3 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca1g3 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop quovadisrootca1g3 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop quovadisrootca1g3 CRL */ /* @@ -310,9 +310,9 @@ * @summary Interoperability tests with QuoVadis Root CA2 G3 CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca2g3 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop quovadisrootca2g3 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca2g3 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca2g3 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop quovadisrootca2g3 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop quovadisrootca2g3 CRL */ /* @@ -321,9 +321,9 @@ * @summary Interoperability tests with QuoVadis Root CA3 G3 CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca3g3 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop quovadisrootca3g3 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop quovadisrootca3g3 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop quovadisrootca3g3 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop quovadisrootca3g3 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop quovadisrootca3g3 CRL */ /* @@ -332,9 +332,9 @@ * @summary Interoperability tests with DigiCert TLS ECC P384 Root G5 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop digicerttlseccrootg5 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop digicerttlseccrootg5 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop digicerttlseccrootg5 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop digicerttlseccrootg5 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop digicerttlseccrootg5 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop digicerttlseccrootg5 CRL */ /* @@ -343,9 +343,9 @@ * @summary Interoperability tests with DigiCert TLS RSA4096 Root G5 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop digicerttlsrsarootg5 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop digicerttlsrsarootg5 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop digicerttlsrsarootg5 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop digicerttlsrsarootg5 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop digicerttlsrsarootg5 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop digicerttlsrsarootg5 CRL */ /* @@ -354,9 +354,9 @@ * @summary Interoperability tests with SSL.com's RSA CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop sslrootrsaca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop sslrootrsaca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop sslrootrsaca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop sslrootrsaca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop sslrootrsaca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop sslrootrsaca CRL */ /* @@ -365,9 +365,9 @@ * @summary Interoperability tests with SSL.com's EV RSA CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop sslrootevrsaca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop sslrootevrsaca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop sslrootevrsaca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop sslrootevrsaca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop sslrootevrsaca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop sslrootevrsaca CRL */ /* @@ -376,9 +376,9 @@ * @summary Interoperability tests with SSL.com's ECC CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop sslrooteccca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop sslrooteccca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop sslrooteccca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop sslrooteccca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop sslrooteccca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop sslrooteccca CRL */ /* @@ -387,9 +387,9 @@ * @summary Interoperability tests with TeliaSonera Root CA v1 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop teliasonerarootcav1 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop teliasonerarootcav1 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop teliasonerarootcav1 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop teliasonerarootcav1 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop teliasonerarootcav1 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop teliasonerarootcav1 CRL */ /* @@ -398,9 +398,9 @@ * @summary Interoperability tests with TWCA Global Root CA from TAIWAN-CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop twcaglobalrootca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop twcaglobalrootca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop twcaglobalrootca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop twcaglobalrootca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop twcaglobalrootca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop twcaglobalrootca CRL */ /* @@ -409,9 +409,9 @@ * @summary Interoperability tests with Certigna Root CAs from Dhimyotis * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop certignarootca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certignarootca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop certignarootca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop certignarootca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certignarootca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop certignarootca CRL */ /* @@ -420,9 +420,9 @@ * @summary Interoperability tests with AffirmTrust Commercial CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustcommercialca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustcommercialca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustcommercialca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop affirmtrustcommercialca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustcommercialca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop affirmtrustcommercialca CRL */ /* @@ -431,9 +431,9 @@ * @summary Interoperability tests with AffirmTrust Networking CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustnetworkingca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustnetworkingca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustnetworkingca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop affirmtrustnetworkingca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustnetworkingca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop affirmtrustnetworkingca CRL */ /* @@ -442,9 +442,9 @@ * @summary Interoperability tests with AffirmTrust Premium CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustpremiumca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustpremiumca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustpremiumca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop affirmtrustpremiumca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustpremiumca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop affirmtrustpremiumca CRL */ /* @@ -453,9 +453,9 @@ * @summary Interoperability tests with AffirmTrust Premium ECC CA * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop affirmtrustpremiumeccca OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustpremiumeccca OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop affirmtrustpremiumeccca CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop affirmtrustpremiumeccca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop affirmtrustpremiumeccca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop affirmtrustpremiumeccca CRL */ /* @@ -464,9 +464,9 @@ * @summary Interoperability tests with Telia Root CA V2 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop teliarootcav2 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop teliarootcav2 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop teliarootcav2 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop teliarootcav2 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop teliarootcav2 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop teliarootcav2 CRL */ /* @@ -475,9 +475,9 @@ * @summary Interoperability tests with eMudhra Root CA G1 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop emsignrootcag1 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop emsignrootcag1 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop emsignrootcag1 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop emsignrootcag1 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop emsignrootcag1 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop emsignrootcag1 CRL */ /* @@ -486,9 +486,9 @@ * @summary Interoperability tests with eMudhra ECC Root CA G3 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop emsigneccrootcag3 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop emsigneccrootcag3 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop emsigneccrootcag3 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop emsigneccrootcag3 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop emsigneccrootcag3 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop emsigneccrootcag3 CRL */ /* @@ -497,8 +497,8 @@ * @summary Interoperability tests with Certainly Root R1 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop certainlyrootr1 DEFAULT - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certainlyrootr1 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop certainlyrootr1 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certainlyrootr1 DEFAULT */ /* @@ -507,8 +507,8 @@ * @summary Interoperability tests with Certainly Root E1 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop certainlyroote1 DEFAULT - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certainlyroote1 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop certainlyroote1 DEFAULT + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop certainlyroote1 DEFAULT */ /* @@ -517,9 +517,9 @@ * @summary Interoperability tests with GlobalSign Root R46 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsignr46 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsignr46 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop globalsignr46 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop globalsignr46 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsignr46 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop globalsignr46 CRL */ /* @@ -528,13 +528,15 @@ * @summary Interoperability tests with GlobalSign Root E46 * @library /test/lib * @build jtreg.SkippedException ValidatePathWithURL CAInterop - * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop globalsigne46 OCSP - * @run main/othervm -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsigne46 OCSP - * @run main/othervm -Djava.security.debug=certpath CAInterop globalsigne46 CRL + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop globalsigne46 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp -Dcom.sun.security.ocsp.useget=false CAInterop globalsigne46 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop globalsigne46 CRL */ /** - * Collection of certificate validation tests for interoperability with external CAs + * Collection of certificate validation tests for interoperability with external CAs. + * These tests are marked as manual as they depend on external infrastructure and may fail + * with external reasons, for instance - change in CA test portal. */ public class CAInterop { diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaCA.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaCA.java index f1dd2d6229a..eb09d56a14e 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaCA.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CertignaCA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, 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,8 +26,8 @@ * @bug 8245654 8256895 * @summary Interoperability tests with Certigna Root CAs from Dhimyotis * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath CertignaCA OCSP - * @run main/othervm -Djava.security.debug=certpath CertignaCA CRL + * @run main/othervm/manual -Djava.security.debug=certpath CertignaCA OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CertignaCA CRL */ public class CertignaCA { // Owner: CN=Certigna Services CA, OID.2.5.4.97=NTRFR-48146308100036, diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DTrustCA.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DTrustCA.java index 152e77907bb..13a2e8044da 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DTrustCA.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DTrustCA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, 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,8 +27,8 @@ * @summary Interoperability tests with "D-Trust Root Class 3 CA 2 2009" and * "D-Trust Root Class 3 CA 2 EV 2009" CAs * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath DTrustCA OCSP - * @run main/othervm -Djava.security.debug=certpath DTrustCA CRL + * @run main/othervm/manual -Djava.security.debug=certpath DTrustCA OCSP + * @run main/othervm/manual -Djava.security.debug=certpath DTrustCA CRL */ public class DTrustCA { diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DigicertCSRootG5.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DigicertCSRootG5.java index 30ad81b1755..4b45bb857ba 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DigicertCSRootG5.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/DigicertCSRootG5.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, 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,8 +26,8 @@ * @bug 8318759 * @summary Interoperability tests with Digicert CS Root G5 certificates * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=ocsp,certpath DigicertCSRootG5 OCSP - * @run main/othervm -Djava.security.debug=certpath DigicertCSRootG5 CRL + * @run main/othervm/manual -Djava.security.debug=ocsp,certpath DigicertCSRootG5 OCSP + * @run main/othervm/manual -Djava.security.debug=certpath DigicertCSRootG5 CRL */ public class DigicertCSRootG5 { diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/EmSignRootG2CA.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/EmSignRootG2CA.java index 8f5df9cce75..14e48a6e78f 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/EmSignRootG2CA.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/EmSignRootG2CA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, 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,8 +26,8 @@ * @bug 8319187 * @summary Interoperability tests with eMudhra emSign Root CA G2 CS root * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath EmSignRootG2CA OCSP - * @run main/othervm -Djava.security.debug=certpath EmSignRootG2CA CRL + * @run main/othervm/manual -Djava.security.debug=certpath EmSignRootG2CA OCSP + * @run main/othervm/manual -Djava.security.debug=certpath EmSignRootG2CA CRL */ public class EmSignRootG2CA { diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/HaricaCA.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/HaricaCA.java index 247502e6e6c..744e9b6bf34 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/HaricaCA.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/HaricaCA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, 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,8 +26,8 @@ * @bug 8256421 * @summary Interoperability tests with Harica CAs * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath HaricaCA OCSP - * @run main/othervm -Djava.security.debug=certpath HaricaCA CRL + * @run main/othervm/manual -Djava.security.debug=certpath HaricaCA OCSP + * @run main/othervm/manual -Djava.security.debug=certpath HaricaCA CRL */ /* diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java index 469501c70c2..3e9631848c2 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/LuxTrustCA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, 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,8 +26,8 @@ * @bug 8232019 8256895 * @summary Interoperability tests with LuxTrust Global Root 2 CA * @build ValidatePathWithParams - * @run main/othervm -Djava.security.debug=certpath LuxTrustCA OCSP - * @run main/othervm -Djava.security.debug=certpath LuxTrustCA CRL + * @run main/othervm/manual -Djava.security.debug=certpath LuxTrustCA OCSP + * @run main/othervm/manual -Djava.security.debug=certpath LuxTrustCA CRL */ /* diff --git a/test/jdk/security/infra/javax/net/ssl/HttpsURLConnectionTest.java b/test/jdk/security/infra/javax/net/ssl/HttpsURLConnectionTest.java index 7aeb67e842d..7e08d6cd4fe 100644 --- a/test/jdk/security/infra/javax/net/ssl/HttpsURLConnectionTest.java +++ b/test/jdk/security/infra/javax/net/ssl/HttpsURLConnectionTest.java @@ -28,7 +28,7 @@ * KEYCHAINSTORE-ROOT trust store * @library /test/lib * @requires os.family == "mac" - * @run main/othervm HttpsURLConnectionTest https://github.com KeychainStore-Root + * @run main/othervm/manual HttpsURLConnectionTest https://github.com KeychainStore-Root */ import java.io.*; import java.net.*; From bbf459c3379038bca1f4fe3671d6476875d68802 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Mon, 24 Jun 2024 06:30:12 +0000 Subject: [PATCH 10/61] 8334708: FFM: two javadoc problems Reviewed-by: jpai Backport-of: a35895765baef678f1105b63b50f2c548971ab11 --- src/java.base/share/classes/java/lang/foreign/Linker.java | 2 +- src/java.base/share/classes/java/lang/foreign/MemoryLayout.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/foreign/Linker.java b/src/java.base/share/classes/java/lang/foreign/Linker.java index 545a83984f8..fd6e820d016 100644 --- a/src/java.base/share/classes/java/lang/foreign/Linker.java +++ b/src/java.base/share/classes/java/lang/foreign/Linker.java @@ -222,7 +222,7 @@ *

  * MemoryLayout.structLayout(
  *     ValueLayout.JAVA_INT.withName("x"),
- *     MemoryLayout.paddingLayout(32),
+ *     MemoryLayout.paddingLayout(4),
  *     ValueLayout.JAVA_LONG.withName("y")
  * );
  * 
diff --git a/src/java.base/share/classes/java/lang/foreign/MemoryLayout.java b/src/java.base/share/classes/java/lang/foreign/MemoryLayout.java index 372b10aab13..989fc134a26 100644 --- a/src/java.base/share/classes/java/lang/foreign/MemoryLayout.java +++ b/src/java.base/share/classes/java/lang/foreign/MemoryLayout.java @@ -369,7 +369,7 @@ * int size = ... * MemorySegment points = ... * for (int i = 0 ; i < size ; i++) { - * ... POINT_ARR_X.get(segment, 0L, (long)i) ... + * ... POINT_ARR_X.get(points, 0L, (long)i) ... * } * } * From 2f8b8872a4ba6f040e9ddd72a34ee8a922341eea Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Mon, 24 Jun 2024 09:53:50 +0000 Subject: [PATCH 11/61] 8333358: java/io/IO/IO.java test fails intermittently Reviewed-by: prappo Backport-of: 77534fc75ac4092f1318aadb0e3e452bbd9094c2 --- test/jdk/java/io/IO/IO.java | 48 ++++++++++++++++++++++++++++++++++ test/jdk/java/io/IO/input.exp | 4 ++- test/jdk/java/io/IO/output.exp | 21 +++++++++++---- 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/test/jdk/java/io/IO/IO.java b/test/jdk/java/io/IO/IO.java index 1a9a25c90c7..328c189fb2f 100644 --- a/test/jdk/java/io/IO/IO.java +++ b/test/jdk/java/io/IO/IO.java @@ -21,6 +21,7 @@ * questions. */ +import java.lang.reflect.Method; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -34,6 +35,10 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.condition.EnabledOnOs; import org.junit.jupiter.api.condition.OS; +import org.junit.jupiter.api.extension.AfterTestExecutionCallback; +import org.junit.jupiter.api.extension.BeforeTestExecutionCallback; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -48,6 +53,7 @@ * @library /test/lib * @run junit IO */ +@ExtendWith(IO.TimingExtension.class) public class IO { @Nested @@ -62,6 +68,11 @@ public static void prepareTTY() { if (!Files.exists(expect) || !Files.isExecutable(expect)) { Assumptions.abort("'" + expect + "' not found"); } + try { + var outputAnalyzer = ProcessTools.executeProcess( + expect.toAbsolutePath().toString(), "-version"); + outputAnalyzer.reportDiagnosticSummary(); + } catch (Exception _) { } } /* @@ -174,4 +185,41 @@ public void nullConsole(String method) throws Exception { assertEquals(1, output.getExitValue()); output.shouldContain("Exception in thread \"main\" java.io.IOError"); } + + + // adapted from https://junit.org/junit5/docs/current/user-guide/#extensions-lifecycle-callbacks-timing-extension + // remove after CODETOOLS-7903752 propagates to jtreg that this test is routinely run by + + public static class TimingExtension implements BeforeTestExecutionCallback, + AfterTestExecutionCallback { + + private static final System.Logger logger = System.getLogger( + TimingExtension.class.getName()); + + private static final String START_TIME = "start time"; + + @Override + public void beforeTestExecution(ExtensionContext context) { + getStore(context).put(START_TIME, time()); + } + + @Override + public void afterTestExecution(ExtensionContext context) { + Method testMethod = context.getRequiredTestMethod(); + long startTime = getStore(context).remove(START_TIME, long.class); + long duration = time() - startTime; + + logger.log(System.Logger.Level.INFO, () -> + String.format("Method [%s] took %s ms.", testMethod.getName(), duration)); + } + + private ExtensionContext.Store getStore(ExtensionContext context) { + return context.getStore(ExtensionContext.Namespace.create(getClass(), + context.getRequiredTestMethod())); + } + + private long time() { + return System.nanoTime() / 1_000_000; + } + } } diff --git a/test/jdk/java/io/IO/input.exp b/test/jdk/java/io/IO/input.exp index ba86b57b131..6f17a1379ec 100644 --- a/test/jdk/java/io/IO/input.exp +++ b/test/jdk/java/io/IO/input.exp @@ -23,6 +23,7 @@ set prompt [lindex $argv $argc-1] set stty_init "rows 24 cols 80" +set timeout -1 spawn {*}$argv expect { @@ -30,7 +31,8 @@ expect { send "hello\r" } timeout { - puts "timeout"; exit 1 + puts "timeout" + exit 1 } } expect eof diff --git a/test/jdk/java/io/IO/output.exp b/test/jdk/java/io/IO/output.exp index 9044912cfaf..a792b8791a4 100644 --- a/test/jdk/java/io/IO/output.exp +++ b/test/jdk/java/io/IO/output.exp @@ -21,12 +21,23 @@ # questions. # -################################################################################ -# This script does not expect/verify anything and is only used to simulate tty # -################################################################################ +# This script doesn't verify any output strings, it's only used to simulate tty -# Use `noecho` below, otherwise, expect will output the expanded "spawn ..." +set stty_init "rows 24 cols 80" +set timeout -1 + +# Use `-noecho` below, otherwise, expect will output the expanded "spawn ..." # command, which will interfere with asserting output from the java test +# counterpart spawn -noecho {*}$argv -expect eof + +expect { + eof { + exit 0 + } + timeout { + puts "timeout" + exit 1 + } +} From 6632889314616ac58e088a4199624dfe3e6574d2 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Mon, 24 Jun 2024 12:38:19 +0000 Subject: [PATCH 12/61] 8334762: [BACKOUT BACKPORT] Improve error for illegal early access from nested class Reviewed-by: liach, mcimadamore --- .../classes/com/sun/tools/javac/comp/Attr.java | 3 ++- .../classes/com/sun/tools/javac/comp/Enter.java | 1 - .../AnonymousInSuperCallNegTest.out | 2 +- .../tools/javac/LocalClassCtorPrologue.out | 2 +- .../EarlyInnerAccessErrorMessageTest.java | 16 ---------------- .../EarlyInnerAccessErrorMessageTest.out | 4 ---- .../tools/javac/SuperInit/EarlyLocalClass.out | 2 +- 7 files changed, 5 insertions(+), 25 deletions(-) delete mode 100644 test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.java delete mode 100644 test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.out diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 08c37fc5aa4..533541bd108 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -950,6 +950,7 @@ public void visitClassDef(JCClassDecl tree) { Optional.ofNullable(env.info.attributionMode.isSpeculative ? argumentAttr.withLocalCacheContext() : null); boolean ctorProloguePrev = env.info.ctorPrologue; + env.info.ctorPrologue = false; try { // Local and anonymous classes have not been entered yet, so we need to // do it now. @@ -994,7 +995,7 @@ public void visitMethodDef(JCMethodDecl tree) { Lint lint = env.info.lint.augment(m); Lint prevLint = chk.setLint(lint); boolean ctorProloguePrev = env.info.ctorPrologue; - Assert.check(!env.info.ctorPrologue); + env.info.ctorPrologue = false; MethodSymbol prevMethod = chk.setMethod(m); try { deferredLintHandler.flush(tree.pos(), lint); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java index 926be3b6e26..7478ef1c907 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java @@ -209,7 +209,6 @@ public Env classEnv(JCClassDecl tree, Env env) { localEnv.info.lint = null; // leave this to be filled in by Attr, // when annotations have been processed localEnv.info.isAnonymousDiamond = TreeInfo.isDiamond(env.tree); - localEnv.info.ctorPrologue = false; return localEnv; } diff --git a/test/langtools/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out b/test/langtools/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out index c04b45bce1e..140521689a0 100644 --- a/test/langtools/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out +++ b/test/langtools/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out @@ -1,2 +1,2 @@ -AnonymousInSuperCallNegTest.java:23:49: compiler.err.cant.ref.before.ctor.called: x +AnonymousInSuperCallNegTest.java:23:49: compiler.err.no.encl.instance.of.type.in.scope: AnonymousInSuperCallNegTest.JavacBug 1 error diff --git a/test/langtools/tools/javac/LocalClassCtorPrologue.out b/test/langtools/tools/javac/LocalClassCtorPrologue.out index 65f3418825d..f1a999af491 100644 --- a/test/langtools/tools/javac/LocalClassCtorPrologue.out +++ b/test/langtools/tools/javac/LocalClassCtorPrologue.out @@ -1,4 +1,4 @@ -LocalClassCtorPrologue.java:16:17: compiler.err.cant.ref.before.ctor.called: x +LocalClassCtorPrologue.java:16:17: compiler.err.no.encl.instance.of.type.in.scope: LocalClassCtorPrologue - compiler.note.preview.filename: LocalClassCtorPrologue.java, DEFAULT - compiler.note.preview.recompile 1 error diff --git a/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.java b/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.java deleted file mode 100644 index a8ee3a2aea5..00000000000 --- a/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * @test /nodynamiccopyright/ - * @bug 8334488 - * @summary Verify the error message generated for early access from inner class - * @compile/fail/ref=EarlyInnerAccessErrorMessageTest.out -XDrawDiagnostics EarlyInnerAccessErrorMessageTest.java - * @enablePreview - */ -public class EarlyInnerAccessErrorMessageTest { - int x; - EarlyInnerAccessErrorMessageTest() { - class Inner { - { System.out.println(x); } - } - super(); - } -} diff --git a/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.out b/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.out deleted file mode 100644 index a8d690a4c23..00000000000 --- a/test/langtools/tools/javac/SuperInit/EarlyInnerAccessErrorMessageTest.out +++ /dev/null @@ -1,4 +0,0 @@ -EarlyInnerAccessErrorMessageTest.java:12:34: compiler.err.cant.ref.before.ctor.called: x -- compiler.note.preview.filename: EarlyInnerAccessErrorMessageTest.java, DEFAULT -- compiler.note.preview.recompile -1 error diff --git a/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out b/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out index ee01f9c403d..390b68ea2c9 100644 --- a/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out +++ b/test/langtools/tools/javac/SuperInit/EarlyLocalClass.out @@ -1,4 +1,4 @@ -EarlyLocalClass.java:12:32: compiler.err.cant.ref.before.ctor.called: this +EarlyLocalClass.java:12:32: compiler.err.no.encl.instance.of.type.in.scope: EarlyLocalClass - compiler.note.preview.filename: EarlyLocalClass.java, DEFAULT - compiler.note.preview.recompile 1 error From e7141a5f08e9b5be330803316c0aed4e1daef7a8 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Mon, 24 Jun 2024 12:57:37 +0000 Subject: [PATCH 13/61] 8333748: javap crash - Fatal error: Unmatched bit position 0x2 for location CLASS Reviewed-by: asotona Backport-of: 4a5ef154de1e90ac0c30c7a271c3b335607ea757 --- .../com/sun/tools/javap/AttributeWriter.java | 4 +- .../com/sun/tools/javap/BasicWriter.java | 42 +++++- .../com/sun/tools/javap/ClassWriter.java | 70 ++-------- .../tools/javap/UndefinedAccessFlagTest.java | 128 ++++++++++++++++++ 4 files changed, 184 insertions(+), 60 deletions(-) create mode 100644 test/langtools/tools/javap/UndefinedAccessFlagTest.java diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java index 839ac2fd041..3b9336c499d 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, 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 @@ -208,7 +208,7 @@ public void write(Attribute a, CodeAttribute lr) { indent(+1); first = false; } - for (var flag : info.flags()) { + for (var flag : maskToAccessFlagsReportUnknown(access_flags, AccessFlag.Location.INNER_CLASS)) { if (flag.sourceModifier() && (flag != AccessFlag.ABSTRACT || !info.has(AccessFlag.INTERFACE))) { print(Modifier.toString(flag.mask()) + " "); diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/BasicWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/BasicWriter.java index 8629957f907..64eecf92082 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/BasicWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/BasicWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, 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,12 @@ package com.sun.tools.javap; import java.io.PrintWriter; +import java.lang.classfile.AccessFlags; +import java.lang.reflect.AccessFlag; +import java.lang.reflect.Modifier; +import java.util.EnumMap; +import java.util.Map; +import java.util.Set; import java.util.function.Supplier; /* @@ -38,6 +44,26 @@ * deletion without notice. */ public class BasicWriter { + private static final Map LOCATION_MASKS; + + static { + var map = new EnumMap(AccessFlag.Location.class); + for (var loc : AccessFlag.Location.values()) { + map.put(loc, 0); + } + + for (var flag : AccessFlag.values()) { + for (var loc : flag.locations()) { + map.compute(loc, (_, v) -> v | flag.mask()); + } + } + + // Peculiarities from AccessFlag.maskToAccessFlag + map.compute(AccessFlag.Location.METHOD, (_, v) -> v | Modifier.STRICT); + + LOCATION_MASKS = map; + } + protected BasicWriter(Context context) { lineWriter = LineWriter.instance(context); out = context.get(PrintWriter.class); @@ -46,6 +72,20 @@ protected BasicWriter(Context context) { throw new AssertionError(); } + protected Set flagsReportUnknown(AccessFlags flags) { + return maskToAccessFlagsReportUnknown(flags.flagsMask(), flags.location()); + } + + protected Set maskToAccessFlagsReportUnknown(int mask, AccessFlag.Location location) { + try { + return AccessFlag.maskToAccessFlags(mask, location); + } catch (IllegalArgumentException ex) { + mask &= LOCATION_MASKS.get(location); + report("Access Flags: " + ex.getMessage()); + return AccessFlag.maskToAccessFlags(mask, location); + } + } + protected void print(String s) { lineWriter.print(s); } diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java index edf3d803af3..2483e99e49a 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java @@ -417,7 +417,7 @@ protected void writeField(FieldModel f) { return; var flags = AccessFlags.ofField(f.flags().flagsMask()); - writeModifiers(flags.flags().stream().filter(fl -> fl.sourceModifier()) + writeModifiers(flagsReportUnknown(flags).stream().filter(fl -> fl.sourceModifier()) .map(fl -> Modifier.toString(fl.mask())).toList()); print(() -> sigPrinter.print( f.findAttribute(Attributes.signature()) @@ -446,7 +446,7 @@ protected void writeField(FieldModel f) { if (options.verbose) writeList(String.format("flags: (0x%04x) ", flags.flagsMask()), - flags.flags().stream().map(fl -> "ACC_" + fl.name()).toList(), + flagsReportUnknown(flags).stream().map(fl -> "ACC_" + fl.name()).toList(), "\n"); if (options.showAllAttrs) { @@ -478,7 +478,7 @@ protected void writeMethod(MethodModel m) { int flags = m.flags().flagsMask(); var modifiers = new ArrayList(); - for (var f : AccessFlags.ofMethod(flags).flags()) + for (var f : flagsReportUnknown(m.flags())) if (f.sourceModifier()) modifiers.add(Modifier.toString(f.mask())); String name = "???"; @@ -561,7 +561,7 @@ protected void writeMethod(MethodModel m) { StringBuilder sb = new StringBuilder(); String sep = ""; sb.append(String.format("flags: (0x%04x) ", flags)); - for (var f : AccessFlags.ofMethod(flags).flags()) { + for (var f : flagsReportUnknown(m.flags())) { sb.append(sep).append("ACC_").append(f.name()); sep = ", "; } @@ -794,17 +794,9 @@ else switch (c) { } } - private static Set getClassModifiers(int mask) { - return getModifiers(AccessFlags.ofClass((mask & ACC_INTERFACE) != 0 - ? mask & ~ACC_ABSTRACT : mask).flags()); - } - - private static Set getMethodModifiers(int mask) { - return getModifiers(AccessFlags.ofMethod(mask).flags()); - } - - private static Set getFieldModifiers(int mask) { - return getModifiers(AccessFlags.ofField(mask).flags()); + private Set getClassModifiers(int mask) { + return getModifiers(flagsReportUnknown(AccessFlags.ofClass((mask & ACC_INTERFACE) != 0 + ? mask & ~ACC_ABSTRACT : mask))); } private static Set getModifiers(Set flags) { @@ -814,16 +806,16 @@ private static Set getModifiers(Set flags) return s; } - private static Set getClassFlags(int mask) { - return getFlags(mask, AccessFlags.ofClass(mask).flags()); + private Set getClassFlags(int mask) { + return getFlags(mask, flagsReportUnknown(AccessFlags.ofClass(mask))); } - private static Set getMethodFlags(int mask) { - return getFlags(mask, AccessFlags.ofMethod(mask).flags()); + private Set getMethodFlags(int mask) { + return getFlags(mask, flagsReportUnknown(AccessFlags.ofMethod(mask))); } - private static Set getFieldFlags(int mask) { - return getFlags(mask, AccessFlags.ofField(mask).flags()); + private Set getFieldFlags(int mask) { + return getFlags(mask, flagsReportUnknown(AccessFlags.ofField(mask))); } private static Set getFlags(int mask, Set flags) { @@ -840,42 +832,6 @@ private static Set getFlags(int mask, Set return s; } - public static enum AccessFlag { - ACC_PUBLIC (ClassFile.ACC_PUBLIC, "public", true, true, true, true ), - ACC_PRIVATE (ClassFile.ACC_PRIVATE, "private", false, true, true, true ), - ACC_PROTECTED (ClassFile.ACC_PROTECTED, "protected", false, true, true, true ), - ACC_STATIC (ClassFile.ACC_STATIC, "static", false, true, true, true ), - ACC_FINAL (ClassFile.ACC_FINAL, "final", true, true, true, true ), - ACC_SUPER (ClassFile.ACC_SUPER, null, true, false, false, false), - ACC_SYNCHRONIZED(ClassFile.ACC_SYNCHRONIZED, "synchronized", false, false, false, true ), - ACC_VOLATILE (ClassFile.ACC_VOLATILE, "volatile", false, false, true, false), - ACC_BRIDGE (ClassFile.ACC_BRIDGE, null, false, false, false, true ), - ACC_TRANSIENT (ClassFile.ACC_TRANSIENT, "transient", false, false, true, false), - ACC_VARARGS (ClassFile.ACC_VARARGS, null, false, false, false, true ), - ACC_NATIVE (ClassFile.ACC_NATIVE, "native", false, false, false, true ), - ACC_INTERFACE (ClassFile.ACC_INTERFACE, null, true, true, false, false), - ACC_ABSTRACT (ClassFile.ACC_ABSTRACT, "abstract", true, true, false, true ), - ACC_STRICT (ClassFile.ACC_STRICT, "strictfp", false, false, false, true ), - ACC_SYNTHETIC (ClassFile.ACC_SYNTHETIC, null, true, true, true, true ), - ACC_ANNOTATION (ClassFile.ACC_ANNOTATION, null, true, true, false, false), - ACC_ENUM (ClassFile.ACC_ENUM, null, true, true, true, false), - ACC_MODULE (ClassFile.ACC_MODULE, null, true, false, false, false); - - public final int flag; - public final String modifier; - public final boolean isClass, isInnerClass, isField, isMethod; - - AccessFlag(int flag, String modifier, boolean isClass, - boolean isInnerClass, boolean isField, boolean isMethod) { - this.flag = flag; - this.modifier = modifier; - this.isClass = isClass; - this.isInnerClass = isInnerClass; - this.isField = isField; - this.isMethod = isMethod; - } - } - private final Options options; private final AttributeWriter attrWriter; private final CodeWriter codeWriter; diff --git a/test/langtools/tools/javap/UndefinedAccessFlagTest.java b/test/langtools/tools/javap/UndefinedAccessFlagTest.java new file mode 100644 index 00000000000..bb531fa369c --- /dev/null +++ b/test/langtools/tools/javap/UndefinedAccessFlagTest.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2024, 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 8333748 + * @summary javap should not fail if reserved access flag bits are set to 1 + * @library /tools/lib + * @modules jdk.jdeps/com.sun.tools.javap + * @enablePreview + * @run junit UndefinedAccessFlagTest + */ + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import toolbox.JavapTask; +import toolbox.Task; +import toolbox.ToolBox; + +import java.lang.classfile.AccessFlags; +import java.lang.classfile.ClassModel; +import java.lang.classfile.FieldModel; +import java.lang.classfile.MethodModel; +import java.lang.classfile.attribute.InnerClassInfo; +import java.lang.classfile.attribute.InnerClassesAttribute; +import java.nio.file.Files; +import java.nio.file.Path; + +import static java.lang.classfile.ClassFile.*; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class UndefinedAccessFlagTest { + + final ToolBox toolBox = new ToolBox(); + + enum TestLocation { + NONE(false), CLASS, FIELD, METHOD, INNER_CLASS(false); + + final boolean fails; + TestLocation() { this(true); } + TestLocation(boolean fails) { this.fails = fails; } + } + + @ParameterizedTest + @EnumSource(TestLocation.class) + void test(TestLocation location) throws Throwable { + var cf = of(); + ClassModel cm; + try (var is = UndefinedAccessFlagTest.class.getResourceAsStream( + "/UndefinedAccessFlagTest$SampleInnerClass.class" + )) { + cm = cf.parse(is.readAllBytes()); + } + var bytes = cf.transform(cm, (cb, ce) -> { + switch (ce) { + case AccessFlags flags when location == TestLocation.CLASS -> cb + .withFlags(flags.flagsMask() | ACC_PRIVATE); + case FieldModel f when location == TestLocation.FIELD -> cb + .transformField(f, (fb, fe) -> { + if (fe instanceof AccessFlags flags) { + fb.withFlags(flags.flagsMask() | ACC_SYNCHRONIZED); + } else { + fb.with(fe); + } + }); + case MethodModel m when location == TestLocation.METHOD -> cb + .transformMethod(m, (mb, me) -> { + if (me instanceof AccessFlags flags) { + mb.withFlags(flags.flagsMask() | ACC_INTERFACE); + } else { + mb.with(me); + } + }); + case InnerClassesAttribute attr when location == TestLocation.INNER_CLASS -> cb + .with(InnerClassesAttribute.of(attr.classes().stream() + .map(ic -> InnerClassInfo.of(ic.innerClass(), ic.outerClass(), ic.innerName(), ic.flagsMask() | 0x0020)) + .toList())); + default -> cb.with(ce); + } + }); + + Files.write(Path.of("transformed.class"), bytes); + + var lines = new JavapTask(toolBox) + .classes("transformed.class") + .options("-c", "-p", "-v") + .run(location.fails ? Task.Expect.FAIL : Task.Expect.SUCCESS) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + + // No termination when access flag error happens + assertTrue(lines.stream().anyMatch(l -> l.contains("java.lang.String field;"))); + assertTrue(lines.stream().anyMatch(l -> l.contains("UndefinedAccessFlagTest$SampleInnerClass();"))); + assertTrue(lines.stream().anyMatch(l -> l.contains("void method();"))); + assertTrue(lines.stream().anyMatch(l -> l.contains("SampleInnerClass=class UndefinedAccessFlagTest$SampleInnerClass of class UndefinedAccessFlagTest"))); + + // Remove non-error lines + assertTrue(lines.removeIf(st -> !st.startsWith("Error:"))); + // Desired locations has errors + assertTrue(location == TestLocation.NONE || !lines.isEmpty()); + // Access Flag errors only + assertTrue(lines.stream().allMatch(l -> l.contains("Access Flags:")), () -> String.join("\n", lines)); + } + + static class SampleInnerClass { + String field; + void method() {} + } +} From 8447d006849b404350965338faa350a07ccb7125 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Mon, 24 Jun 2024 17:26:11 +0000 Subject: [PATCH 14/61] 8334509: Cancelling PageDialog does not return the same PageFormat object Reviewed-by: prr Backport-of: be7f663143fbcf807b7c01d3d5741ab8bd800974 --- .../native/libawt/windows/awt_PrintJob.cpp | 16 ++--- .../PrinterJob/PageDialogCancelTest.java | 58 +++++++++++++++++++ 2 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 test/jdk/java/awt/print/PrinterJob/PageDialogCancelTest.java diff --git a/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp b/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp index c7615336218..9f126bded94 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp @@ -522,6 +522,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) AwtComponent *awtParent = (parent != NULL) ? (AwtComponent *)JNI_GET_PDATA(parent) : NULL; HWND hwndOwner = awtParent ? awtParent->GetHWnd() : NULL; + jboolean doIt = JNI_FALSE; PAGESETUPDLG setup; memset(&setup, 0, sizeof(setup)); @@ -577,7 +578,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) */ if ((setup.hDevMode == NULL) && (setup.hDevNames == NULL)) { CLEANUP_SHOW; - return JNI_FALSE; + return doIt; } } else { int measure = PSD_INTHOUSANDTHSOFINCHES; @@ -605,7 +606,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) pageFormatToSetup(env, self, page, &setup, AwtPrintControl::getPrintDC(env, self)); if (env->ExceptionCheck()) { CLEANUP_SHOW; - return JNI_FALSE; + return doIt; } setup.lpfnPageSetupHook = reinterpret_cast(pageDlgHook); @@ -619,7 +620,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) jobject paper = getPaper(env, page); if (paper == NULL) { CLEANUP_SHOW; - return JNI_FALSE; + return doIt; } int units = setup.Flags & PSD_INTHOUSANDTHSOFINCHES ? MM_HIENGLISH : @@ -661,7 +662,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) setPaperValues(env, paper, &paperSize, &margins, units); if (env->ExceptionCheck()) { CLEANUP_SHOW; - return JNI_FALSE; + return doIt; } /* * Put the updated Paper instance and the orientation into @@ -670,7 +671,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) setPaper(env, page, paper); if (env->ExceptionCheck()) { CLEANUP_SHOW; - return JNI_FALSE; + return doIt; } setPageFormatOrientation(env, page, orientation); if (env->ExceptionCheck()) { @@ -684,12 +685,13 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) jboolean err = setPrintPaperSize(env, self, devmode->dmPaperSize); if (err) { CLEANUP_SHOW; - return JNI_FALSE; + return doIt; } } } ::GlobalUnlock(setup.hDevMode); } + doIt = JNI_TRUE; } AwtDialog::CheckUninstallModalHook(); @@ -708,7 +710,7 @@ Java_sun_awt_windows_WPageDialogPeer__1show(JNIEnv *env, jobject peer) CLEANUP_SHOW; - return JNI_TRUE; + return doIt; CATCH_BAD_ALLOC_RET(0); } diff --git a/test/jdk/java/awt/print/PrinterJob/PageDialogCancelTest.java b/test/jdk/java/awt/print/PrinterJob/PageDialogCancelTest.java new file mode 100644 index 00000000000..f9ce1b7c196 --- /dev/null +++ b/test/jdk/java/awt/print/PrinterJob/PageDialogCancelTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024, 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 8334366 + * @key headful printer + * @summary Verifies original pageobject is returned unmodified + * on cancelling pagedialog + * @requires (os.family == "windows") + * @run main PageDialogCancelTest + */ + +import java.awt.Robot; +import java.awt.event.KeyEvent; +import java.awt.print.PageFormat; +import java.awt.print.PrinterJob; + +public class PageDialogCancelTest { + + public static void main(String[] args) throws Exception { + PrinterJob pj = PrinterJob.getPrinterJob(); + PageFormat oldFormat = new PageFormat(); + Robot robot = new Robot(); + Thread t1 = new Thread(() -> { + robot.delay(2000); + robot.keyPress(KeyEvent.VK_ESCAPE); + robot.keyRelease(KeyEvent.VK_ESCAPE); + robot.waitForIdle(); + }); + t1.start(); + PageFormat newFormat = pj.pageDialog(oldFormat); + if (!newFormat.equals(oldFormat)) { + throw new RuntimeException("Original PageFormat not returned on cancelling PageDialog"); + } + } +} + From d5427ffd9dcb1b38b946ba85a608c3ff86b77df5 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Mon, 24 Jun 2024 17:53:14 +0000 Subject: [PATCH 15/61] 8323196: jdk/jfr/api/consumer/filestream/TestOrdered.java failed with "Events are not ordered! Reuse = false" Reviewed-by: mgronlun Backport-of: e2f266591cb352c08d980ce0cdf9c3b1f59b92ba --- .../api/consumer/filestream/TestOrdered.java | 58 ++++++++++++------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java b/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java index 8edb74b847a..58f23350dd0 100644 --- a/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java +++ b/test/jdk/jdk/jfr/api/consumer/filestream/TestOrdered.java @@ -29,6 +29,7 @@ import java.util.List; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import jdk.jfr.Event; @@ -143,28 +144,43 @@ private static void printTimestamp(Instant timestamp) { } private static Path makeUnorderedRecording() throws Exception { - CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); - - try (Recording r = new Recording()) { - r.start(); - List emitters = new ArrayList<>(); - for (int i = 0; i < THREAD_COUNT; i++) { - Emitter e = new Emitter(barrier); - e.start(); - emitters.add(e); - } - // Thread buffers should now have one event each - barrier.await(); - // Add another event to each thread buffer, so - // events are bound to come out of order when they - // are flushed - for (Emitter e : emitters) { - e.join(); + while (true) { + CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1); + try (Recording r = new Recording()) { + r.start(); + List emitters = new ArrayList<>(); + for (int i = 0; i < THREAD_COUNT; i++) { + Emitter e = new Emitter(barrier); + e.start(); + emitters.add(e); + } + // Thread buffers should now have one event each + barrier.await(); + // Add another event to each thread buffer, so + // events are bound to come out of order when they + // are flushed + for (Emitter e : emitters) { + e.join(); + } + r.stop(); + Path p = Utils.createTempFile("recording", ".jfr"); + r.dump(p); + // Order is only guaranteed within a segment. + int segments = countSegments(p); + if (segments < 2) { + return p; + } + System.out.println("File contains more than one segment (" + segments + "). Retrying."); } - r.stop(); - Path p = Utils.createTempFile("recording", ".jfr"); - r.dump(p); - return p; + } + } + + private static int countSegments(Path file) throws Exception { + AtomicInteger segments = new AtomicInteger(); + try (EventStream es = EventStream.openFile(file)) { + es.onFlush(segments::incrementAndGet); + es.start(); + return segments.get(); } } } From 7ddc206871e0653d11c2c74515ac19717597a562 Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Tue, 25 Jun 2024 03:38:09 +0000 Subject: [PATCH 16/61] 8222884: ConcurrentClassDescLookup.java times out intermittently Reviewed-by: mdoerr Backport-of: f1c926e00af359ff9900be0659c5aa68a0161fa2 --- .../ConcurrentClassDescLookup.java | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/test/jdk/java/io/Serializable/concurrentClassDescLookup/ConcurrentClassDescLookup.java b/test/jdk/java/io/Serializable/concurrentClassDescLookup/ConcurrentClassDescLookup.java index 48cbd1b0ffe..196a27b52ba 100644 --- a/test/jdk/java/io/Serializable/concurrentClassDescLookup/ConcurrentClassDescLookup.java +++ b/test/jdk/java/io/Serializable/concurrentClassDescLookup/ConcurrentClassDescLookup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, 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,7 @@ */ import java.io.*; +import java.util.concurrent.CountDownLatch; class Good implements Serializable { private static final long serialVersionUID = 6319710844400051132L; @@ -51,19 +52,20 @@ class Bad implements Serializable { class SuccessfulLookup extends Thread { Class cl; long suid; - Object barrier; + final CountDownLatch lookupLatch; boolean ok; - SuccessfulLookup(Class cl, long suid, Object barrier) { + SuccessfulLookup(Class cl, long suid, CountDownLatch lookupLatch) { this.cl = cl; this.suid = suid; - this.barrier = barrier; + this.lookupLatch = lookupLatch; } public void run() { - synchronized (barrier) { - try { barrier.wait(); } catch (InterruptedException ex) {} - } + lookupLatch.countDown(); // let others know we are ready + try { + lookupLatch.await(); // await for others + } catch (InterruptedException ex) {} for (int i = 0; i < 100; i++) { if (ObjectStreamClass.lookup(cl).getSerialVersionUID() != suid) { return; @@ -75,18 +77,19 @@ public void run() { class FailingLookup extends Thread { Class cl; - final Object barrier; + final CountDownLatch lookupLatch; boolean ok; - FailingLookup(Class cl, Object barrier) { + FailingLookup(Class cl, CountDownLatch lookupLatch) { this.cl = cl; - this.barrier = barrier; + this.lookupLatch = lookupLatch; } public void run() { - synchronized (barrier) { - try { barrier.wait(); } catch (InterruptedException ex) {} - } + lookupLatch.countDown(); // let others know we are ready + try { + lookupLatch.await(); // await for others + } catch (InterruptedException ex) {} for (int i = 0; i < 100; i++) { try { ObjectStreamClass.lookup(cl); @@ -102,39 +105,36 @@ public class ConcurrentClassDescLookup { public static void main(String[] args) throws Exception { ClassLoader loader = ConcurrentClassDescLookup.class.getClassLoader(); Class cl = Class.forName("Good", false, loader); - Object barrier = new Object(); - SuccessfulLookup[] slookups = new SuccessfulLookup[50]; + int numSuccessfulLookups = 50; + CountDownLatch sLookupLatch = new CountDownLatch(numSuccessfulLookups); + SuccessfulLookup[] slookups = new SuccessfulLookup[numSuccessfulLookups]; for (int i = 0; i < slookups.length; i++) { - slookups[i] = - new SuccessfulLookup(cl, 6319710844400051132L, barrier); + slookups[i] = new SuccessfulLookup(cl, 6319710844400051132L, sLookupLatch); slookups[i].start(); } - Thread.sleep(1000); - synchronized (barrier) { - barrier.notifyAll(); - } + System.out.println("awaiting completion of " + slookups.length + " SuccessfulLookup"); for (int i = 0; i < slookups.length; i++) { slookups[i].join(); if (!slookups[i].ok) { throw new Error(); } } - + System.out.println("all " + slookups.length + " SuccessfulLookup completed"); cl = Class.forName("Bad", false, loader); - FailingLookup[] flookups = new FailingLookup[50]; + int numFailingLookups = 50; + CountDownLatch fLookupLatch = new CountDownLatch(numFailingLookups); + FailingLookup[] flookups = new FailingLookup[numFailingLookups]; for (int i = 0; i < flookups.length; i++) { - flookups[i] = new FailingLookup(cl, barrier); + flookups[i] = new FailingLookup(cl, fLookupLatch); flookups[i].start(); } - Thread.sleep(1000); - synchronized (barrier) { - barrier.notifyAll(); - } - for (int i = 0; i < slookups.length; i++) { + System.out.println("awaiting completion of " + flookups.length + " FailingLookup"); + for (int i = 0; i < flookups.length; i++) { flookups[i].join(); if (!flookups[i].ok) { throw new Error(); } } + System.out.println("all " + flookups.length + " FailingLookup completed"); } } From d2c098a0d72a98d24baa4e686ba792213b3d408e Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Wed, 26 Jun 2024 02:59:02 +0000 Subject: [PATCH 17/61] 8334580: Deprecate no-arg constructor BasicSliderUI() for removal Reviewed-by: aivanov Backport-of: 2649ccc759c31485efda0c231f02b48cb48bab2b --- .../share/classes/javax/swing/plaf/basic/BasicSliderUI.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSliderUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSliderUI.java index 7b94bedea0d..ad5cb9c9ab9 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSliderUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSliderUI.java @@ -150,7 +150,10 @@ public class BasicSliderUI extends SliderUI{ /** * Constructs a {@code BasicSliderUI}. + * @deprecated This constructor was exposed erroneously and will be removed in a future release. + * Use {@link #BasicSliderUI(JSlider)} instead. */ + @Deprecated(since = "23", forRemoval = true) public BasicSliderUI() {} /** From 6ff5d96907f68520044232e90728afe6744a767a Mon Sep 17 00:00:00 2001 From: Tobias Hartmann Date: Wed, 26 Jun 2024 10:49:44 +0000 Subject: [PATCH 18/61] 8334629: [BACKOUT] PhaseIdealLoop::conditional_move is too conservative Reviewed-by: chagedorn, qamai Backport-of: a4985b130a086f53c723ea3293f4d85b055b1b3e --- test/hotspot/jtreg/ProblemList.txt | 1 + .../org/openjdk/bench/vm/compiler/CMove.java | 59 ------------------- 2 files changed, 1 insertion(+), 59 deletions(-) delete mode 100644 test/micro/org/openjdk/bench/vm/compiler/CMove.java diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index c1b7551f7d5..a3d27d47b84 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -67,6 +67,7 @@ compiler/c2/Test8004741.java 8235801 generic-all compiler/c2/TestMergeStores.java#id0 8331311 generic-ppc64,linux-s390x compiler/c2/TestMergeStores.java#id1 8331311 generic-ppc64,linux-s390x compiler/c2/irTests/TestDuplicateBackedge.java 8318904 generic-all +compiler/c2/irTests/TestIfMinMax.java 8334816 generic-all compiler/codecache/jmx/PoolsIndependenceTest.java 8264632 macosx-all compiler/codecache/CheckLargePages.java 8332654 linux-x64 diff --git a/test/micro/org/openjdk/bench/vm/compiler/CMove.java b/test/micro/org/openjdk/bench/vm/compiler/CMove.java deleted file mode 100644 index 0f92a681c72..00000000000 --- a/test/micro/org/openjdk/bench/vm/compiler/CMove.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2023, 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 org.openjdk.bench.vm.compiler; - -import java.util.concurrent.TimeUnit; -import java.util.random.RandomGeneratorFactory; -import org.openjdk.jmh.annotations.*; -import org.openjdk.jmh.infra.Blackhole; - -@BenchmarkMode(Mode.AverageTime) -@OutputTimeUnit(TimeUnit.MICROSECONDS) -@State(Scope.Thread) -@Warmup(iterations = 5, time = 1) -@Measurement(iterations = 5, time = 1) -@Fork(value = 1) -public class CMove { - static final int SIZE = 1000000; - - @Param({"0.003", "0.006", "0.01", "0.02", "0.03", "0.06", "0.1", "0.2", "0.3", "0.6"}) - double freq; - - boolean[] conds; - - @Setup(Level.Iteration) - public void setup() { - var r = RandomGeneratorFactory.getDefault().create(1); - conds = new boolean[SIZE]; - for (int i = 0; i < SIZE; i++) { - conds[i] = r.nextDouble() < freq; - } - } - - @Benchmark - public void run(Blackhole bh) { - for (int i = 0; i < conds.length; i++) { - bh.consume(conds[i] ? 2 : 1); - } - } -} \ No newline at end of file From 370d1f8696af938b3b91fbf829bcb32ef2ccafbb Mon Sep 17 00:00:00 2001 From: Volodymyr Paprotski Date: Wed, 26 Jun 2024 15:24:19 +0000 Subject: [PATCH 19/61] 8333583: Crypto-XDH.generateSecret regression after JDK-8329538 Reviewed-by: thartmann, sviswanathan Backport-of: f6cfe8c63f6dfbf50bbdda1d5de3925467239d3c --- .../classes/build/tools/intpoly/FieldGen.java | 10 +- .../util/math/intpoly/IntegerPolynomial.java | 24 ++-- .../math/intpoly/IntegerPolynomial1305.java | 6 +- .../intpoly/IntegerPolynomialModBinP.java | 6 +- .../MontgomeryIntegerPolynomialP256.java | 104 +++++++++--------- 5 files changed, 68 insertions(+), 82 deletions(-) diff --git a/make/jdk/src/classes/build/tools/intpoly/FieldGen.java b/make/jdk/src/classes/build/tools/intpoly/FieldGen.java index 234f5cfce0d..2bf8c5c0b20 100644 --- a/make/jdk/src/classes/build/tools/intpoly/FieldGen.java +++ b/make/jdk/src/classes/build/tools/intpoly/FieldGen.java @@ -778,7 +778,7 @@ private String generate(FieldParams params) throws IOException { result.appendLine("}"); result.appendLine("@Override"); - result.appendLine("protected int mult(long[] a, long[] b, long[] r) {"); + result.appendLine("protected void mult(long[] a, long[] b, long[] r) {"); result.incrIndent(); for (int i = 0; i < 2 * params.getNumLimbs() - 1; i++) { result.appendIndent(); @@ -804,9 +804,6 @@ private String generate(FieldParams params) throws IOException { } } result.append(");\n"); - result.appendIndent(); - result.append("return 0;"); - result.appendLine(); result.decrIndent(); result.appendLine("}"); @@ -836,7 +833,7 @@ private String generate(FieldParams params) throws IOException { // } // } result.appendLine("@Override"); - result.appendLine("protected int square(long[] a, long[] r) {"); + result.appendLine("protected void square(long[] a, long[] r) {"); result.incrIndent(); for (int i = 0; i < 2 * params.getNumLimbs() - 1; i++) { result.appendIndent(); @@ -877,9 +874,6 @@ private String generate(FieldParams params) throws IOException { } } result.append(");\n"); - result.appendIndent(); - result.append("return 0;"); - result.appendLine(); result.decrIndent(); result.appendLine("}"); diff --git a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial.java b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial.java index bb8d727ba98..404c0dbd469 100644 --- a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial.java +++ b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial.java @@ -90,12 +90,11 @@ public abstract sealed class IntegerPolynomial implements IntegerFieldModuloP * store the result in an IntegerPolynomial representation in a. Requires * that a.length == numLimbs. */ - protected int multByInt(long[] a, long b) { + protected void multByInt(long[] a, long b) { for (int i = 0; i < a.length; i++) { a[i] *= b; } reduce(a); - return 0; } /** @@ -104,7 +103,7 @@ protected int multByInt(long[] a, long b) { * a.length == b.length == r.length == numLimbs. It is allowed for a and r * to be the same array. */ - protected abstract int mult(long[] a, long[] b, long[] r); + protected abstract void mult(long[] a, long[] b, long[] r); /** * Multiply an IntegerPolynomial representation (a) with itself and store @@ -112,7 +111,7 @@ protected int multByInt(long[] a, long b) { * a.length == r.length == numLimbs. It is allowed for a and r * to be the same array. */ - protected abstract int square(long[] a, long[] r); + protected abstract void square(long[] a, long[] r); IntegerPolynomial(int bitsPerLimb, int numLimbs, @@ -622,8 +621,8 @@ public ImmutableElement multiply(IntegerModuloP genB) { } long[] newLimbs = new long[limbs.length]; - int numAdds = mult(limbs, b.limbs, newLimbs); - return new ImmutableElement(newLimbs, numAdds); + mult(limbs, b.limbs, newLimbs); + return new ImmutableElement(newLimbs, 0); } @Override @@ -635,8 +634,8 @@ public ImmutableElement square() { } long[] newLimbs = new long[limbs.length]; - int numAdds = IntegerPolynomial.this.square(limbs, newLimbs); - return new ImmutableElement(newLimbs, numAdds); + IntegerPolynomial.this.square(limbs, newLimbs); + return new ImmutableElement(newLimbs, 0); } public void addModPowerTwo(IntegerModuloP arg, byte[] result) { @@ -751,7 +750,8 @@ public MutableElement setProduct(IntegerModuloP genB) { b.numAdds = 0; } - numAdds = mult(limbs, b.limbs, limbs); + mult(limbs, b.limbs, limbs); + numAdds = 0; return this; } @@ -764,7 +764,8 @@ public MutableElement setProduct(SmallValue v) { } int value = ((Limb)v).value; - numAdds += multByInt(limbs, value); + multByInt(limbs, value); + numAdds = 0; return this; } @@ -824,7 +825,8 @@ public MutableElement setSquare() { numAdds = 0; } - numAdds = IntegerPolynomial.this.square(limbs, limbs); + IntegerPolynomial.this.square(limbs, limbs); + numAdds = 0; return this; } diff --git a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial1305.java b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial1305.java index 706651330d3..c4cd6b9da7d 100644 --- a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial1305.java +++ b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomial1305.java @@ -50,7 +50,7 @@ private IntegerPolynomial1305() { super(BITS_PER_LIMB, NUM_LIMBS, 1, MODULUS); } - protected int mult(long[] a, long[] b, long[] r) { + protected void mult(long[] a, long[] b, long[] r) { // Use grade-school multiplication into primitives to avoid the // temporary array allocation. This is equivalent to the following @@ -73,7 +73,6 @@ protected int mult(long[] a, long[] b, long[] r) { long c8 = (a[4] * b[4]); carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8); - return 0; } private void carryReduce(long[] r, long c0, long c1, long c2, long c3, @@ -100,7 +99,7 @@ private void carryReduce(long[] r, long c0, long c1, long c2, long c3, } @Override - protected int square(long[] a, long[] r) { + protected void square(long[] a, long[] r) { // Use grade-school multiplication with a simple squaring optimization. // Multiply into primitives to avoid the temporary array allocation. // This is equivalent to the following code: @@ -123,7 +122,6 @@ protected int square(long[] a, long[] r) { long c8 = (a[4] * a[4]); carryReduce(r, c0, c1, c2, c3, c4, c5, c6, c7, c8); - return 0; } @Override diff --git a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomialModBinP.java b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomialModBinP.java index e57316ed964..3e9b191ddce 100644 --- a/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomialModBinP.java +++ b/src/java.base/share/classes/sun/security/util/math/intpoly/IntegerPolynomialModBinP.java @@ -131,12 +131,11 @@ private void multOnly(long[] a, long[] b, long[] c) { } @Override - protected int mult(long[] a, long[] b, long[] r) { + protected void mult(long[] a, long[] b, long[] r) { long[] c = new long[2 * numLimbs]; multOnly(a, b, c); carryReduce(c, r); - return 0; } private void modReduceInBits(long[] limbs, int index, int bits, long x) { @@ -189,7 +188,7 @@ protected void reduce(long[] a) { } @Override - protected int square(long[] a, long[] r) { + protected void square(long[] a, long[] r) { long[] c = new long[2 * numLimbs]; for (int i = 0; i < numLimbs; i++) { @@ -200,7 +199,6 @@ protected int square(long[] a, long[] r) { } carryReduce(c, r); - return 0; } /** diff --git a/src/java.base/share/classes/sun/security/util/math/intpoly/MontgomeryIntegerPolynomialP256.java b/src/java.base/share/classes/sun/security/util/math/intpoly/MontgomeryIntegerPolynomialP256.java index 3a84b5f5088..e50890bd976 100644 --- a/src/java.base/share/classes/sun/security/util/math/intpoly/MontgomeryIntegerPolynomialP256.java +++ b/src/java.base/share/classes/sun/security/util/math/intpoly/MontgomeryIntegerPolynomialP256.java @@ -31,6 +31,7 @@ import sun.security.util.math.IntegerFieldModuloP; import java.math.BigInteger; import jdk.internal.vm.annotation.IntrinsicCandidate; +import jdk.internal.vm.annotation.ForceInline; // Reference: // - [1] Shay Gueron and Vlad Krasnov "Fast Prime Field Elliptic Curve @@ -103,8 +104,8 @@ public ImmutableElement getElement(BigInteger v) { setLimbsValuePositive(v, vLimbs); // Convert to Montgomery domain - int numAdds = mult(vLimbs, h, montLimbs); - return new ImmutableElement(montLimbs, numAdds); + mult(vLimbs, h, montLimbs); + return new ImmutableElement(montLimbs, 0); } @Override @@ -114,24 +115,6 @@ public SmallValue getSmallValue(int value) { return super.getSmallValue(value); } - /* - * This function is used by IntegerPolynomial.setProduct(SmallValue v) to - * multiply by a small constant (i.e. (int) 1,2,3,4). Instead of doing a - * montgomery conversion followed by a montgomery multiplication, just use - * the spare top (64-BITS_PER_LIMB) bits to multiply by a constant. (See [1] - * Section 4 ) - * - * Will return an unreduced value - */ - @Override - protected int multByInt(long[] a, long b) { - assert (b < (1 << BITS_PER_LIMB)); - for (int i = 0; i < a.length; i++) { - a[i] *= b; - } - return (int) (b - 1); - } - @Override public ImmutableIntegerModuloP fromMontgomery(ImmutableIntegerModuloP n) { assert n.getField() == MontgomeryIntegerPolynomialP256.ONE; @@ -163,10 +146,11 @@ private void halfLimbs(long[] a, long[] r) { } @Override - protected int square(long[] a, long[] r) { - return mult(a, a, r); + protected void square(long[] a, long[] r) { + mult(a, a, r); } + /** * Unrolled Word-by-Word Montgomery Multiplication r = a * b * 2^-260 (mod P) * @@ -174,8 +158,15 @@ protected int square(long[] a, long[] r) { * for a Montgomery Friendly modulus p". Note: Step 6. Skipped; Instead use * numAdds to reuse existing overflow logic. */ + @Override + protected void mult(long[] a, long[] b, long[] r) { + multImpl(a, b, r); + reducePositive(r); + } + + @ForceInline @IntrinsicCandidate - protected int mult(long[] a, long[] b, long[] r) { + private void multImpl(long[] a, long[] b, long[] r) { long aa0 = a[0]; long aa1 = a[1]; long aa2 = a[2]; @@ -408,36 +399,16 @@ protected int mult(long[] a, long[] b, long[] r) { d4 += n4 & LIMB_MASK; c5 += d1 + dd0 + (d0 >>> BITS_PER_LIMB); - c6 += d2 + dd1 + (c5 >>> BITS_PER_LIMB); - c7 += d3 + dd2 + (c6 >>> BITS_PER_LIMB); - c8 += d4 + dd3 + (c7 >>> BITS_PER_LIMB); - c9 = dd4 + (c8 >>> BITS_PER_LIMB); - - c5 &= LIMB_MASK; - c6 &= LIMB_MASK; - c7 &= LIMB_MASK; - c8 &= LIMB_MASK; - - // At this point, the result could overflow by one modulus. - c0 = c5 - modulus[0]; - c1 = c6 - modulus[1] + (c0 >> BITS_PER_LIMB); - c0 &= LIMB_MASK; - c2 = c7 - modulus[2] + (c1 >> BITS_PER_LIMB); - c1 &= LIMB_MASK; - c3 = c8 - modulus[3] + (c2 >> BITS_PER_LIMB); - c2 &= LIMB_MASK; - c4 = c9 - modulus[4] + (c3 >> BITS_PER_LIMB); - c3 &= LIMB_MASK; - - long mask = c4 >> BITS_PER_LIMB; // Signed shift! - - r[0] = ((c5 & mask) | (c0 & ~mask)); - r[1] = ((c6 & mask) | (c1 & ~mask)); - r[2] = ((c7 & mask) | (c2 & ~mask)); - r[3] = ((c8 & mask) | (c3 & ~mask)); - r[4] = ((c9 & mask) | (c4 & ~mask)); - - return 0; + c6 += d2 + dd1; + c7 += d3 + dd2; + c8 += d4 + dd3; + c9 = dd4; + + r[0] = c5; + r[1] = c6; + r[2] = c7; + r[3] = c8; + r[4] = c9; } @Override @@ -516,8 +487,8 @@ public ImmutableElement getElement(byte[] v, int offset, int length, super.encode(v, offset, length, highByte, vLimbs); // Convert to Montgomery domain - int numAdds = mult(vLimbs, h, montLimbs); - return new ImmutableElement(montLimbs, numAdds); + mult(vLimbs, h, montLimbs); + return new ImmutableElement(montLimbs, 0); } /* @@ -556,4 +527,27 @@ protected void reduceIn(long[] limbs, long v, int i) { limbs[i - 5] += (v << 4) & LIMB_MASK; limbs[i - 4] += v >> 48; } + + // Used when limbs a could overflow by one modulus. + @ForceInline + protected void reducePositive(long[] a) { + long aa0 = a[0]; + long aa1 = a[1] + (aa0>>BITS_PER_LIMB); + long aa2 = a[2] + (aa1>>BITS_PER_LIMB); + long aa3 = a[3] + (aa2>>BITS_PER_LIMB); + long aa4 = a[4] + (aa3>>BITS_PER_LIMB); + + long c0 = a[0] - modulus[0]; + long c1 = a[1] - modulus[1] + (c0 >> BITS_PER_LIMB); + long c2 = a[2] - modulus[2] + (c1 >> BITS_PER_LIMB); + long c3 = a[3] - modulus[3] + (c2 >> BITS_PER_LIMB); + long c4 = a[4] - modulus[4] + (c3 >> BITS_PER_LIMB); + long mask = c4 >> BITS_PER_LIMB; // Signed shift! + + a[0] = ((aa0 & mask) | (c0 & ~mask)) & LIMB_MASK; + a[1] = ((aa1 & mask) | (c1 & ~mask)) & LIMB_MASK; + a[2] = ((aa2 & mask) | (c2 & ~mask)) & LIMB_MASK; + a[3] = ((aa3 & mask) | (c3 & ~mask)) & LIMB_MASK; + a[4] = ((aa4 & mask) | (c4 & ~mask)); + } } From 0b4f7241459de12d9ab4108d7127e011d37a59a7 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Thu, 27 Jun 2024 14:01:23 +0000 Subject: [PATCH 20/61] 8324781: runtime/Thread/TestAlwaysPreTouchStacks.java failed with Expected a higher ratio between stack committed and reserved 8325218: gc/parallel/TestAlwaysPreTouchBehavior.java fails Reviewed-by: tschatzl Backport-of: e0f246e90d6549b10cad4c80bcbcae0a642ed434 --- test/hotspot/jtreg/ProblemList.txt | 2 -- .../gc/parallel/TestAlwaysPreTouchBehavior.java | 3 +-- .../runtime/Thread/TestAlwaysPreTouchStacks.java | 14 +++++++++----- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index a3d27d47b84..541376e15f6 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -94,7 +94,6 @@ gc/epsilon/TestMemoryMXBeans.java 8206434 generic-all gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java 8156755 generic-all gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all -gc/parallel/TestAlwaysPreTouchBehavior.java 8325218 linux-all gc/TestAllocHumongousFragment.java#adaptive 8298781 generic-all gc/TestAllocHumongousFragment.java#aggressive 8298781 generic-all gc/TestAllocHumongousFragment.java#iu-aggressive 8298781 generic-all @@ -119,7 +118,6 @@ runtime/StackGuardPages/TestStackGuardPagesNative.java 8303612 linux-all runtime/ErrorHandling/TestDwarf.java#checkDecoder 8305489 linux-all runtime/ErrorHandling/MachCodeFramesInErrorFile.java 8313315 linux-ppc64le runtime/cds/appcds/customLoader/HelloCustom_JFR.java 8241075 linux-all,windows-x64 -runtime/Thread/TestAlwaysPreTouchStacks.java 8324781 linux-all applications/jcstress/accessAtomic.java 8325984 generic-all applications/jcstress/acqrel.java 8325984 generic-all diff --git a/test/hotspot/jtreg/gc/parallel/TestAlwaysPreTouchBehavior.java b/test/hotspot/jtreg/gc/parallel/TestAlwaysPreTouchBehavior.java index 12c03661e0e..3a5b2b557cc 100644 --- a/test/hotspot/jtreg/gc/parallel/TestAlwaysPreTouchBehavior.java +++ b/test/hotspot/jtreg/gc/parallel/TestAlwaysPreTouchBehavior.java @@ -31,7 +31,7 @@ * @requires os.family == "linux" * @requires os.maxMemory > 2G * @library /test/lib - * @run main/othervm -Xmx1g -Xms1g -XX:+UseParallelGC -XX:+AlwaysPreTouch gc.parallel.TestAlwaysPreTouchBehavior + * @run main/othervm -Xmx1g -Xms1g -XX:+UseParallelGC -XX:+AlwaysPreTouch -XX:+UnlockDiagnosticVMOptions -XX:-UseMadvPopulateWrite gc.parallel.TestAlwaysPreTouchBehavior */ import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; @@ -77,4 +77,3 @@ public static void main(String [] args) { Asserts.assertGreaterThanOrEqual(rss, committedMemory, "RSS of this process(" + rss + "kb) should be bigger than or equal to committed heap mem(" + committedMemory + "kb)"); } } - diff --git a/test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java b/test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java index a10f4193234..b12eff0cf84 100644 --- a/test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java +++ b/test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java @@ -27,6 +27,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.concurrent.CyclicBarrier; @@ -89,14 +90,17 @@ public static void main(String[] args) throws Exception { // should show up with fully - or almost fully - committed thread stacks. } else { - - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + ArrayList vmArgs = new ArrayList<>(); + Collections.addAll(vmArgs, "-XX:+UnlockDiagnosticVMOptions", "-Xmx100M", "-XX:+AlwaysPreTouchStacks", - "-XX:NativeMemoryTracking=summary", "-XX:+PrintNMTStatistics", - "TestAlwaysPreTouchStacks", - "test"); + "-XX:NativeMemoryTracking=summary", "-XX:+PrintNMTStatistics"); + if (System.getProperty("os.name").contains("Linux")) { + vmArgs.add("-XX:-UseMadvPopulateWrite"); + } + Collections.addAll(vmArgs, "TestAlwaysPreTouchStacks", "test"); + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(vmArgs); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.reportDiagnosticSummary(); From afab6ad29748a48402d1375e716a164bff4d302b Mon Sep 17 00:00:00 2001 From: Anthony Scarpino Date: Thu, 27 Jun 2024 14:17:56 +0000 Subject: [PATCH 21/61] 8326705: Test CertMsgCheck.java fails to find alert certificate_required Reviewed-by: rhalade Backport-of: 88b971834f7f94f0233f02f058e510f153f9e4da --- test/jdk/ProblemList.txt | 1 - .../net/ssl/SSLSession/CertMsgCheck.java | 29 +++++++++++-------- test/jdk/javax/net/ssl/templates/TLSBase.java | 24 ++++++++------- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 546f95b0054..47a8f09442e 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -616,7 +616,6 @@ com/sun/security/sasl/gsskerb/ConfSecurityLayer.java 8039280 generic- com/sun/security/sasl/gsskerb/NoSecurityLayer.java 8039280 generic-all sun/security/provider/PolicyFile/GrantAllPermToExtWhenNoPolicy.java 8039280 generic-all sun/security/provider/PolicyParser/PrincipalExpansionError.java 8039280 generic-all -javax/net/ssl/SSLSession/CertMsgCheck.java 8326705 generic-all sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java 8316183,8333317 generic-all diff --git a/test/jdk/javax/net/ssl/SSLSession/CertMsgCheck.java b/test/jdk/javax/net/ssl/SSLSession/CertMsgCheck.java index 37c252bc6f0..498c17672b2 100644 --- a/test/jdk/javax/net/ssl/SSLSession/CertMsgCheck.java +++ b/test/jdk/javax/net/ssl/SSLSession/CertMsgCheck.java @@ -40,20 +40,25 @@ public static void main(String[] args) throws Exception { // Initial client session TLSBase.Client client1 = new TLSBase.Client(true, false); - if (server.getSession(client1).getSessionContext() == null) { - for (Exception e : server.getExceptionList()) { - System.out.println("Looking at " + e.getClass() + " " + - e.getMessage()); - if (e.getMessage().contains(args[0])) { - System.out.println("Found correct exception: " + args[0] + + + server.getSession(client1).getSessionContext(); + server.done(); + + var eList = server.getExceptionList(); + System.out.println("Exception list size is " + eList.size()); + + for (Exception e : eList) { + System.out.println("Looking at " + e.getClass() + " " + + e.getMessage()); + if (e.getMessage().contains(args[0])) { + System.out.println("Found correct exception: " + args[0] + " in " + e.getMessage()); - return; - } else { - System.out.println("No \"" + args[0] + "\" found."); - } + return; + } else { + System.out.println("No \"" + args[0] + "\" found."); } - - throw new Exception("Failed to find expected alert: " + args[0]); } + + throw new Exception("Failed to find expected alert: " + args[0]); } } diff --git a/test/jdk/javax/net/ssl/templates/TLSBase.java b/test/jdk/javax/net/ssl/templates/TLSBase.java index 812aea09fea..5c95253e6f0 100644 --- a/test/jdk/javax/net/ssl/templates/TLSBase.java +++ b/test/jdk/javax/net/ssl/templates/TLSBase.java @@ -97,8 +97,8 @@ public void write(SSLSocket sock, byte[] data) throws Exception { private static KeyManager[] getKeyManager(boolean empty) throws Exception { FileInputStream fis = null; if (!empty) { - fis = new FileInputStream(System.getProperty("test.src", "./") + "/" + pathToStores + - "/" + keyStoreFile); + fis = new FileInputStream(System.getProperty("test.src", "./") + + "/" + pathToStores + "/" + keyStoreFile); } // Load the keystore char[] pwd = passwd.toCharArray(); @@ -113,8 +113,8 @@ private static KeyManager[] getKeyManager(boolean empty) throws Exception { private static TrustManager[] getTrustManager(boolean empty) throws Exception { FileInputStream fis = null; if (!empty) { - fis = new FileInputStream(System.getProperty("test.src", "./") + "/" + pathToStores + - "/" + trustStoreFile); + fis = new FileInputStream(System.getProperty("test.src", "./") + + "/" + pathToStores + "/" + trustStoreFile); } // Load the keystore KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); @@ -148,7 +148,6 @@ static class Server extends TLSBase { // Clients sockets are kept in a hash table with the port as the key. ConcurrentHashMap clientMap = new ConcurrentHashMap<>(); - boolean exit = false; Thread t; List exceptionList = new ArrayList<>(); @@ -157,13 +156,14 @@ static class Server extends TLSBase { name = "server"; try { sslContext = SSLContext.getInstance("TLS"); - sslContext.init(TLSBase.getKeyManager(builder.km), TLSBase.getTrustManager(builder.tm), null); + sslContext.init(TLSBase.getKeyManager(builder.km), + TLSBase.getTrustManager(builder.tm), null); fac = sslContext.getServerSocketFactory(); ssock = (SSLServerSocket) fac.createServerSocket(0); ssock.setNeedClientAuth(builder.clientauth); serverPort = ssock.getLocalPort(); } catch (Exception e) { - System.err.println(e.getMessage()); + System.err.println("Failure during server initialization"); e.printStackTrace(); } @@ -178,6 +178,7 @@ static class Server extends TLSBase { try { write(c, read(c)); } catch (Exception e) { + System.out.println("Caught " + e.getMessage()); e.printStackTrace(); exceptionList.add(e); } @@ -203,13 +204,14 @@ static class Server extends TLSBase { name = "server"; try { sslContext = SSLContext.getInstance("TLS"); - sslContext.init(TLSBase.getKeyManager(km), TLSBase.getTrustManager(tm), null); + sslContext.init(TLSBase.getKeyManager(km), + TLSBase.getTrustManager(tm), null); fac = sslContext.getServerSocketFactory(); ssock = (SSLServerSocket) fac.createServerSocket(0); ssock.setNeedClientAuth(true); serverPort = ssock.getLocalPort(); } catch (Exception e) { - System.err.println(e.getMessage()); + System.err.println("Failure during server initialization"); e.printStackTrace(); } @@ -224,7 +226,9 @@ static class Server extends TLSBase { try { write(c, read(c)); } catch (Exception e) { + System.out.println("Caught " + e.getMessage()); e.printStackTrace(); + exceptionList.add(e); } } } catch (Exception ex) { @@ -239,7 +243,7 @@ static class Server extends TLSBase { // test or the test will never end. void done() { try { - t.interrupt(); + t.join(5000); ssock.close(); } catch (Exception e) { System.err.println(e.getMessage()); From fa2fb700b9e1ef96a68d78318dc3d1ab6f800160 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Thu, 27 Jun 2024 19:29:18 +0000 Subject: [PATCH 22/61] 8334421: assert(!oldbox->is_unbalanced()) failed: this should not be called for unbalanced region Reviewed-by: shade, thartmann Backport-of: 8d694869f7660429fe1e425fc39080fa1d9d9214 --- ...oarsenedAndNotEscapedLocksElimination.java | 205 ++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/locks/TestCoarsenedAndNotEscapedLocksElimination.java diff --git a/test/hotspot/jtreg/compiler/locks/TestCoarsenedAndNotEscapedLocksElimination.java b/test/hotspot/jtreg/compiler/locks/TestCoarsenedAndNotEscapedLocksElimination.java new file mode 100644 index 00000000000..4b20ddc0033 --- /dev/null +++ b/test/hotspot/jtreg/compiler/locks/TestCoarsenedAndNotEscapedLocksElimination.java @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2024, 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 8334421 + * @summary C2 incorrectly marks not-escaped locks for elimination after + * coarsened locks were eliminated and created unbalanced regions. + * @requires vm.compMode != "Xint" + * @run main/othervm -XX:-TieredCompilation TestCoarsenedAndNotEscapedLocksElimination + * @run main TestCoarsenedAndNotEscapedLocksElimination + */ + +import java.util.Vector; + +class TestVector extends Vector { + + TestVector() { + super(); + } + + TestVector(int initialCapacity) { + super(initialCapacity); + } + + TestVector(int initialCapacity, int capacityIncrement) { + super(initialCapacity, capacityIncrement); + } + + Object[] getElementData () { + return elementData; // access protected field + } +} + +public class TestCoarsenedAndNotEscapedLocksElimination { + + public static void main(String[] strArr) { + TestCoarsenedAndNotEscapedLocksElimination tc = new TestCoarsenedAndNotEscapedLocksElimination(); + String result = null; + for (int i = 0; i < 12000; ++i) { + result = tc.test(); + if (result != null) break; + } + System.out.println(result == null? "passed" : result); + } + + int [][] vector_types = { + {-1, -1}, + {0, -1}, + {1, -1}, + {2, -1}, + {1025, -1}, + {0, -2}, + {1, -2}, + {2, -2}, + {1025, -2}, + {0, 0}, + {1, 0}, + {2, 0}, + {1025, 0}, + {0, 1}, + {1, 1}, + {2, 1}, + {1025, 1}, + {0, 1025 }, + {1, 1025 }, + {2, 1025 }, + {1025, 1025 } + }; + + Object [] elems = { + null, + new Object(), + new Vector(), + new Object[0] + }; + + int cntr = 0, mode = 0; + + void reset() { + cntr = 0; + mode = 0; + } + + TestVector nextVector() { + if (cntr == vector_types.length) { + return null; + } else { + TestVector vect; + if (vector_types[cntr][0] < 0) { + vect = new TestVector(); + } else if (vector_types[cntr][1] == -2) { + vect = new TestVector(vector_types[cntr][0]); + } else { + vect = new TestVector(vector_types[cntr][0], vector_types[cntr][1]); + } + if (mode == 1) { + vect.addElement(null); + vect.addElement(new Object()); + vect.addElement(new Vector()); + vect.addElement(new Object[0]); + } else if (mode == 2) { + int cap = vect.capacity(); + vect.addElement(null); + for (int i = 0; i < cap; i++) { + vect.addElement(new Object()); + } + } + if (++mode == 3) { + mode = 0; + cntr++; + } + return vect; + } + } + + public String test() { + reset(); + TestVector vect = (TestVector)nextVector(); + while (vect != null) { + Object [] backup_array = new Object[vect.size()]; + System.arraycopy(vect.getElementData(),0,backup_array,0,vect.size()); + + int old_size = vect.size(); + vect.setSize(vect.size()); + if (vect.size() != old_size) { + return "Vector: "+vect+" size changed after setSize(size())"; + } + for (int i = 0; i < vect.size(); i++) { + if (vect.elementAt(i) != backup_array[i]) { + return "Vector: "+vect+" : "+i+"th element changed after setSize(size())"; + } + } + + old_size = vect.size(); + vect.setSize(vect.size()*2); + if (vect.size() != old_size*2) { + return "Vector: "+vect+" size incorrectly changed after setSize(size()*2)"; + } + for (int i = 0; i < old_size; i++) { + if (vect.elementAt(i) != backup_array[i]) { + return "Vector: "+vect+" : "+i+"th element changed after setSize(size()*2)"; + } + } + for (int i = old_size; i < old_size*2; i++) { + if (vect.elementAt(i) != null) { + return "Vector: "+vect+" : "+i+"th element not null after setSize(size()*2)"; + } + } + + old_size = vect.size(); + int old_cap = vect.capacity(); + vect.setSize(vect.capacity()+1); + if (vect.size() != old_cap+1) { + return "Vector: "+vect+" size incorrectly changed after setSize(capacity()+1)"; + } + for (int i = 0; i < old_size && i < backup_array.length; i++) { + if (vect.elementAt(i) != backup_array[i]) { + return "Vector: "+vect+" : "+i+"th element changed after setSize(capacity()+1)"; + } + } + for (int i = old_size; i < old_cap + 1; i++) { + if (vect.elementAt(i) != null) { + return "Vector: "+vect+" : "+i+"th element not null after setSize(capacity()+1)"; + } + } + + old_size = vect.size(); + vect.setSize(vect.size()/2); + if (vect.size() != old_size/2) { + return "Vector: "+vect+" size incorrectly changed after setSize(size()/2)"; + } + for (int i = 0; i < old_size/2 && i < backup_array.length; i++) { + if (vect.elementAt(i) != backup_array[i]) { + return "Vector: "+vect+" : "+i+"th element changed after setSize(size()/2)"; + } + } + + vect = nextVector(); + } + return null; + } + +} + From c4317d18d8e556dc7747fc14fef858b6d63a3c05 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Thu, 27 Jun 2024 22:07:32 +0000 Subject: [PATCH 23/61] 8334886: jdk/jfr/api/recording/time/TestTimeMultiple.java failed with RuntimeException: getStopTime() > afterStop Reviewed-by: mgronlun Backport-of: 2abfc976c18ad6158daabf0af5edcfcb61c255dc --- src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java index 345d2fdcc8d..114052ecea2 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java @@ -103,7 +103,6 @@ static long nanosToTicks(long nanos) { static long getChunkStartNanos() { long nanos = JVM.getChunkStartNanos(); - // JVM::getChunkStartNanos() may return a bumped timestamp, +1 ns or +2 ns. // Spin here to give Instant.now() a chance to catch up. awaitUniqueTimestamp(); return nanos; From 99cd701bda4076ef3a25f4a0dac4fabfb5179f06 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Mon, 1 Jul 2024 07:55:31 +0000 Subject: [PATCH 24/61] 8333849: (dc) DatagramChannel send/receive fails with UOE if buffer backed by memory segment allocated from shared arena Reviewed-by: alanb Backport-of: 8ce3acb495232845a140ae04c6dc41d00ccfa0b7 --- .../sun/nio/ch/DatagramChannelImpl.java | 18 +- .../java/nio/channels/etc/MemorySegments.java | 494 ++++++++++++++++++ 2 files changed, 509 insertions(+), 3 deletions(-) create mode 100644 test/jdk/java/nio/channels/etc/MemorySegments.java diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java index 4790ee75dd9..31823cfbb87 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java @@ -806,14 +806,19 @@ private int receive(ByteBuffer dst, boolean connected) throws IOException { } } + /** + * Receives a datagram into a direct buffer. + */ private int receiveIntoNativeBuffer(ByteBuffer bb, int rem, int pos, boolean connected) throws IOException { NIO_ACCESS.acquireSession(bb); try { + long bufAddress = NIO_ACCESS.getBufferAddress(bb); int n = receive0(fd, - ((DirectBuffer)bb).address() + pos, rem, + bufAddress + pos, + rem, sourceSockAddr.address(), connected); if (n > 0) @@ -991,6 +996,9 @@ private int send(FileDescriptor fd, ByteBuffer src, InetSocketAddress target) } } + /** + * Send a datagram contained in a direct buffer. + */ private int sendFromNativeBuffer(FileDescriptor fd, ByteBuffer bb, InetSocketAddress target) throws IOException @@ -1003,9 +1011,13 @@ private int sendFromNativeBuffer(FileDescriptor fd, ByteBuffer bb, int written; NIO_ACCESS.acquireSession(bb); try { + long bufAddress = NIO_ACCESS.getBufferAddress(bb); int addressLen = targetSocketAddress(target); - written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, - targetSockAddr.address(), addressLen); + written = send0(fd, + bufAddress + pos, + rem, + targetSockAddr.address(), + addressLen); } catch (PortUnreachableException pue) { if (isConnected()) throw pue; diff --git a/test/jdk/java/nio/channels/etc/MemorySegments.java b/test/jdk/java/nio/channels/etc/MemorySegments.java new file mode 100644 index 00000000000..77da11759c7 --- /dev/null +++ b/test/jdk/java/nio/channels/etc/MemorySegments.java @@ -0,0 +1,494 @@ +/* + * Copyright (c) 2024, 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 8333849 + * @summary Test ByteChannel implementations of read and write with ByteBuffers that are + * backed by MemorySegments allocated from an Arena + * @run junit MemorySegments + */ + +import java.io.IOException; +import java.lang.foreign.Arena; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.DatagramChannel; +import java.nio.channels.FileChannel; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Random; +import java.util.function.Supplier; +import java.util.stream.Stream; +import static java.nio.file.StandardOpenOption.*; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.*; + +class MemorySegments { + private static final int SIZE = 100; // buffer size used by tests + + /** + * Return a stream of suppliers for each Arena type. A supplier is used to avoid JUnit + * closing the Arena and failing (as some Arenas are not closable). + */ + static Stream> arenaSuppliers() { + return Stream.of(Arena::global, Arena::ofAuto, Arena::ofConfined, Arena::ofShared); + } + + /** + * SocketChannel read/write(ByteBuffer). + */ + @ParameterizedTest + @MethodSource("arenaSuppliers") + void testSocketChannelReadWrite(Supplier arenaSupplier) throws IOException { + Arena arena = arenaSupplier.get(); + try (ServerSocketChannel ssc = ServerSocketChannel.open()) { + ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + + try (SocketChannel sc1 = SocketChannel.open(ssc.getLocalAddress()); + SocketChannel sc2 = ssc.accept()) { + + // write + ByteBuffer src = arena.allocate(SIZE).asByteBuffer(); + fillRandom(src); + int nwritten = sc1.write(src); + assertTrue(nwritten > 0); + assertTrue(nwritten <= SIZE); + assertEquals(nwritten, src.position()); + + // read + ByteBuffer dst = arena.allocate(SIZE + 100).asByteBuffer(); + int nread = sc2.read(dst); + assertTrue(nread > 0); + assertTrue(nread <= nwritten); + assertEquals(nread, dst.position()); + + // check contents + dst.flip(); + assertEquals(src.slice(0, nread), dst); + } + + } finally { + tryClose(arena); + } + } + + /** + * SocketChannel write(ByteBuffer[]). + */ + @ParameterizedTest + @MethodSource("arenaSuppliers") + void testSocketChannelGatheringWrite(Supplier arenaSupplier) throws IOException { + Arena arena = arenaSupplier.get(); + try (ServerSocketChannel ssc = ServerSocketChannel.open()) { + ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + + try (SocketChannel sc1 = SocketChannel.open(ssc.getLocalAddress()); + SocketChannel sc2 = ssc.accept()) { + + // gathering write + ByteBuffer src = arena.allocate(SIZE * 2).asByteBuffer(); + fillRandom(src); + ByteBuffer src1 = src.slice(0, SIZE); + ByteBuffer src2 = src.slice(SIZE, SIZE); + var srcs = new ByteBuffer[] { src1, src2 }; + int nwritten = (int) sc1.write(srcs); + assertTrue(nwritten > 0); + assertEquals(Math.min(nwritten, SIZE), src1.position()); + assertEquals(nwritten, src1.position() + src2.position()); + + // read + ByteBuffer dst = arena.allocate(SIZE * 2 + 50).asByteBuffer(); + int nread = sc2.read(dst); + assertTrue(nread > 0); + assertTrue(nread <= nwritten); + assertEquals(nread, dst.position()); + + // check contents + dst.flip(); + assertEquals(src.slice(0, nread), dst); + } + + } finally { + tryClose(arena); + } + } + + /** + * SocketChannel read(ByteBuffer[]). + */ + @ParameterizedTest + @MethodSource("arenaSuppliers") + void testSocketChannelScatteringRead(Supplier arenaSupplier) throws IOException { + Arena arena = arenaSupplier.get(); + try (ServerSocketChannel ssc = ServerSocketChannel.open()) { + ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + + try (SocketChannel sc1 = SocketChannel.open(ssc.getLocalAddress()); + SocketChannel sc2 = ssc.accept()) { + + // write + ByteBuffer src = arena.allocate(SIZE).asByteBuffer(); + fillRandom(src); + int nwritten = sc1.write(src); + assertTrue(nwritten > 0); + assertTrue(nwritten <= SIZE); + assertEquals(nwritten, src.position()); + + // scattering read + ByteBuffer dst = arena.allocate(SIZE + 50).asByteBuffer(); + ByteBuffer dst1 = dst.slice(0, 50); + ByteBuffer dst2 = dst.slice(50, dst.capacity() - 50); + var dsts = new ByteBuffer[]{ dst1, dst2 }; + int nread = (int) sc2.read(dsts); + assertTrue(nread > 0); + assertTrue(nread <= nwritten); + assertTrue(dst1.position() > 0); + assertEquals(nread, dst1.position() + dst2.position()); + + // check contents + src.flip(); + assertEquals(src, dst.slice(0, nread)); + } + + } finally { + tryClose(arena); + } + } + + /** + * DatagramChannel send/receive(ByteBuffer). + */ + @ParameterizedTest + @MethodSource("arenaSuppliers") + void testDatagramChannelSendReceive(Supplier arenaSupplier) throws IOException { + Arena arena = arenaSupplier.get(); + try (DatagramChannel dc = DatagramChannel.open()) { + dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + SocketAddress target = dc.getLocalAddress(); + + // send + ByteBuffer src = arena.allocate(SIZE).asByteBuffer(); + fillRandom(src); + int n = dc.send(src, target); + assertEquals(SIZE, n); + assertFalse(src.hasRemaining()); + + // receive + ByteBuffer dst = arena.allocate(SIZE + 100).asByteBuffer(); + SocketAddress remote = dc.receive(dst); + assertEquals(remote, target); + assertEquals(SIZE, dst.position()); + + // check contents + src.clear(); + dst.flip(); + assertEquals(src, dst); + } finally { + tryClose(arena); + } + } + + /** + * DatagramChannel read/write(ByteBuffer). + */ + @ParameterizedTest + @MethodSource("arenaSuppliers") + void testDatagramChannelReadWrite(Supplier arenaSupplier) throws IOException { + Arena arena = arenaSupplier.get(); + try (DatagramChannel dc = DatagramChannel.open()) { + dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + SocketAddress target = dc.getLocalAddress(); + dc.connect(target); + + // write + ByteBuffer src = arena.allocate(SIZE).asByteBuffer(); + fillRandom(src); + int n = dc.write(src); + assertEquals(SIZE, n); + assertFalse(src.hasRemaining()); + + // read + ByteBuffer dst = arena.allocate(SIZE + 100).asByteBuffer(); + n = dc.read(dst); + assertEquals(SIZE, n); + assertEquals(SIZE, dst.position()); + + // check contents + src.clear(); + dst.flip(); + assertEquals(src, dst); + } finally { + tryClose(arena); + } + } + + /** + * DatagramChannel write(ByteBuffer[]). + */ + @ParameterizedTest + @MethodSource("arenaSuppliers") + void testDatagramChannelGatheringWrite(Supplier arenaSupplier) throws IOException { + Arena arena = arenaSupplier.get(); + try (DatagramChannel dc = DatagramChannel.open()) { + dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + SocketAddress target = dc.getLocalAddress(); + dc.connect(target); + + // gathering write + ByteBuffer src1 = arena.allocate(SIZE).asByteBuffer(); + ByteBuffer src2 = arena.allocate(SIZE).asByteBuffer(); + fillRandom(src1); + fillRandom(src2); + var srcs = new ByteBuffer[] { src1, src2 }; + int nwritten = (int) dc.write(srcs); + assertEquals(SIZE*2, nwritten); + assertFalse(src1.hasRemaining()); + assertFalse(src2.hasRemaining()); + + // read + ByteBuffer dst = arena.allocate(SIZE*2 + 50).asByteBuffer(); + int nread = dc.read(dst); + assertEquals(SIZE*2, nread); + assertEquals(SIZE*2, dst.position()); + + // check contents + src1.flip(); + src2.flip(); + assertEquals(src1, dst.slice(0, SIZE)); + assertEquals(src2, dst.slice(SIZE, SIZE)); + } finally { + tryClose(arena); + } + } + + /** + * DatagramChannel read(ByteBuffer[]). + */ + @ParameterizedTest + @MethodSource("arenaSuppliers") + void testDatagramChannelScatteringRead(Supplier arenaSupplier) throws IOException { + Arena arena = arenaSupplier.get(); + try (DatagramChannel dc = DatagramChannel.open()) { + dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + SocketAddress target = dc.getLocalAddress(); + dc.connect(target); + + // write + ByteBuffer src = arena.allocate(SIZE*2).asByteBuffer(); + fillRandom(src); + int nwritten = dc.write(src); + assertEquals(SIZE*2, nwritten); + assertEquals(nwritten, src.position()); + + // scattering read + ByteBuffer dst1 = arena.allocate(SIZE).asByteBuffer(); + ByteBuffer dst2 = arena.allocate(SIZE + 50).asByteBuffer(); + var dsts = new ByteBuffer[] { dst1, dst2 }; + int nread = (int) dc.read(dsts); + assertEquals(SIZE*2, nread); + assertEquals(nread, dst1.position() + dst2.position()); + + // check contents + dst1.flip(); + assertEquals(src.slice(0, SIZE), dst1); + dst2.flip(); + assertEquals(src.slice(SIZE, SIZE), dst2); + } finally { + tryClose(arena); + } + } + + /** + * FileChannel read/write(ByteBuffer). + */ + @ParameterizedTest + @MethodSource("arenaSuppliers") + void testFileChannelReadWrite(Supplier arenaSupplier) throws IOException { + Arena arena = arenaSupplier.get(); + Path file = Files.createTempFile(Path.of("."), "test", "dat"); + try (FileChannel fc = FileChannel.open(file, READ, WRITE)) { + + // write + ByteBuffer src = arena.allocate(SIZE).asByteBuffer(); + fillRandom(src); + int nwritten = fc.write(src); + assertTrue(nwritten > 0); + assertTrue(nwritten <= SIZE); + assertEquals(nwritten, src.position()); + assertEquals(nwritten, (int) fc.position()); + assertEquals(nwritten, (int) fc.size()); + + // read + ByteBuffer dst = arena.allocate(SIZE + 100).asByteBuffer(); + fc.position(0); + int nread = fc.read(dst); + assertTrue(nread > 0); + assertTrue(nread <= nwritten); + assertEquals(nread, dst.position()); + assertEquals(nread, (int) fc.position()); + + // check contents + dst.flip(); + assertEquals(src.slice(0, nread), dst); + + // reset + fc.truncate(0L); + src.clear(); + dst.clear(); + + // write with position + nwritten = fc.write(src, 10L); + assertTrue(nwritten > 0); + assertTrue(nwritten <= SIZE); + assertEquals(nwritten, src.position()); + assertEquals(0, (int) fc.position()); + assertEquals(nwritten + 10, (int) fc.size()); + + // read with position + nread = fc.read(dst, 10L); + assertTrue(nread > 0); + assertTrue(nread <= nwritten); + assertEquals(nread, dst.position()); + assertEquals(0, (int)fc.position()); + + // check contents + dst.flip(); + assertEquals(src.slice(0, nread), dst); + } finally { + tryClose(arena); + } + } + + /** + * FileChannel write(ByteBuffer[]). + */ + @ParameterizedTest + @MethodSource("arenaSuppliers") + void testFileChannelGatheringWrite(Supplier arenaSupplier) throws IOException { + Arena arena = arenaSupplier.get(); + Path file = Files.createTempFile(Path.of(""), "test", "dat"); + try (FileChannel fc = FileChannel.open(file, READ, WRITE)) { + + // gathering write + ByteBuffer src = arena.allocate(SIZE * 2).asByteBuffer(); + fillRandom(src); + ByteBuffer src1 = src.slice(0, SIZE); + ByteBuffer src2 = src.slice(SIZE, SIZE); + var srcs = new ByteBuffer[] { src1, src2 }; + int nwritten = (int) fc.write(srcs); + assertTrue(nwritten > 0); + assertEquals(Math.min(nwritten, SIZE), src1.position()); + assertEquals(nwritten, src1.position() + src2.position()); + assertEquals(nwritten, (int) fc.position()); + assertEquals(nwritten, (int) fc.size()); + + // read + ByteBuffer dst = arena.allocate(SIZE*2 + 50).asByteBuffer(); + fc.position(0); + int nread = fc.read(dst); + assertTrue(nread > 0); + assertTrue(nread <= nwritten); + assertEquals(nread, dst.position()); + assertEquals(nread, (int) fc.position()); + + // check contents + dst.flip(); + assertEquals(src.slice(0, nread), dst); + } finally { + tryClose(arena); + } + } + + /** + * FileChannel read(ByteBuffer[]). + */ + @ParameterizedTest + @MethodSource("arenaSuppliers") + void testFileChannelScatteringRead(Supplier arenaSupplier) throws IOException { + Arena arena = arenaSupplier.get(); + Path file = Files.createTempFile(Path.of(""), "test", "dat"); + try (FileChannel fc = FileChannel.open(file, READ, WRITE)) { + + // write + ByteBuffer src = arena.allocate(SIZE).asByteBuffer(); + fillRandom(src); + int nwritten = fc.write(src); + assertTrue(nwritten > 0); + assertTrue(nwritten <= SIZE); + assertEquals(nwritten, src.position()); + assertEquals(nwritten, (int) fc.position()); + assertEquals(nwritten, (int) fc.size()); + + // scattering read + ByteBuffer dst = arena.allocate(SIZE + 50).asByteBuffer(); + ByteBuffer dst1 = dst.slice(0, 50); + ByteBuffer dst2 = dst.slice(50, dst.capacity() - 50); + var dsts = new ByteBuffer[] { dst1, dst2 }; + fc.position(0); + int nread = (int) fc.read(dsts); + assertTrue(nread > 0); + assertTrue(nread <= nwritten); + assertTrue(dst1.position() > 0); + assertEquals(nread, dst1.position() + dst2.position()); + assertEquals(nread, (int) fc.position()); + + // check contents + dst.limit(nread); + assertEquals(src.slice(0, nread), dst); + } finally { + tryClose(arena); + } + } + + /** + * Fill the buffer with random bytes. + */ + private void fillRandom(ByteBuffer bb) { + Random r = new Random(); + int pos = bb.position(); + while (bb.hasRemaining()) { + bb.put((byte) r.nextInt(256)); + } + bb.position(pos); + } + + /** + * Attempt to close the given Arena. + */ + private boolean tryClose(Arena arena) { + try { + arena.close(); + return true; + } catch (UnsupportedOperationException e) { + return false; + } + } + +} From 91a27f892ef2228b4dba8b9543a0ea1bf91dc879 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Mon, 1 Jul 2024 12:16:58 +0000 Subject: [PATCH 25/61] 8333542: Breakpoint in parallel code does not work Reviewed-by: cjplummer Backport-of: 97d3d57944082b44cccd9b6f4a1e2afeb9c160ad --- .../TestThreadDumpClassInitMonitor.java | 7 +- .../com/sun/jdi/BreakpointOnClassPrepare.java | 156 ++++++++++++++++++ 2 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 test/jdk/com/sun/jdi/BreakpointOnClassPrepare.java diff --git a/test/hotspot/jtreg/runtime/Thread/TestThreadDumpClassInitMonitor.java b/test/hotspot/jtreg/runtime/Thread/TestThreadDumpClassInitMonitor.java index 0154f43244e..6260088fa33 100644 --- a/test/hotspot/jtreg/runtime/Thread/TestThreadDumpClassInitMonitor.java +++ b/test/hotspot/jtreg/runtime/Thread/TestThreadDumpClassInitMonitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -60,8 +60,7 @@ public class TestThreadDumpClassInitMonitor { */ final static String TEST_THREAD = "TestThread"; final static String TEST_THREAD_ENTRY = "\"" + TEST_THREAD; - // final static String IN_OBJECT_WAIT = "in Object.wait()"; - final static String IN_CONVAR_WAIT = "waiting on condition"; + final static String IN_OBJECT_WAIT = "in Object.wait()"; final static String THREAD_STATE = "java.lang.Thread.State: RUNNABLE"; final static String THREAD_INFO = "Thread:"; // the details are not important final static String JAVATHREAD_STATE = "JavaThread state: _thread_blocked"; @@ -140,7 +139,7 @@ public static void main(String[] args) throws Throwable { continue; } foundLines++; - if (!line.contains(IN_CONVAR_WAIT)) { + if (!line.contains(IN_OBJECT_WAIT)) { throw new Error("Unexpected initial stack line: " + line); } continue; diff --git a/test/jdk/com/sun/jdi/BreakpointOnClassPrepare.java b/test/jdk/com/sun/jdi/BreakpointOnClassPrepare.java new file mode 100644 index 00000000000..f4f1427e39b --- /dev/null +++ b/test/jdk/com/sun/jdi/BreakpointOnClassPrepare.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2024, 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 8333542 + * @summary Missed breakpoint due to JVM not blocking other threads while + * delivering a ClassPrepareEvent. + * + * @run build TestScaffold VMConnection TargetListener TargetAdapter + * @run compile -g BreakpointOnClassPrepare.java + * @run driver BreakpointOnClassPrepare SUSPEND_NONE + * @run driver BreakpointOnClassPrepare SUSPEND_EVENT_THREAD + * @run driver BreakpointOnClassPrepare SUSPEND_ALL + */ + +import com.sun.jdi.*; +import com.sun.jdi.event.*; +import com.sun.jdi.request.*; + +import java.util.*; + +// The debuggee spawns 50 threads that call LoadedClass.foo(). The debugger enables +// ClassPrepareEvent for LoadedClass, and sets a breakpoint on LoadedClass.foo() when +// the ClassPrepareEvent arrives. The debugger expects 50 breakpoints to be hit. +// This verifies that the thread that causes the generation of the ClassPrepareEvent +// has properly blocked all other threads from executing LoadedClass.foo() until the +// ClassPrepareEvent has been delivered. + +class LoadedClass { + static void foo(int k) { + System.out.println("HIT = " + k); // set breakpoint here + } +} + +class BreakpointOnClassPrepareTarg { + public static void main(String[] args) throws InterruptedException { + System.out.println("Start"); + Thread threads[] = new Thread[BreakpointOnClassPrepare.NUM_BREAKPOINTS]; + for (int i = 0; i < BreakpointOnClassPrepare.NUM_BREAKPOINTS; i++) { + int k = i; + Thread t = DebuggeeWrapper.newThread(() -> { + System.out.println("k = " + k); + LoadedClass.foo(k); + }); + threads[i] = t; + t.setDaemon(true); + t.setName("MyThread-" + k); + t.start(); + } + + for (int i = 0; i < BreakpointOnClassPrepare.NUM_BREAKPOINTS; i++) { + try { + Thread t = threads[i]; + t.join(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + System.out.println("Finish"); + } +} + + /********** test program **********/ + +public class BreakpointOnClassPrepare extends TestScaffold { + ClassType targetClass; + ThreadReference mainThread; + + BreakpointOnClassPrepare(String args[]) { + super(args); + } + + public static void main(String[] args) throws Exception { + new BreakpointOnClassPrepare(args).startTests(); + } + + /********** event handlers **********/ + + static final int NUM_BREAKPOINTS = 50; + int bkptCount; + BreakpointRequest bkptRequest; + + public void breakpointReached(BreakpointEvent event) { + bkptCount++; + System.out.println("Got BreakpointEvent: " + bkptCount + " for thread " + event.thread()); + } + + public void vmDisconnected(VMDisconnectEvent event) { + println("Got VMDisconnectEvent"); + } + + /********** test core **********/ + + protected void runTests() throws Exception { + /* Determine which suspend policy to use. */ + int policy; + if (args.length != 1) { + throw new RuntimeException("Invalid number of args: " + args.length); + } + String policyString = args[0]; + if (policyString.equals("SUSPEND_NONE")) { + policy = EventRequest.SUSPEND_NONE; + } else if (policyString.equals("SUSPEND_ALL")) { + policy = EventRequest.SUSPEND_ALL; + } else if (policyString.equals("SUSPEND_EVENT_THREAD")) { + policy = EventRequest.SUSPEND_EVENT_THREAD; + } else { + throw new RuntimeException("Invalid suspend policy: " + policyString); + } + + /* Stop when the target is loaded. */ + BreakpointEvent bpe = startToMain("BreakpointOnClassPrepareTarg"); + + /* Stop when "LoadedClass" is loaded. */ + EventRequestManager erm = vm().eventRequestManager(); + ClassPrepareEvent cpe = resumeToPrepareOf("LoadedClass"); + println("Got ClassPrepareEvent: " + cpe); + + /* Set a breakpoint for each time LoadedClass.foo() is called. */ + ClassType loadedClass = (ClassType)cpe.referenceType() ; + Location loc1 = findMethodLocation(loadedClass, "foo", "(I)V", 1); + bkptRequest = erm.createBreakpointRequest(loc1); + bkptRequest.setSuspendPolicy(policy); + bkptRequest.enable(); + + listenUntilVMDisconnect(); + + if (!testFailed && bkptCount == NUM_BREAKPOINTS) { + println("BreakpointOnClassPrepare: passed"); + } else { + throw new Exception("BreakpointOnClassPrepare: failed. bkptCount == " + bkptCount); + } + } +} From 9b246ba8686b096590347508fb14240c14c714b4 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Mon, 1 Jul 2024 15:48:32 +0000 Subject: [PATCH 26/61] 8334600: TEST java/net/MulticastSocket/IPMulticastIF.java fails on linux-aarch64 Reviewed-by: clanger Backport-of: 9f3a72417e6bca4770f4600c17fa008d3cf97dd3 --- .../net/MulticastSocket/IPMulticastIF.java | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/test/jdk/java/net/MulticastSocket/IPMulticastIF.java b/test/jdk/java/net/MulticastSocket/IPMulticastIF.java index 566e3603fa6..3909f6d6276 100644 --- a/test/jdk/java/net/MulticastSocket/IPMulticastIF.java +++ b/test/jdk/java/net/MulticastSocket/IPMulticastIF.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, 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 @@ -63,9 +63,25 @@ public Object[][] positive() throws Exception { InetAddress.getLoopbackAddress()); List list = new ArrayList<>(); NetworkConfiguration nc = NetworkConfiguration.probe(); + // retains only network interface whose bound addresses match addrs.stream().forEach(a -> nc.multicastInterfaces(true) - .map(nif -> new Object[] { new InetSocketAddress(a, 0), nif }) - .forEach(list::add) ); + .filter(nif -> nif.inetAddresses().toList().contains(a)) + .map(nif -> new Object[] { new InetSocketAddress(a, 0), nif }) + .forEach(list::add) ); + // any network interface should work with the wildcard address + nc.multicastInterfaces(true) + .map(nif -> new Object[] {new InetSocketAddress(0), nif}) + .forEach(list::add); + return list.stream().toArray(Object[][]::new); + } + + @DataProvider(name = "interfaces") + public Object[][] interfaces() throws Exception { + List list = new ArrayList<>(); + NetworkConfiguration nc = NetworkConfiguration.probe(); + nc.multicastInterfaces(true) + .map(nif -> new Object[] {nif}) + .forEach(list::add); return list.stream().toArray(Object[][]::new); } @@ -82,8 +98,8 @@ public void testSetGetInterfaceBound(InetSocketAddress bindAddr, NetworkInterfac } } - @Test(dataProvider = "scenarios") - public void testSetGetInterfaceUnbound(InetSocketAddress ignore, NetworkInterface nif) + @Test(dataProvider = "interfaces") + public void testSetGetInterfaceUnbound(NetworkInterface nif) throws Exception { out.println(format("\n\n--- testSetGetInterfaceUnbound nif=[%s]", nif)); @@ -106,8 +122,8 @@ public void testSetGetOptionBound(InetSocketAddress bindAddr, NetworkInterface n } } - @Test(dataProvider = "scenarios") - public void testSetGetOptionUnbound(InetSocketAddress ignore, NetworkInterface nif) + @Test(dataProvider = "interfaces") + public void testSetGetOptionUnbound(NetworkInterface nif) throws Exception { out.println(format("\n\n--- testSetGetOptionUnbound nif=[%s]", nif)); @@ -139,8 +155,8 @@ public void testGetInterfaceBound(InetSocketAddress bindAddr) } @Test - public void testGettInterfaceUnbound() throws Exception { - out.println("\n\n--- testGettInterfaceUnbound "); + public void testGetInterfaceUnbound() throws Exception { + out.println("\n\n--- testGetInterfaceUnbound "); try (MulticastSocket ms = new MulticastSocket()) { assertPlaceHolder(ms.getNetworkInterface()); } From f604cb76b84195c697d0afd3e0e525f5108ca413 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Mon, 1 Jul 2024 22:43:47 +0000 Subject: [PATCH 27/61] 8335134: Test com/sun/jdi/BreakpointOnClassPrepare.java timeout Reviewed-by: dholmes Backport-of: 5e43ec37aad851e67cd95e99fc45e94fcc2aff05 --- test/jdk/com/sun/jdi/BreakpointOnClassPrepare.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/jdk/com/sun/jdi/BreakpointOnClassPrepare.java b/test/jdk/com/sun/jdi/BreakpointOnClassPrepare.java index f4f1427e39b..deffffc0fa8 100644 --- a/test/jdk/com/sun/jdi/BreakpointOnClassPrepare.java +++ b/test/jdk/com/sun/jdi/BreakpointOnClassPrepare.java @@ -104,7 +104,15 @@ public static void main(String[] args) throws Exception { public void breakpointReached(BreakpointEvent event) { bkptCount++; - System.out.println("Got BreakpointEvent: " + bkptCount + " for thread " + event.thread()); + String threadInfo; + try { + threadInfo = event.thread().toString(); + } catch (ObjectCollectedException e) { + // It's possible the Thread already terminated and was collected + // if the SUSPEND_NONE policy was used. + threadInfo = "(thread collected)"; + } + System.out.println("Got BreakpointEvent: " + bkptCount + " for thread " + threadInfo); } public void vmDisconnected(VMDisconnectEvent event) { From bc87e3e892fc8ae403252d3a243ab859edc2772d Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Tue, 2 Jul 2024 14:27:45 +0000 Subject: [PATCH 28/61] 8335390: C2 MergeStores: wrong result with Unsafe Reviewed-by: thartmann Backport-of: a5e2afe92ef2ce3188342d76657b0e9a48bc5aaa --- .../jtreg/compiler/c2/TestMergeStores.java | 5 +- .../c2/TestMergeStoresUnsafeArrayPointer.java | 132 ++++++++++++++++++ 2 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/c2/TestMergeStoresUnsafeArrayPointer.java diff --git a/test/hotspot/jtreg/compiler/c2/TestMergeStores.java b/test/hotspot/jtreg/compiler/c2/TestMergeStores.java index 55594650219..affe4d0f3a6 100644 --- a/test/hotspot/jtreg/compiler/c2/TestMergeStores.java +++ b/test/hotspot/jtreg/compiler/c2/TestMergeStores.java @@ -509,8 +509,9 @@ static Object[] test1e(byte[] a) { } @Test - @IR(counts = {IRNode.STORE_L_OF_CLASS, "byte\\\\[int:>=0] \\\\(java/lang/Cloneable,java/io/Serializable\\\\)", "1"}, - applyIf = {"UseUnalignedAccesses", "true"}) + // Disabled by JDK-8335390, to be enabled again by JDK-8335392. + // @IR(counts = {IRNode.STORE_L_OF_CLASS, "byte\\\\[int:>=0] \\\\(java/lang/Cloneable,java/io/Serializable\\\\)", "1"}, + // applyIf = {"UseUnalignedAccesses", "true"}) static Object[] test1f(byte[] a) { UNSAFE.putByte(a, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 0, (byte)0xbe); UNSAFE.putByte(a, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 1, (byte)0xba); diff --git a/test/hotspot/jtreg/compiler/c2/TestMergeStoresUnsafeArrayPointer.java b/test/hotspot/jtreg/compiler/c2/TestMergeStoresUnsafeArrayPointer.java new file mode 100644 index 00000000000..dbfdfe68957 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestMergeStoresUnsafeArrayPointer.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2024, 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 8335390 + * @summary Test merge stores for some Unsafe store address patterns. + * @modules java.base/jdk.internal.misc + * @requires vm.bits == 64 + * @requires os.maxMemory > 8G + * @run main/othervm -XX:CompileCommand=compileonly,compiler.c2.TestMergeStoresUnsafeArrayPointer::test* + * -Xbatch + * -Xmx8g + * compiler.c2.TestMergeStoresUnsafeArrayPointer + * @run main/othervm -Xmx8g + * compiler.c2.TestMergeStoresUnsafeArrayPointer + */ + +package compiler.c2; +import jdk.internal.misc.Unsafe; + +public class TestMergeStoresUnsafeArrayPointer { + static final Unsafe UNSAFE = Unsafe.getUnsafe(); + + // We allocate a big int array of length: + static final int SIZE = (1 << 30) + 100; + + // This gives us a memory region of 4x as many bytes: + static final long BYTE_SIZE = 4L * SIZE; // = 1L << 32 + 400L + + // We set an "anchor" in the middle of this memory region, in bytes: + static final long ANCHOR = BYTE_SIZE / 2; + + static int four = 4; + + public static void main(String[] args) { + System.out.println("Allocate big array of SIZE = " + SIZE); + int[] big = new int[SIZE]; + + // Each test is executed a few times, so that we can see the difference between + // interpreter and compiler. + int errors = 0; + + long val = 0; + System.out.println("test1"); + for (int i = 0; i < 100_000; i++) { + testClear(big); + test1(big, ANCHOR); + long sum = testSum(big); + if (i == 0) { + val = sum; + } else { + if (sum != val) { + System.out.println("ERROR: test1 had wrong value: " + val + " != " + sum); + errors++; + break; + } + } + } + + val = 0; + System.out.println("test2"); + for (int i = 0; i < 100_000; i++) { + testClear(big); + test2(big, ANCHOR); + long sum = testSum(big); + if (i == 0) { + val = sum; + } else { + if (sum != val) { + System.out.println("ERROR: test2 had wrong value: " + val + " != " + sum); + errors++; + break; + } + } + } + + if (errors > 0) { + throw new RuntimeException("ERRORS: " + errors); + } + System.out.println("PASSED"); + } + + // Only clear and sum over relevant parts of array to make the test fast. + static void testClear(int[] a) { + for (int j = 0 ; j < 100; j++) { a[j] = j; } + for (int j = a.length/2 - 100; j < a.length/2 + 100; j++) { a[j] = j; } + for (int j = a.length - 100; j < a.length + 0; j++) { a[j] = j; } + } + + static long testSum(int[] a) { + long sum = 0; + for (int j = 0 ; j < 100; j++) { sum += a[j]; } + for (int j = a.length/2 - 100; j < a.length/2 + 100; j++) { sum += a[j]; } + for (int j = a.length - 100; j < a.length + 0; j++) { sum += a[j]; } + return sum; + } + + // Reference: expected to merge. + static void test1(int[] a, long anchor) { + long base = UNSAFE.ARRAY_INT_BASE_OFFSET + anchor; + UNSAFE.putInt(a, base + 0, 0x42424242); + UNSAFE.putInt(a, base + 4, 0x66666666); + } + + // Test: if MergeStores is applied this can lead to wrong results + static void test2(int[] a, long anchor) { + long base = UNSAFE.ARRAY_INT_BASE_OFFSET + ANCHOR; + UNSAFE.putInt(a, base + 0 + (long)(four + Integer.MAX_VALUE), 0x42424242); + UNSAFE.putInt(a, base + Integer.MAX_VALUE + (long)(four + 4 ), 0x66666666); + } +} From 6e444df06a4dcdaf029e5a4fd9c4ef13f7c4f0b8 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 5 Jul 2024 09:58:56 +0000 Subject: [PATCH 29/61] 8322812: Manpage for jcmd is missing JFR.view command Reviewed-by: mgronlun Backport-of: 897323c026819f228261b2aa74a8f229ffb7fc87 --- src/jdk.jcmd/share/man/jcmd.1 | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/jdk.jcmd/share/man/jcmd.1 b/src/jdk.jcmd/share/man/jcmd.1 index c88d2a22a41..4080fb8b7cb 100644 --- a/src/jdk.jcmd/share/man/jcmd.1 +++ b/src/jdk.jcmd/share/man/jcmd.1 @@ -681,6 +681,55 @@ If no path is provided, the data from the recording is discarded. value) .RE .TP +\f[V]JFR.view\f[R] [\f[I]options\f[R]] +Display event data in predefined views. +.RS +.PP +Impact: Medium +.PP +\f[B]Note:\f[R] +.PP +The \f[I]options\f[R] must be specified using either \f[I]key\f[R] or +\f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. +If no parameters are entered, then a list of available views are +displayed. +.PP +\f[I]options\f[R]: +.IP \[bu] 2 +\f[V]cell-height\f[R]: (Optional) Maximum number of rows in a table +cell. +(INT, default value depends on the view) +.IP \[bu] 2 +\f[V]maxage\f[R]: (Optional) Length of time for the view to span. +(INT followed by \[aq]s\[aq] for seconds \[aq]m\[aq] for minutes or +\[aq]h\[aq] for hours, default value is 10m) +.IP \[bu] 2 +\f[V]maxsize\f[R]: (Optional) Maximum size for the view to span in bytes +if one of the following suffixes is not used: \[aq]m\[aq] or \[aq]M\[aq] +for megabytes OR \[aq]g\[aq] or \[aq]G\[aq] for gigabytes. +(STRING, default value is 32MB) +.IP \[bu] 2 +\f[V]truncate\f[R]: (Optional) Maximum number of rows in a table cell. +(INT, default value depends on the view) +.IP \[bu] 2 +\f[V]verbose\f[R]: (Optional) Displays the query that makes up the view. +(BOOLEAN, default value is false) +.IP \[bu] 2 +\f[V]width\f[R]: (Optional) The width of the view in characters. +(INT, default value depends on the view) +.PP +\f[I]arguments\f[R]: +.IP \[bu] 2 +\f[V]view\f[R]: Name of the view or event type to display. +Use \f[V]help JFR.view\f[R] to see a list of available views. +(STRING, no default value) +.PP +The view parameter can be an event type name. +Use \f[V]JFR.view types\f[R] to see a list. +To display all views, use \f[V]JFR.view all-views\f[R]. +To display all events, use \f[V]JFR.view all-events\f[R]. +.RE +.TP \f[V]JVMTI.agent_load\f[R] [\f[I]arguments\f[R]] Loads JVMTI native agent. .RS From 65679dceb425f2903ccaadd02b02b3087653b2c5 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 5 Jul 2024 10:17:50 +0000 Subject: [PATCH 30/61] 8335479: JFR: Missing documentation for -XX:StartFlightRecording Reviewed-by: mgronlun Backport-of: c1f123672ed63651260cb3a12b3ce673ce11815b --- src/java.base/share/man/java.1 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/man/java.1 b/src/java.base/share/man/java.1 index 6cef707d19a..414f4d85dc2 100644 --- a/src/java.base/share/man/java.1 +++ b/src/java.base/share/man/java.1 @@ -1710,10 +1710,12 @@ This prevents the JVM from exiting and keeps the process active so that you can attach a debugger to it to investigate the cause of the error. By default, this option is disabled. .TP -\f[V]-XX:StartFlightRecording=\f[R]\f[I]parameter\f[R]\f[V]=\f[R]\f[I]value\f[R] +\f[V]-XX:StartFlightRecording:\f[R]\f[I]parameter\f[R]\f[V]=\f[R]\f[I]value\f[R] Starts a JFR recording for the Java application. This option is equivalent to the \f[V]JFR.start\f[R] diagnostic command that starts a recording during runtime. +\f[V]-XX:StartFlightRecording:help\f[R] prints available options and +example command lines. You can set the following \f[I]parameter\f[R]\f[V]=\f[R]\f[I]value\f[R] entries when starting a JFR recording: .RS @@ -1760,6 +1762,8 @@ written when the recording is stopped, for example: .PP If %p and/or %t is specified in the filename, it expands to the JVM\[aq]s PID and the current timestamp, respectively. +The filename may also be a directory in which case, the filename is +generated from the PID and the current date in the specified directory. .RE .TP \f[V]name=\f[R]\f[I]identifier\f[R] @@ -1840,6 +1844,9 @@ The whitespace delimiter can be omitted for timespan values, i.e. 20ms. For more information about the settings syntax, see Javadoc of the jdk.jfr package. +.PP +To only see warnings and errors from JFR during startup set +-Xlog:jfr+startup=warning. .RE .TP \f[V]-XX:ThreadStackSize=\f[R]\f[I]size\f[R] From ce862ff1349a57c9413b2bc4a79e55b2f3c0aa88 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 5 Jul 2024 10:53:09 +0000 Subject: [PATCH 31/61] 8324089: Fix typo in the manual page for "jcmd" (man jcmd) Reviewed-by: mgronlun Backport-of: e5f8576d3705e541b8eb5f399c35228e4fe3ec2b --- src/jdk.jcmd/share/man/jcmd.1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/jdk.jcmd/share/man/jcmd.1 b/src/jdk.jcmd/share/man/jcmd.1 index 4080fb8b7cb..abec120e5f0 100644 --- a/src/jdk.jcmd/share/man/jcmd.1 +++ b/src/jdk.jcmd/share/man/jcmd.1 @@ -528,7 +528,7 @@ is not used: \[aq]m\[aq] or \[aq]M\[aq] for megabytes OR \[aq]g\[aq] or If no name is given, data from all recordings is dumped. (STRING, no default value) .IP \[bu] 2 -\f[V]path-to-gc-root\f[R]: (Optional) Flag for saving the path to +\f[V]path-to-gc-roots\f[R]: (Optional) Flag for saving the path to garbage collection (GC) roots at the time the recording data is dumped. The path information is useful for finding memory leaks but collecting it can cause the application to pause for a short period of time. @@ -606,7 +606,7 @@ Make note of the generated name that is shown in the response to the command so that you can use it with other commands. (STRING, system-generated default name) .IP \[bu] 2 -\f[V]path-to-gc-root\f[R]: (Optional) Flag for saving the path to +\f[V]path-to-gc-roots\f[R]: (Optional) Flag for saving the path to garbage collection (GC) roots at the end of a recording. The path information is useful for finding memory leaks but collecting it is time consuming. From 59d0ab57fe54b10eefe7410c38764848224f9d2a Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Sat, 6 Jul 2024 20:01:16 +0000 Subject: [PATCH 32/61] 8334297: (so) java/nio/channels/SocketChannel/OpenLeak.java should not depend on SecurityManager Reviewed-by: mbaesken, dfuchs Backport-of: 03cb2667404091892b3d70189c3be84bc21cfc71 --- .../nio/channels/SocketChannel/OpenLeak.java | 104 ++++++++++++++++-- 1 file changed, 93 insertions(+), 11 deletions(-) diff --git a/test/jdk/java/nio/channels/SocketChannel/OpenLeak.java b/test/jdk/java/nio/channels/SocketChannel/OpenLeak.java index 8d8673355ef..c7eed1f27a0 100644 --- a/test/jdk/java/nio/channels/SocketChannel/OpenLeak.java +++ b/test/jdk/java/nio/channels/SocketChannel/OpenLeak.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, 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,28 +25,110 @@ * @bug 6548464 * @summary SocketChannel.open(SocketAddress) leaks file descriptor if * connection cannot be established + * @requires vm.flagless * @build OpenLeak - * @run main/othervm -Djava.security.manager=allow OpenLeak + * @run junit/othervm OpenLeak */ +import java.io.IOException; +import java.net.ConnectException; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.nio.channels.SocketChannel; +import java.nio.channels.UnresolvedAddressException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertThrows; + public class OpenLeak { - public static void main(String[] args) throws Exception { - InetAddress lh = InetAddress.getLocalHost(); - InetSocketAddress isa = new InetSocketAddress(lh, 12345); + static final String OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ROOT); + static final boolean IS_WINDOWS_2016 = OS_NAME.contains("windows") && OS_NAME.contains("2016"); + + // On Windows Server 2016 trying to connect to port 47 consumes the + // whole connect timeout - which makes the test fail in timeout. + // We skip this part of the test on Windows Server 2016 + static final boolean TEST_WITH_RESERVED_PORT = !IS_WINDOWS_2016; + + private static final int MAX_LOOP = 250000; - System.setSecurityManager( new SecurityManager() ); - for (int i=0; i<100000; i++) { - try { - SocketChannel.open(isa); - throw new RuntimeException("This should not happen"); - } catch (SecurityException x) { } + + // Try to find a suitable port to provoke a "Connection Refused" + // error. + private static InetSocketAddress findSuitableRefusedAddress(InetSocketAddress isa) + throws IOException { + if (!TEST_WITH_RESERVED_PORT) return null; + var addr = isa.getAddress(); + try (SocketChannel sc1 = SocketChannel.open(isa)) { + // If we manage to connect, let's try to use some other + // port. + // port 51 is reserved too - there should be nothing there... + isa = new InetSocketAddress(addr, 51); + try (SocketChannel sc2 = SocketChannel.open(isa)) { + } + // OK, last attempt... + // port 61 is reserved too - there should be nothing there... + isa = new InetSocketAddress(addr, 61); + try (SocketChannel sc3 = SocketChannel.open(isa)) { + } + System.err.println("Could not find a suitable port"); + return null; + } catch (ConnectException x) { } + return isa; + } + + private static InetSocketAddress createUnresolved(InetSocketAddress isa, InetSocketAddress def) { + var sa = isa == null ? def : isa; + return InetSocketAddress.createUnresolved(sa.getHostString(), sa.getPort()); + } + + // Builds a list of test cases + static List testCases() throws Exception { + InetAddress lo = InetAddress.getLoopbackAddress(); + + // Try to find a suitable port that will cause a + // Connection Refused exception + // port 47 is reserved - there should be nothing there... + InetSocketAddress def = new InetSocketAddress(lo, 47); + InetSocketAddress isa = findSuitableRefusedAddress(def); + InetSocketAddress sa = createUnresolved(isa, def); + + final List cases = new ArrayList<>(); + cases.add(new Object[]{sa, UnresolvedAddressException.class}); + if (isa != null) { + cases.add(new Object[]{isa, ConnectException.class}); + } + return cases; + } + + @ParameterizedTest + @MethodSource("testCases") + public void test(SocketAddress sa, Class expectedException) throws Exception { + System.err.printf("%nExpecting %s for %s%n", expectedException, sa); + + int i = 0; + try { + for (i = 0; i < MAX_LOOP; i++) { + Throwable x = + assertThrows(expectedException, () -> SocketChannel.open(sa)); + if (i < 5 || i >= MAX_LOOP - 5) { + // print a message for the first five and last 5 exceptions + System.err.println(x); + } + } + } catch (Throwable t) { + System.err.println("Failed at " + i + " with " + t); + throw t; + } } } From 19cc3049de20906d35f4933093fa0843b9c25801 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Mon, 8 Jul 2024 11:01:53 +0000 Subject: [PATCH 33/61] 8335475: ClassBuilder incorrectly calculates max_locals in some cases Reviewed-by: asotona Backport-of: d8180b62e87afed70fadfa4e2f8d31e0496b9bde --- .../classfile/impl/StackMapGenerator.java | 2 +- test/jdk/jdk/classfile/StackMapsTest.java | 34 +++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java b/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java index ba032c7b0c2..dd4d7d42070 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java @@ -1047,7 +1047,7 @@ private void setLocalRawInternal(int index, Type type) { void setLocalsFromArg(String name, MethodTypeDesc methodDesc, boolean isStatic, Type thisKlass) { int localsSize = 0; // Pre-emptively create a locals array that encompass all parameter slots - checkLocal(methodDesc.parameterCount() + (isStatic ? 0 : -1)); + checkLocal(methodDesc.parameterCount() + (isStatic ? -1 : 0)); if (!isStatic) { localsSize++; if (OBJECT_INITIALIZER_NAME.equals(name) && !CD_Object.equals(thisKlass.sym)) { diff --git a/test/jdk/jdk/classfile/StackMapsTest.java b/test/jdk/jdk/classfile/StackMapsTest.java index b3df31291bc..f72c237aa8f 100644 --- a/test/jdk/jdk/classfile/StackMapsTest.java +++ b/test/jdk/jdk/classfile/StackMapsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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 @@ -24,7 +24,7 @@ /* * @test * @summary Testing Classfile stack maps generator. - * @bug 8305990 8320222 8320618 + * @bug 8305990 8320222 8320618 8335475 * @build testdata.* * @run junit StackMapsTest */ @@ -36,6 +36,10 @@ import java.nio.file.FileSystems; import java.nio.file.Files; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +import static java.lang.constant.ConstantDescs.MTD_void; import static org.junit.jupiter.api.Assertions.*; import static helpers.TestUtil.assertEmpty; import static java.lang.classfile.ClassFile.ACC_STATIC; @@ -238,7 +242,7 @@ void testClassVersions() throws Exception { @Test void testInvalidAALOADStack() { ClassFile.of().build(ClassDesc.of("Test"), clb - -> clb.withMethodBody("test", ConstantDescs.MTD_void, 0, cob + -> clb.withMethodBody("test", MTD_void, 0, cob -> cob.bipush(10) .anewarray(ConstantDescs.CD_Object) .lconst_1() //long on stack caused NPE, see 8320618 @@ -312,4 +316,28 @@ void testInvalidStack() throws Exception { cb.pop(); }))); } + + @ParameterizedTest + @EnumSource(ClassFile.StackMapsOption.class) + void testEmptyCounters(ClassFile.StackMapsOption option) { + var cf = ClassFile.of(option); + var bytes = cf.build(ClassDesc.of("Test"), clb -> clb + .withMethodBody("a", MTD_void, ACC_STATIC, CodeBuilder::return_) + .withMethodBody("b", MTD_void, 0, CodeBuilder::return_) + ); + + var cm = ClassFile.of().parse(bytes); + for (var method : cm.methods()) { + var name = method.methodName(); + var code = method.code().orElseThrow(); + if (name.equalsString("a")) { + assertEquals(0, code.maxLocals()); // static method + assertEquals(0, code.maxStack()); + } else { + assertTrue(name.equalsString("b")); + assertEquals(1, code.maxLocals()); // instance method + assertEquals(0, code.maxStack()); + } + } + } } From 2e40ae6cc2b997dc91857181711a3b29f6e2942b Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Tue, 9 Jul 2024 07:35:22 +0000 Subject: [PATCH 34/61] 8334433: jshell.exe runs an executable test.exe on startup Reviewed-by: vromero Backport-of: 24be82b720926f2bca6b2b6e2266dfed5b198952 --- .../jdk/internal/org/jline/utils/OSUtils.java | 2 +- .../jshell/tool/ConsoleIOContext.java | 7 +- .../jdk/jshell/TerminalNoExecTest.java | 96 +++++++++++++++++++ 3 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 test/langtools/jdk/jshell/TerminalNoExecTest.java diff --git a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java index 344d081c124..7fdfb9a028f 100644 --- a/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java +++ b/src/jdk.internal.le/share/classes/jdk/internal/org/jline/utils/OSUtils.java @@ -63,7 +63,7 @@ private static boolean isExecutable(File f) { String sttyfopt = null; String infocmp = null; String test = null; - String path = System.getenv("PATH"); + String path = "/usr/bin" + File.pathSeparator + "/bin";//was: System.getenv("PATH"); if (path != null) { String[] paths = path.split(File.pathSeparator); for (String p : paths) { diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java index 2812dc19695..cd3266ae710 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java @@ -155,7 +155,12 @@ public int readBuffered(byte[] b) throws IOException { setupReader = setupReader.andThen(r -> r.option(Option.DISABLE_HIGHLIGHTER, !enableHighlighter)); input.setInputStream(cmdin); } else { - terminal = TerminalBuilder.builder().inputStreamWrapper(in -> { + //on platforms which are known to be fully supported by + //the FFMTerminalProvider, do not permit the ExecTerminalProvider: + boolean allowExecTerminal = !OSUtils.IS_WINDOWS && + !OSUtils.IS_LINUX && + !OSUtils.IS_OSX; + terminal = TerminalBuilder.builder().exec(allowExecTerminal).inputStreamWrapper(in -> { input.setInputStream(in); return nonBlockingInput; }).nativeSignals(false).build(); diff --git a/test/langtools/jdk/jshell/TerminalNoExecTest.java b/test/langtools/jdk/jshell/TerminalNoExecTest.java new file mode 100644 index 00000000000..3d76157fd26 --- /dev/null +++ b/test/langtools/jdk/jshell/TerminalNoExecTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024, 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 8334433 + * @summary Verify that when running JShell on platforms that support FFMTerminalProvider, + * no new processes are spawned. + * @requires os.family == "windows" | os.family == "mac" | os.family == "linux" + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.compiler/com.sun.tools.javac.util + * @build toolbox.ToolBox toolbox.JavaTask TerminalNoExecTest + * @run main TerminalNoExecTest + */ + +import java.io.Writer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import jdk.jfr.consumer.RecordingStream; +import jdk.jshell.tool.JavaShellToolBuilder; + +import toolbox.ToolBox; + +public class TerminalNoExecTest { + + public static void main(String... args) throws Exception { + if (args.length > 0) { + AtomicBoolean spawnedNewProcess = new AtomicBoolean(); + try (var rs = new RecordingStream()) { + rs.enable("jdk.ProcessStart").withoutThreshold(); + rs.onEvent(evt -> { + System.err.println("evt: " + evt); + spawnedNewProcess.set(true); + }); + rs.startAsync(); + JavaShellToolBuilder.builder().run("--execution=local", "--no-startup"); + rs.stop(); + } + if (spawnedNewProcess.get()) { + System.err.println("Spawned a new process!"); + System.exit(1); + } + System.exit(0); + } else { + Path testScript = Paths.get("do-exit"); + try (Writer w = Files.newBufferedWriter(testScript)) { + w.append("/exit\n"); + } + + ToolBox tb = new ToolBox(); + Process target = + new ProcessBuilder(tb.getJDKTool("java").toString(), + "-classpath", System.getProperty("java.class.path"), + TerminalNoExecTest.class.getName(), + "run-test") + .redirectError(ProcessBuilder.Redirect.INHERIT) + .redirectOutput(ProcessBuilder.Redirect.INHERIT) + .redirectInput(testScript.toFile()) + .start(); + + target.waitFor(); + + int exitCode = target.exitValue(); + + if (exitCode != 0) { + throw new AssertionError("Incorrect exit value, expected 0, got: " + exitCode); + } + } + } + +} From 355c5fbbcd683068a13787e6a2b72ed55be73524 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Tue, 9 Jul 2024 08:12:38 +0000 Subject: [PATCH 35/61] 8335824: Test gc/arguments/TestMinInitialErgonomics.java is timing out Reviewed-by: kbarrett, ayang Backport-of: 3dc9a560f7b45a089b506f21935b4f143adb67f8 --- test/hotspot/jtreg/gc/arguments/TestMinInitialErgonomics.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/gc/arguments/TestMinInitialErgonomics.java b/test/hotspot/jtreg/gc/arguments/TestMinInitialErgonomics.java index 6b03401a563..6912499e53f 100644 --- a/test/hotspot/jtreg/gc/arguments/TestMinInitialErgonomics.java +++ b/test/hotspot/jtreg/gc/arguments/TestMinInitialErgonomics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, 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 @@ * @test TestMinInitialErgonomics * @bug 8006088 * @requires vm.gc.Parallel + * @requires vm.compMode != "Xcomp" * @summary Test Parallel GC ergonomics decisions related to minimum and initial heap size. * @library /test/lib * @library / From 576caf1c9754760e416a01bfa268edeca17f2eb5 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Tue, 9 Jul 2024 16:05:45 +0000 Subject: [PATCH 36/61] 8334757: AssertionError: Missing type variable in where clause Reviewed-by: jlahoda, vromero Backport-of: 0fcb0b9e94c0812695abc5618418adcfed8f4d0f --- .../javac/util/RichDiagnosticFormatter.java | 3 +++ .../CantAnnotateClassWithTypeVariable.java | 19 +++++++++++++++++++ .../CantAnnotateClassWithTypeVariable.out | 2 ++ 3 files changed, 24 insertions(+) create mode 100644 test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateClassWithTypeVariable.java create mode 100644 test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateClassWithTypeVariable.out diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java index e1faa02bd38..3bc5c671bfd 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java @@ -184,6 +184,9 @@ protected void preprocessArgument(Object arg) { if (arg instanceof Type type) { preprocessType(type); } + else if (arg instanceof JCDiagnostic.AnnotatedType type) { + preprocessType(type.type()); + } else if (arg instanceof Symbol symbol) { preprocessSymbol(symbol); } diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateClassWithTypeVariable.java b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateClassWithTypeVariable.java new file mode 100644 index 00000000000..8d575caec57 --- /dev/null +++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateClassWithTypeVariable.java @@ -0,0 +1,19 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8334757 + * @compile/fail/ref=CantAnnotateClassWithTypeVariable.out -XDrawDiagnostics CantAnnotateClassWithTypeVariable.java + */ + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +public class CantAnnotateClassWithTypeVariable { + @Target(ElementType.TYPE_USE) + @interface TA {} + + static class A { + static class B {} + } + + @TA A.B f() {} +} diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateClassWithTypeVariable.out b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateClassWithTypeVariable.out new file mode 100644 index 00000000000..80fa9f2cdd9 --- /dev/null +++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateClassWithTypeVariable.out @@ -0,0 +1,2 @@ +CantAnnotateClassWithTypeVariable.java:18:14: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @CantAnnotateClassWithTypeVariable.TA), CantAnnotateClassWithTypeVariable.A, @CantAnnotateClassWithTypeVariable.TA CantAnnotateClassWithTypeVariable.A.B +1 error From eee3abcc19e1f65c4bd812fee074c10e5e62580e Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Tue, 9 Jul 2024 19:39:25 +0000 Subject: [PATCH 37/61] 8335124: com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java failed with CPU time out of expected range Reviewed-by: cjplummer Backport-of: 218213668b850edaaa404835e997b744b32475c0 --- .../com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/jdk/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java b/test/jdk/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java index 83e37f0b475..6b0302aafbf 100644 --- a/test/jdk/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java +++ b/test/jdk/com/sun/management/ThreadMXBean/ThreadCpuTimeArray.java @@ -75,7 +75,6 @@ public static void main(String[] argv) // threads block after doing some computation waitUntilThreadBlocked(); - long times[] = mbean.getThreadCpuTime(ids); long userTimes[] = mbean.getThreadUserTime(ids); @@ -222,6 +221,8 @@ private static void waitUntilThreadBlocked() } } } + // Account for threads using CPU for a few millis after their WAITING state is visible: + goSleep(500); } public static void doit() { From f74ecc4dd947b5612ca110bbe772adb5ff1e3540 Mon Sep 17 00:00:00 2001 From: Jorn Vernee Date: Wed, 10 Jul 2024 16:58:04 +0000 Subject: [PATCH 38/61] 8333886: Explicitly specify that asSlice and reinterpret return a memory segment backed by the same region of memory. Reviewed-by: sundar Backport-of: 41a9ce5a12c6f91d035e84fffa8ba36c5ce793b1 --- .../java/lang/foreign/MemorySegment.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java index 6c75c0385fa..1b378512316 100644 --- a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java +++ b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java @@ -630,6 +630,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * {@snippet lang=java : * asSlice(offset, newSize, 1); * } + *

+ * The returned memory segment shares a region of backing memory with this segment. + * Hence, no memory will be allocated or freed by this method. * * @see #asSlice(long, long, long) * @@ -646,6 +649,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * Returns a slice of this memory segment, at the given offset, with the provided * alignment constraint. The returned segment's address is the address of this * segment plus the given offset; its size is specified by the given argument. + *

+ * The returned memory segment shares a region of backing memory with this segment. + * Hence, no memory will be allocated or freed by this method. * * @param offset The new segment base offset (relative to the address of this segment), * specified in bytes @@ -670,6 +676,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * {@snippet lang=java : * asSlice(offset, layout.byteSize(), layout.byteAlignment()); * } + *

+ * The returned memory segment shares a region of backing memory with this segment. + * Hence, no memory will be allocated or freed by this method. * * @see #asSlice(long, long, long) * @@ -693,6 +702,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * {@snippet lang=java : * asSlice(offset, byteSize() - offset); * } + *

+ * The returned memory segment shares a region of backing memory with this segment. + * Hence, no memory will be allocated or freed by this method. * * @see #asSlice(long, long) * @@ -706,6 +718,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { /** * Returns a new memory segment that has the same address and scope as this segment, * but with the provided size. + *

+ * The returned memory segment shares a region of backing memory with this segment. + * Hence, no memory will be allocated or freed by this method. * * @param newSize the size of the returned segment * @return a new memory segment that has the same address and scope as @@ -741,6 +756,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * That is, the cleanup action receives a segment that is associated with the global * scope, and is accessible from any thread. The size of the segment accepted by the * cleanup action is {@link #byteSize()}. + *

+ * The returned memory segment shares a region of backing memory with this segment. + * Hence, no memory will be allocated or freed by this method. * * @apiNote The cleanup action (if present) should take care not to leak the received * segment to external clients that might access the segment after its @@ -786,6 +804,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * That is, the cleanup action receives a segment that is associated with the global * scope, and is accessible from any thread. The size of the segment accepted by the * cleanup action is {@code newSize}. + *

+ * The returned memory segment shares a region of backing memory with this segment. + * Hence, no memory will be allocated or freed by this method. * * @apiNote The cleanup action (if present) should take care not to leak the received * segment to external clients that might access the segment after its From cc5de1b0c1b4c101ae7b081e6eda59aadec05d51 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 11 Jul 2024 03:06:38 +0000 Subject: [PATCH 39/61] 8335637: Add explicit non-null return value expectations to Object.toString() Reviewed-by: jpai Backport-of: 36e04b9aa3a93f0e277377eb8ad3a3491583c1df --- src/java.base/share/classes/java/lang/Object.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/java.base/share/classes/java/lang/Object.java b/src/java.base/share/classes/java/lang/Object.java index b8bfdc3e3f9..d9813df57a4 100644 --- a/src/java.base/share/classes/java/lang/Object.java +++ b/src/java.base/share/classes/java/lang/Object.java @@ -237,6 +237,10 @@ public boolean equals(Object obj) { /** * {@return a string representation of the object} + * + * Satisfying this method's contract implies a non-{@code null} + * result must be returned. + * * @apiNote * In general, the * {@code toString} method returns a string that From 4d04191f970f0b59010fefeea8778cb23ad96aff Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Thu, 11 Jul 2024 08:20:10 +0000 Subject: [PATCH 40/61] 8335966: Remove incorrect problem listing of java/lang/instrument/NativeMethodPrefixAgent.java in ProblemList-Virtual.txt Reviewed-by: kevinw Backport-of: 0fef72767f66ed27b04421e0af0721e4d78bc8df --- test/jdk/ProblemList-Virtual.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/jdk/ProblemList-Virtual.txt b/test/jdk/ProblemList-Virtual.txt index c45353e65ed..d7692b578cd 100644 --- a/test/jdk/ProblemList-Virtual.txt +++ b/test/jdk/ProblemList-Virtual.txt @@ -36,8 +36,6 @@ javax/management/remote/mandatory/loading/MissingClassTest.java 8145413 windows- javax/management/remote/mandatory/loading/RMIDownloadTest.java 8308366 windows-x64 -java/lang/instrument/NativeMethodPrefixAgent.java 8307169 generic-all - java/lang/ScopedValue/StressStackOverflow.java#default 8309646 generic-all java/lang/ScopedValue/StressStackOverflow.java#no-TieredCompilation 8309646 generic-all java/lang/ScopedValue/StressStackOverflow.java#TieredStopAtLevel1 8309646 generic-all From a1f525e24565dcc92bf79e0fbb1c1fdddf24e225 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Thu, 11 Jul 2024 11:08:31 +0000 Subject: [PATCH 41/61] 8335766: Switch case with pattern matching and guard clause compiles inconsistently Reviewed-by: vromero Backport-of: b16b7f2aa2c322e86d75336ca7ec2e275464956d --- .../com/sun/tools/javac/parser/JavacParser.java | 10 +++++++++- .../tools/javac/patterns/DisambiguatePatterns.java | 6 +++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index ce484e14b05..2ec0b1eadf4 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -3436,7 +3436,15 @@ PatternResult analyzePattern(int lookahead) { : PatternResult.PATTERN; } parenDepth++; break; - case RPAREN: parenDepth--; break; + case RPAREN: + parenDepth--; + if (parenDepth == 0 && + typeDepth == 0 && + peekToken(lookahead, TokenKind.IDENTIFIER) && + S.token(lookahead + 1).name() == names.when) { + return PatternResult.PATTERN; + } + break; case ARROW: return parenDepth > 0 ? PatternResult.EXPRESSION : pendingResult; case FINAL: diff --git a/test/langtools/tools/javac/patterns/DisambiguatePatterns.java b/test/langtools/tools/javac/patterns/DisambiguatePatterns.java index ef4d065f912..d6180c1810f 100644 --- a/test/langtools/tools/javac/patterns/DisambiguatePatterns.java +++ b/test/langtools/tools/javac/patterns/DisambiguatePatterns.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, 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 @@ -109,6 +109,10 @@ public static void main(String... args) throws Throwable { ExpressionType.EXPRESSION); test.disambiguationTest("a & b", ExpressionType.EXPRESSION); + test.disambiguationTest("R r when (x > 0)", + ExpressionType.PATTERN); + test.disambiguationTest("R(int x) when (x > 0)", + ExpressionType.PATTERN); } private final ParserFactory factory; From c41034ec926e7b8b800763caf31bc86216954884 Mon Sep 17 00:00:00 2001 From: Jorn Vernee Date: Thu, 11 Jul 2024 12:42:21 +0000 Subject: [PATCH 42/61] 8333884: MemorySegment::reinterpret removes read-only property Reviewed-by: liach, sundar Backport-of: 3c4f0965a83e8373325802f6ab6ea4ecd6bde107 --- .../java/lang/foreign/MemorySegment.java | 21 +++++++++++++++++++ .../foreign/AbstractMemorySegmentImpl.java | 2 +- .../internal/foreign/SegmentFactories.java | 10 ++++++--- test/jdk/java/foreign/TestSegments.java | 12 +++++++---- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java index 1b378512316..78b81297e36 100644 --- a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java +++ b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java @@ -631,6 +631,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * asSlice(offset, newSize, 1); * } *

+ * If this segment is {@linkplain MemorySegment#isReadOnly() read-only}, + * the returned segment is also {@linkplain MemorySegment#isReadOnly() read-only}. + *

* The returned memory segment shares a region of backing memory with this segment. * Hence, no memory will be allocated or freed by this method. * @@ -650,6 +653,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * alignment constraint. The returned segment's address is the address of this * segment plus the given offset; its size is specified by the given argument. *

+ * If this segment is {@linkplain MemorySegment#isReadOnly() read-only}, + * the returned segment is also {@linkplain MemorySegment#isReadOnly() read-only}. + *

* The returned memory segment shares a region of backing memory with this segment. * Hence, no memory will be allocated or freed by this method. * @@ -677,6 +683,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * asSlice(offset, layout.byteSize(), layout.byteAlignment()); * } *

+ * If this segment is {@linkplain MemorySegment#isReadOnly() read-only}, + * the returned segment is also {@linkplain MemorySegment#isReadOnly() read-only}. + *

* The returned memory segment shares a region of backing memory with this segment. * Hence, no memory will be allocated or freed by this method. * @@ -703,6 +712,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * asSlice(offset, byteSize() - offset); * } *

+ * If this segment is {@linkplain MemorySegment#isReadOnly() read-only}, + * the returned segment is also {@linkplain MemorySegment#isReadOnly() read-only}. + *

* The returned memory segment shares a region of backing memory with this segment. * Hence, no memory will be allocated or freed by this method. * @@ -719,6 +731,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * Returns a new memory segment that has the same address and scope as this segment, * but with the provided size. *

+ * If this segment is {@linkplain MemorySegment#isReadOnly() read-only}, + * the returned segment is also {@linkplain MemorySegment#isReadOnly() read-only}. + *

* The returned memory segment shares a region of backing memory with this segment. * Hence, no memory will be allocated or freed by this method. * @@ -757,6 +772,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * scope, and is accessible from any thread. The size of the segment accepted by the * cleanup action is {@link #byteSize()}. *

+ * If this segment is {@linkplain MemorySegment#isReadOnly() read-only}, + * the returned segment is also {@linkplain MemorySegment#isReadOnly() read-only}. + *

* The returned memory segment shares a region of backing memory with this segment. * Hence, no memory will be allocated or freed by this method. * @@ -805,6 +823,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl { * scope, and is accessible from any thread. The size of the segment accepted by the * cleanup action is {@code newSize}. *

+ * If this segment is {@linkplain MemorySegment#isReadOnly() read-only}, + * the returned segment is also {@linkplain MemorySegment#isReadOnly() read-only}. + *

* The returned memory segment shares a region of backing memory with this segment. * Hence, no memory will be allocated or freed by this method. * diff --git a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index f9f6ac2022a..325dbe1093f 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -159,7 +159,7 @@ public MemorySegment reinterpretInternal(Class callerClass, long newSize, Sco () -> cleanup.accept(SegmentFactories.makeNativeSegmentUnchecked(address(), newSize)) : null; return SegmentFactories.makeNativeSegmentUnchecked(address(), newSize, - (MemorySessionImpl)scope, action); + (MemorySessionImpl)scope, readOnly, action); } private AbstractMemorySegmentImpl asSliceNoCheck(long offset, long newSize) { diff --git a/src/java.base/share/classes/jdk/internal/foreign/SegmentFactories.java b/src/java.base/share/classes/jdk/internal/foreign/SegmentFactories.java index 17f141b4e8c..133631e2aa4 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/SegmentFactories.java +++ b/src/java.base/share/classes/jdk/internal/foreign/SegmentFactories.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, 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 @@ -57,14 +57,18 @@ public class SegmentFactories { // associated with MemorySegment::ofAddress. @ForceInline - public static MemorySegment makeNativeSegmentUnchecked(long min, long byteSize, MemorySessionImpl sessionImpl, Runnable action) { + public static MemorySegment makeNativeSegmentUnchecked(long min, + long byteSize, + MemorySessionImpl sessionImpl, + boolean readOnly, + Runnable action) { ensureInitialized(); if (action == null) { sessionImpl.checkValidState(); } else { sessionImpl.addCloseAction(action); } - return new NativeMemorySegmentImpl(min, byteSize, false, sessionImpl); + return new NativeMemorySegmentImpl(min, byteSize, readOnly, sessionImpl); } @ForceInline diff --git a/test/jdk/java/foreign/TestSegments.java b/test/jdk/java/foreign/TestSegments.java index 44ecd12ba5e..b361abac3df 100644 --- a/test/jdk/java/foreign/TestSegments.java +++ b/test/jdk/java/foreign/TestSegments.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, 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 @@ -43,7 +43,6 @@ import java.util.function.Supplier; import static java.lang.foreign.ValueLayout.JAVA_INT; -import static java.lang.foreign.ValueLayout.JAVA_LONG; import static org.testng.Assert.*; public class TestSegments { @@ -383,9 +382,14 @@ void testReinterpret() { assertEquals(MemorySegment.ofAddress(42).reinterpret(100, Arena.ofAuto(), null).byteSize(), 100); // check scope and cleanup assertEquals(MemorySegment.ofAddress(42).reinterpret(100, arena, s -> counter.incrementAndGet()).scope(), arena.scope()); - assertEquals(MemorySegment.ofAddress(42).reinterpret(arena, s -> counter.incrementAndGet()).scope(), arena.scope()); + assertEquals(MemorySegment.ofAddress(42).reinterpret(arena, _ -> counter.incrementAndGet()).scope(), arena.scope()); + // check read-only state + assertFalse(MemorySegment.ofAddress(42).reinterpret(100).isReadOnly()); + assertTrue(MemorySegment.ofAddress(42).asReadOnly().reinterpret(100).isReadOnly()); + assertTrue(MemorySegment.ofAddress(42).asReadOnly().reinterpret(100, Arena.ofAuto(), null).isReadOnly()); + assertTrue(MemorySegment.ofAddress(42).asReadOnly().reinterpret(arena, _ -> counter.incrementAndGet()).isReadOnly()); } - assertEquals(counter.get(), 2); + assertEquals(counter.get(), 3); } @Test From 3bf8cbd8d6f077e8141daa392b698ac881d84732 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Thu, 11 Jul 2024 20:51:38 +0000 Subject: [PATCH 43/61] 8335935: Chained builders not sending transformed models to next transforms Reviewed-by: asotona Backport-of: 934144934324e58c9a103a93648b79ba8d3d168f --- .../java/lang/classfile/CodeBuilder.java | 4 +- .../classfile/impl/BlockCodeBuilderImpl.java | 16 +- .../classfile/impl/BufferedCodeBuilder.java | 4 +- .../classfile/impl/ChainedClassBuilder.java | 16 +- .../classfile/impl/ChainedMethodBuilder.java | 10 +- .../classfile/impl/DirectCodeBuilder.java | 4 +- .../internal/classfile/impl/LabelContext.java | 4 +- .../classfile/impl/TerminalCodeBuilder.java | 8 +- .../impl/TransformingCodeBuilder.java | 91 ---------- test/jdk/jdk/classfile/TransformTests.java | 163 ++++++++++++++++++ 10 files changed, 196 insertions(+), 124 deletions(-) delete mode 100644 src/java.base/share/classes/jdk/internal/classfile/impl/TransformingCodeBuilder.java diff --git a/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java b/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java index e954be079fa..ad64d7d60a1 100644 --- a/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java @@ -86,7 +86,7 @@ import static java.util.Objects.requireNonNull; import static jdk.internal.classfile.impl.BytecodeHelpers.handleDescToHandleInfo; -import jdk.internal.classfile.impl.TransformingCodeBuilder; + import jdk.internal.javac.PreviewFeature; /** @@ -171,7 +171,7 @@ public sealed interface CodeBuilder default CodeBuilder transforming(CodeTransform transform, Consumer handler) { var resolved = transform.resolve(this); resolved.startHandler().run(); - handler.accept(new TransformingCodeBuilder(this, resolved.consumer())); + handler.accept(new ChainedCodeBuilder(this, resolved.consumer())); resolved.endHandler().run(); return this; } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/BlockCodeBuilderImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/BlockCodeBuilderImpl.java index ffe1a2bd616..66e974b4a51 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/BlockCodeBuilderImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/BlockCodeBuilderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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 @@ -51,13 +51,13 @@ public BlockCodeBuilderImpl(CodeBuilder parent, Label breakLabel) { public void start() { topLocal = topLocal(parent); - terminalMaxLocals = topLocal(terminal); - terminal.with((LabelTarget) startLabel); + terminalMaxLocals = terminal.curTopLocal(); + parent.with((LabelTarget) startLabel); } public void end() { - terminal.with((LabelTarget) endLabel); - if (terminalMaxLocals != topLocal(terminal)) { + parent.with((LabelTarget) endLabel); + if (terminalMaxLocals != terminal.curTopLocal()) { throw new IllegalStateException("Interference in local variable slot management"); } } @@ -73,10 +73,8 @@ public boolean isEmpty() { private int topLocal(CodeBuilder parent) { return switch (parent) { case BlockCodeBuilderImpl b -> b.topLocal; - case ChainedCodeBuilder b -> topLocal(b.terminal); - case DirectCodeBuilder b -> b.curTopLocal(); - case BufferedCodeBuilder b -> b.curTopLocal(); - case TransformingCodeBuilder b -> topLocal(b.delegate); + case ChainedCodeBuilder b -> b.terminal.curTopLocal(); + case TerminalCodeBuilder b -> b.curTopLocal(); }; } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/BufferedCodeBuilder.java b/src/java.base/share/classes/jdk/internal/classfile/impl/BufferedCodeBuilder.java index 60e73cdd987..8603c77ab8b 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/BufferedCodeBuilder.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/BufferedCodeBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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 @@ -43,7 +43,7 @@ import java.util.function.Consumer; public final class BufferedCodeBuilder - implements TerminalCodeBuilder, LabelContext { + implements TerminalCodeBuilder { private final SplitConstantPool constantPool; private final ClassFileImpl context; private final List elements = new ArrayList<>(); diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ChainedClassBuilder.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ChainedClassBuilder.java index cc19bf9d31c..b33d192f9b3 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/ChainedClassBuilder.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ChainedClassBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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,13 +33,11 @@ public final class ChainedClassBuilder implements ClassBuilder, Consumer { - private final ClassBuilder downstream; private final DirectClassBuilder terminal; private final Consumer consumer; public ChainedClassBuilder(ClassBuilder downstream, Consumer consumer) { - this.downstream = downstream; this.consumer = consumer; this.terminal = switch (downstream) { case ChainedClassBuilder cb -> cb.terminal; @@ -60,10 +58,11 @@ public Optional original() { @Override public ClassBuilder withField(Utf8Entry name, Utf8Entry descriptor, Consumer handler) { - return downstream.with(new BufferedFieldBuilder(terminal.constantPool, terminal.context, + consumer.accept(new BufferedFieldBuilder(terminal.constantPool, terminal.context, name, descriptor, null) .run(handler) .toModel()); + return this; } @Override @@ -72,16 +71,18 @@ public ClassBuilder transformField(FieldModel field, FieldTransform transform) { field.fieldName(), field.fieldType(), field); builder.transform(field, transform); - return downstream.with(builder.toModel()); + consumer.accept(builder.toModel()); + return this; } @Override public ClassBuilder withMethod(Utf8Entry name, Utf8Entry descriptor, int flags, Consumer handler) { - return downstream.with(new BufferedMethodBuilder(terminal.constantPool, terminal.context, + consumer.accept(new BufferedMethodBuilder(terminal.constantPool, terminal.context, name, descriptor, null) .run(handler) .toModel()); + return this; } @Override @@ -89,7 +90,8 @@ public ClassBuilder transformMethod(MethodModel method, MethodTransform transfor BufferedMethodBuilder builder = new BufferedMethodBuilder(terminal.constantPool, terminal.context, method.methodName(), method.methodType(), method); builder.transform(method, transform); - return downstream.with(builder.toModel()); + consumer.accept(builder.toModel()); + return this; } @Override diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ChainedMethodBuilder.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ChainedMethodBuilder.java index 38850aec109..866dda2c5bc 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/ChainedMethodBuilder.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ChainedMethodBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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 @@ -36,13 +36,11 @@ import java.lang.classfile.constantpool.ConstantPoolBuilder; public final class ChainedMethodBuilder implements MethodBuilder { - final MethodBuilder downstream; final TerminalMethodBuilder terminal; final Consumer consumer; public ChainedMethodBuilder(MethodBuilder downstream, Consumer consumer) { - this.downstream = downstream; this.consumer = consumer; this.terminal = switch (downstream) { case ChainedMethodBuilder cb -> cb.terminal; @@ -58,16 +56,18 @@ public MethodBuilder with(MethodElement element) { @Override public MethodBuilder withCode(Consumer handler) { - return downstream.with(terminal.bufferedCodeBuilder(null) + consumer.accept(terminal.bufferedCodeBuilder(null) .run(handler) .toModel()); + return this; } @Override public MethodBuilder transformCode(CodeModel code, CodeTransform transform) { BufferedCodeBuilder builder = terminal.bufferedCodeBuilder(code); builder.transform(code, transform); - return downstream.with(builder.toModel()); + consumer.accept(builder.toModel()); + return this; } @Override diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java b/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java index b961a12031f..0b6549a82da 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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 @@ -75,7 +75,7 @@ public final class DirectCodeBuilder extends AbstractDirectBuilder - implements TerminalCodeBuilder, LabelContext { + implements TerminalCodeBuilder { private final List characterRanges = new ArrayList<>(); final List handlers = new ArrayList<>(); private final List localVariables = new ArrayList<>(); diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/LabelContext.java b/src/java.base/share/classes/jdk/internal/classfile/impl/LabelContext.java index e17adcbcf12..749abbed23b 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/LabelContext.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/LabelContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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,7 +27,7 @@ import java.lang.classfile.Label; public sealed interface LabelContext - permits BufferedCodeBuilder, CodeImpl, DirectCodeBuilder { + permits TerminalCodeBuilder, CodeImpl { Label newLabel(); Label getLabel(int bci); void setLabelTarget(Label label, int bci); diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/TerminalCodeBuilder.java b/src/java.base/share/classes/jdk/internal/classfile/impl/TerminalCodeBuilder.java index e13b09b0a4d..6e3ca516bf4 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/TerminalCodeBuilder.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/TerminalCodeBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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 @@ import java.lang.classfile.CodeBuilder; -public sealed interface TerminalCodeBuilder extends CodeBuilder - permits DirectCodeBuilder, BufferedCodeBuilder, TransformingCodeBuilder { - +public sealed interface TerminalCodeBuilder extends CodeBuilder, LabelContext + permits DirectCodeBuilder, BufferedCodeBuilder { + int curTopLocal(); } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/TransformingCodeBuilder.java b/src/java.base/share/classes/jdk/internal/classfile/impl/TransformingCodeBuilder.java deleted file mode 100644 index 4ffc75d3edc..00000000000 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/TransformingCodeBuilder.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2022, 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.classfile.impl; - -import java.lang.classfile.CodeBuilder; -import java.lang.classfile.CodeModel; -import java.util.Optional; -import java.util.function.Consumer; -import java.lang.classfile.CodeElement; -import java.lang.classfile.Label; -import java.lang.classfile.TypeKind; -import java.lang.classfile.constantpool.ConstantPoolBuilder; - -public final class TransformingCodeBuilder implements TerminalCodeBuilder { - - final CodeBuilder delegate; - final Consumer consumer; - - public TransformingCodeBuilder(CodeBuilder delegate, Consumer consumer) { - this.delegate = delegate; - this.consumer = consumer; - } - - @Override - public CodeBuilder with(CodeElement e) { - consumer.accept(e); - return this; - } - - @Override - public Optional original() { - return delegate.original(); - } - - @Override - public Label newLabel() { - return delegate.newLabel(); - } - - @Override - public Label startLabel() { - return delegate.startLabel(); - } - - @Override - public Label endLabel() { - return delegate.endLabel(); - } - - @Override - public int receiverSlot() { - return delegate.receiverSlot(); - } - - @Override - public int parameterSlot(int paramNo) { - return delegate.parameterSlot(paramNo); - } - - @Override - public int allocateLocal(TypeKind typeKind) { - return delegate.allocateLocal(typeKind); - } - - @Override - public ConstantPoolBuilder constantPool() { - return delegate.constantPool(); - } -} diff --git a/test/jdk/jdk/classfile/TransformTests.java b/test/jdk/jdk/classfile/TransformTests.java index 13abca0ec52..08cfe432b42 100644 --- a/test/jdk/jdk/classfile/TransformTests.java +++ b/test/jdk/jdk/classfile/TransformTests.java @@ -23,9 +23,22 @@ /* * @test + * @bug 8336010 * @summary Testing ClassFile transformations. * @run junit TransformTests */ +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.CodeBuilder; +import java.lang.classfile.CodeElement; +import java.lang.classfile.FieldModel; +import java.lang.classfile.FieldTransform; +import java.lang.classfile.Label; +import java.lang.classfile.MethodTransform; +import java.lang.classfile.instruction.BranchInstruction; +import java.lang.classfile.instruction.LabelTarget; +import java.lang.constant.ClassDesc; +import java.lang.constant.MethodTypeDesc; +import java.lang.reflect.AccessFlag; import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; @@ -39,8 +52,13 @@ import java.lang.classfile.CodeTransform; import java.lang.classfile.MethodModel; import java.lang.classfile.instruction.ConstantInstruction; +import java.util.HashSet; +import java.util.Set; + import org.junit.jupiter.api.Test; +import static java.lang.classfile.ClassFile.*; +import static java.lang.constant.ConstantDescs.*; import static org.junit.jupiter.api.Assertions.*; /** @@ -126,6 +144,151 @@ void testSeqN() throws Exception { assertEquals(invoke(cc.transform(cm, transformCode(foo2foo.andThen(foo2bar).andThen(bar2baz)))), "baz"); } + /** + * Test to ensure class elements, such as field and + * methods defined with transform/with, are visible + * to next transforms. + */ + @Test + void testClassChaining() throws Exception { + var bytes = Files.readAllBytes(testClassPath); + var cf = ClassFile.of(); + var cm = cf.parse(bytes); + var otherCm = cf.parse(cf.build(ClassDesc.of("Temp"), clb -> clb + .withMethodBody("baz", MTD_void, ACC_STATIC, CodeBuilder::return_) + .withField("baz", CD_long, ACC_STATIC))); + + var methodBaz = otherCm.methods().getFirst(); + var fieldBaz = otherCm.fields().getFirst(); + + ClassTransform transform1 = ClassTransform.endHandler(cb -> { + ClassBuilder ret; + ret = cb.withMethodBody("bar", MTD_void, ACC_STATIC, CodeBuilder::return_); + assertSame(cb, ret); + ret = cb.transformMethod(methodBaz, MethodTransform.ACCEPT_ALL); + assertSame(cb, ret); + ret = cb.withField("bar", CD_int, ACC_STATIC); + assertSame(cb, ret); + ret = cb.transformField(fieldBaz, FieldTransform.ACCEPT_ALL); + assertSame(cb, ret); + }); + + Set methodNames = new HashSet<>(); + Set fieldNames = new HashSet<>(); + ClassTransform transform2 = (cb, ce) -> { + if (ce instanceof MethodModel mm) { + methodNames.add(mm.methodName().stringValue()); + } + if (ce instanceof FieldModel fm) { + fieldNames.add(fm.fieldName().stringValue()); + } + cb.with(ce); + }; + + cf.transform(cm, transform1.andThen(transform2)); + + assertEquals(Set.of(INIT_NAME, "foo", "bar", "baz"), methodNames); + assertEquals(Set.of("bar", "baz"), fieldNames); + } + + /** + * Test to ensure method elements, such as generated + * or transformed code, are visible to transforms. + */ + @Test + void testMethodChaining() throws Exception { + var mtd = MethodTypeDesc.of(CD_String); + + var cf = ClassFile.of(); + + // withCode + var cm = cf.parse(cf.build(ClassDesc.of("Temp"), clb -> clb + .withMethod("baz", mtd, ACC_STATIC | ACC_NATIVE, _ -> {}))); + + MethodTransform transform1 = MethodTransform.endHandler(mb -> { + var ret = mb.withCode(cob -> cob.loadConstant("foo").areturn()); + assertSame(mb, ret); + }); + + boolean[] sawWithCode = { false }; + MethodTransform transform2 = (mb, me) -> { + if (me instanceof CodeModel) { + sawWithCode[0] = true; + } + mb.with(me); + }; + + cf.transform(cm, ClassTransform.transformingMethods(transform1.andThen(transform2))); + + assertTrue(sawWithCode[0], "Code attribute generated not visible"); + + // transformCode + var outerCm = cf.parse(testClassPath); + var foo = outerCm.methods().stream() + .filter(m -> m.flags().has(AccessFlag.STATIC)) + .findFirst().orElseThrow(); + + MethodTransform transform3 = MethodTransform.endHandler(mb -> { + var ret = mb.transformCode(foo.code().orElseThrow(), CodeTransform.ACCEPT_ALL); + assertSame(mb, ret); + }); + + boolean[] sawTransformCode = { false }; + MethodTransform transform4 = (mb, me) -> { + if (me instanceof CodeModel) { + sawTransformCode[0] = true; + } + mb.with(me); + }; + + cf.transform(cm, ClassTransform.transformingMethods(transform3.andThen(transform4))); + + assertTrue(sawTransformCode[0], "Code attribute transformed not visible"); + } + + /** + * Test to ensure code elements, such as code block + * begin and end labels, are visible to transforms. + */ + @Test + void testCodeChaining() throws Exception { + var bytes = Files.readAllBytes(testClassPath); + var cf = ClassFile.of(); + var cm = cf.parse(bytes); + + CodeTransform transform1 = new CodeTransform() { + @Override + public void atStart(CodeBuilder builder) { + builder.block(bcb -> { + bcb.loadConstant(9876L); + bcb.goto_(bcb.endLabel()); + }); + } + + @Override + public void accept(CodeBuilder builder, CodeElement element) { + builder.with(element); + } + }; + Set

-
   this is snippet_standalone
+                    
   this is snippet_standalone
                     
@@ -131,7 +131,7 @@ public void snippet_wrapped() { }

First sentence.

Before.

-
   this is a snippet_wrapped
+                    
   this is a snippet_wrapped
                     
diff --git a/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestLangProperties.java b/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestLangProperties.java index 49b328f314d..2edd2d34c4c 100644 --- a/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestLangProperties.java +++ b/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestLangProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, 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 @@ -179,7 +179,7 @@ public class A {
%s
""".formatted(index, getSnippetHtmlRepresentation("A.html", - t.expectedOutput(), Optional.of("properties"))); + t.expectedOutput(), Optional.of("properties"), Optional.of("snippet-case" + index + "()2"))); checkOutput("A.html", true, html); }); } diff --git a/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetMarkup.java b/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetMarkup.java index 5d9eb794613..9a332fde1a9 100644 --- a/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetMarkup.java +++ b/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetMarkup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, 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 @@ -52,6 +52,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Function; import java.util.regex.MatchResult; @@ -365,7 +366,7 @@ public class A { case%s()
%s -
""".formatted(index, getSnippetHtmlRepresentation("A.html", t.expectedOutput())); + """.formatted(index, getSnippetHtmlRepresentation("A.html", t.expectedOutput(), Optional.empty(), Optional.of("snippet-case" + index + "()2"))); checkOutput("A.html", true, html); }); } diff --git a/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetTag.java b/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetTag.java index b7b54dfdb26..7e79232ef72 100644 --- a/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetTag.java +++ b/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetTag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, 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 @@ -220,8 +220,9 @@ record SnippetAttributes(String content, String id, String lang) { } checkLinks(); for (int j = 0; j < snippets.size(); j++) { var attr = snippets.get(j); + Optional id = (attr.id() != null ? Optional.of(attr.id()) : Optional.of("snippet-case" + j + "()1")); var snippetHtml = getSnippetHtmlRepresentation("pkg/A.html", " Hello, Snippet!\n", - Optional.ofNullable(attr.lang()), Optional.ofNullable(attr.id())); + Optional.ofNullable(attr.lang()), id); checkOutput("pkg/A.html", true, """ case%s() @@ -879,7 +880,8 @@ record TestCase(String input, String expectedOutput) { } """ case%s()
- %s""".formatted(id, getSnippetHtmlRepresentation("pkg/A.html", t.expectedOutput()))); + %s""".formatted(id, getSnippetHtmlRepresentation("pkg/A.html", t.expectedOutput(), Optional.empty(), + Optional.of("snippet-case" + id + "()2")))); }); } @@ -971,7 +973,8 @@ record TestCase(String input, Function expectedTransformation) { """ case%s()
- %s""".formatted(index, getSnippetHtmlRepresentation("pkg/A.html", expectedOutput))); + %s""".formatted(index, getSnippetHtmlRepresentation("pkg/A.html", expectedOutput, Optional.empty(), + Optional.of("snippet-case" + index + "()2")))); }); } @@ -1549,7 +1552,8 @@ record TestCase(Snippet snippet, String expectedOutput) { } """ case%s()
- %s""".formatted(index, getSnippetHtmlRepresentation("pkg/A.html", t.expectedOutput()))); + %s""".formatted(index, getSnippetHtmlRepresentation("pkg/A.html", t.expectedOutput(), Optional.empty(), + Optional.of("snippet-case" + index + "()2")))); }); } @@ -1662,12 +1666,14 @@ public void testPositiveInlineTagMarkup_SyntaxCurly(Path base) throws Exception """ case0()
- """ + getSnippetHtmlRepresentation("pkg/A.html", "")); + """ + getSnippetHtmlRepresentation("pkg/A.html", "", Optional.empty(), + Optional.of("snippet-case0()2"))); checkOutput("pkg/A.html", true, """ case1()
- """ + getSnippetHtmlRepresentation("pkg/A.html", "")); + """ + getSnippetHtmlRepresentation("pkg/A.html", "", Optional.empty(), + Optional.of("snippet-case1()2"))); } @Test // TODO: use combinatorial methods @@ -1765,7 +1771,8 @@ public void testPositiveExternalTagMarkup_AttributeValueSyntax(Path base) throws case%s()
%s - """.formatted(j, getSnippetHtmlRepresentation("pkg/A.html", "2"))); + """.formatted(j, getSnippetHtmlRepresentation("pkg/A.html", "2", Optional.empty(), + Optional.of("snippet-case" + j + "()2")))); } } @@ -1844,7 +1851,8 @@ record TestCase(Snippet snippet, String expectedOutput) { } """ case%s()
- %s""".formatted(index, getSnippetHtmlRepresentation("pkg/A.html", t.expectedOutput()))); + %s""".formatted(index, getSnippetHtmlRepresentation("pkg/A.html", t.expectedOutput(), Optional.empty(), + Optional.of("snippet-case" + index + "()2")))); }); } @@ -2302,7 +2310,8 @@ record TestCase(Snippet snippet, String expectedOutput) { } """ case%s()
- %s""".formatted(index, getSnippetHtmlRepresentation("pkg/A.html", t.expectedOutput()))); + %s""".formatted(index, getSnippetHtmlRepresentation("pkg/A.html", t.expectedOutput(), Optional.empty(), + Optional.of("snippet-case" + index + "()2")))); }); } diff --git a/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetUnnamedPackage.java b/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetUnnamedPackage.java index 4f5c3e32223..616eb3a7ed7 100644 --- a/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetUnnamedPackage.java +++ b/test/langtools/jdk/javadoc/doclet/testSnippetTag/TestSnippetUnnamedPackage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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,6 +91,6 @@ private C() { } %s After.""".formatted(getSnippetHtmlRepresentation("C.html", - "public class S { }", Optional.of("java")))); + "public class S { }", Optional.of("java"), Optional.of("snippet-C1")))); } } From 6c32473a415d746f0fa0e56059c58569e2cd2a10 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Mon, 15 Jul 2024 01:37:34 +0000 Subject: [PATCH 47/61] 8334719: (se) Deferred close of SelectableChannel may result in a Selector doing the final close before concurrent I/O on channel has completed Reviewed-by: alanb Backport-of: 258303fce65a374e1ab4b1507a826b216234352b --- .../sun/nio/ch/DatagramChannelImpl.java | 5 + .../sun/nio/ch/ServerSocketChannelImpl.java | 3 + .../classes/sun/nio/ch/SocketChannelImpl.java | 5 + .../classes/sun/nio/ch/SinkChannelImpl.java | 3 + .../classes/sun/nio/ch/SourceChannelImpl.java | 3 + .../DeferredClose/DeferredCloseTest.java | 484 ++++++++++++++++++ .../java.base/java/net/InetSocketAddress.java | 202 ++++++++ 7 files changed, 705 insertions(+) create mode 100644 test/jdk/java/nio/channels/Selector/DeferredClose/DeferredCloseTest.java create mode 100644 test/jdk/java/nio/channels/Selector/DeferredClose/java.base/java/net/InetSocketAddress.java diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java index 31823cfbb87..5c06ac7d9be 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java @@ -1945,6 +1945,11 @@ protected void implCloseSelectableChannel() throws IOException { @Override public void kill() { + // wait for any read/write operations to complete before trying to close + readLock.lock(); + readLock.unlock(); + writeLock.lock(); + writeLock.unlock(); synchronized (stateLock) { if (state == ST_CLOSING) { tryFinishClose(); diff --git a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java index c6ddad2a05c..0bd72bacf0b 100644 --- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java @@ -654,6 +654,9 @@ protected void implCloseSelectableChannel() throws IOException { @Override public void kill() { + // wait for any accept operation to complete before trying to close + acceptLock.lock(); + acceptLock.unlock(); synchronized (stateLock) { if (state == ST_CLOSING) { tryFinishClose(); diff --git a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java index f23a0aa0152..ebbf55acd97 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java @@ -1216,6 +1216,11 @@ protected void implCloseSelectableChannel() throws IOException { @Override public void kill() { + // wait for any read/write operations to complete before trying to close + readLock.lock(); + readLock.unlock(); + writeLock.lock(); + writeLock.unlock(); synchronized (stateLock) { if (state == ST_CLOSING) { tryFinishClose(); diff --git a/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java b/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java index 491e0104765..bc15d8d156b 100644 --- a/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java +++ b/src/java.base/unix/classes/sun/nio/ch/SinkChannelImpl.java @@ -201,6 +201,9 @@ protected void implCloseSelectableChannel() throws IOException { @Override public void kill() { + // wait for any write operation to complete before trying to close + writeLock.lock(); + writeLock.unlock(); synchronized (stateLock) { if (state == ST_CLOSING) { tryFinishClose(); diff --git a/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java b/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java index 102041dd294..2990d35b516 100644 --- a/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java +++ b/src/java.base/unix/classes/sun/nio/ch/SourceChannelImpl.java @@ -200,6 +200,9 @@ protected void implCloseSelectableChannel() throws IOException { } @Override public void kill() { + // wait for any read operation to complete before trying to close + readLock.lock(); + readLock.unlock(); synchronized (stateLock) { assert !isOpen(); if (state == ST_CLOSING) { diff --git a/test/jdk/java/nio/channels/Selector/DeferredClose/DeferredCloseTest.java b/test/jdk/java/nio/channels/Selector/DeferredClose/DeferredCloseTest.java new file mode 100644 index 00000000000..42dd7d42f56 --- /dev/null +++ b/test/jdk/java/nio/channels/Selector/DeferredClose/DeferredCloseTest.java @@ -0,0 +1,484 @@ +/* + * Copyright (c) 2024, 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.io.IOException; +import java.io.UncheckedIOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.ClosedSelectorException; +import java.nio.channels.DatagramChannel; +import java.nio.channels.Pipe; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.time.Instant; +import java.util.Objects; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.function.Function; +import java.util.stream.Stream; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/* + * @test + * @bug 8334719 + * @summary verifies that if a registered channel has in-progress operations, then + * the Selector during its deferred close implementation won't prematurely release + * the channel's resources + * + * @comment we use a patched java.net.InetSocketAddress to allow the test to intentionally + * craft some delays at specific locations in the implementation of InetSocketAddress + * to trigger race conditions + * @compile/module=java.base java/net/InetSocketAddress.java + * @run junit/othervm DeferredCloseTest + */ +public class DeferredCloseTest { + + private static final int NUM_ITERATIONS = 10; + private static final InetSocketAddress BIND_ADDR = new InetSocketAddress( + InetAddress.getLoopbackAddress(), 0); + + @BeforeAll + public static void beforeAll() throws Exception { + // configure our patched java.net.InetSocketAddress implementation + // to introduce delay in certain methods which get invoked + // internally from the DC.send() implementation + InetSocketAddress.enableDelay(); + } + + @AfterAll + public static void afterAll() throws Exception { + // delays in patched InetSocketAddress are no longer needed + InetSocketAddress.disableDelay(); + } + + private static Stream dcOperations() { + return Stream.of( + Arguments.of( + // repeatedly do DC.send() till there's a ClosedChannelException + "DC.send()", + null, + (Function) (dc) -> { + ByteBuffer bb = ByteBuffer.allocate(100); + try { + // We send to ourselves. Target, content and + // receipt of the Datagram isn't of importance + // in this test. + SocketAddress target = dc.getLocalAddress(); + System.out.println("DC: " + dc + " sending to " + target); + while (true) { + bb.clear(); + dc.send(bb, target); + } + } catch (ClosedChannelException _) { + } catch (Exception e) { + throw new RuntimeException(e); + } + return null; + } + ), + Arguments.of( + // repeatedly do DC.receive() till there's a ClosedChannelException + "DC.receive()", + (Function) (dc) -> { + try { + SocketAddress target = dc.getLocalAddress(); + ByteBuffer sendBB = ByteBuffer.allocate(100); + // first send() a few datagrams so that subsequent + // receive() does receive them and thus triggers + // the potential race with the deferred close + for (int i = 0; i < 5; i++) { + sendBB.clear(); + dc.send(sendBB, target); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return null; + }, + (Function) (dc) -> { + try { + ByteBuffer rcvBB = ByteBuffer.allocate(10); + while (true) { + rcvBB.clear(); + dc.receive(rcvBB); + } + } catch (ClosedChannelException _) { + } catch (Exception e) { + throw new RuntimeException(e); + } + return null; + } + ) + ); + } + + /** + * Runs the test for DatagramChannel. + * + * @see #runTest(ExecutorService, SelectionKey, Callable, CountDownLatch) + */ + @ParameterizedTest + @MethodSource("dcOperations") + public void testDatagramChannel(String opName, Function preOp, + Function dcOperation) + throws Exception { + try (ExecutorService executor = Executors.newFixedThreadPool(2)) { + for (int i = 1; i <= NUM_ITERATIONS; i++) { + System.out.format("%s DatagramChannel - %d of %d ...%n", + Instant.now(), i, NUM_ITERATIONS); + try (Selector sel = Selector.open(); + DatagramChannel dc = DatagramChannel.open()) { + // create a non-blocking bound DatagramChannel + dc.bind(BIND_ADDR); + dc.configureBlocking(false); + // register the DatagramChannel with a selector + // (doesn't matter the interestOps) + SelectionKey key = dc.register(sel, SelectionKey.OP_READ); + if (preOp != null) { + preOp.apply(dc); + } + CountDownLatch opStartLatch = new CountDownLatch(1); + runTest(executor, key, () -> { + // notify that we will now start operation on the DC + opStartLatch.countDown(); + return dcOperation.apply(dc); + }, opStartLatch); + } + } + } + } + + + private static Stream scOperations() { + return Stream.of( + Arguments.of( + // repeatedly do SC.write() till there's a ClosedChannelException + "SC.write()", (Function) (sc) -> { + ByteBuffer bb = ByteBuffer.allocate(100); + try { + System.out.println("SC: " + sc + " writing"); + while (true) { + bb.clear(); + sc.write(bb); + } + } catch (ClosedChannelException _) { + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + return null; + } + ), + Arguments.of( + // repeatedly do SC.read() till there's a ClosedChannelException + "SC.read()", (Function) (sc) -> { + ByteBuffer bb = ByteBuffer.allocate(100); + try { + System.out.println("SC: " + sc + " reading"); + while (true) { + bb.clear(); + sc.read(bb); + } + } catch (ClosedChannelException _) { + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + return null; + } + ) + ); + } + + /** + * Runs the test for SocketChannel + * + * @see #runTest(ExecutorService, SelectionKey, Callable, CountDownLatch) + */ + @ParameterizedTest + @MethodSource("scOperations") + public void testSocketChannel(String opName, Function scOperation) + throws Exception { + try (ExecutorService executor = Executors.newFixedThreadPool(3)) { + for (int i = 1; i <= NUM_ITERATIONS; i++) { + System.out.format("%s SocketChannel - %d of %d ...%n", + Instant.now(), i, NUM_ITERATIONS); + try (Selector sel = Selector.open(); + SocketChannel sc = SocketChannel.open()) { + // create and bind a SocketChannel + sc.bind(BIND_ADDR); + // stay in blocking mode till the SocketChannel is connected + sc.configureBlocking(true); + Future acceptedChannel; + SocketChannel conn; + // create a remote server and connect to it + try (ServerSocketChannel server = ServerSocketChannel.open()) { + server.bind(BIND_ADDR); + SocketAddress remoteAddr = server.getLocalAddress(); + acceptedChannel = executor.submit(new ConnAcceptor(server)); + System.out.println("connecting to " + remoteAddr); + sc.connect(remoteAddr); + conn = acceptedChannel.get(); + } + try (conn) { + // switch to non-blocking + sc.configureBlocking(false); + System.out.println("switched to non-blocking: " + sc); + // register the SocketChannel with a selector + // (doesn't matter the interestOps) + SelectionKey key = sc.register(sel, SelectionKey.OP_READ); + CountDownLatch opStartLatch = new CountDownLatch(1); + runTest(executor, key, () -> { + // notify that we will now start operation on the SC + opStartLatch.countDown(); + return scOperation.apply(sc); + }, opStartLatch); + } + } + } + } + } + + /** + * Runs the test for ServerSocketChannel + * + * @see #runTest(ExecutorService, SelectionKey, Callable, CountDownLatch) + */ + @Test + public void testServerSocketChannel() throws Exception { + try (ExecutorService executor = Executors.newFixedThreadPool(2)) { + for (int i = 1; i <= NUM_ITERATIONS; i++) { + System.out.format("%s ServerSocketChannel - %d of %d ...%n", + Instant.now(), i, NUM_ITERATIONS); + try (Selector sel = Selector.open(); + ServerSocketChannel ssc = ServerSocketChannel.open()) { + // create and bind a ServerSocketChannel + ssc.bind(BIND_ADDR); + ssc.configureBlocking(false); + // register the ServerSocketChannel with a selector + SelectionKey key = ssc.register(sel, SelectionKey.OP_ACCEPT); + CountDownLatch opStartLatch = new CountDownLatch(1); + runTest(executor, key, () -> { + // notify that we will now start accept()ing + opStartLatch.countDown(); + // repeatedly do SSC.accept() till there's a ClosedChannelException + try { + while (true) { + ssc.accept(); + } + } catch (ClosedChannelException _) { + } + return null; + }, opStartLatch); + } + } + } + } + + /** + * Runs the test for SinkChannel + * + * @see #runTest(ExecutorService, SelectionKey, Callable, CountDownLatch) + */ + @Test + public void testSinkChannel() throws Exception { + try (ExecutorService executor = Executors.newFixedThreadPool(2)) { + for (int i = 1; i <= NUM_ITERATIONS; i++) { + System.out.format("%s SinkChannel - %d of %d ...%n", + Instant.now(), i, NUM_ITERATIONS); + Pipe pipe = Pipe.open(); + try (Selector sel = Selector.open(); + Pipe.SinkChannel sink = pipe.sink()) { + sink.configureBlocking(false); + SelectionKey key = sink.register(sel, SelectionKey.OP_WRITE); + CountDownLatch opStartLatch = new CountDownLatch(1); + runTest(executor, key, () -> { + // notify that we will now start write()ing + opStartLatch.countDown(); + // repeatedly do SC.write() till there's a ClosedChannelException + ByteBuffer bb = ByteBuffer.allocate(100); + try { + while (true) { + bb.clear(); + sink.write(bb); + } + } catch (ClosedChannelException _) { + } + return null; + }, opStartLatch); + } + } + } + } + + /** + * Runs the test for SourceChannel + * + * @see #runTest(ExecutorService, SelectionKey, Callable, CountDownLatch) + */ + @Test + public void testSourceChannel() throws Exception { + try (ExecutorService executor = Executors.newFixedThreadPool(2)) { + for (int i = 1; i <= NUM_ITERATIONS; i++) { + System.out.format("%s SourceChannel - %d of %d ...%n", + Instant.now(), i, NUM_ITERATIONS); + Pipe pipe = Pipe.open(); + try (Selector sel = Selector.open(); + Pipe.SourceChannel source = pipe.source()) { + source.configureBlocking(false); + SelectionKey key = source.register(sel, SelectionKey.OP_READ); + CountDownLatch opStartLatch = new CountDownLatch(1); + runTest(executor, key, () -> { + // notify that we will now start read()ing + opStartLatch.countDown(); + // repeatedly do SC.read() till there's a ClosedChannelException + ByteBuffer bb = ByteBuffer.allocate(100); + try { + while (true) { + bb.clear(); + source.read(bb); + } + } catch (ClosedChannelException _) { + } + return null; + }, opStartLatch); + } + } + } + } + + /** + * SelectableChannel implementations internally have a deferred close implementation. When a + * channel is registered with a Selector and close() is invoked on the channel from a certain + * thread, then the implementation of close() defers the actual close if the channel has + * in-progress operations (for example, read/write/send/receive and such) in some other thread. + * A subsequent operation through the Selector (like Selector.select()) then completes the + * deferred close (waiting for any in-progress operations to complete). This test method + * verifies that the deferred close implementation doesn't prematurely close and release + * the resources used by the channel, while there are in-progress operations. + *

+ * Launches 2 threads, T1 and T2. When T1 and T2 are in progress, this method closes the + * channel that is registered with the Selector. + * T1 is running the channelOperation (which keeps running operations on the channel). + * T2 is running a task which keeps invoking Selector.select(), until the channel is closed. + * When T2 notices that the channel is closed, it cancels the selectionKey and then + * invokes one last Selector.select() operation to finish the deferred close of the channel. + */ + private static void runTest(ExecutorService executor, SelectionKey selectionKey, + Callable channelOperation, CountDownLatch chanOpStartLatch) + throws Exception { + + SelectableChannel channel = selectionKey.channel(); + assertFalse(channel.isBlocking(), "channel isn't non-blocking: " + channel); + selectionKey.selector().selectNow(); + // run the channel operations + Future channelOpResult = executor.submit(channelOperation); + CountDownLatch selectorTaskStartLatch = new CountDownLatch(1); + // run the Selector.select() task + Future selectorTaskResult = executor.submit( + new SelectorTask(selectionKey, selectorTaskStartLatch)); + // await for the channel operation task and the selector task to start + chanOpStartLatch.await(); + selectorTaskStartLatch.await(); + // close the channel while it's still registered with the Selector, + // so that the close is deferred by the channel implementations. + System.out.println("closing channel: " + channel); + assertTrue(channel.isOpen(), "channel already closed: " + channel); + assertTrue(channel.isRegistered(), "channel isn't registered: " + channel); + channel.close(); + // wait for the operation on the channel and the selector task to complete + channelOpResult.get(); + selectorTaskResult.get(); + } + + /* + * Keeps invoking Selector.select() until the channel is closed, after which + * it cancels the SelectionKey and does one last Selector.select() to finish + * the deferred close. + */ + private static final class SelectorTask implements Callable { + private final SelectionKey selectionKey; + private final CountDownLatch startedLatch; + + private SelectorTask(SelectionKey selectionKey, CountDownLatch startedLatch) { + this.selectionKey = Objects.requireNonNull(selectionKey); + this.startedLatch = startedLatch; + } + + @Override + public Void call() throws Exception { + try { + Selector selector = selectionKey.selector(); + SelectableChannel channel = selectionKey.channel(); + // notify that the task has started + startedLatch.countDown(); + while (true) { + selector.select(10); + if (!channel.isOpen()) { + // the channel is (defer) closed, cancel the registration and then + // issue a select() so that the Selector finishes the deferred + // close of the channel. + System.out.println("channel: " + channel + " isn't open," + + " now cancelling key: " + selectionKey); + selectionKey.cancel(); + System.out.println("initiating select after key cancelled: " + selectionKey); + selector.select(5); + break; + } + } + } catch (ClosedSelectorException _) { + } + return null; + } + } + + private static final class ConnAcceptor implements Callable { + private final ServerSocketChannel serverSocketChannel; + + private ConnAcceptor(ServerSocketChannel serverSocketChannel) { + this.serverSocketChannel = serverSocketChannel; + } + + @Override + public SocketChannel call() throws Exception { + SocketChannel accepted = serverSocketChannel.accept(); + System.out.println("Accepted connection: " + accepted); + return accepted; + } + } +} diff --git a/test/jdk/java/nio/channels/Selector/DeferredClose/java.base/java/net/InetSocketAddress.java b/test/jdk/java/nio/channels/Selector/DeferredClose/java.base/java/net/InetSocketAddress.java new file mode 100644 index 00000000000..5994e9268a1 --- /dev/null +++ b/test/jdk/java/nio/channels/Selector/DeferredClose/java.base/java/net/InetSocketAddress.java @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2024, 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 java.net; + + +import java.util.Locale; + +// Patched implementation only meant to be used in certain tests +public class InetSocketAddress extends SocketAddress { + + @java.io.Serial + private static final long serialVersionUID = 5076001401234631237L; + + private static boolean enableDelay; + + static { + System.out.println("patched InetSocketAddress class in use"); + } + + private final String hostname; + private final InetAddress addr; + private final int port; + + public InetSocketAddress(int port) { + this(InetAddress.anyLocalAddress(), port); + } + + public InetSocketAddress(InetAddress addr, int port) { + this(null, + addr == null ? InetAddress.anyLocalAddress() : addr, + checkPort(port)); + } + + public InetSocketAddress(String hostname, int port) { + checkHost(hostname); + InetAddress addr = null; + String host = null; + try { + addr = InetAddress.getByName(hostname); + } catch (UnknownHostException e) { + host = hostname; + } + this.hostname = host; + this.addr = addr; + this.port = checkPort(port); + } + + public static InetSocketAddress createUnresolved(String host, int port) { + return new InetSocketAddress(checkHost(host), null, checkPort(port)); + } + + public static void enableDelay() { + enableDelay = true; + } + + public static void disableDelay() { + enableDelay = false; + } + + private InetSocketAddress(String hostname, InetAddress addr, int port) { + this.hostname = hostname; + this.addr = addr; + this.port = port; + if (enableDelay) { + doDelay(); + } + } + + /** + * Gets the port number. + * + * @return the port number. + */ + public final int getPort() { + if (enableDelay) { + doDelay(); + } + return this.port; + } + + /** + * Gets the {@code InetAddress}. + * + * @return the InetAddress or {@code null} if it is unresolved. + */ + public final InetAddress getAddress() { + return this.addr; + } + + public final String getHostName() { + if (hostname != null) { + return hostname; + } + if (addr != null) { + return addr.getHostName(); + } + return null; + } + + public final String getHostString() { + if (hostname != null) { + return hostname; + } + if (addr != null) { + if (addr.holder().getHostName() != null) { + return addr.holder().getHostName(); + } else { + return addr.getHostAddress(); + } + } + return null; + } + + public final boolean isUnresolved() { + return addr == null; + } + + @Override + public String toString() { + String formatted; + if (isUnresolved()) { + formatted = hostname + "/"; + } else { + formatted = addr.toString(); + if (addr instanceof Inet6Address) { + int i = formatted.lastIndexOf("/"); + formatted = formatted.substring(0, i + 1) + + "[" + formatted.substring(i + 1) + "]"; + } + } + return formatted + ":" + port; + } + + @Override + public final boolean equals(Object other) { + if (!(other instanceof InetSocketAddress that)) { + return false; + } + boolean sameIP; + if (addr != null) { + sameIP = addr.equals(that.addr); + } else if (hostname != null) { + sameIP = (that.addr == null) && + hostname.equalsIgnoreCase(that.hostname); + } else { + sameIP = (that.addr == null) && (that.hostname == null); + } + return sameIP && (port == that.port); + } + + @Override + public final int hashCode() { + if (addr != null) { + return addr.hashCode() + port; + } + if (hostname != null) { + return hostname.toLowerCase(Locale.ROOT).hashCode() + port; + } + return port; + } + + private static int checkPort(int port) { + if (port < 0 || port > 0xFFFF) + throw new IllegalArgumentException("port out of range:" + port); + return port; + } + + private static String checkHost(String hostname) { + if (hostname == null) + throw new IllegalArgumentException("hostname can't be null"); + return hostname; + } + + private static void doDelay() { + System.out.println("intentional delay injected in InetSocketAddress"); + try { + Thread.sleep(10); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } +} From 40d8d376562ee8905f2798fe62abce3cb63c1854 Mon Sep 17 00:00:00 2001 From: Adam Sotona Date: Mon, 15 Jul 2024 09:04:12 +0000 Subject: [PATCH 48/61] 8335820: java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java fails due to IllegalArgumentException: hash must be nonzero Reviewed-by: jpai Backport-of: 4f60e071b1d05a533b952b461cecdb9c78b2e14e --- .../classfile/impl/AbstractPoolEntry.java | 13 ++-- .../impl/BootstrapMethodEntryImpl.java | 6 +- .../classfile/impl/BoundAttribute.java | 72 +++++++++---------- test/jdk/jdk/classfile/LimitsTest.java | 9 ++- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java b/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java index a494c21085c..f846ca6fa90 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java @@ -68,24 +68,19 @@ public abstract sealed class AbstractPoolEntry { */ private static final int TAG_SMEAR = 0x13C4B2D1; - private static final int INT_PHI = 0x9E3779B9; + static final int NON_ZERO = 0x40000000; public static int hash1(int tag, int x1) { - return phiMix(tag * TAG_SMEAR + x1); + return (tag * TAG_SMEAR + x1) | NON_ZERO; } public static int hash2(int tag, int x1, int x2) { - return phiMix(tag * TAG_SMEAR + x1 + 31*x2); + return (tag * TAG_SMEAR + x1 + 31 * x2) | NON_ZERO; } // Ensure that hash is never zero public static int hashString(int stringHash) { - return phiMix(stringHash | (1 << 30)); - } - - public static int phiMix(int x) { - int h = x * INT_PHI; - return h ^ (h >> 16); + return stringHash | NON_ZERO; } public static Utf8Entry rawUtf8EntryFromStandardAttributeName(String name) { diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/BootstrapMethodEntryImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/BootstrapMethodEntryImpl.java index 3d15f097b13..d6876a82a9c 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/BootstrapMethodEntryImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/BootstrapMethodEntryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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,9 +76,7 @@ public boolean equals(Object obj) { static int computeHashCode(MethodHandleEntryImpl handle, List arguments) { - int hash = handle.hashCode(); - hash = 31 * hash + arguments.hashCode(); - return AbstractPoolEntry.phiMix(hash); + return (31 * handle.hashCode() + arguments.hashCode()) | AbstractPoolEntry.NON_ZERO; } @Override diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/BoundAttribute.java b/src/java.base/share/classes/jdk/internal/classfile/impl/BoundAttribute.java index 45e0c092c3e..6fea4e44bc6 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/BoundAttribute.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/BoundAttribute.java @@ -988,77 +988,77 @@ public byte[] codeArray() { public static AttributeMapper standardAttribute(Utf8Entry name) { // critical bootstrap path, so no lambdas nor method handles here return switch (name.hashCode()) { - case 0x78147009 -> + case 0x46699ff2 -> name.equalsString(NAME_ANNOTATION_DEFAULT) ? annotationDefault() : null; - case 0x665e3a3a -> + case 0x5208e184 -> name.equalsString(NAME_BOOTSTRAP_METHODS) ? bootstrapMethods() : null; - case 0xcb7e162 -> + case 0xcb60907a -> name.equalsString(NAME_CHARACTER_RANGE_TABLE) ? characterRangeTable() : null; - case 0x21e41e7e -> + case 0x4020220d -> name.equalsString(NAME_CODE) ? code() : null; - case 0x5a306b41 -> + case 0xc20dd1fe -> name.equalsString(NAME_COMPILATION_ID) ? compilationId() : null; - case 0x3e191c7c -> + case 0xcab1940d -> name.equalsString(NAME_CONSTANT_VALUE) ? constantValue() : null; - case 0x5e88ed0c -> + case 0x558641d3 -> name.equalsString(NAME_DEPRECATED) ? deprecated() : null; - case 0x7284695e -> + case 0x51d443cd -> name.equalsString(NAME_ENCLOSING_METHOD) ? enclosingMethod() : null; - case 0x21df25db -> + case 0x687c1624 -> name.equalsString(NAME_EXCEPTIONS) ? exceptions() : null; - case 0x11392da9 -> + case 0x7adb2910 -> name.equalsString(NAME_INNER_CLASSES) ? innerClasses() : null; - case 0x167536fc -> + case 0x653f0551 -> name.equalsString(NAME_LINE_NUMBER_TABLE) ? lineNumberTable() : null; - case 0x46939abc -> + case 0x64c75927 -> name.equalsString(NAME_LOCAL_VARIABLE_TABLE) ? localVariableTable() : null; - case 0x63ee67f4 -> + case 0x6697f98d -> name.equalsString(NAME_LOCAL_VARIABLE_TYPE_TABLE) ? localVariableTypeTable() : null; - case 0x2b597e15 -> + case 0xdbb0cdcb -> name.equalsString(NAME_METHOD_PARAMETERS) ? methodParameters() : null; - case 0x19f20ade -> + case 0xc9b0928c -> name.equalsString(NAME_MODULE) ? module() : null; - case 0x47f6395e -> + case 0x41cd27e8 -> name.equalsString(NAME_MODULE_HASHES) ? moduleHashes() : null; - case 0x54db809 -> + case 0x7deb0a13 -> name.equalsString(NAME_MODULE_MAIN_CLASS) ? moduleMainClass() : null; - case 0x1abd1c2c -> + case 0x6706ff99 -> name.equalsString(NAME_MODULE_PACKAGES) ? modulePackages() : null; - case 0x6ba46dd -> + case 0x60272858 -> name.equalsString(NAME_MODULE_RESOLUTION) ? moduleResolution() : null; - case 0x46f7d91d -> + case 0x5646d73d -> name.equalsString(NAME_MODULE_TARGET) ? moduleTarget() : null; - case 0x5137f53 -> + case 0x50336c40 -> name.equalsString(NAME_NEST_HOST) ? nestHost() : null; - case 0x4a8fa3b6 -> + case 0x4735ab81 -> name.equalsString(NAME_NEST_MEMBERS) ? nestMembers() : null; - case 0x55c73cb6 -> + case 0x7100d9fe -> name.equalsString(NAME_PERMITTED_SUBCLASSES) ? permittedSubclasses() : null; - case 0x3fe76d4e -> + case 0xd1ab5871 -> name.equalsString(NAME_RECORD) ? record() : null; - case 0x180d6925 -> + case 0x7588550f -> name.equalsString(NAME_RUNTIME_INVISIBLE_ANNOTATIONS) ? runtimeInvisibleAnnotations() : null; - case 0x7be22752 -> + case 0xcc74da30 -> name.equalsString(NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS) ? runtimeInvisibleParameterAnnotations() : null; - case 0x5299824 -> + case 0xf67697f5 -> name.equalsString(NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS) ? runtimeInvisibleTypeAnnotations() : null; - case 0x3534786e -> + case 0xe0837d2a -> name.equalsString(NAME_RUNTIME_VISIBLE_ANNOTATIONS) ? runtimeVisibleAnnotations() : null; - case 0xb4b4ac6 -> + case 0xc945a075 -> name.equalsString(NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS) ? runtimeVisibleParameterAnnotations() : null; - case 0x6926482 -> + case 0x611a3a90 -> name.equalsString(NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS) ? runtimeVisibleTypeAnnotations() : null; - case 0x16a42b7c -> + case 0xf76fb898 -> name.equalsString(NAME_SIGNATURE) ? signature() : null; - case 0x400ab245 -> + case 0x6b41b047 -> name.equalsString(NAME_SOURCE_DEBUG_EXTENSION) ? sourceDebugExtension() : null; - case 0x2af490d4 -> + case 0x748c2857 -> name.equalsString(NAME_SOURCE_FILE) ? sourceFile() : null; - case 0x303e0c58 -> + case 0x6bf13a96 -> name.equalsString(NAME_SOURCE_ID) ? sourceId() : null; - case 0x19c7d0cd -> + case 0xfa85ee5a -> name.equalsString(NAME_STACK_MAP_TABLE) ? stackMapTable() : null; - case 0x3dc79b7a -> + case 0xf2670725 -> name.equalsString(NAME_SYNTHETIC) ? synthetic() : null; default -> null; }; diff --git a/test/jdk/jdk/classfile/LimitsTest.java b/test/jdk/jdk/classfile/LimitsTest.java index 40ae8a5fb1f..442707ecd17 100644 --- a/test/jdk/jdk/classfile/LimitsTest.java +++ b/test/jdk/jdk/classfile/LimitsTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8320360 8330684 8331320 8331655 8331940 8332486 + * @bug 8320360 8330684 8331320 8331655 8331940 8332486 8335820 * @summary Testing ClassFile limits. * @run junit LimitsTest */ @@ -39,6 +39,7 @@ import java.lang.classfile.attribute.LineNumberTableAttribute; import java.lang.classfile.attribute.LocalVariableInfo; import java.lang.classfile.attribute.LocalVariableTableAttribute; +import java.lang.classfile.constantpool.ConstantPoolBuilder; import java.lang.classfile.constantpool.ConstantPoolException; import java.lang.classfile.constantpool.IntegerEntry; import java.lang.classfile.instruction.LocalVariable; @@ -190,4 +191,10 @@ void testLocalVariableOutOfBounds() { cob.constantPool().utf8Entry("a"), cob.constantPool().utf8Entry("A"), 0)))) ))).methods().get(0).code().get().elementList()); } + + @Test + void testZeroHashCPEntry() { + var cpb = ConstantPoolBuilder.of(); + cpb.intEntry(-cpb.intEntry(0).hashCode()); + } } From 7a14c52718aa67d89a1f2b1cc6f5c206ebe24073 Mon Sep 17 00:00:00 2001 From: Matthew Donovan Date: Mon, 15 Jul 2024 11:56:46 +0000 Subject: [PATCH 49/61] 8324841: PKCS11 tests still skip execution Reviewed-by: jpai Backport-of: 4c389c6d18fd291cd33ce6ce0c6f1ef3644cb491 --- test/jdk/sun/security/pkcs11/PKCS11Test.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/sun/security/pkcs11/PKCS11Test.java b/test/jdk/sun/security/pkcs11/PKCS11Test.java index ffd1c42fd88..2810040e376 100644 --- a/test/jdk/sun/security/pkcs11/PKCS11Test.java +++ b/test/jdk/sun/security/pkcs11/PKCS11Test.java @@ -791,8 +791,8 @@ private static Path findNSSLibrary(Path path, Path libraryName) throws IOExcepti (tp, attr) -> tp.getFileName().equals(libraryName))) { return files.findAny() - .orElseThrow(() -> new SkippedException( - "NSS library \"" + libraryName + "\" was not found in " + path)); + .orElseThrow(() -> + new RuntimeException("NSS library \"" + libraryName + "\" was not found in " + path)); } } From 8b80e22291022fa5822a2ca8cefd886c1084c823 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Mon, 15 Jul 2024 15:41:25 +0000 Subject: [PATCH 50/61] 8325369: @sealedGraph: Bad link to image for tag on nested classes Reviewed-by: prappo Backport-of: de9d758f6f78922e75e2d2899221b34edfadf539 --- .../build/tools/taglet/SealedGraph.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/make/jdk/src/classes/build/tools/taglet/SealedGraph.java b/make/jdk/src/classes/build/tools/taglet/SealedGraph.java index fd1b73355b3..17867b99595 100644 --- a/make/jdk/src/classes/build/tools/taglet/SealedGraph.java +++ b/make/jdk/src/classes/build/tools/taglet/SealedGraph.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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 @@ -107,7 +107,7 @@ public String toString(List tags, Element element) { throw new RuntimeException(e); } - String simpleTypeName = element.getSimpleName().toString(); + String simpleTypeName = packagelessCanonicalName(typeElement).replace('.', '/'); String imageFile = simpleTypeName + "-sealed-graph.svg"; int thumbnailHeight = 100; // also appears in the stylesheet String hoverImage = "" @@ -315,14 +315,14 @@ private static Optional packageName(TypeElement element) { case MEMBER -> packageName((TypeElement) element.getEnclosingElement()); }; } + } - private static String packagelessCanonicalName(TypeElement element) { - String result = element.getSimpleName().toString(); - while (element.getNestingKind() == NestingKind.MEMBER) { - element = (TypeElement) element.getEnclosingElement(); - result = element.getSimpleName().toString() + '.' + result; - } - return result; + private static String packagelessCanonicalName(TypeElement element) { + String result = element.getSimpleName().toString(); + while (element.getNestingKind() == NestingKind.MEMBER) { + element = (TypeElement) element.getEnclosingElement(); + result = element.getSimpleName().toString() + '.' + result; } + return result; } } From 3734da627ed60bf635c936d9ebb12e4257d94b74 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Mon, 15 Jul 2024 15:41:41 +0000 Subject: [PATCH 51/61] 8336259: Wrong link to stylesheet.css in JavaDoc API documentation Reviewed-by: iris, prappo Backport-of: 5aff5e0f33f1451ad91783a2933d8d475a072e72 --- .../share/classes/java/lang/doc-files/ValueBased.html | 3 +-- .../java/lang/doc-files/threadPrimitiveDeprecation.html | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/lang/doc-files/ValueBased.html b/src/java.base/share/classes/java/lang/doc-files/ValueBased.html index 86d9b359557..6a935afe04b 100644 --- a/src/java.base/share/classes/java/lang/doc-files/ValueBased.html +++ b/src/java.base/share/classes/java/lang/doc-files/ValueBased.html @@ -1,6 +1,6 @@