From 194425d7875ef42fce52516ed59c81ee97720399 Mon Sep 17 00:00:00 2001 From: Shaojin Wen Date: Fri, 5 Jul 2024 12:50:09 +0000 Subject: [PATCH 001/401] 8335645: j.u.Formatter#trailingZeros improved with String repeat Reviewed-by: liach, jlu, naoto --- src/java.base/share/classes/java/util/Formatter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/util/Formatter.java b/src/java.base/share/classes/java/util/Formatter.java index 41b9540001c83..dfdb77cc6ace2 100644 --- a/src/java.base/share/classes/java/util/Formatter.java +++ b/src/java.base/share/classes/java/util/Formatter.java @@ -4249,8 +4249,8 @@ private int adjustWidth(int width, int flags, boolean neg) { // Add trailing zeros private void trailingZeros(StringBuilder sb, int nzeros) { - for (int i = 0; i < nzeros; i++) { - sb.append('0'); + if (nzeros > 0) { + sb.repeat('0', nzeros); } } From ff49f677ee5017019c90823bc412ceb90068ffbd Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Fri, 5 Jul 2024 13:44:35 +0000 Subject: [PATCH 002/401] 8335775: Remove extraneous 's' in comment of rawmonitor.cpp test file Reviewed-by: gdams, stuefe --- .../nsk/jvmti/unit/functions/rawmonitor/rawmonitor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/rawmonitor/rawmonitor.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/rawmonitor/rawmonitor.cpp index 11ef7e18d7bd9..6ee955ae420dd 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/rawmonitor/rawmonitor.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/functions/rawmonitor/rawmonitor.cpp @@ -1,5 +1,4 @@ /* -s * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * From 7efe16038e5df9894a265ea1214068060f595c4e Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 5 Jul 2024 16:44:41 +0000 Subject: [PATCH 003/401] 8335730: JFR: Clean up jdk.jfr Reviewed-by: mgronlun --- .../share/classes/jdk/jfr/consumer/RecordedClass.java | 4 ++-- .../share/classes/jdk/jfr/consumer/RecordedFrame.java | 6 +++--- .../share/classes/jdk/jfr/consumer/RecordedMethod.java | 4 ++-- .../share/classes/jdk/jfr/consumer/RecordedObject.java | 5 ++++- .../share/classes/jdk/jfr/consumer/RecordedThread.java | 6 +++--- .../jdk/jfr/events/AbstractBufferStatisticsEvent.java | 4 ++-- .../classes/jdk/jfr/events/ActiveRecordingEvent.java | 1 - .../share/classes/jdk/jfr/events/ActiveSettingEvent.java | 1 - .../classes/jdk/jfr/events/ExceptionStatisticsEvent.java | 1 - .../share/classes/jdk/jfr/internal/EventControl.java | 1 - .../classes/jdk/jfr/internal/MetadataRepository.java | 2 -- .../share/classes/jdk/jfr/internal/OldObjectSample.java | 3 +-- .../share/classes/jdk/jfr/internal/RepositoryChunk.java | 5 +---- .../share/classes/jdk/jfr/internal/ShutdownHook.java | 2 -- .../classes/jdk/jfr/internal/dcmd/QueryRecording.java | 7 +------ src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java | 4 ++-- .../classes/jdk/jfr/internal/jfc/model/XmlSetting.java | 4 ++-- src/jdk.jfr/share/classes/jdk/jfr/internal/query/Row.java | 4 ++-- .../share/classes/jdk/jfr/internal/query/TableSorter.java | 5 +---- .../classes/jdk/jfr/internal/settings/LevelSetting.java | 4 ++-- .../share/classes/jdk/jfr/internal/tool/Disassemble.java | 8 ++++---- .../share/classes/jdk/jfr/internal/tool/PrettyWriter.java | 3 +-- src/jdk.jfr/share/classes/jdk/jfr/internal/tool/View.java | 3 +-- .../share/classes/jdk/jfr/internal/util/ValueParser.java | 4 ++-- 24 files changed, 36 insertions(+), 55 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedClass.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedClass.java index 8d6b5647f2f58..d0ae1e7d297e1 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedClass.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, 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 @@ -49,7 +49,7 @@ public final class RecordedClass extends RecordedObject { * @see java.lang.reflect.Modifier */ public int getModifiers() { - return getTyped("modifiers", Integer.class, -1); + return getTyped("modifiers", Integer.class, INTEGER_MINUS_ONE); } /** diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedFrame.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedFrame.java index 9640330fca2fc..cdb893274acd0 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedFrame.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, 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 @@ -65,7 +65,7 @@ public boolean isJavaFrame() { * @return byte code index, or {@code -1} if doesn't exist */ public int getBytecodeIndex() { - return getTyped("bytecodeIndex", Integer.class, Integer.valueOf(-1)); + return getTyped("bytecodeIndex", Integer.class, INTEGER_MINUS_ONE); } /** @@ -75,7 +75,7 @@ public int getBytecodeIndex() { * @return the line number, or {@code -1} if doesn't exist */ public int getLineNumber() { - return getTyped("lineNumber", Integer.class, Integer.valueOf(-1)); + return getTyped("lineNumber", Integer.class, INTEGER_MINUS_ONE); } /** diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedMethod.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedMethod.java index a82b43ffc363b..6c8f23aa02a86 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedMethod.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, 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 @@ -94,7 +94,7 @@ public String getDescriptor() { * @see RecordedFrame#isJavaFrame */ public int getModifiers() { - return getTyped("modifiers", Integer.class, Integer.valueOf(0)); + return getTyped("modifiers", Integer.class, INTEGER_ZERO); } /** diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java index e5825b8ea07c5..21bd30a8248d1 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.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 @@ -154,6 +154,9 @@ public MetadataEvent newMetadataEvent(List previous, List private static final record UnsignedValue(Object value) { } + static final Integer INTEGER_MINUS_ONE = Integer.valueOf(-1); + static final Integer INTEGER_ZERO = Integer.valueOf(0); + static final Long LONG_MINUS_ONE = Long.valueOf(-1L); final Object[] objects; final ObjectContext objectContext; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedThread.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedThread.java index 4031e70d24b56..d12d65faf10ea 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedThread.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedThread.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 @@ -59,7 +59,7 @@ public long getOSThreadId() { if (isVirtual()) { return -1L; } - Long l = getTyped("osThreadId", Long.class, -1L); + Long l = getTyped("osThreadId", Long.class, LONG_MINUS_ONE); return l.longValue(); } @@ -92,7 +92,7 @@ public String getJavaName() { * @see java.lang.Thread#threadId() */ public long getJavaThreadId() { - Long l = getTyped("javaThreadId", Long.class, -1L); + Long l = getTyped("javaThreadId", Long.class, LONG_MINUS_ONE); long id = l.longValue(); return id == 0 ? -1L : id; } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractBufferStatisticsEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractBufferStatisticsEvent.java index d436b32db83e3..f7a03c7446e84 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractBufferStatisticsEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/AbstractBufferStatisticsEvent.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 @@ -30,7 +30,7 @@ import jdk.jfr.*; @Category({ "Java Application", "Statistics" }) -public abstract class AbstractBufferStatisticsEvent extends AbstractPeriodicEvent { +abstract class AbstractBufferStatisticsEvent extends AbstractPeriodicEvent { protected AbstractBufferStatisticsEvent(BufferPool bufferPool) { count = bufferPool.getCount(); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveRecordingEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveRecordingEvent.java index 352a8b6a07397..ffb45caa42cf9 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveRecordingEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveRecordingEvent.java @@ -29,7 +29,6 @@ import jdk.jfr.Label; import jdk.jfr.DataAmount; import jdk.jfr.Name; -import jdk.jfr.StackTrace; import jdk.jfr.Timespan; import jdk.jfr.Timestamp; import jdk.jfr.internal.RemoveFields; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java index 3658b06eb14a8..6aade8e01f5d5 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ActiveSettingEvent.java @@ -28,7 +28,6 @@ import jdk.jfr.Category; import jdk.jfr.Label; import jdk.jfr.Name; -import jdk.jfr.StackTrace; import jdk.jfr.internal.RemoveFields; import jdk.jfr.internal.Type; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionStatisticsEvent.java b/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionStatisticsEvent.java index 795f618b4e62a..0cdd987227193 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionStatisticsEvent.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/events/ExceptionStatisticsEvent.java @@ -29,7 +29,6 @@ import jdk.jfr.Description; import jdk.jfr.Label; import jdk.jfr.Name; -import jdk.jfr.StackTrace; import jdk.jfr.internal.MirrorEvent; import jdk.jfr.internal.RemoveFields; import jdk.jfr.internal.Type; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java index 2a758aa8addc6..71569c30273be 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/EventControl.java @@ -46,7 +46,6 @@ import jdk.jfr.Threshold; import jdk.jfr.events.ActiveSettingEvent; import jdk.jfr.events.StackFilter; -import jdk.jfr.internal.JVM; import jdk.jfr.internal.settings.CutoffSetting; import jdk.jfr.internal.settings.EnabledSetting; import jdk.jfr.internal.settings.LevelSetting; 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 75be70a0d1dae..4a7bc734d7571 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java @@ -44,8 +44,6 @@ import jdk.jfr.EventType; import jdk.jfr.Name; import jdk.jfr.Period; -import jdk.jfr.StackTrace; -import jdk.jfr.Threshold; import jdk.jfr.ValueDescriptor; import jdk.jfr.internal.consumer.RepositoryFiles; import jdk.jfr.internal.event.EventConfiguration; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/OldObjectSample.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/OldObjectSample.java index 5fa9eb709ef08..21079fab3a912 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/OldObjectSample.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/OldObjectSample.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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,7 +33,6 @@ import jdk.jfr.RecordingState; import jdk.jfr.internal.settings.CutoffSetting; import jdk.jfr.internal.test.WhiteBox; -import jdk.jfr.internal.util.Utils; // The Old Object event could have been implemented as a periodic event, but // due to chunk rotations and how settings are calculated when multiple recordings diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java index 72d3a719452f4..e46b6020d5dbd 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/RepositoryChunk.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -29,10 +29,7 @@ import java.io.RandomAccessFile; import java.nio.channels.ReadableByteChannel; import java.time.Instant; -import java.time.Period; -import java.time.Duration; import java.util.Comparator; -import java.util.Optional; import jdk.jfr.internal.SecuritySupport.SafePath; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/ShutdownHook.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/ShutdownHook.java index afd9ec09bd9f1..8375dab0bcce3 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/ShutdownHook.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/ShutdownHook.java @@ -25,14 +25,12 @@ package jdk.jfr.internal; -import java.io.IOException; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import jdk.jfr.RecordingState; -import jdk.jfr.internal.util.Utils; /** * Class responsible for dumping recordings on exit diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/QueryRecording.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/QueryRecording.java index 75fefca0f08af..fa60079b52247 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/QueryRecording.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/QueryRecording.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 @@ -27,7 +27,6 @@ import java.io.IOException; import java.time.Duration; import java.time.Instant; -import java.util.ArrayList; import java.util.List; import java.util.ListIterator; @@ -37,12 +36,8 @@ import jdk.jfr.internal.PrivateAccess; import jdk.jfr.internal.RepositoryChunk; import jdk.jfr.internal.query.Configuration; -import jdk.jfr.internal.query.QueryPrinter; -import jdk.jfr.internal.query.ViewPrinter; import jdk.jfr.internal.query.Configuration.Truncate; import jdk.jfr.internal.util.UserDataException; -import jdk.jfr.internal.util.UserSyntaxException; -import jdk.jfr.internal.util.Output; /** * Helper class that holds recording chunks alive during a query. It also helps diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java index 6d7cccfb2a6d0..0511ce57001c6 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/JFC.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 @@ -293,7 +293,7 @@ public static Reader newReader(SafePath sf) throws IOException { public static String formatException(String prefix, Exception e, String input) { String message = prefix + " " + JFC.exceptionToVerb(e) + " file '" + input + "'"; String details = e.getMessage(); - if (e instanceof JFCModelException m) { + if (e instanceof JFCModelException) { return message + ". " + details; } if (e instanceof ParseException && !details.isEmpty()) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlSetting.java index 56f2208ded313..536c5051f54e1 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlSetting.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/jfc/model/XmlSetting.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 @@ -59,7 +59,7 @@ public void onChange() { @Override final void setContent(String value) { super.setContent(value); - if (getParent() instanceof XmlEvent event) { + if (getParent() instanceof XmlEvent) { SettingsLog.log(this, value); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Row.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Row.java index da32f86c171ba..cb54b6b651abd 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Row.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Row.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 @@ -53,6 +53,6 @@ public void putText(int index, String text) { @Override public String toString() { - return Arrays.asList(values).toString(); + return Arrays.toString(values); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/TableSorter.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/TableSorter.java index 65f664018bab2..8869516280960 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/TableSorter.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/TableSorter.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 @@ -24,10 +24,7 @@ */ package jdk.jfr.internal.query; -import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; -import java.util.List; import java.util.function.Predicate; import jdk.jfr.internal.query.Query.OrderElement; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/LevelSetting.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/LevelSetting.java index acf67c0aa06a5..b6aa7500d4b68 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/LevelSetting.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/settings/LevelSetting.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 @@ -39,7 +39,7 @@ @MetadataDefinition @Label("Level") @Name(Type.SETTINGS_PREFIX + "Level") -public class LevelSetting extends JDKSettingControl { +public final class LevelSetting extends JDKSettingControl { private final PlatformEventType eventType; private final List levels; private String value; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Disassemble.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Disassemble.java index 06616771cf9cf..48dd52475685a 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Disassemble.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Disassemble.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 @@ -223,9 +223,9 @@ private void splitFile(Path directory, Path file, List splitPositions) thr Path p = directory.resolve(formattedFilename); File splittedFile = p.toFile(); println("Writing " + splittedFile + " ... " + bytes.length); - FileOutputStream fos = new FileOutputStream(splittedFile); - fos.write(bytes); - fos.close(); + try (var fos = new FileOutputStream(splittedFile)) { + fos.write(bytes); + } } } catch (IOException ioe) { throw new UserDataException("i/o error writing file " + file); diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java index aec1f18546c77..77b3f4d1e8c41 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/PrettyWriter.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 @@ -30,7 +30,6 @@ import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; -import java.util.ArrayList; import java.util.List; import java.util.StringJoiner; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/View.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/View.java index a22c64c931e8f..613e315ff1390 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/View.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/View.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 @@ -33,7 +33,6 @@ import java.util.List; import jdk.jfr.consumer.EventStream; -import jdk.jfr.internal.util.Columnizer; import jdk.jfr.internal.query.ViewPrinter; import jdk.jfr.internal.query.Configuration; import jdk.jfr.internal.query.Configuration.Truncate; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ValueParser.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ValueParser.java index 1c6561f45c4a6..730c83daaae67 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ValueParser.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/util/ValueParser.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 @@ -31,7 +31,7 @@ import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.SECONDS; -public class ValueParser { +public final class ValueParser { private static final String INFINITY = "infinity"; public static long parseTimespanWithInfinity(String s) { From b83766e59063a41ea8801ac9e7c15dce67727c62 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 5 Jul 2024 17:07:22 +0000 Subject: [PATCH 004/401] 8335632: jdk/jfr/api/consumer/streaming/TestJVMExit.java failed with "Process [...] is no longer alive" Reviewed-by: mgronlun --- .../jfr/api/consumer/streaming/TestJVMExit.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMExit.java b/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMExit.java index 5b30a52e4b757..77eba735d7a3b 100644 --- a/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMExit.java +++ b/test/jdk/jdk/jfr/api/consumer/streaming/TestJVMExit.java @@ -34,12 +34,29 @@ * @requires vm.hasJFR * @library /test/lib /test/jdk * @modules jdk.jfr jdk.attach java.base/jdk.internal.misc + * @build jdk.jfr.api.consumer.streaming.TestProcess * * @run main/othervm -Dsun.tools.attach.attachTimeout=100000 jdk.jfr.api.consumer.streaming.TestJVMExit */ public class TestJVMExit { public static void main(String... args) throws Exception { + while (true) { + try { + testExit(); + return; + } catch (RuntimeException e) { + String message = String.valueOf(e.getMessage()); + // If the test application crashes during startup, retry. + if (!message.contains("is no longer alive")) { + throw e; + } + System.out.println("Application not alive when trying to get repository. Retrying."); + } + } + } + + private static void testExit() throws Exception { try (TestProcess process = new TestProcess("exit-application")) { AtomicInteger eventCounter = new AtomicInteger(); try (EventStream es = EventStream.openRepository(process.getRepository())) { From 6f7f0f1de05fdc0f6a88ccd90b806e8a5c5074ef Mon Sep 17 00:00:00 2001 From: Per Minborg Date: Sat, 6 Jul 2024 15:05:26 +0000 Subject: [PATCH 005/401] 8333884: MemorySegment::reinterpret removes read-only property Reviewed-by: jvernee, mcimadamore --- .../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 aa1f1762aec65..83a8b09f9d453 100644 --- a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java +++ b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java @@ -633,6 +633,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. * @@ -652,6 +655,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. * @@ -679,6 +685,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. * @@ -705,6 +714,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. * @@ -721,6 +733,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. * @@ -759,6 +774,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. * @@ -807,6 +825,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 f9f6ac2022a2b..325dbe1093f25 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 17f141b4e8c64..133631e2aa4d8 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 44ecd12ba5ebd..b361abac3dfa4 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 3f37c5718d676b7001e6a084aed3ba645745a144 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Mon, 8 Jul 2024 01:19:36 +0000 Subject: [PATCH 006/401] 8335806: RISC-V: Corrected typos Bizarrely Reviewed-by: aph, amitkumar --- src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp | 2 +- src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp index 7e3ceb1f02029..251ea3813ff84 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp @@ -1154,7 +1154,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, BLOCK_COMMENT("string_compare {"); - // Bizzarely, the counts are passed in bytes, regardless of whether they + // Bizarrely, the counts are passed in bytes, regardless of whether they // are L or U strings, however the result is always in characters. if (!str1_isL) asrw(cnt1, cnt1, 1); if (!str2_isL) asrw(cnt2, cnt2, 1); diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 887baa4a506d1..3cb2e52c8cb93 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -1322,7 +1322,7 @@ void C2_MacroAssembler::string_compare(Register str1, Register str2, BLOCK_COMMENT("string_compare {"); - // Bizzarely, the counts are passed in bytes, regardless of whether they + // Bizarrely, the counts are passed in bytes, regardless of whether they // are L or U strings, however the result is always in characters. if (!str1_isL) { sraiw(cnt1, cnt1, 1); From 02956ab6e161ca8556a73f328f79bcbfba997cbc Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Mon, 8 Jul 2024 06:23:03 +0000 Subject: [PATCH 007/401] 8332163: C2 SuperWord: refactor PacksetGraph and SuperWord::output into VTransformGraph Reviewed-by: chagedorn, kvn --- src/hotspot/share/opto/superword.cpp | 816 +++--------------- src/hotspot/share/opto/superword.hpp | 18 +- .../share/opto/superwordVTransformBuilder.cpp | 308 +++++++ .../share/opto/superwordVTransformBuilder.hpp | 87 ++ .../share/opto/traceAutoVectorizationTag.hpp | 1 + src/hotspot/share/opto/vectorization.cpp | 1 - src/hotspot/share/opto/vectorization.hpp | 16 +- src/hotspot/share/opto/vtransform.cpp | 450 ++++++++++ src/hotspot/share/opto/vtransform.hpp | 515 +++++++++++ 9 files changed, 1489 insertions(+), 723 deletions(-) create mode 100644 src/hotspot/share/opto/superwordVTransformBuilder.cpp create mode 100644 src/hotspot/share/opto/superwordVTransformBuilder.hpp create mode 100644 src/hotspot/share/opto/vtransform.cpp create mode 100644 src/hotspot/share/opto/vtransform.hpp diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp index f78a9b63926fd..ba2dd423bf51d 100644 --- a/src/hotspot/share/opto/superword.cpp +++ b/src/hotspot/share/opto/superword.cpp @@ -22,22 +22,13 @@ */ #include "precompiled.hpp" -#include "libadt/vectset.hpp" -#include "memory/allocation.inline.hpp" -#include "memory/resourceArea.hpp" #include "opto/addnode.hpp" -#include "opto/c2compiler.hpp" #include "opto/castnode.hpp" #include "opto/convertnode.hpp" -#include "opto/matcher.hpp" -#include "opto/memnode.hpp" -#include "opto/opcodes.hpp" -#include "opto/opaquenode.hpp" -#include "opto/rootnode.hpp" #include "opto/superword.hpp" +#include "opto/superwordVTransformBuilder.hpp" #include "opto/vectornode.hpp" #include "opto/movenode.hpp" -#include "utilities/powerOfTwo.hpp" SuperWord::SuperWord(const VLoopAnalyzer &vloop_analyzer) : _vloop_analyzer(vloop_analyzer), @@ -707,7 +698,7 @@ bool SuperWord::can_pack_into_pair(Node* s1, Node* s2) { } // Forbid anything that looks like a PopulateIndex to be packed. It does not need to be packed, - // and will still be vectorized by SuperWord::vector_opd. + // and will still be vectorized by SuperWordVTransformBuilder::get_or_make_vtnode_vector_input_at_index. if (isomorphic(s1, s2) && !is_populate_index(s1, s2)) { if ((independent(s1, s2) && have_similar_inputs(s1, s2)) || reduction(s1, s2)) { if (!_pairset.is_left(s1) && !_pairset.is_right(s2)) { @@ -769,8 +760,9 @@ bool SuperWord::isomorphic(Node* s1, Node* s2) { } } -// Look for pattern n1 = (iv + c) and n2 = (iv + c + 1), which may lead to PopulateIndex vector node. -// We skip the pack creation of these nodes. They will be vectorized by SuperWord::vector_opd. +// Look for pattern n1 = (iv + c) and n2 = (iv + c + 1), which may lead to +// PopulateIndex vector node. We skip the pack creation of these nodes. They +// will be vectorized by SuperWordVTransformBuilder::get_or_make_vtnode_vector_input_at_index. bool SuperWord::is_populate_index(const Node* n1, const Node* n2) const { return n1->is_Add() && n2->is_Add() && @@ -1858,307 +1850,74 @@ void PackSet::verify() const { } #endif -// The PacksetGraph combines the dependency graph with the packset. In the PackSet -// graph, we have two kinds of nodes: -// (1) pack-node: Represents all nodes of some pack p in a single node, which -// shall later become a vector node. -// (2) scalar-node: Represents a node that is not in any pack. -// For any edge (n1, n2) in the dependency graph, we add an edge to the PacksetGraph for -// the PacksetGraph nodes corresponding to n1 and n2. -// We work from the dependency graph, because it gives us all the data-dependencies, -// as well as more refined memory-dependencies than the C2 graph. The dependency graph -// does not have cycles. But packing nodes can introduce cyclic dependencies. Example: -// -// +--------+ -// A -> X | v -// Pack [A,B] and [X,Y] [A,B] [X,Y] -// Y -> B ^ | -// +--------+ -// -class PacksetGraph { -private: - // pid: packset graph node id. - GrowableArray _pid; // bb_idx(n) -> pid - GrowableArray _pid_to_node; // one node per pid, find rest via _packset.pack - GrowableArray> _out; // out-edges - GrowableArray _incnt; // number of (implicit) in-edges - int _max_pid = 0; - - bool _schedule_success; - - SuperWord* _slp; -public: - PacksetGraph(SuperWord* slp) - : _pid(8, 0, /* default */ 0), _slp(slp) { - } - // Get pid, if there is a packset node that n belongs to. Else return 0. - int get_pid_or_zero(const Node* n) const { - if (!_slp->in_bb(n)) { - return 0; - } - int idx = _slp->bb_idx(n); - if (idx >= _pid.length()) { - return 0; - } else { - return _pid.at(idx); - } - } - int get_pid(const Node* n) { - int poz = get_pid_or_zero(n); - assert(poz != 0, "pid should not be zero"); - return poz; - } - void set_pid(Node* n, int pid) { - assert(n != nullptr && pid > 0, "sane inputs"); - assert(_slp->in_bb(n), "must be"); - int idx = _slp->bb_idx(n); - _pid.at_put_grow(idx, pid); - _pid_to_node.at_put_grow(pid - 1, n, nullptr); - } - Node* get_node(int pid) { - assert(pid > 0 && pid <= _pid_to_node.length(), "pid must be mapped"); - Node* n = _pid_to_node.at(pid - 1); - assert(n != nullptr, "sanity"); - return n; - } - int new_pid() { - _incnt.push(0); - _out.push(GrowableArray()); - return ++_max_pid; - } - int incnt(int pid) { return _incnt.at(pid - 1); } - void incnt_set(int pid, int cnt) { return _incnt.at_put(pid - 1, cnt); } - GrowableArray& out(int pid) { return _out.at(pid - 1); } - bool schedule_success() const { return _schedule_success; } - - // Create nodes (from packs and scalar-nodes), and add edges, based on the dependency graph. - void build() { - const PackSet& packset = _slp->packset(); - const GrowableArray& body = _slp->body(); - // Map nodes in packsets - for (int i = 0; i < packset.length(); i++) { - Node_List* p = packset.at(i); - int pid = new_pid(); - for (uint k = 0; k < p->size(); k++) { - Node* n = p->at(k); - set_pid(n, pid); - assert(packset.get_pack(n) == p, "matching packset"); - } - } - - int max_pid_packset = _max_pid; - - // Map nodes not in packset - for (int i = 0; i < body.length(); i++) { - Node* n = body.at(i); - if (n->is_Phi() || n->is_CFG()) { - continue; // ignore control flow - } - int pid = get_pid_or_zero(n); - if (pid == 0) { - pid = new_pid(); - set_pid(n, pid); - assert(packset.get_pack(n) == nullptr, "no packset"); - } - } - - // Map edges for packset nodes - VectorSet set; - for (int i = 0; i < packset.length(); i++) { - Node_List* p = packset.at(i); - set.clear(); - int pid = get_pid(p->at(0)); - for (uint k = 0; k < p->size(); k++) { - Node* n = p->at(k); - assert(pid == get_pid(n), "all nodes in pack have same pid"); - for (VLoopDependencyGraph::PredsIterator preds(_slp->dependency_graph(), n); !preds.done(); preds.next()) { - Node* pred = preds.current(); - int pred_pid = get_pid_or_zero(pred); - if (pred_pid == pid && _slp->is_marked_reduction(n)) { - continue; // reduction -> self-cycle is not a cyclic dependency - } - // Only add edges once, and only for mapped nodes (in body) - if (pred_pid > 0 && !set.test_set(pred_pid)) { - incnt_set(pid, incnt(pid) + 1); // increment - out(pred_pid).push(pid); - } - } - } - } - - // Map edges for nodes not in packset - for (int i = 0; i < body.length(); i++) { - Node* n = body.at(i); - int pid = get_pid_or_zero(n); // zero for Phi or CFG - if (pid <= max_pid_packset) { - continue; // Only scalar-nodes - } - for (VLoopDependencyGraph::PredsIterator preds(_slp->dependency_graph(), n); !preds.done(); preds.next()) { - Node* pred = preds.current(); - int pred_pid = get_pid_or_zero(pred); - // Only add edges for mapped nodes (in body) - if (pred_pid > 0) { - incnt_set(pid, incnt(pid) + 1); // increment - out(pred_pid).push(pid); - } - } - } - } - - // Schedule nodes of PacksetGraph to worklist, using topsort: schedule a node - // that has zero incnt. If a PacksetGraph node corresponds to memops, then add - // those to the memops_schedule. At the end, we return the memops_schedule, and - // note if topsort was successful. - Node_List schedule() { - Node_List memops_schedule; - GrowableArray worklist; - // Directly schedule all nodes without precedence - for (int pid = 1; pid <= _max_pid; pid++) { - if (incnt(pid) == 0) { - worklist.push(pid); - } - } - // Continue scheduling via topological sort - for (int i = 0; i < worklist.length(); i++) { - int pid = worklist.at(i); - - // Add memops to memops_schedule - Node* n = get_node(pid); - Node_List* p = _slp->packset().get_pack(n); - if (n->is_Mem()) { - if (p == nullptr) { - memops_schedule.push(n); - } else { - for (uint k = 0; k < p->size(); k++) { - memops_schedule.push(p->at(k)); - assert(p->at(k)->is_Mem(), "only schedule memops"); - } - } - } +bool SuperWord::schedule_and_apply() const { + if (_packset.is_empty()) { return false; } - // Decrement incnt for all successors - for (int j = 0; j < out(pid).length(); j++){ - int pid_use = out(pid).at(j); - int incnt_use = incnt(pid_use) - 1; - incnt_set(pid_use, incnt_use); - // Did use lose its last input? - if (incnt_use == 0) { - worklist.push(pid_use); - } - } - } - - // Was every pid scheduled? If not, we found some cycles in the PacksetGraph. - _schedule_success = (worklist.length() == _max_pid); - return memops_schedule; - } - - // Print the PacksetGraph. - // print_nodes = true: print all C2 nodes beloning to PacksetGrahp node. - // print_zero_incnt = false: do not print nodes that have no in-edges (any more). - void print(bool print_nodes, bool print_zero_incnt) { - const GrowableArray &body = _slp->body(); - tty->print_cr("PacksetGraph"); - for (int pid = 1; pid <= _max_pid; pid++) { - if (incnt(pid) == 0 && !print_zero_incnt) { - continue; - } - tty->print("Node %d. incnt %d [", pid, incnt(pid)); - for (int j = 0; j < out(pid).length(); j++) { - tty->print("%d ", out(pid).at(j)); - } - tty->print_cr("]"); + // Make an empty transform. #ifndef PRODUCT - if (print_nodes) { - for (int i = 0; i < body.length(); i++) { - Node* n = body.at(i); - if (get_pid_or_zero(n) == pid) { - tty->print(" "); - n->dump(); - } - } - } + VTransformTrace trace(_vloop.vtrace(), + is_trace_superword_rejections(), + is_trace_align_vector(), + is_trace_superword_info()); #endif - } - } -}; - -// We want to replace the packed scalars from the PackSet and replace them -// with vector operations. This requires scheduling and re-ordering the memory -// graph. We take these steps: -// (1) Build the PacksetGraph. It combines the dependency graph with the -// packset. The PacksetGraph gives us the dependencies that must be -// respected after scheduling. -// (2) Schedule the PacksetGraph to the memops_schedule, which represents -// a linear order of all memops in the body. The order respects the -// dependencies of the PacksetGraph. -// (3) If the PacksetGraph has cycles, we cannot schedule. Abort. -// (4) Apply the vectorization, including re-ordering the memops and replacing -// packed scalars with vector operations. -bool SuperWord::schedule_and_apply() { - if (_packset.is_empty()) { - return false; - } - ResourceMark rm; + VTransform vtransform(_vloop_analyzer, + _mem_ref_for_main_loop_alignment, + _aw_for_main_loop_alignment + NOT_PRODUCT(COMMA trace) + ); - // (1) Build the PacksetGraph. - PacksetGraph graph(this); - graph.build(); + // Build the transform from the packset. + { + ResourceMark rm; + SuperWordVTransformBuilder builder(_packset, vtransform); + } - // (2) Schedule the PacksetGraph. - Node_List memops_schedule = graph.schedule(); + if (!vtransform.schedule()) { return false; } + vtransform.apply(); + return true; +} - // (3) Check if the PacksetGraph schedule succeeded (had no cycles). - // We now know that we only have independent packs, see verify_packs. - // This is a necessary but not a sufficient condition for an acyclic - // graph (DAG) after scheduling. Thus, we must check if the packs have - // introduced a cycle. The SuperWord paper mentions the need for this - // in "3.7 Scheduling". - if (!graph.schedule_success()) { +// Apply the vectorization, i.e. we irreversibly edit the C2 graph. At this point, all +// correctness and profitability checks have passed, and the graph was successfully scheduled. +void VTransform::apply() { #ifndef PRODUCT - if (is_trace_superword_rejections()) { - tty->print_cr("SuperWord::schedule found cycle in PacksetGraph:"); - graph.print(true, false); - tty->print_cr("removing all packs from packset."); - } -#endif - _packset.clear(); - return false; + if (_trace._info || TraceLoopOpts) { + tty->print_cr("\nVTransform::apply:"); + lpt()->dump_head(); + lpt()->head()->dump(); } + assert(cl()->is_main_loop(), "auto vectorization only for main loops"); + assert(_graph.is_scheduled(), "must already be scheduled"); +#endif - // (4) Apply the vectorization, including re-ordering the memops. - return apply(memops_schedule); -} - -bool SuperWord::apply(Node_List& memops_schedule) { Compile* C = phase()->C; - CountedLoopNode* cl = lpt()->_head->as_CountedLoop(); - C->print_method(PHASE_AUTO_VECTORIZATION1_BEFORE_APPLY, 4, cl); + C->print_method(PHASE_AUTO_VECTORIZATION1_BEFORE_APPLY, 4, cl()); - apply_memops_reordering_with_schedule(memops_schedule); - C->print_method(PHASE_AUTO_VECTORIZATION2_AFTER_REORDER, 4, cl); + _graph.apply_memops_reordering_with_schedule(); + C->print_method(PHASE_AUTO_VECTORIZATION2_AFTER_REORDER, 4, cl()); adjust_pre_loop_limit_to_align_main_loop_vectors(); - C->print_method(PHASE_AUTO_VECTORIZATION3_AFTER_ADJUST_LIMIT, 4, cl); - - bool is_success = apply_vectorization(); - C->print_method(PHASE_AUTO_VECTORIZATION4_AFTER_APPLY, 4, cl); + C->print_method(PHASE_AUTO_VECTORIZATION3_AFTER_ADJUST_LIMIT, 4, cl()); - return is_success; + apply_vectorization(); + C->print_method(PHASE_AUTO_VECTORIZATION4_AFTER_APPLY, 4, cl()); } -// Reorder the memory graph for all slices in parallel. We walk over the schedule once, -// and track the current memory state of each slice. -void SuperWord::apply_memops_reordering_with_schedule(Node_List& memops_schedule) { +// We prepare the memory graph for the replacement of scalar memops with vector memops. +// We reorder all slices in parallel, ensuring that the memops inside each slice are +// ordered according to the _schedule. This means that all packed memops are consecutive +// in the memory graph after the reordering. +void VTransformGraph::apply_memops_reordering_with_schedule() const { #ifndef PRODUCT - if (is_trace_superword_info()) { - tty->print_cr("\nSuperWord::apply_memops_reordering_with_schedule:"); - memops_schedule.dump(); + assert(is_scheduled(), "must be already scheduled"); + if (_trace._info) { + print_memops_schedule(); } #endif + ResourceMark rm; int max_slices = phase()->C->num_alias_types(); - // When iterating over the memops_schedule, we keep track of the current memory state, + // When iterating over the schedule, we keep track of the current memory state, // which is the Phi or a store in the loop. GrowableArray current_state_in_slice(max_slices, max_slices, nullptr); // The memory state after the loop is the last store inside the loop. If we reorder the @@ -2179,10 +1938,9 @@ void SuperWord::apply_memops_reordering_with_schedule(Node_List& memops_schedule old_last_store_in_slice.at_put(alias_idx, last_store); } - // (2) Walk over memops_schedule, append memops to the current state + // (2) Walk over schedule, append memops to the current state // of that slice. If it is a Store, we take it as the new state. - for (uint i = 0; i < memops_schedule.size(); i++) { - MemNode* n = memops_schedule.at(i)->as_Mem(); + for_each_memop_in_schedule([&] (MemNode* n) { assert(n->is_Load() || n->is_Store(), "only loads or stores"); int alias_idx = phase()->C->get_alias_index(n->adr_type()); Node* current_state = current_state_in_slice.at(alias_idx); @@ -2198,12 +1956,12 @@ void SuperWord::apply_memops_reordering_with_schedule(Node_List& memops_schedule current_state_in_slice.at_put(alias_idx, n); } } - } + }); // (3) For each slice, we add the current state to the backedge // in the Phi. Further, we replace uses of the old last store // with uses of the new last store (current_state). - Node_List uses_after_loop; + GrowableArray uses_after_loop; for (int i = 0; i < mem_slice_head.length(); i++) { Node* phi = mem_slice_head.at(i); int alias_idx = phase()->C->get_alias_index(phi->adr_type()); @@ -2225,7 +1983,7 @@ void SuperWord::apply_memops_reordering_with_schedule(Node_List& memops_schedule uses_after_loop.push(use); } } - for (uint k = 0; k < uses_after_loop.size(); k++) { + for (int k = 0; k < uses_after_loop.length(); k++) { Node* use = uses_after_loop.at(k); for (uint j = 0; j < use->req(); j++) { Node* def = use->in(j); @@ -2237,396 +1995,65 @@ void SuperWord::apply_memops_reordering_with_schedule(Node_List& memops_schedule } } -// Convert packs into vector node operations -// At this point, all correctness and profitability checks have passed. -// We start the irreversible process of editing the C2 graph. Should -// there be an unexpected situation (assert fails), then we can only -// bail out of the compilation, as the graph has already been partially -// modified. We bail out, and retry without SuperWord. -bool SuperWord::apply_vectorization() { - CountedLoopNode *cl = lpt()->_head->as_CountedLoop(); - assert(cl->is_main_loop(), "SLP should only work on main loops"); - Compile* C = phase()->C; - assert(!_packset.is_empty(), "vectorization requires non-empty packset"); - -#ifndef PRODUCT - if (TraceLoopOpts) { - tty->print("SuperWord::apply_vectorization "); - lpt()->dump_head(); - } -#endif - - uint max_vlen_in_bytes = 0; - uint max_vlen = 0; - - for (int i = 0; i < body().length(); i++) { - Node* n = body().at(i); - Node_List* p = get_pack(n); - if (p != nullptr && n == p->at(p->size()-1)) { - // After apply_memops_reordering_with_schedule, we know that the memops have the same order in the pack - // as in the memory slice. Hence, "first" is the first memop in the slice from the pack, - // and "n" is the last node in the slice from the pack. - Node* first = p->at(0); - uint vlen = p->size(); - uint vlen_in_bytes = 0; - Node* vn = nullptr; - int opc = n->Opcode(); - if (n->is_Load()) { - Node* ctl = n->in(MemNode::Control); - Node* mem = first->in(MemNode::Memory); - // Set the memory dependency of the LoadVector as early as possible. - // Walk up the memory chain, and ignore any StoreVector that provably - // does not have any memory dependency. - while (mem->is_StoreVector()) { - VPointer p_store(mem->as_Mem(), _vloop); - if (p_store.overlap_possible_with_any_in(p)) { - break; - } else { - mem = mem->in(MemNode::Memory); - } - } - Node* adr = first->in(MemNode::Address); - const TypePtr* atyp = n->adr_type(); - vn = LoadVectorNode::make(opc, ctl, mem, adr, atyp, vlen, velt_basic_type(n), control_dependency(p)); - vlen_in_bytes = vn->as_LoadVector()->memory_size(); - } else if (n->is_Store()) { - // Promote value to be stored to vector - Node* val = vector_opd(p, MemNode::ValueIn); - if (val == nullptr) { - assert(false, "input to vector store was not created"); - C->record_failure(C2Compiler::retry_no_superword()); - return false; // bailout - } +void VTransformGraph::apply_vectorization_for_each_vtnode(uint& max_vector_length, uint& max_vector_width) const { + ResourceMark rm; + // We keep track of the resulting Nodes from every "VTransformNode::apply" call. + // Since "apply" is called on defs before uses, this allows us to find the + // generated def (input) nodes when we are generating the use nodes in "apply". + int length = _vtnodes.length(); + GrowableArray vtnode_idx_to_transformed_node(length, length, nullptr); - Node* ctl = n->in(MemNode::Control); - Node* mem = first->in(MemNode::Memory); - Node* adr = first->in(MemNode::Address); - const TypePtr* atyp = n->adr_type(); - vn = StoreVectorNode::make(opc, ctl, mem, adr, atyp, val, vlen); - vlen_in_bytes = vn->as_StoreVector()->memory_size(); - } else if (VectorNode::is_scalar_rotate(n)) { - Node* in1 = vector_opd(p, 1); - Node* in2 = first->in(2); - // If rotation count is non-constant or greater than 8bit value create a vector. - if (!in2->is_Con() || !Matcher::supports_vector_constant_rotates(in2->get_int())) { - in2 = vector_opd(p, 2); - } - vn = VectorNode::make(opc, in1, in2, vlen, velt_basic_type(n)); - vlen_in_bytes = vn->as_Vector()->length_in_bytes(); - } else if (VectorNode::is_roundopD(n)) { - Node* in1 = vector_opd(p, 1); - Node* in2 = first->in(2); - assert(in2->is_Con(), "Constant rounding mode expected."); - vn = VectorNode::make(opc, in1, in2, vlen, velt_basic_type(n)); - vlen_in_bytes = vn->as_Vector()->length_in_bytes(); - } else if (VectorNode::is_muladds2i(n)) { - assert(n->req() == 5u, "MulAddS2I should have 4 operands."); - Node* in1 = vector_opd(p, 1); - Node* in2 = vector_opd(p, 2); - vn = VectorNode::make(opc, in1, in2, vlen, velt_basic_type(n)); - vlen_in_bytes = vn->as_Vector()->length_in_bytes(); - } else if (opc == Op_SignumF || opc == Op_SignumD) { - assert(n->req() == 4, "four inputs expected"); - Node* in = vector_opd(p, 1); - Node* zero = vector_opd(p, 2); - Node* one = vector_opd(p, 3); - vn = VectorNode::make(opc, in, zero, one, vlen, velt_basic_type(n)); - vlen_in_bytes = vn->as_Vector()->length_in_bytes(); - } else if (n->is_Cmp()) { - // Bool + Cmp + CMove -> VectorMaskCmp + VectorBlend - continue; - } else if (n->is_Bool()) { - // Bool + Cmp + CMove -> VectorMaskCmp + VectorBlend - continue; - } else if (n->is_CMove()) { - // Bool + Cmp + CMove -> VectorMaskCmp + VectorBlend - - BoolNode* bol = n->in(1)->as_Bool(); - assert(bol != nullptr, "must have Bool above CMove"); - Node_List* bool_pack = get_pack(bol); - assert(bool_pack != nullptr, "CMove must have matching Bool pack"); - - CmpNode* cmp = bol->in(1)->as_Cmp(); - assert(cmp != nullptr, "must have cmp above CMove"); - Node_List* cmp_pack = get_pack(cmp); - assert(cmp_pack != nullptr, "Bool must have matching Cmp pack"); - - Node* cmp_in1 = vector_opd(cmp_pack, 1); - Node* cmp_in2 = vector_opd(cmp_pack, 2); - - Node* blend_in1 = vector_opd(p, 2); - Node* blend_in2 = vector_opd(p, 3); - - VTransformBoolTest bool_test = _packset.get_bool_test(bool_pack); - BoolTest::mask test_mask = bool_test._mask; - if (bool_test._is_negated) { - // We can cancel out the negation by swapping the blend inputs. - swap(blend_in1, blend_in2); - } + for (int i = 0; i < _schedule.length(); i++) { + VTransformNode* vtn = _schedule.at(i); + VTransformApplyResult result = vtn->apply(_vloop_analyzer, + vtnode_idx_to_transformed_node); + NOT_PRODUCT( if (_trace._verbose) { result.trace(vtn); } ) - // VectorMaskCmp - ConINode* test_mask_node = igvn().intcon((int)test_mask); - BasicType bt = velt_basic_type(cmp); - const TypeVect* vt = TypeVect::make(bt, vlen); - VectorNode* mask = new VectorMaskCmpNode(test_mask, cmp_in1, cmp_in2, test_mask_node, vt); - phase()->register_new_node_with_ctrl_of(mask, p->at(0)); - igvn()._worklist.push(mask); - - // VectorBlend - vn = new VectorBlendNode(blend_in1, blend_in2, mask); - } else if (n->req() == 3) { - // Promote operands to vector - Node* in1 = nullptr; - bool node_isa_reduction = is_marked_reduction(n); - if (node_isa_reduction) { - // the input to the first reduction operation is retained - in1 = first->in(1); - } else { - in1 = vector_opd(p, 1); - if (in1 == nullptr) { - assert(false, "input in1 to vector operand was not created"); - C->record_failure(C2Compiler::retry_no_superword()); - return false; // bailout - } - } - Node* in2 = vector_opd(p, 2); - if (in2 == nullptr) { - assert(false, "input in2 to vector operand was not created"); - C->record_failure(C2Compiler::retry_no_superword()); - return false; // bailout - } - if (in1->Opcode() == Op_Replicate && (node_isa_reduction == false) && (n->is_Add() || n->is_Mul())) { - // Move invariant vector input into second position to avoid register spilling. - Node* tmp = in1; - in1 = in2; - in2 = tmp; - } - if (node_isa_reduction) { - const Type *arith_type = n->bottom_type(); - vn = ReductionNode::make(opc, nullptr, in1, in2, arith_type->basic_type()); - if (in2->is_Load()) { - vlen_in_bytes = in2->as_LoadVector()->memory_size(); - } else { - vlen_in_bytes = in2->as_Vector()->length_in_bytes(); - } - } else { - if (VectorNode::can_use_RShiftI_instead_of_URShiftI(n, velt_basic_type(n))) { - opc = Op_RShiftI; - } - vn = VectorNode::make(opc, in1, in2, vlen, velt_basic_type(n)); - vlen_in_bytes = vn->as_Vector()->length_in_bytes(); - } - } else if (VectorNode::is_scalar_unary_op_with_equal_input_and_output_types(opc)) { - assert(n->req() == 2, "only one input expected"); - Node* in = vector_opd(p, 1); - vn = VectorNode::make(opc, in, nullptr, vlen, velt_basic_type(n)); - vlen_in_bytes = vn->as_Vector()->length_in_bytes(); - } else if (VectorNode::is_scalar_op_that_returns_int_but_vector_op_returns_long(opc)) { - assert(n->req() == 2, "only one input expected"); - Node* in = vector_opd(p, 1); - Node* longval = VectorNode::make(opc, in, nullptr, vlen, T_LONG); - phase()->register_new_node_with_ctrl_of(longval, first); - // Requires extra vector long -> int conversion. - vn = VectorCastNode::make(Op_VectorCastL2X, longval, T_INT, vlen); - vlen_in_bytes = vn->as_Vector()->length_in_bytes(); - } else if (VectorNode::is_convert_opcode(opc)) { - assert(n->req() == 2, "only one input expected"); - BasicType bt = velt_basic_type(n); - Node* in = vector_opd(p, 1); - int vopc = VectorCastNode::opcode(opc, in->bottom_type()->is_vect()->element_basic_type()); - vn = VectorCastNode::make(vopc, in, bt, vlen); - vlen_in_bytes = vn->as_Vector()->length_in_bytes(); - } else if (opc == Op_FmaD || opc == Op_FmaF) { - // Promote operands to vector - Node* in1 = vector_opd(p, 1); - Node* in2 = vector_opd(p, 2); - Node* in3 = vector_opd(p, 3); - vn = VectorNode::make(opc, in1, in2, in3, vlen, velt_basic_type(n)); - vlen_in_bytes = vn->as_Vector()->length_in_bytes(); - } else { - assert(false, "Unhandled scalar opcode (%s)", NodeClassNames[opc]); - C->record_failure(C2Compiler::retry_no_superword()); - return false; // bailout - } - - if (vn == nullptr) { - assert(false, "got null node instead of vector node"); - C->record_failure(C2Compiler::retry_no_superword()); - return false; // bailout - } + vtnode_idx_to_transformed_node.at_put(vtn->_idx, result.node()); + max_vector_length = MAX2(max_vector_length, result.vector_length()); + max_vector_width = MAX2(max_vector_width, result.vector_width()); + } +} -#ifdef ASSERT - // Mark Load/Store Vector for alignment verification - if (VerifyAlignVector) { - if (vn->Opcode() == Op_LoadVector) { - vn->as_LoadVector()->set_must_verify_alignment(); - } else if (vn->Opcode() == Op_StoreVector) { - vn->as_StoreVector()->set_must_verify_alignment(); - } - } +// We call "apply" on every VTransformNode, which replaces the packed scalar nodes with vector nodes. +void VTransform::apply_vectorization() const { + Compile* C = phase()->C; +#ifndef PRODUCT + if (_trace._verbose) { + tty->print_cr("\nVTransform::apply_vectorization:"); + } #endif - phase()->register_new_node_with_ctrl_of(vn, first); - for (uint j = 0; j < p->size(); j++) { - Node* pm = p->at(j); - igvn().replace_node(pm, vn); - } - igvn()._worklist.push(vn); + uint max_vector_length = 0; // number of elements + uint max_vector_width = 0; // total width in bytes + _graph.apply_vectorization_for_each_vtnode(max_vector_length, max_vector_width); - if (vlen > max_vlen) { - max_vlen = vlen; - } - if (vlen_in_bytes > max_vlen_in_bytes) { - max_vlen_in_bytes = vlen_in_bytes; - } - VectorNode::trace_new_vector(vn, "SuperWord"); - } - }//for (int i = 0; i < body().length(); i++) + assert(max_vector_length > 0 && max_vector_width > 0, "must have vectorized"); + cl()->mark_loop_vectorized(); - if (max_vlen_in_bytes > C->max_vector_size()) { - C->set_max_vector_size(max_vlen_in_bytes); - } - if (max_vlen_in_bytes > 0) { - cl->mark_loop_vectorized(); + if (max_vector_width > C->max_vector_size()) { + C->set_max_vector_size(max_vector_width); } if (SuperWordLoopUnrollAnalysis) { - if (cl->has_passed_slp()) { - uint slp_max_unroll_factor = cl->slp_max_unroll(); - if (slp_max_unroll_factor == max_vlen) { + if (cl()->has_passed_slp()) { + uint slp_max_unroll_factor = cl()->slp_max_unroll(); + if (slp_max_unroll_factor == max_vector_length) { #ifndef PRODUCT if (TraceSuperWordLoopUnrollAnalysis) { - tty->print_cr("vector loop(unroll=%d, len=%d)\n", max_vlen, max_vlen_in_bytes*BitsPerByte); + tty->print_cr("vector loop(unroll=%d, len=%d)\n", max_vector_length, max_vector_width * BitsPerByte); } #endif // For atomic unrolled loops which are vector mapped, instigate more unrolling - cl->set_notpassed_slp(); + cl()->set_notpassed_slp(); // if vector resources are limited, do not allow additional unrolling if (Matcher::float_pressure_limit() > 8) { C->set_major_progress(); - cl->mark_do_unroll_only(); + cl()->mark_do_unroll_only(); } } } } - - return true; -} - -//------------------------------vector_opd--------------------------- -// Create a vector operand for the nodes in pack p for operand: in(opd_idx) -Node* SuperWord::vector_opd(Node_List* p, int opd_idx) { - Node* p0 = p->at(0); - uint vlen = p->size(); - Node* opd = p0->in(opd_idx); - CountedLoopNode *cl = lpt()->_head->as_CountedLoop(); - Node* same_input = _packset.same_inputs_at_index_or_null(p, opd_idx); - - // Insert index population operation to create a vector of increasing - // indices starting from the iv value. In some special unrolled loops - // (see JDK-8286125), we need scalar replications of the iv value if - // all inputs are the same iv, so we do a same inputs check here. - if (opd == iv() && same_input == nullptr) { - BasicType p0_bt = velt_basic_type(p0); - BasicType iv_bt = is_subword_type(p0_bt) ? p0_bt : T_INT; - assert(VectorNode::is_populate_index_supported(iv_bt), "Should support"); - const TypeVect* vt = TypeVect::make(iv_bt, vlen); - Node* vn = new PopulateIndexNode(iv(), igvn().intcon(1), vt); - VectorNode::trace_new_vector(vn, "SuperWord"); - phase()->register_new_node_with_ctrl_of(vn, opd); - return vn; - } - - if (same_input != nullptr) { - if (opd->is_Vector() || opd->is_LoadVector()) { - if (opd_idx == 2 && VectorNode::is_shift(p0)) { - assert(false, "shift's count can't be vector"); - return nullptr; - } - return opd; // input is matching vector - } - if ((opd_idx == 2) && VectorNode::is_shift(p0)) { - Node* cnt = opd; - // Vector instructions do not mask shift count, do it here. - juint mask = (p0->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1); - const TypeInt* t = opd->find_int_type(); - if (t != nullptr && t->is_con()) { - juint shift = t->get_con(); - if (shift > mask) { // Unsigned cmp - cnt = igvn().intcon(shift & mask); - phase()->set_ctrl(cnt, phase()->C->root()); - } - } else { - if (t == nullptr || t->_lo < 0 || t->_hi > (int)mask) { - cnt = igvn().intcon(mask); - cnt = new AndINode(opd, cnt); - phase()->register_new_node_with_ctrl_of(cnt, opd); - } - if (!opd->bottom_type()->isa_int()) { - assert(false, "int type only"); - return nullptr; - } - } - // Move shift count into vector register. - cnt = VectorNode::shift_count(p0->Opcode(), cnt, vlen, velt_basic_type(p0)); - phase()->register_new_node_with_ctrl_of(cnt, opd); - return cnt; - } - if (opd->is_StoreVector()) { - assert(false, "StoreVector is not expected here"); - return nullptr; - } - // Convert scalar input to vector with the same number of elements as - // p0's vector. Use p0's type because size of operand's container in - // vector should match p0's size regardless operand's size. - const Type* p0_t = nullptr; - VectorNode* vn = nullptr; - if (opd_idx == 2 && VectorNode::is_scalar_rotate(p0)) { - Node* conv = opd; - p0_t = TypeInt::INT; - if (p0->bottom_type()->isa_long()) { - p0_t = TypeLong::LONG; - conv = new ConvI2LNode(opd); - phase()->register_new_node_with_ctrl_of(conv, opd); - } - vn = VectorNode::scalar2vector(conv, vlen, p0_t); - } else { - p0_t = velt_type(p0); - vn = VectorNode::scalar2vector(opd, vlen, p0_t); - } - - phase()->register_new_node_with_ctrl_of(vn, opd); - VectorNode::trace_new_vector(vn, "SuperWord"); - return vn; - } - - // Insert pack operation - BasicType bt = velt_basic_type(p0); - PackNode* pk = PackNode::make(opd, vlen, bt); - DEBUG_ONLY( const BasicType opd_bt = opd->bottom_type()->basic_type(); ) - - for (uint i = 1; i < vlen; i++) { - Node* pi = p->at(i); - Node* in = pi->in(opd_idx); - if (get_pack(in) != nullptr) { - assert(false, "Should already have been unpacked"); - return nullptr; - } - assert(opd_bt == in->bottom_type()->basic_type(), "all same type"); - pk->add_opd(in); - if (VectorNode::is_muladds2i(pi)) { - Node* in2 = pi->in(opd_idx + 2); - if (get_pack(in2) != nullptr) { - assert(false, "Should already have been unpacked"); - return nullptr; - } - assert(opd_bt == in2->bottom_type()->basic_type(), "all same type"); - pk->add_opd(in2); - } - } - phase()->register_new_node_with_ctrl_of(pk, opd); - VectorNode::trace_new_vector(pk, "SuperWord"); - return pk; } #ifdef ASSERT @@ -2797,18 +2224,7 @@ bool SuperWord::is_vector_use(Node* use, int u_idx) const { return _packset.is_muladds2i_pack_with_pack_inputs(u_pk); } - if (u_pk->size() != d_pk->size()) { - return false; - } - - for (uint i = 0; i < u_pk->size(); i++) { - Node* ui = u_pk->at(i); - Node* di = d_pk->at(i); - if (ui->in(u_idx) != di) { - return false; - } - } - return true; + return _packset.pack_input_at_index_or_null(u_pk, u_idx) != nullptr; } // MulAddS2I takes 4 shorts and produces an int. We can reinterpret @@ -3182,10 +2598,10 @@ bool VLoopMemorySlices::same_memory_slice(MemNode* m1, MemNode* m2) const { _vloop.phase()->C->get_alias_index(m2->adr_type()); } -LoadNode::ControlDependency SuperWord::control_dependency(Node_List* p) { +LoadNode::ControlDependency VTransformLoadVectorNode::control_dependency() const { LoadNode::ControlDependency dep = LoadNode::DependsOnlyOnTest; - for (uint i = 0; i < p->size(); i++) { - Node* n = p->at(i); + for (int i = 0; i < nodes().length(); i++) { + Node* n = nodes().at(i); assert(n->is_Load(), "only meaningful for loads"); if (!n->depends_only_on_test()) { if (n->as_Load()->has_unknown_control_dependency() && @@ -3202,8 +2618,8 @@ LoadNode::ControlDependency SuperWord::control_dependency(Node_List* p) { } // Find the memop pack with the maximum vector width, unless they were already -// determined by SuperWord::filter_packs_for_alignment(). -void SuperWord::determine_mem_ref_and_aw_for_main_loop_alignment() { +// determined (e.g. by SuperWord::filter_packs_for_alignment()). +void VTransform::determine_mem_ref_and_aw_for_main_loop_alignment() { if (_mem_ref_for_main_loop_alignment != nullptr) { assert(VLoop::vectors_should_be_aligned(), "mem_ref only set if filtered for alignment"); return; @@ -3211,15 +2627,18 @@ void SuperWord::determine_mem_ref_and_aw_for_main_loop_alignment() { MemNode const* mem_ref = nullptr; int max_aw = 0; - for (int i = 0; i < _packset.length(); i++) { - Node_List* pack = _packset.at(i); - MemNode* first = pack->at(0)->isa_Mem(); - if (first == nullptr) { continue; } - int vw = first->memory_size() * pack->size(); + const GrowableArray& vtnodes = _graph.vtnodes(); + for (int i = 0; i < vtnodes.length(); i++) { + VTransformVectorNode* vtn = vtnodes.at(i)->isa_Vector(); + if (vtn == nullptr) { continue; } + MemNode* p0 = vtn->nodes().at(0)->isa_Mem(); + if (p0 == nullptr) { continue; } + + int vw = p0->memory_size() * vtn->nodes().length(); if (vw > max_aw) { max_aw = vw; - mem_ref = first; + mem_ref = p0; } } assert(mem_ref != nullptr && max_aw > 0, "found mem_ref and aw"); @@ -3229,7 +2648,7 @@ void SuperWord::determine_mem_ref_and_aw_for_main_loop_alignment() { #define TRACE_ALIGN_VECTOR_NODE(node) { \ DEBUG_ONLY( \ - if (is_trace_align_vector()) { \ + if (_trace._align_vector) { \ tty->print(" " #node ": "); \ node->dump(); \ } \ @@ -3240,7 +2659,7 @@ void SuperWord::determine_mem_ref_and_aw_for_main_loop_alignment() { // the address of "_mem_ref_for_main_loop_alignment" to "_aw_for_main_loop_alignment", which is a // sufficiently large alignment width. We adjust the pre-loop iteration count by adjusting the // pre-loop limit. -void SuperWord::adjust_pre_loop_limit_to_align_main_loop_vectors() { +void VTransform::adjust_pre_loop_limit_to_align_main_loop_vectors() { determine_mem_ref_and_aw_for_main_loop_alignment(); const MemNode* align_to_ref = _mem_ref_for_main_loop_alignment; const int aw = _aw_for_main_loop_alignment; @@ -3397,8 +2816,8 @@ void SuperWord::adjust_pre_loop_limit_to_align_main_loop_vectors() { Node* invar = align_to_ref_p.invar(); #ifdef ASSERT - if (is_trace_align_vector()) { - tty->print_cr("\nadjust_pre_loop_limit_to_align_main_loop_vectors:"); + if (_trace._align_vector) { + tty->print_cr("\nVTransform::adjust_pre_loop_limit_to_align_main_loop_vectors:"); tty->print(" align_to_ref:"); align_to_ref->dump(); tty->print_cr(" aw: %d", aw); @@ -3424,7 +2843,7 @@ void SuperWord::adjust_pre_loop_limit_to_align_main_loop_vectors() { scale == 0 || !is_power_of_2(abs(scale)) || abs(scale) >= aw) { #ifdef ASSERT - if (is_trace_align_vector()) { + if (_trace._align_vector) { tty->print_cr(" Alignment cannot be affected by changing pre-loop limit because"); tty->print_cr(" stride or scale are not power of 2, or abs(scale) >= aw."); } @@ -3440,7 +2859,7 @@ void SuperWord::adjust_pre_loop_limit_to_align_main_loop_vectors() { const int AW = aw / abs(scale); #ifdef ASSERT - if (is_trace_align_vector()) { + if (_trace._align_vector) { tty->print_cr(" AW = aw(%d) / abs(scale(%d)) = %d", aw, scale, AW); } #endif @@ -3595,10 +3014,10 @@ void PackSet::print_pack(Node_List* pack) { #ifndef PRODUCT void VLoopBody::print() const { - tty->print_cr("\nBlock"); + tty->print_cr("\nVLoopBody::print"); for (int i = 0; i < body().length(); i++) { Node* n = body().at(i); - tty->print("%d ", i); + tty->print("%4d ", i); if (n != nullptr) { n->dump(); } @@ -3615,3 +3034,4 @@ bool SuperWord::same_origin_idx(Node* a, Node* b) const { bool SuperWord::same_generation(Node* a, Node* b) const { return a != nullptr && b != nullptr && _clone_map.same_gen(a->_idx, b->_idx); } + diff --git a/src/hotspot/share/opto/superword.hpp b/src/hotspot/share/opto/superword.hpp index fb91d014faebb..65f870825251f 100644 --- a/src/hotspot/share/opto/superword.hpp +++ b/src/hotspot/share/opto/superword.hpp @@ -25,6 +25,7 @@ #define SHARE_OPTO_SUPERWORD_HPP #include "opto/vectorization.hpp" +#include "opto/vtransform.hpp" #include "utilities/growableArray.hpp" // @@ -367,6 +368,10 @@ class PackSet : public StackObj { Node* same_inputs_at_index_or_null(const Node_List* pack, const int index) const; VTransformBoolTest get_bool_test(const Node_List* bool_pack) const; + Node_List* pack_input_at_index_or_null(const Node_List* pack, const int index) const { + return strided_pack_input_at_index_or_null(pack, index, 1, 0); + } + private: SplitStatus split_pack(const char* split_name, Node_List* pack, SplitTask task); public: @@ -599,13 +604,6 @@ class SuperWord : public ResourceObj { DEBUG_ONLY(void verify_packs() const;) - bool schedule_and_apply(); - bool apply(Node_List& memops_schedule); - void apply_memops_reordering_with_schedule(Node_List& memops_schedule); - bool apply_vectorization(); - // Create a vector operand for the nodes in pack p for operand: in(opd_idx) - Node* vector_opd(Node_List* p, int opd_idx); - // Can code be generated for the pack, restricted to size nodes? bool implemented(const Node_List* pack, const uint size) const; // Find the maximal implemented size smaller or equal to the packs size @@ -630,11 +628,7 @@ class SuperWord : public ResourceObj { bool is_velt_basic_type_compatible_use_def(Node* use, Node* def) const; - static LoadNode::ControlDependency control_dependency(Node_List* p); - - // Ensure that the main loop vectors are aligned by adjusting the pre loop limit. - void determine_mem_ref_and_aw_for_main_loop_alignment(); - void adjust_pre_loop_limit_to_align_main_loop_vectors(); + bool schedule_and_apply() const; }; #endif // SHARE_OPTO_SUPERWORD_HPP diff --git a/src/hotspot/share/opto/superwordVTransformBuilder.cpp b/src/hotspot/share/opto/superwordVTransformBuilder.cpp new file mode 100644 index 0000000000000..b0a0c97cb1676 --- /dev/null +++ b/src/hotspot/share/opto/superwordVTransformBuilder.cpp @@ -0,0 +1,308 @@ +/* + * 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. + */ + +#include "precompiled.hpp" +#include "opto/superwordVTransformBuilder.hpp" +#include "opto/vectornode.hpp" + +void SuperWordVTransformBuilder::build() { + assert(!_packset.is_empty(), "must have non-empty packset"); + assert(!_vtransform.has_graph(), "start with empty vtransform"); + + // Create vtnodes for all nodes in the loop. + build_vector_vtnodes_for_packed_nodes(); + build_scalar_vtnodes_for_non_packed_nodes(); + + // Connect all vtnodes with their inputs. Possibly create vtnodes for input + // nodes that are outside the loop. + VectorSet vtn_dependencies; // Shared, but cleared for every vtnode. + build_inputs_for_vector_vtnodes(vtn_dependencies); + build_inputs_for_scalar_vtnodes(vtn_dependencies); +} + +void SuperWordVTransformBuilder::build_vector_vtnodes_for_packed_nodes() { + for (int i = 0; i < _packset.length(); i++) { + Node_List* pack = _packset.at(i); + VTransformVectorNode* vtn = make_vector_vtnode_for_pack(pack); + for (uint k = 0; k < pack->size(); k++) { + map_node_to_vtnode(pack->at(k), vtn); + } + } +} + +void SuperWordVTransformBuilder::build_scalar_vtnodes_for_non_packed_nodes() { + for (int i = 0; i < _vloop_analyzer.body().body().length(); i++) { + Node* n = _vloop_analyzer.body().body().at(i); + if (_packset.get_pack(n) != nullptr) { continue; } + VTransformScalarNode* vtn = new (_vtransform.arena()) VTransformScalarNode(_vtransform, n); + map_node_to_vtnode(n, vtn); + } +} + +void SuperWordVTransformBuilder::build_inputs_for_vector_vtnodes(VectorSet& vtn_dependencies) { + for (int i = 0; i < _packset.length(); i++) { + Node_List* pack = _packset.at(i); + Node* p0 = pack->at(0); + + VTransformVectorNode* vtn = get_vtnode(p0)->isa_Vector(); + assert(vtn != nullptr, "all packs must have vector vtnodes"); + vtn_dependencies.clear(); // Add every dependency only once per vtn. + + if (p0->is_Load()) { + set_req_with_scalar(p0, vtn, vtn_dependencies, MemNode::Address); + } else if (p0->is_Store()) { + set_req_with_scalar(p0, vtn, vtn_dependencies, MemNode::Address); + set_req_with_vector(pack, vtn, vtn_dependencies, MemNode::ValueIn); + } else if (vtn->isa_ReductionVector() != nullptr) { + set_req_with_scalar(p0, vtn, vtn_dependencies, 1); // scalar init + set_req_with_vector(pack, vtn, vtn_dependencies, 2); // vector + } else { + assert(vtn->isa_ElementWiseVector() != nullptr, "all other vtnodes are handled above"); + if (VectorNode::is_scalar_rotate(p0) && + p0->in(2)->is_Con() && + Matcher::supports_vector_constant_rotates(p0->in(2)->get_int())) { + set_req_with_vector(pack, vtn, vtn_dependencies, 1); + set_req_with_scalar(p0, vtn, vtn_dependencies, 2); // constant rotation + } else if (VectorNode::is_roundopD(p0)) { + set_req_with_vector(pack, vtn, vtn_dependencies, 1); + set_req_with_scalar(p0, vtn, vtn_dependencies, 2); // constant rounding mode + } else if (p0->is_CMove()) { + // Cmp + Bool + CMove -> VectorMaskCmp + VectorBlend. + set_all_req_with_vectors(pack, vtn, vtn_dependencies); + VTransformBoolVectorNode* vtn_mask_cmp = vtn->in(1)->isa_BoolVector(); + if (vtn_mask_cmp->test()._is_negated) { + vtn->swap_req(2, 3); // swap if test was negated. + } + } else { + set_all_req_with_vectors(pack, vtn, vtn_dependencies); + } + } + + for (uint k = 0; k < pack->size(); k++) { + add_dependencies_of_node_to_vtnode(pack->at(k), vtn, vtn_dependencies); + } + } +} + +void SuperWordVTransformBuilder::build_inputs_for_scalar_vtnodes(VectorSet& vtn_dependencies) { + for (int i = 0; i < _vloop_analyzer.body().body().length(); i++) { + Node* n = _vloop_analyzer.body().body().at(i); + VTransformScalarNode* vtn = get_vtnode(n)->isa_Scalar(); + if (vtn == nullptr) { continue; } + vtn_dependencies.clear(); // Add every dependency only once per vtn. + + if (n->is_Load()) { + set_req_with_scalar(n, vtn, vtn_dependencies, MemNode::Address); + } else if (n->is_Store()) { + set_req_with_scalar(n, vtn, vtn_dependencies, MemNode::Address); + set_req_with_scalar(n, vtn, vtn_dependencies, MemNode::ValueIn); + } else if (n->is_CountedLoop()) { + continue; // Is "root", has no dependency. + } else if (n->is_Phi()) { + // CountedLoop Phi's: ignore backedge (and entry value). + assert(n->in(0) == _vloop.cl(), "only Phi's from the CountedLoop allowed"); + set_req_with_scalar(n, vtn, vtn_dependencies, 0); + continue; + } else { + set_all_req_with_scalars(n, vtn, vtn_dependencies); + } + + add_dependencies_of_node_to_vtnode(n, vtn, vtn_dependencies); + } +} + +// Create a vtnode for each pack. No in/out edges set yet. +VTransformVectorNode* SuperWordVTransformBuilder::make_vector_vtnode_for_pack(const Node_List* pack) const { + uint pack_size = pack->size(); + Node* p0 = pack->at(0); + int opc = p0->Opcode(); + VTransformVectorNode* vtn = nullptr; + + if (p0->is_Load()) { + vtn = new (_vtransform.arena()) VTransformLoadVectorNode(_vtransform, pack_size); + } else if (p0->is_Store()) { + vtn = new (_vtransform.arena()) VTransformStoreVectorNode(_vtransform, pack_size); + } else if (p0->is_Bool()) { + VTransformBoolTest kind = _packset.get_bool_test(pack); + vtn = new (_vtransform.arena()) VTransformBoolVectorNode(_vtransform, pack_size, kind); + } else if (_vloop_analyzer.reductions().is_marked_reduction(p0)) { + vtn = new (_vtransform.arena()) VTransformReductionVectorNode(_vtransform, pack_size); + } else if (VectorNode::is_muladds2i(p0)) { + // A special kind of binary element-wise vector op: the inputs are "ints" a and b, + // but reinterpreted as two "shorts" [a0, a1] and [b0, b1]: + // v = MulAddS2I(a, b) = a0 * b0 + a1 + b1 + assert(p0->req() == 5, "MulAddS2I should have 4 operands"); + vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, 3, pack_size); + } else { + assert(p0->req() == 3 || + p0->is_CMove() || + VectorNode::is_scalar_op_that_returns_int_but_vector_op_returns_long(opc) || + VectorNode::is_convert_opcode(opc) || + VectorNode::is_scalar_unary_op_with_equal_input_and_output_types(opc) || + opc == Op_FmaD || + opc == Op_FmaF || + opc == Op_SignumF || + opc == Op_SignumD, + "pack type must be in this list"); + vtn = new (_vtransform.arena()) VTransformElementWiseVectorNode(_vtransform, p0->req(), pack_size); + } + vtn->set_nodes(pack); + return vtn; +} + +void SuperWordVTransformBuilder::set_req_with_scalar(Node* n, VTransformNode* vtn, VectorSet& vtn_dependencies, const int index) { + VTransformNode* req = get_vtnode_or_wrap_as_input_scalar(n->in(index)); + vtn->set_req(index, req); + vtn_dependencies.set(req->_idx); +} + +// Either get the existing vtnode vector input (when input is a pack), or else make a +// new vector vtnode for the input (e.g. for Replicate or PopulateIndex). +VTransformNode* SuperWordVTransformBuilder::get_or_make_vtnode_vector_input_at_index(const Node_List* pack, const int index) { + Node* p0 = pack->at(0); + + Node_List* pack_in = _packset.pack_input_at_index_or_null(pack, index); + if (pack_in != nullptr) { + // Input is a matching pack -> vtnode already exists. + assert(index != 2 || !VectorNode::is_shift(p0), "shift's count cannot be vector"); + return get_vtnode(pack_in->at(0)); + } + + if (VectorNode::is_muladds2i(p0)) { + assert(_packset.is_muladds2i_pack_with_pack_inputs(pack), "inputs must all be packs"); + // All inputs are strided (stride = 2), either with offset 0 or 1. + Node_List* pack_in0 = _packset.strided_pack_input_at_index_or_null(pack, index, 2, 0); + if (pack_in0 != nullptr) { + return get_vtnode(pack_in0->at(0)); + } + Node_List* pack_in1 = _packset.strided_pack_input_at_index_or_null(pack, index, 2, 1); + if (pack_in1 != nullptr) { + return get_vtnode(pack_in1->at(0)); + } + } + + Node* same_input = _packset.same_inputs_at_index_or_null(pack, index); + if (same_input == nullptr && p0->in(index) == _vloop.iv()) { + // PopulateIndex: [iv+0, iv+1, iv+2, ...] + VTransformNode* iv_vtn = get_vtnode_or_wrap_as_input_scalar(_vloop.iv()); + BasicType p0_bt = _vloop_analyzer.types().velt_basic_type(p0); + // If we have subword type, take that type directly. If p0 is some ConvI2L/F/D, + // then the p0_bt can also be L/F/D but we need to produce ints for the input of + // the ConvI2L/F/D. + BasicType element_bt = is_subword_type(p0_bt) ? p0_bt : T_INT; + VTransformNode* populate_index = new (_vtransform.arena()) VTransformPopulateIndexNode(_vtransform, pack->size(), element_bt); + populate_index->set_req(1, iv_vtn); + return populate_index; + } + + if (same_input != nullptr) { + VTransformNode* same_input_vtn = get_vtnode_or_wrap_as_input_scalar(same_input); + if (index == 2 && VectorNode::is_shift(p0)) { + // Scalar shift count for vector shift operation: vec2 = shiftV(vec1, scalar_count) + // Scalar shift operations masks the shift count, but the vector shift does not, so + // create a special ShiftCount node. + BasicType element_bt = _vloop_analyzer.types().velt_basic_type(p0); + juint mask = (p0->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1); + VTransformNode* shift_count = new (_vtransform.arena()) VTransformShiftCountNode(_vtransform, pack->size(), element_bt, mask, p0->Opcode()); + shift_count->set_req(1, same_input_vtn); + return shift_count; + } else { + // Replicate the scalar same_input to every vector element. + const Type* element_type = _vloop_analyzer.types().velt_type(p0); + if (index == 2 && VectorNode::is_scalar_rotate(p0) && element_type->isa_long()) { + // Scalar rotate has int rotation value, but the scalar rotate expects longs. + assert(same_input->bottom_type()->isa_int(), "scalar rotate expects int rotation"); + VTransformNode* conv = new (_vtransform.arena()) VTransformConvI2LNode(_vtransform); + conv->set_req(1, same_input_vtn); + same_input_vtn = conv; + } + VTransformNode* replicate = new (_vtransform.arena()) VTransformReplicateNode(_vtransform, pack->size(), element_type); + replicate->set_req(1, same_input_vtn); + return replicate; + } + } + + // The input is neither a pack not a same_input node. SuperWord::profitable does not allow + // any other case. In the future, we could insert a PackNode. +#ifdef ASSERT + tty->print_cr("\nSuperWordVTransformBuilder::get_or_make_vtnode_vector_input_at_index: index=%d", index); + pack->dump(); + assert(false, "Pack input was neither a pack nor a same_input node"); +#endif + ShouldNotReachHere(); +} + +VTransformNode* SuperWordVTransformBuilder::get_vtnode_or_wrap_as_input_scalar(Node* n) { + VTransformNode* vtn = get_vtnode_or_null(n); + if (vtn != nullptr) { return vtn; } + + assert(!_vloop.in_bb(n), "only nodes outside the loop can be input nodes to the loop"); + vtn = new (_vtransform.arena()) VTransformInputScalarNode(_vtransform, n); + map_node_to_vtnode(n, vtn); + return vtn; +} + +void SuperWordVTransformBuilder::set_req_with_vector(const Node_List* pack, VTransformNode* vtn, VectorSet& vtn_dependencies, int j) { + VTransformNode* req = get_or_make_vtnode_vector_input_at_index(pack, j); + vtn->set_req(j, req); + vtn_dependencies.set(req->_idx); +} + +void SuperWordVTransformBuilder::set_all_req_with_scalars(Node* n, VTransformNode* vtn, VectorSet& vtn_dependencies) { + assert(vtn->req() == n->req(), "scalars must have same number of reqs"); + for (uint j = 0; j < n->req(); j++) { + Node* def = n->in(j); + if (def == nullptr) { continue; } + set_req_with_scalar(n, vtn, vtn_dependencies, j); + } +} + +void SuperWordVTransformBuilder::set_all_req_with_vectors(const Node_List* pack, VTransformNode* vtn, VectorSet& vtn_dependencies) { + Node* p0 = pack->at(0); + assert(vtn->req() <= p0->req(), "must have at at most as many reqs"); + // Vectors have no ctrl, so ignore it. + for (uint j = 1; j < vtn->req(); j++) { + Node* def = p0->in(j); + if (def == nullptr) { continue; } + set_req_with_vector(pack, vtn, vtn_dependencies, j); + } +} + +void SuperWordVTransformBuilder::add_dependencies_of_node_to_vtnode(Node*n, VTransformNode* vtn, VectorSet& vtn_dependencies) { + for (VLoopDependencyGraph::PredsIterator preds(_vloop_analyzer.dependency_graph(), n); !preds.done(); preds.next()) { + Node* pred = preds.current(); + if (!_vloop.in_bb(pred)) { continue; } + + // Only add memory dependencies to memory nodes. All others are taken care of with the req. + if (n->is_Mem() && !pred->is_Mem()) { continue; } + + VTransformNode* dependency = get_vtnode(pred); + + // Reduction self-cycle? + if (vtn == dependency && _vloop_analyzer.reductions().is_marked_reduction(n)) { continue; } + + if (vtn_dependencies.test_set(dependency->_idx)) { continue; } + vtn->add_dependency(dependency); // Add every dependency only once per vtn. + } +} + diff --git a/src/hotspot/share/opto/superwordVTransformBuilder.hpp b/src/hotspot/share/opto/superwordVTransformBuilder.hpp new file mode 100644 index 0000000000000..847f870bef616 --- /dev/null +++ b/src/hotspot/share/opto/superwordVTransformBuilder.hpp @@ -0,0 +1,87 @@ +/* + * 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. + */ + +#include "opto/vtransform.hpp" +#include "opto/superword.hpp" + +#ifndef SHARE_OPTO_SUPERWORD_VTRANSFORM_BUILDER_HPP +#define SHARE_OPTO_SUPERWORD_VTRANSFORM_BUILDER_HPP + +// Facility class that builds a VTransform from a SuperWord PackSet. +class SuperWordVTransformBuilder : public StackObj { +private: + const VLoopAnalyzer& _vloop_analyzer; + const VLoop& _vloop; + const PackSet& _packset; + VTransform& _vtransform; + + ResourceHashtable _idx_to_vtnode; + +public: + SuperWordVTransformBuilder(const PackSet& packset, + VTransform& vtransform) : + _vloop_analyzer(vtransform.vloop_analyzer()), + _vloop(_vloop_analyzer.vloop()), + _packset(packset), + _vtransform(vtransform) + { + assert(!_vtransform.has_graph(), "constructor is passed an empty vtransform"); + build(); + assert(_vtransform.has_graph(), "vtransform must contain some vtnodes now"); + } + +private: + void build(); + void build_vector_vtnodes_for_packed_nodes(); + void build_scalar_vtnodes_for_non_packed_nodes(); + void build_inputs_for_vector_vtnodes(VectorSet& vtn_dependencies); + void build_inputs_for_scalar_vtnodes(VectorSet& vtn_dependencies); + + // Helper methods for building VTransform. + VTransformNode* get_vtnode_or_null(Node* n) const { + VTransformNode** ptr = _idx_to_vtnode.get(n->_idx); + return (ptr == nullptr) ? nullptr : *ptr; + } + + VTransformNode* get_vtnode(Node* n) const { + VTransformNode* vtn = get_vtnode_or_null(n); + assert(vtn != nullptr, "expect non-null vtnode"); + return vtn; + } + + void map_node_to_vtnode(Node* n, VTransformNode* vtn) { + assert(vtn != nullptr, "only set non-null vtnodes"); + _idx_to_vtnode.put_when_absent(n->_idx, vtn); + } + + VTransformVectorNode* make_vector_vtnode_for_pack(const Node_List* pack) const; + VTransformNode* get_or_make_vtnode_vector_input_at_index(const Node_List* pack, const int index); + VTransformNode* get_vtnode_or_wrap_as_input_scalar(Node* n); + void set_req_with_scalar(Node* n, VTransformNode* vtn, VectorSet& vtn_dependencies, const int index); + void set_req_with_vector(const Node_List* pack, VTransformNode* vtn, VectorSet& vtn_dependencies, const int index); + void set_all_req_with_scalars(Node* n, VTransformNode* vtn, VectorSet& vtn_dependencies); + void set_all_req_with_vectors(const Node_List* pack, VTransformNode* vtn, VectorSet& vtn_dependencies); + void add_dependencies_of_node_to_vtnode(Node* n, VTransformNode* vtn, VectorSet& vtn_dependencies); +}; + +#endif // SHARE_OPTO_SUPERWORD_VTRANSFORM_BUILDER_HPP diff --git a/src/hotspot/share/opto/traceAutoVectorizationTag.hpp b/src/hotspot/share/opto/traceAutoVectorizationTag.hpp index 3aae04c9453f5..038e04fe0c50b 100644 --- a/src/hotspot/share/opto/traceAutoVectorizationTag.hpp +++ b/src/hotspot/share/opto/traceAutoVectorizationTag.hpp @@ -43,6 +43,7 @@ flags(SW_INFO, "Trace SuperWord info (equivalent to TraceSuperWord)") \ flags(SW_VERBOSE, "Trace SuperWord verbose (all SW tags enabled)") \ flags(ALIGN_VECTOR, "Trace AlignVector") \ + flags(VTRANSFORM, "Trace VTransform Graph") \ flags(ALL, "Trace everything (very verbose)") #define table_entry(name, description) name, diff --git a/src/hotspot/share/opto/vectorization.cpp b/src/hotspot/share/opto/vectorization.cpp index 01b235e8b27e8..8d2d3868fe635 100644 --- a/src/hotspot/share/opto/vectorization.cpp +++ b/src/hotspot/share/opto/vectorization.cpp @@ -26,7 +26,6 @@ #include "opto/addnode.hpp" #include "opto/connode.hpp" #include "opto/convertnode.hpp" -#include "opto/matcher.hpp" #include "opto/mulnode.hpp" #include "opto/rootnode.hpp" #include "opto/vectorization.hpp" diff --git a/src/hotspot/share/opto/vectorization.hpp b/src/hotspot/share/opto/vectorization.hpp index c9f54594910ab..3984407c5654b 100644 --- a/src/hotspot/share/opto/vectorization.hpp +++ b/src/hotspot/share/opto/vectorization.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_OPTO_VECTORIZATION_HPP #define SHARE_OPTO_VECTORIZATION_HPP -#include "opto/node.hpp" +#include "opto/matcher.hpp" #include "opto/loopnode.hpp" #include "opto/traceAutoVectorizationTag.hpp" #include "utilities/pair.hpp" @@ -763,9 +763,9 @@ class VPointer : public ArenaObj { } } - bool overlap_possible_with_any_in(const Node_List* p) const { - for (uint k = 0; k < p->size(); k++) { - MemNode* mem = p->at(k)->as_Mem(); + bool overlap_possible_with_any_in(const GrowableArray& nodes) const { + for (int i = 0; i < nodes.length(); i++) { + MemNode* mem = nodes.at(i)->as_Mem(); VPointer p_mem(mem, _vloop); // Only if we know that we have Less or Greater can we // be sure that there can never be an overlap between @@ -1323,12 +1323,4 @@ class AlignmentSolver { #endif }; -struct VTransformBoolTest { - const BoolTest::mask _mask; - const bool _is_negated; - - VTransformBoolTest(const BoolTest::mask mask, bool is_negated) : - _mask(mask), _is_negated(is_negated) {} -}; - #endif // SHARE_OPTO_VECTORIZATION_HPP diff --git a/src/hotspot/share/opto/vtransform.cpp b/src/hotspot/share/opto/vtransform.cpp new file mode 100644 index 0000000000000..e40157caa362b --- /dev/null +++ b/src/hotspot/share/opto/vtransform.cpp @@ -0,0 +1,450 @@ +/* + * 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. + */ + +#include "precompiled.hpp" +#include "opto/vtransform.hpp" +#include "opto/vectornode.hpp" +#include "opto/convertnode.hpp" + +void VTransformGraph::add_vtnode(VTransformNode* vtnode) { + assert(vtnode->_idx == _vtnodes.length(), "position must match idx"); + _vtnodes.push(vtnode); +} + +// Compute a linearization of the graph. We do this with a reverse-post-order of a DFS. +// This only works if the graph is a directed acyclic graph (DAG). The C2 graph, and +// the VLoopDependencyGraph are both DAGs, but after introduction of vectors/packs, the +// graph has additional constraints which can introduce cycles. Example: +// +// +--------+ +// A -> X | v +// Pack [A,B] and [X,Y] [A,B] [X,Y] +// Y -> B ^ | +// +--------+ +// +// We return "true" IFF we find no cycle, i.e. if the linearization succeeds. +bool VTransformGraph::schedule() { + assert(!is_scheduled(), "not yet scheduled"); + +#ifndef PRODUCT + if (_trace._verbose) { + print_vtnodes(); + } +#endif + + ResourceMark rm; + GrowableArray stack; + VectorSet pre_visited; + VectorSet post_visited; + + collect_nodes_without_req_or_dependency(stack); + + // We create a reverse-post-visit order. This gives us a linearization, if there are + // no cycles. Then, we simply reverse the order, and we have a schedule. + int rpo_idx = _vtnodes.length() - 1; + while (!stack.is_empty()) { + VTransformNode* vtn = stack.top(); + if (!pre_visited.test_set(vtn->_idx)) { + // Forward arc in graph (pre-visit). + } else if (!post_visited.test(vtn->_idx)) { + // Forward arc in graph. Check if all uses were already visited: + // Yes -> post-visit. + // No -> we are mid-visit. + bool all_uses_already_visited = true; + + for (int i = 0; i < vtn->outs(); i++) { + VTransformNode* use = vtn->out(i); + if (post_visited.test(use->_idx)) { continue; } + if (pre_visited.test(use->_idx)) { + // Cycle detected! + // The nodes that are pre_visited but not yet post_visited form a path from + // the "root" to the current vtn. Now, we are looking at an edge (vtn, use), + // and discover that use is also pre_visited but not post_visited. Thus, use + // lies on that path from "root" to vtn, and the edge (vtn, use) closes a + // cycle. + NOT_PRODUCT(if (_trace._rejections) { trace_schedule_cycle(stack, pre_visited, post_visited); } ) + return false; + } + stack.push(use); + all_uses_already_visited = false; + } + + if (all_uses_already_visited) { + stack.pop(); + post_visited.set(vtn->_idx); // post-visit + _schedule.at_put_grow(rpo_idx--, vtn); // assign rpo_idx + } + } else { + stack.pop(); // Already post-visited. Ignore secondary edge. + } + } + +#ifndef PRODUCT + if (_trace._verbose) { + print_schedule(); + } +#endif + + assert(rpo_idx == -1, "used up all rpo_idx, rpo_idx=%d", rpo_idx); + return true; +} + +// Push all "root" nodes, i.e. those that have no inputs (req or dependency): +void VTransformGraph::collect_nodes_without_req_or_dependency(GrowableArray& stack) const { + for (int i = 0; i < _vtnodes.length(); i++) { + VTransformNode* vtn = _vtnodes.at(i); + if (!vtn->has_req_or_dependency()) { + stack.push(vtn); + } + } +} + +#ifndef PRODUCT +void VTransformGraph::trace_schedule_cycle(const GrowableArray& stack, + const VectorSet& pre_visited, + const VectorSet& post_visited) const { + tty->print_cr("\nVTransform::schedule found a cycle on path (P), vectorization attempt fails."); + for (int j = 0; j < stack.length(); j++) { + VTransformNode* n = stack.at(j); + bool on_path = pre_visited.test(n->_idx) && !post_visited.test(n->_idx); + tty->print(" %s ", on_path ? "P" : "_"); + n->print(); + } +} + +void VTransformApplyResult::trace(VTransformNode* vtnode) const { + tty->print(" apply: "); + vtnode->print(); + tty->print(" -> "); + if (_node == nullptr) { + tty->print_cr("nullptr"); + } else { + _node->dump(); + } +} +#endif + +Node* VTransformNode::find_transformed_input(int i, const GrowableArray& vnode_idx_to_transformed_node) const { + Node* n = vnode_idx_to_transformed_node.at(in(i)->_idx); + assert(n != nullptr, "must find input IR node"); + return n; +} + +VTransformApplyResult VTransformScalarNode::apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const { + // This was just wrapped. Now we simply unwap without touching the inputs. + return VTransformApplyResult::make_scalar(_node); +} + +VTransformApplyResult VTransformReplicateNode::apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const { + Node* val = find_transformed_input(1, vnode_idx_to_transformed_node); + VectorNode* vn = VectorNode::scalar2vector(val, _vlen, _element_type); + register_new_node_from_vectorization(vloop_analyzer, vn, val); + return VTransformApplyResult::make_vector(vn, _vlen, vn->length_in_bytes()); +} + +VTransformApplyResult VTransformConvI2LNode::apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const { + Node* val = find_transformed_input(1, vnode_idx_to_transformed_node); + Node* n = new ConvI2LNode(val); + register_new_node_from_vectorization(vloop_analyzer, n, val); + return VTransformApplyResult::make_scalar(n); +} + +VTransformApplyResult VTransformShiftCountNode::apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const { + PhaseIdealLoop* phase = vloop_analyzer.vloop().phase(); + Node* shift_count_in = find_transformed_input(1, vnode_idx_to_transformed_node); + assert(shift_count_in->bottom_type()->isa_int(), "int type only for shift count"); + // The shift_count_in would be automatically truncated to the lowest _mask + // bits in a scalar shift operation. But vector shift does not truncate, so + // we must apply the mask now. + Node* shift_count_masked = new AndINode(shift_count_in, phase->igvn().intcon(_mask)); + register_new_node_from_vectorization(vloop_analyzer, shift_count_masked, shift_count_in); + // Now that masked value is "boadcast" (some platforms only set the lowest element). + VectorNode* vn = VectorNode::shift_count(_shift_opcode, shift_count_masked, _vlen, _element_bt); + register_new_node_from_vectorization(vloop_analyzer, vn, shift_count_in); + return VTransformApplyResult::make_vector(vn, _vlen, vn->length_in_bytes()); +} + + +VTransformApplyResult VTransformPopulateIndexNode::apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const { + PhaseIdealLoop* phase = vloop_analyzer.vloop().phase(); + Node* val = find_transformed_input(1, vnode_idx_to_transformed_node); + assert(val->is_Phi(), "expected to be iv"); + assert(VectorNode::is_populate_index_supported(_element_bt), "should support"); + const TypeVect* vt = TypeVect::make(_element_bt, _vlen); + VectorNode* vn = new PopulateIndexNode(val, phase->igvn().intcon(1), vt); + register_new_node_from_vectorization(vloop_analyzer, vn, val); + return VTransformApplyResult::make_vector(vn, _vlen, vn->length_in_bytes()); +} + +VTransformApplyResult VTransformElementWiseVectorNode::apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const { + Node* first = nodes().at(0); + uint vlen = nodes().length(); + int opc = first->Opcode(); + BasicType bt = vloop_analyzer.types().velt_basic_type(first); + + if (first->is_Cmp()) { + // Cmp + Bool -> VectorMaskCmp + // Handled by Bool / VTransformBoolVectorNode, so we do not generate any nodes here. + return VTransformApplyResult::make_empty(); + } + + assert(2 <= req() && req() <= 4, "Must have 1-3 inputs"); + VectorNode* vn = nullptr; + Node* in1 = find_transformed_input(1, vnode_idx_to_transformed_node); + Node* in2 = (req() >= 3) ? find_transformed_input(2, vnode_idx_to_transformed_node) : nullptr; + Node* in3 = (req() >= 4) ? find_transformed_input(3, vnode_idx_to_transformed_node) : nullptr; + + if (first->is_CMove()) { + assert(req() == 4, "three inputs expected: mask, blend1, blend2"); + vn = new VectorBlendNode(/* blend1 */ in2, /* blend2 */ in3, /* mask */ in1); + } else if (VectorNode::is_convert_opcode(opc)) { + assert(first->req() == 2 && req() == 2, "only one input expected"); + int vopc = VectorCastNode::opcode(opc, in1->bottom_type()->is_vect()->element_basic_type()); + vn = VectorCastNode::make(vopc, in1, bt, vlen); + } else if (VectorNode::can_use_RShiftI_instead_of_URShiftI(first, bt)) { + opc = Op_RShiftI; + vn = VectorNode::make(opc, in1, in2, vlen, bt); + } else if (VectorNode::is_scalar_op_that_returns_int_but_vector_op_returns_long(opc)) { + // The scalar operation was a long -> int operation. + // However, the vector operation is long -> long. + VectorNode* long_vn = VectorNode::make(opc, in1, nullptr, vlen, T_LONG); + register_new_node_from_vectorization(vloop_analyzer, long_vn, first); + // Cast long -> int, to mimic the scalar long -> int operation. + vn = VectorCastNode::make(Op_VectorCastL2X, long_vn, T_INT, vlen); + } else if (req() == 3 || + VectorNode::is_scalar_unary_op_with_equal_input_and_output_types(opc)) { + assert(!VectorNode::is_roundopD(first) || in2->is_Con(), "rounding mode must be constant"); + vn = VectorNode::make(opc, in1, in2, vlen, bt); // unary and binary + } else { + assert(req() == 4, "three inputs expected"); + assert(opc == Op_FmaD || + opc == Op_FmaF || + opc == Op_SignumF || + opc == Op_SignumD, + "element wise operation must be from this list"); + vn = VectorNode::make(opc, in1, in2, in3, vlen, bt); // ternary + } + + register_new_node_from_vectorization_and_replace_scalar_nodes(vloop_analyzer, vn); + return VTransformApplyResult::make_vector(vn, vlen, vn->length_in_bytes()); +} + +VTransformApplyResult VTransformBoolVectorNode::apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const { + BoolNode* first = nodes().at(0)->as_Bool(); + uint vlen = nodes().length(); + BasicType bt = vloop_analyzer.types().velt_basic_type(first); + + // Cmp + Bool -> VectorMaskCmp + VTransformElementWiseVectorNode* vtn_cmp = in(1)->isa_ElementWiseVector(); + assert(vtn_cmp != nullptr && vtn_cmp->nodes().at(0)->is_Cmp(), + "bool vtn expects cmp vtn as input"); + + Node* cmp_in1 = vtn_cmp->find_transformed_input(1, vnode_idx_to_transformed_node); + Node* cmp_in2 = vtn_cmp->find_transformed_input(2, vnode_idx_to_transformed_node); + BoolTest::mask mask = test()._mask; + + PhaseIdealLoop* phase = vloop_analyzer.vloop().phase(); + ConINode* mask_node = phase->igvn().intcon((int)mask); + const TypeVect* vt = TypeVect::make(bt, vlen); + VectorNode* vn = new VectorMaskCmpNode(mask, cmp_in1, cmp_in2, mask_node, vt); + register_new_node_from_vectorization_and_replace_scalar_nodes(vloop_analyzer, vn); + return VTransformApplyResult::make_vector(vn, vlen, vn->vect_type()->length_in_bytes()); +} + +VTransformApplyResult VTransformReductionVectorNode::apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const { + Node* first = nodes().at(0); + uint vlen = nodes().length(); + int opc = first->Opcode(); + BasicType bt = first->bottom_type()->basic_type(); + + Node* init = find_transformed_input(1, vnode_idx_to_transformed_node); + Node* vec = find_transformed_input(2, vnode_idx_to_transformed_node); + + ReductionNode* vn = ReductionNode::make(opc, nullptr, init, vec, bt); + register_new_node_from_vectorization_and_replace_scalar_nodes(vloop_analyzer, vn); + return VTransformApplyResult::make_vector(vn, vlen, vn->vect_type()->length_in_bytes()); +} + +VTransformApplyResult VTransformLoadVectorNode::apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const { + LoadNode* first = nodes().at(0)->as_Load(); + uint vlen = nodes().length(); + Node* ctrl = first->in(MemNode::Control); + Node* mem = first->in(MemNode::Memory); + Node* adr = first->in(MemNode::Address); + int opc = first->Opcode(); + const TypePtr* adr_type = first->adr_type(); + BasicType bt = vloop_analyzer.types().velt_basic_type(first); + + // Set the memory dependency of the LoadVector as early as possible. + // Walk up the memory chain, and ignore any StoreVector that provably + // does not have any memory dependency. + while (mem->is_StoreVector()) { + VPointer p_store(mem->as_Mem(), vloop_analyzer.vloop()); + if (p_store.overlap_possible_with_any_in(nodes())) { + break; + } else { + mem = mem->in(MemNode::Memory); + } + } + + LoadVectorNode* vn = LoadVectorNode::make(opc, ctrl, mem, adr, adr_type, vlen, bt, + control_dependency()); + DEBUG_ONLY( if (VerifyAlignVector) { vn->set_must_verify_alignment(); } ) + register_new_node_from_vectorization_and_replace_scalar_nodes(vloop_analyzer, vn); + return VTransformApplyResult::make_vector(vn, vlen, vn->memory_size()); +} + +VTransformApplyResult VTransformStoreVectorNode::apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const { + StoreNode* first = nodes().at(0)->as_Store(); + uint vlen = nodes().length(); + Node* ctrl = first->in(MemNode::Control); + Node* mem = first->in(MemNode::Memory); + Node* adr = first->in(MemNode::Address); + int opc = first->Opcode(); + const TypePtr* adr_type = first->adr_type(); + + Node* value = find_transformed_input(MemNode::ValueIn, vnode_idx_to_transformed_node); + StoreVectorNode* vn = StoreVectorNode::make(opc, ctrl, mem, adr, adr_type, value, vlen); + DEBUG_ONLY( if (VerifyAlignVector) { vn->set_must_verify_alignment(); } ) + register_new_node_from_vectorization_and_replace_scalar_nodes(vloop_analyzer, vn); + return VTransformApplyResult::make_vector(vn, vlen, vn->memory_size()); +} + +void VTransformVectorNode::register_new_node_from_vectorization_and_replace_scalar_nodes(const VLoopAnalyzer& vloop_analyzer, Node* vn) const { + PhaseIdealLoop* phase = vloop_analyzer.vloop().phase(); + Node* first = nodes().at(0); + + register_new_node_from_vectorization(vloop_analyzer, vn, first); + + for (int i = 0; i < _nodes.length(); i++) { + Node* n = _nodes.at(i); + phase->igvn().replace_node(n, vn); + } +} + +void VTransformNode::register_new_node_from_vectorization(const VLoopAnalyzer& vloop_analyzer, Node* vn, Node* old_node) const { + PhaseIdealLoop* phase = vloop_analyzer.vloop().phase(); + phase->register_new_node_with_ctrl_of(vn, old_node); + phase->igvn()._worklist.push(vn); + VectorNode::trace_new_vector(vn, "AutoVectorization"); +} + +#ifndef PRODUCT +void VTransformGraph::print_vtnodes() const { + tty->print_cr("\nVTransformGraph::print_vtnodes:"); + for (int i = 0; i < _vtnodes.length(); i++) { + _vtnodes.at(i)->print(); + } +} + +void VTransformGraph::print_schedule() const { + tty->print_cr("\nVTransformGraph::print_schedule:"); + for (int i = 0; i < _schedule.length(); i++) { + tty->print(" %3d: ", i); + VTransformNode* vtn = _schedule.at(i); + if (vtn == nullptr) { + tty->print_cr("nullptr"); + } else { + vtn->print(); + } + } +} + +void VTransformGraph::print_memops_schedule() const { + tty->print_cr("\nVTransformGraph::print_memops_schedule:"); + int i = 0; + for_each_memop_in_schedule([&] (MemNode* mem) { + tty->print(" %3d: ", i++); + mem->dump(); + }); +} + +void VTransformNode::print() const { + tty->print("%3d %s (", _idx, name()); + for (uint i = 0; i < _req; i++) { + print_node_idx(_in.at(i)); + } + if ((uint)_in.length() > _req) { + tty->print(" |"); + for (int i = _req; i < _in.length(); i++) { + print_node_idx(_in.at(i)); + } + } + tty->print(") ["); + for (int i = 0; i < _out.length(); i++) { + print_node_idx(_out.at(i)); + } + tty->print("] "); + print_spec(); + tty->cr(); +} + +void VTransformNode::print_node_idx(const VTransformNode* vtn) { + if (vtn == nullptr) { + tty->print(" _"); + } else { + tty->print(" %d", vtn->_idx); + } +} + +void VTransformScalarNode::print_spec() const { + tty->print("node[%d %s]", _node->_idx, _node->Name()); +} + +void VTransformReplicateNode::print_spec() const { + tty->print("vlen=%d element_type=", _vlen); + _element_type->dump(); +} + +void VTransformShiftCountNode::print_spec() const { + tty->print("vlen=%d element_bt=%s mask=%d shift_opcode=%s", + _vlen, type2name(_element_bt), _mask, + NodeClassNames[_shift_opcode]); +} + +void VTransformPopulateIndexNode::print_spec() const { + tty->print("vlen=%d element_bt=%s", _vlen, type2name(_element_bt)); +} + +void VTransformVectorNode::print_spec() const { + tty->print("%d-pack[", _nodes.length()); + for (int i = 0; i < _nodes.length(); i++) { + Node* n = _nodes.at(i); + if (i > 0) { + tty->print(", "); + } + tty->print("%d %s", n->_idx, n->Name()); + } + tty->print("]"); +} +#endif diff --git a/src/hotspot/share/opto/vtransform.hpp b/src/hotspot/share/opto/vtransform.hpp new file mode 100644 index 0000000000000..071674533a798 --- /dev/null +++ b/src/hotspot/share/opto/vtransform.hpp @@ -0,0 +1,515 @@ +/* + * 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. + */ + +#ifndef SHARE_OPTO_VTRANSFORM_HPP +#define SHARE_OPTO_VTRANSFORM_HPP + +#include "opto/node.hpp" +#include "opto/vectorization.hpp" + +// VTransform: +// - Models the transformation of the scalar loop to vectorized loop: +// It is a "C2 subgraph" -> "C2 subgraph" mapping. +// - The VTransform contains a graph (VTransformGraph), which consists of +// many vtnodes (VTransformNode). +// - Each vtnode models a part of the transformation, and is supposed +// to represent the output C2 nodes after the vectorization as closely +// as possible. +// +// This is the life-cycle of a VTransform: +// - Construction: +// - From SuperWord, with the SuperWordVTransformBuilder. +// +// - Future Plans: optimize, if-conversion, etc. +// +// - Schedule: +// - Compute linearization of the VTransformGraph, into an order that respects +// all edges in the graph (bailout if cycle detected). +// +// - Apply: +// - Changes to the C2 IR are only made once the "apply" method is called. +// - Each vtnode generates its corresponding scalar and vector C2 nodes, +// possibly replacing old scalar C2 nodes. +// +// Future Plans with VTransform: +// - Cost model: estimate if vectorization is profitable. +// - Optimizations: moving unordered reductions out of the loop, whih decreases cost. +// - Pack/Unpack/Shuffle: introduce additional nodes not present in the scalar loop. +// This is difficult to do with the SuperWord packset approach. +// - If-conversion: convert predicated nodes into CFG. + +typedef int VTransformNodeIDX; +class VTransformNode; +class VTransformScalarNode; +class VTransformInputScalarNode; +class VTransformVectorNode; +class VTransformElementWiseVectorNode; +class VTransformBoolVectorNode; +class VTransformReductionVectorNode; + +// Result from VTransformNode::apply +class VTransformApplyResult { +private: + Node* const _node; + const uint _vector_length; // number of elements + const uint _vector_width; // total width in bytes + + VTransformApplyResult(Node* n, uint vector_length, uint vector_width) : + _node(n), + _vector_length(vector_length), + _vector_width(vector_width) {} + +public: + static VTransformApplyResult make_scalar(Node* n) { + return VTransformApplyResult(n, 0, 0); + } + + static VTransformApplyResult make_vector(Node* n, uint vector_length, uint vector_width) { + assert(vector_length > 0 && vector_width > 0, "must have nonzero size"); + return VTransformApplyResult(n, vector_length, vector_width); + } + + static VTransformApplyResult make_empty() { + return VTransformApplyResult(nullptr, 0, 0); + } + + Node* node() const { return _node; } + uint vector_length() const { return _vector_length; } + uint vector_width() const { return _vector_width; } + NOT_PRODUCT( void trace(VTransformNode* vtnode) const; ) +}; + +#ifndef PRODUCT +// Convenience class for tracing flags. +class VTransformTrace { +public: + const bool _verbose; + const bool _rejections; + const bool _align_vector; + const bool _info; + + VTransformTrace(const VTrace& vtrace, + const bool is_trace_rejections, + const bool is_trace_align_vector, + const bool is_trace_info) : + _verbose (vtrace.is_trace(TraceAutoVectorizationTag::ALL)), + _rejections (_verbose | is_trace_vtransform(vtrace) | is_trace_rejections), + _align_vector(_verbose | is_trace_vtransform(vtrace) | is_trace_align_vector), + _info (_verbose | is_trace_vtransform(vtrace) | is_trace_info) {} + + static bool is_trace_vtransform(const VTrace& vtrace) { + return vtrace.is_trace(TraceAutoVectorizationTag::VTRANSFORM); + } +}; +#endif + +// VTransformGraph: component of VTransform +// See description at top of this file. +class VTransformGraph : public StackObj { +private: + const VLoopAnalyzer& _vloop_analyzer; + const VLoop& _vloop; + + NOT_PRODUCT(const VTransformTrace _trace;) + + VTransformNodeIDX _next_idx; + GrowableArray _vtnodes; + + // Schedule (linearization) of the graph. We use this to reorder the memory graph + // before inserting vector operations. + GrowableArray _schedule; + +public: + VTransformGraph(const VLoopAnalyzer& vloop_analyzer, + Arena& arena + NOT_PRODUCT( COMMA const VTransformTrace trace)) : + _vloop_analyzer(vloop_analyzer), + _vloop(vloop_analyzer.vloop()), + NOT_PRODUCT(_trace(trace) COMMA) + _next_idx(0), + _vtnodes(&arena, _vloop.estimated_body_length(), 0, nullptr), + _schedule(&arena, _vloop.estimated_body_length(), 0, nullptr) {} + + VTransformNodeIDX new_idx() { return _next_idx++; } + void add_vtnode(VTransformNode* vtnode); + DEBUG_ONLY( bool is_empty() const { return _vtnodes.is_empty(); } ) + DEBUG_ONLY( bool is_scheduled() const { return _schedule.is_nonempty(); } ) + const GrowableArray& vtnodes() const { return _vtnodes; } + + bool schedule(); + void apply_memops_reordering_with_schedule() const; + void apply_vectorization_for_each_vtnode(uint& max_vector_length, uint& max_vector_width) const; + +private: + // VLoop accessors + PhaseIdealLoop* phase() const { return _vloop.phase(); } + PhaseIterGVN& igvn() const { return _vloop.phase()->igvn(); } + bool in_bb(const Node* n) const { return _vloop.in_bb(n); } + + void collect_nodes_without_req_or_dependency(GrowableArray& stack) const; + + template + void for_each_memop_in_schedule(Callback callback) const; + +#ifndef PRODUCT + void print_vtnodes() const; + void print_schedule() const; + void print_memops_schedule() const; + void trace_schedule_cycle(const GrowableArray& stack, + const VectorSet& pre_visited, + const VectorSet& post_visited) const; +#endif +}; + +// VTransform: models the transformation of the scalar loop to vectorized loop. +// It is a "C2 subgraph" to "C2 subgraph" mapping. +// See description at top of this file. +class VTransform : public StackObj { +private: + const VLoopAnalyzer& _vloop_analyzer; + const VLoop& _vloop; + + NOT_PRODUCT(const VTransformTrace _trace;) + + // Everything in the vtransform is allocated from this arena, including all vtnodes. + Arena _arena; + + VTransformGraph _graph; + + // Memory reference, and the alignment width (aw) for which we align the main-loop, + // by adjusting the pre-loop limit. + MemNode const* _mem_ref_for_main_loop_alignment; + int _aw_for_main_loop_alignment; + +public: + VTransform(const VLoopAnalyzer& vloop_analyzer, + MemNode const* mem_ref_for_main_loop_alignment, + int aw_for_main_loop_alignment + NOT_PRODUCT( COMMA const VTransformTrace trace) + ) : + _vloop_analyzer(vloop_analyzer), + _vloop(vloop_analyzer.vloop()), + NOT_PRODUCT(_trace(trace) COMMA) + _arena(mtCompiler), + _graph(_vloop_analyzer, _arena NOT_PRODUCT(COMMA _trace)), + _mem_ref_for_main_loop_alignment(mem_ref_for_main_loop_alignment), + _aw_for_main_loop_alignment(aw_for_main_loop_alignment) {} + + const VLoopAnalyzer& vloop_analyzer() const { return _vloop_analyzer; } + Arena* arena() { return &_arena; } + DEBUG_ONLY( bool has_graph() const { return !_graph.is_empty(); } ) + VTransformGraph& graph() { return _graph; } + + bool schedule() { return _graph.schedule(); } + void apply(); + +private: + // VLoop accessors + PhaseIdealLoop* phase() const { return _vloop.phase(); } + PhaseIterGVN& igvn() const { return _vloop.phase()->igvn(); } + IdealLoopTree* lpt() const { return _vloop.lpt(); } + CountedLoopNode* cl() const { return _vloop.cl(); } + int iv_stride() const { return cl()->stride_con(); } + + // VLoopVPointers accessors + const VPointer& vpointer(const MemNode* mem) const { + return _vloop_analyzer.vpointers().vpointer(mem); + } + + // Ensure that the main loop vectors are aligned by adjusting the pre loop limit. + void determine_mem_ref_and_aw_for_main_loop_alignment(); + void adjust_pre_loop_limit_to_align_main_loop_vectors(); + + void apply_vectorization() const; +}; + +// The vtnodes (VTransformNode) resemble the C2 IR Nodes, and model a part of the +// VTransform. Many such vtnodes make up the VTransformGraph. The vtnodes represent +// the resulting scalar and vector nodes as closely as possible. +// See description at top of this file. +class VTransformNode : public ArenaObj { +public: + const VTransformNodeIDX _idx; + +private: + // _in is split into required inputs (_req), and additional dependencies. + const uint _req; + GrowableArray _in; + GrowableArray _out; + +public: + VTransformNode(VTransform& vtransform, const uint req) : + _idx(vtransform.graph().new_idx()), + _req(req), + _in(vtransform.arena(), req, req, nullptr), + _out(vtransform.arena(), 4, 0, nullptr) + { + vtransform.graph().add_vtnode(this); + } + + void set_req(uint i, VTransformNode* n) { + assert(i < _req, "must be a req"); + assert(_in.at(i) == nullptr && n != nullptr, "only set once"); + _in.at_put(i, n); + n->add_out(this); + } + + void swap_req(uint i, uint j) { + assert(i < _req, "must be a req"); + assert(j < _req, "must be a req"); + VTransformNode* tmp = _in.at(i); + _in.at_put(i, _in.at(j)); + _in.at_put(j, tmp); + } + + void add_dependency(VTransformNode* n) { + assert(n != nullptr, "no need to add nullptr"); + _in.push(n); + n->add_out(this); + } + + void add_out(VTransformNode* n) { + _out.push(n); + } + + uint req() const { return _req; } + VTransformNode* in(int i) const { return _in.at(i); } + int outs() const { return _out.length(); } + VTransformNode* out(int i) const { return _out.at(i); } + + bool has_req_or_dependency() const { + for (int i = 0; i < _in.length(); i++) { + if (_in.at(i) != nullptr) { return true; } + } + return false; + } + + virtual VTransformScalarNode* isa_Scalar() { return nullptr; } + virtual VTransformInputScalarNode* isa_InputScalar() { return nullptr; } + virtual VTransformVectorNode* isa_Vector() { return nullptr; } + virtual VTransformElementWiseVectorNode* isa_ElementWiseVector() { return nullptr; } + virtual VTransformBoolVectorNode* isa_BoolVector() { return nullptr; } + virtual VTransformReductionVectorNode* isa_ReductionVector() { return nullptr; } + + virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const = 0; + + Node* find_transformed_input(int i, const GrowableArray& vnode_idx_to_transformed_node) const; + + void register_new_node_from_vectorization(const VLoopAnalyzer& vloop_analyzer, Node* vn, Node* old_node) const; + + NOT_PRODUCT(virtual const char* name() const = 0;) + NOT_PRODUCT(void print() const;) + NOT_PRODUCT(virtual void print_spec() const {};) + NOT_PRODUCT(static void print_node_idx(const VTransformNode* vtn);) +}; + +// Identity transform for scalar nodes. +class VTransformScalarNode : public VTransformNode { +private: + Node* _node; +public: + VTransformScalarNode(VTransform& vtransform, Node* n) : + VTransformNode(vtransform, n->req()), _node(n) {} + Node* node() const { return _node; } + virtual VTransformScalarNode* isa_Scalar() override { return this; } + virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const override; + NOT_PRODUCT(virtual const char* name() const override { return "Scalar"; };) + NOT_PRODUCT(virtual void print_spec() const override;) +}; + +// Wrapper node for nodes outside the loop that are inputs to nodes in the loop. +// Since we want the loop-internal nodes to be able to reference all inputs as vtnodes, +// we must wrap the inputs that are outside the loop into special vtnodes, too. +class VTransformInputScalarNode : public VTransformScalarNode { +public: + VTransformInputScalarNode(VTransform& vtransform, Node* n) : + VTransformScalarNode(vtransform, n) {} + virtual VTransformInputScalarNode* isa_InputScalar() override { return this; } + NOT_PRODUCT(virtual const char* name() const override { return "InputScalar"; };) +}; + +// Transform produces a ReplicateNode, replicating the input to all vector lanes. +class VTransformReplicateNode : public VTransformNode { +private: + int _vlen; + const Type* _element_type; +public: + VTransformReplicateNode(VTransform& vtransform, int vlen, const Type* element_type) : + VTransformNode(vtransform, 2), _vlen(vlen), _element_type(element_type) {} + virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const override; + NOT_PRODUCT(virtual const char* name() const override { return "Replicate"; };) + NOT_PRODUCT(virtual void print_spec() const override;) +}; + +// Transform introduces a scalar ConvI2LNode that was not previously in the C2 graph. +class VTransformConvI2LNode : public VTransformNode { +public: + VTransformConvI2LNode(VTransform& vtransform) : VTransformNode(vtransform, 2) {} + virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const override; + NOT_PRODUCT(virtual const char* name() const override { return "ConvI2L"; };) +}; + +// Transform introduces a shift-count node that truncates the shift count for a vector shift. +class VTransformShiftCountNode : public VTransformNode { +private: + int _vlen; + const BasicType _element_bt; + juint _mask; + int _shift_opcode; +public: + VTransformShiftCountNode(VTransform& vtransform, int vlen, BasicType element_bt, juint mask, int shift_opcode) : + VTransformNode(vtransform, 2), _vlen(vlen), _element_bt(element_bt), _mask(mask), _shift_opcode(shift_opcode) {} + virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const override; + NOT_PRODUCT(virtual const char* name() const override { return "ShiftCount"; };) + NOT_PRODUCT(virtual void print_spec() const override;) +}; + +// Transform introduces a PopulateIndex node: [phi, phi+1, phi+2, phi+3, ...]. +class VTransformPopulateIndexNode : public VTransformNode { +private: + int _vlen; + const BasicType _element_bt; +public: + VTransformPopulateIndexNode(VTransform& vtransform, int vlen, const BasicType element_bt) : + VTransformNode(vtransform, 2), _vlen(vlen), _element_bt(element_bt) {} + virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const override; + NOT_PRODUCT(virtual const char* name() const override { return "PopulateIndex"; };) + NOT_PRODUCT(virtual void print_spec() const override;) +}; + +// Base class for all vector vtnodes. +class VTransformVectorNode : public VTransformNode { +private: + GrowableArray _nodes; +public: + VTransformVectorNode(VTransform& vtransform, const uint req, const uint number_of_nodes) : + VTransformNode(vtransform, req), _nodes(vtransform.arena(), number_of_nodes, number_of_nodes, nullptr) {} + + void set_nodes(const Node_List* pack) { + for (uint k = 0; k < pack->size(); k++) { + _nodes.at_put(k, pack->at(k)); + } + } + + const GrowableArray& nodes() const { return _nodes; } + virtual VTransformVectorNode* isa_Vector() override { return this; } + void register_new_node_from_vectorization_and_replace_scalar_nodes(const VLoopAnalyzer& vloop_analyzer, Node* vn) const; + NOT_PRODUCT(virtual void print_spec() const override;) +}; + +// Catch all for all element-wise vector operations. +class VTransformElementWiseVectorNode : public VTransformVectorNode { +public: + VTransformElementWiseVectorNode(VTransform& vtransform, uint req, uint number_of_nodes) : + VTransformVectorNode(vtransform, req, number_of_nodes) {} + virtual VTransformElementWiseVectorNode* isa_ElementWiseVector() override { return this; } + virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const override; + NOT_PRODUCT(virtual const char* name() const override { return "ElementWiseVector"; };) +}; + +struct VTransformBoolTest { + const BoolTest::mask _mask; + const bool _is_negated; + + VTransformBoolTest(const BoolTest::mask mask, bool is_negated) : + _mask(mask), _is_negated(is_negated) {} +}; + +class VTransformBoolVectorNode : public VTransformElementWiseVectorNode { +private: + const VTransformBoolTest _test; +public: + VTransformBoolVectorNode(VTransform& vtransform, uint number_of_nodes, VTransformBoolTest test) : + VTransformElementWiseVectorNode(vtransform, 2, number_of_nodes), _test(test) {} + VTransformBoolTest test() const { return _test; } + virtual VTransformBoolVectorNode* isa_BoolVector() override { return this; } + virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const override; + NOT_PRODUCT(virtual const char* name() const override { return "BoolVector"; };) +}; + +class VTransformReductionVectorNode : public VTransformVectorNode { +public: + // req = 3 -> [ctrl, scalar init, vector] + VTransformReductionVectorNode(VTransform& vtransform, uint number_of_nodes) : + VTransformVectorNode(vtransform, 3, number_of_nodes) {} + virtual VTransformReductionVectorNode* isa_ReductionVector() override { return this; } + virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const override; + NOT_PRODUCT(virtual const char* name() const override { return "ReductionVector"; };) +}; + +class VTransformLoadVectorNode : public VTransformVectorNode { +public: + // req = 3 -> [ctrl, mem, adr] + VTransformLoadVectorNode(VTransform& vtransform, uint number_of_nodes) : + VTransformVectorNode(vtransform, 3, number_of_nodes) {} + LoadNode::ControlDependency control_dependency() const; + virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const override; + NOT_PRODUCT(virtual const char* name() const override { return "LoadVector"; };) +}; + +class VTransformStoreVectorNode : public VTransformVectorNode { +public: + // req = 4 -> [ctrl, mem, adr, val] + VTransformStoreVectorNode(VTransform& vtransform, uint number_of_nodes) : + VTransformVectorNode(vtransform, 4, number_of_nodes) {} + virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, + const GrowableArray& vnode_idx_to_transformed_node) const override; + NOT_PRODUCT(virtual const char* name() const override { return "StoreVector"; };) +}; + +// Invoke callback on all memops, in the order of the schedule. +template +void VTransformGraph::for_each_memop_in_schedule(Callback callback) const { + assert(_schedule.length() == _vtnodes.length(), "schedule was computed"); + + for (int i = 0; i < _schedule.length(); i++) { + VTransformNode* vtn = _schedule.at(i); + + // We can ignore input nodes, they are outside the loop. + if (vtn->isa_InputScalar() != nullptr) { continue; } + + VTransformScalarNode* scalar = vtn->isa_Scalar(); + if (scalar != nullptr && scalar->node()->is_Mem()) { + callback(scalar->node()->as_Mem()); + } + + VTransformVectorNode* vector = vtn->isa_Vector(); + if (vector != nullptr && vector->nodes().at(0)->is_Mem()) { + for (int j = 0; j < vector->nodes().length(); j++) { + callback(vector->nodes().at(j)->as_Mem()); + } + } + } +} + +#endif // SHARE_OPTO_VTRANSFORM_HPP From 55fd1ed228ea3c42aaf92579e5dcb818fe14351d Mon Sep 17 00:00:00 2001 From: Jatin Bhateja Date: Mon, 8 Jul 2024 06:42:46 +0000 Subject: [PATCH 008/401] 8333890: Fatal error in auto-vectorizer with float16 kernel. Reviewed-by: kvn --- src/hotspot/share/opto/superword.cpp | 6 ++ .../TestFloat16VectorConvChain.java | 65 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/vectorization/TestFloat16VectorConvChain.java diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp index ba2dd423bf51d..5721f7bcd5420 100644 --- a/src/hotspot/share/opto/superword.cpp +++ b/src/hotspot/share/opto/superword.cpp @@ -2586,6 +2586,12 @@ const Type* VLoopTypes::container_type(Node* n) const { } const Type* t = _vloop.phase()->igvn().type(n); if (t->basic_type() == T_INT) { + // Float to half float conversion may be succeeded by a conversion from + // half float to float, in such a case back propagation of narrow type (SHORT) + // may not be possible. + if (n->Opcode() == Op_ConvF2HF) { + return TypeInt::SHORT; + } // A narrow type of arithmetic operations will be determined by // propagating the type of memory operations. return TypeInt::INT; diff --git a/test/hotspot/jtreg/compiler/vectorization/TestFloat16VectorConvChain.java b/test/hotspot/jtreg/compiler/vectorization/TestFloat16VectorConvChain.java new file mode 100644 index 0000000000000..6b090c965bb8c --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorization/TestFloat16VectorConvChain.java @@ -0,0 +1,65 @@ +/* + * 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 +* @summary Test Float16 vector conversion chain. +* @requires vm.compiler2.enabled +* @library /test/lib / +* @run driver compiler.vectorization.TestFloat16VectorConvChain +*/ + +package compiler.vectorization; + +import compiler.lib.ir_framework.*; +import java.util.Random; +import java.util.Arrays; + + +public class TestFloat16VectorConvChain { + + @Test + @IR(counts = {IRNode.VECTOR_CAST_HF2F, IRNode.VECTOR_SIZE_ANY, ">= 1", IRNode.VECTOR_CAST_F2HF, IRNode.VECTOR_SIZE_ANY, " >= 1"}) + public static void test(short [] res, short [] src1, short [] src2) { + for (int i = 0; i < res.length; i++) { + res[i] = (short)Float.float16ToFloat(Float.floatToFloat16(Float.float16ToFloat(src1[i]) + Float.float16ToFloat(src2[i]))); + } + } + + @Run(test = {"test"}) + @Warmup(1000) + public static void micro() { + short [] res = new short[1024]; + short [] src1 = new short[1024]; + short [] src2 = new short[1024]; + Arrays.fill(src1, (short)Float.floatToFloat16(1.0f)); + Arrays.fill(src2, (short)Float.floatToFloat16(2.0f)); + for (int i = 0; i < 1000; i++) { + test(res, src1, src2); + } + } + + public static void main(String [] args) { + TestFramework.run(TestFloat16VectorConvChain.class); + } +} From 3cce31ad8877ec62429981871bcb0067770f9ccb Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Mon, 8 Jul 2024 08:06:56 +0000 Subject: [PATCH 009/401] 8335643: serviceability/dcmd/vm tests fail for ZGC after JDK-8322475 Reviewed-by: sgehwolf, dholmes --- test/hotspot/jtreg/ProblemList-generational-zgc.txt | 3 --- test/hotspot/jtreg/ProblemList-zgc.txt | 3 --- .../jtreg/serviceability/dcmd/vm/SystemMapTestBase.java | 4 +++- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList-generational-zgc.txt b/test/hotspot/jtreg/ProblemList-generational-zgc.txt index bdeed9947c571..db8182641ac54 100644 --- a/test/hotspot/jtreg/ProblemList-generational-zgc.txt +++ b/test/hotspot/jtreg/ProblemList-generational-zgc.txt @@ -114,7 +114,4 @@ serviceability/sa/sadebugd/PmapOnDebugdTest.java 8307393 generic- serviceability/sa/sadebugd/RunCommandOnServerTest.java 8307393 generic-all serviceability/sa/sadebugd/SADebugDTest.java 8307393 generic-all -serviceability/dcmd/vm/SystemMapTest.java 8335643 generic-all -serviceability/dcmd/vm/SystemDumpMapTest.java 8335643 generic-all - vmTestbase/gc/gctests/MemoryEaterMT/MemoryEaterMT.java 8289582 windows-x64 diff --git a/test/hotspot/jtreg/ProblemList-zgc.txt b/test/hotspot/jtreg/ProblemList-zgc.txt index 892c980b0696d..1afe56c99f8af 100644 --- a/test/hotspot/jtreg/ProblemList-zgc.txt +++ b/test/hotspot/jtreg/ProblemList-zgc.txt @@ -45,7 +45,4 @@ serviceability/sa/TestSysProps.java 8302055 generic- serviceability/sa/TestHeapDumpForInvokeDynamic.java 8315646 generic-all -serviceability/dcmd/vm/SystemMapTest.java 8335643 generic-all -serviceability/dcmd/vm/SystemDumpMapTest.java 8335643 generic-all - vmTestbase/gc/gctests/MemoryEaterMT/MemoryEaterMT.java 8289582 windows-x64 diff --git a/test/hotspot/jtreg/serviceability/dcmd/vm/SystemMapTestBase.java b/test/hotspot/jtreg/serviceability/dcmd/vm/SystemMapTestBase.java index 20dc8d70d7a47..000e977a590e5 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/vm/SystemMapTestBase.java +++ b/test/hotspot/jtreg/serviceability/dcmd/vm/SystemMapTestBase.java @@ -42,6 +42,8 @@ public class SystemMapTestBase { private static final String regexBase_committed = regexBase + "com.*"; private static final String regexBase_shared_and_committed = regexBase + "shrd,com.*"; + // java heap is either committed, non-shared, or - in case of ZGC - committed and shared. + private static final String regexBase_java_heap = regexBase + "(shrd,)?com.*"; protected static final String shouldMatchUnconditionally[] = { // java launcher regexBase_committed + "/bin/java", @@ -54,7 +56,7 @@ public class SystemMapTestBase { }; protected static final String shouldMatchIfNMTIsEnabled[] = { - regexBase_committed + "JAVAHEAP.*", + regexBase_java_heap + "JAVAHEAP.*", // metaspace regexBase_committed + "META.*", // parts of metaspace should be uncommitted From 540188fdebd089d4145eca18c0f95bf338cbcefc Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Mon, 8 Jul 2024 10:03:39 +0000 Subject: [PATCH 010/401] 8334445: Parallel: Decouple maximum compaction from SoftReference clearing Reviewed-by: zgu, lmao --- .../gc/parallel/parallelScavengeHeap.cpp | 6 +-- .../share/gc/parallel/psParallelCompact.cpp | 50 +++++++++---------- .../share/gc/parallel/psParallelCompact.hpp | 9 ++-- src/hotspot/share/gc/parallel/psScavenge.cpp | 4 +- 4 files changed, 31 insertions(+), 38 deletions(-) diff --git a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp index 665b14bb1eabf..33a499ce47134 100644 --- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp @@ -441,11 +441,7 @@ HeapWord* ParallelScavengeHeap::mem_allocate_old_gen(size_t size) { } void ParallelScavengeHeap::do_full_collection(bool clear_all_soft_refs) { - // The do_full_collection() parameter clear_all_soft_refs - // is interpreted here as maximum_compaction which will - // cause SoftRefs to be cleared. - bool maximum_compaction = clear_all_soft_refs; - PSParallelCompact::invoke(maximum_compaction); + PSParallelCompact::invoke(clear_all_soft_refs); } // Failed allocation policy. Must be called from the VM thread, and diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index b4fe706d1e410..d4a24b710cfae 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -826,15 +826,21 @@ void PSParallelCompact::fill_dense_prefix_end(SpaceId id) { } } -bool PSParallelCompact::reassess_maximum_compaction(bool maximum_compaction, - size_t total_live_words, - MutableSpace* const old_space, - HeapWord* full_region_prefix_end) { +bool PSParallelCompact::check_maximum_compaction(size_t total_live_words, + MutableSpace* const old_space, + HeapWord* full_region_prefix_end) { + + ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); + + // Check System.GC + bool is_max_on_system_gc = UseMaximumCompactionOnSystemGC + && GCCause::is_user_requested_gc(heap->gc_cause()); + // Check if all live objs are larger than old-gen. const bool is_old_gen_overflowing = (total_live_words > old_space->capacity_in_words()); // JVM flags - const uint total_invocations = ParallelScavengeHeap::heap()->total_full_collections(); + const uint total_invocations = heap->total_full_collections(); assert(total_invocations >= _maximum_compaction_gc_num, "sanity"); const size_t gcs_since_max = total_invocations - _maximum_compaction_gc_num; const bool is_interval_ended = gcs_since_max > HeapMaximumCompactionInterval; @@ -843,7 +849,7 @@ bool PSParallelCompact::reassess_maximum_compaction(bool maximum_compaction, const bool is_region_full = full_region_prefix_end >= _summary_data.region_align_down(old_space->top()); - if (maximum_compaction || is_old_gen_overflowing || is_interval_ended || is_region_full) { + if (is_max_on_system_gc || is_old_gen_overflowing || is_interval_ended || is_region_full) { _maximum_compaction_gc_num = total_invocations; return true; } @@ -851,7 +857,7 @@ bool PSParallelCompact::reassess_maximum_compaction(bool maximum_compaction, return false; } -void PSParallelCompact::summary_phase(bool maximum_compaction) +void PSParallelCompact::summary_phase() { GCTraceTime(Info, gc, phases) tm("Summary Phase", &_gc_timer); @@ -874,10 +880,9 @@ void PSParallelCompact::summary_phase(bool maximum_compaction) _space_info[i].set_dense_prefix(space->bottom()); } - maximum_compaction = reassess_maximum_compaction(maximum_compaction, - total_live_words, - old_space, - full_region_prefix_end); + bool maximum_compaction = check_maximum_compaction(total_live_words, + old_space, + full_region_prefix_end); HeapWord* dense_prefix_end = maximum_compaction ? full_region_prefix_end : compute_dense_prefix_for_old_space(old_space, @@ -958,26 +963,23 @@ void PSParallelCompact::summary_phase(bool maximum_compaction) // may be true because this method can be called without intervening // activity. For example when the heap space is tight and full measure // are being taken to free space. -bool PSParallelCompact::invoke(bool maximum_heap_compaction) { +bool PSParallelCompact::invoke(bool clear_all_soft_refs) { assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - assert(!heap->is_stw_gc_active(), "not reentrant"); - IsSTWGCActiveMark mark; - const bool clear_all_soft_refs = - heap->soft_ref_policy()->should_clear_all_soft_refs(); + ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); + clear_all_soft_refs = clear_all_soft_refs + || heap->soft_ref_policy()->should_clear_all_soft_refs(); - return PSParallelCompact::invoke_no_policy(clear_all_soft_refs || - maximum_heap_compaction); + return PSParallelCompact::invoke_no_policy(clear_all_soft_refs); } // This method contains no policy. You should probably // be calling invoke() instead. -bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { +bool PSParallelCompact::invoke_no_policy(bool clear_all_soft_refs) { assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); assert(ref_processor() != nullptr, "Sanity"); @@ -998,7 +1000,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { // The scope of casr should end after code that can change // SoftRefPolicy::_should_clear_all_soft_refs. - ClearedAllSoftRefs casr(maximum_heap_compaction, + ClearedAllSoftRefs casr(clear_all_soft_refs, heap->soft_ref_policy()); // Make sure data structures are sane, make the heap parsable, and do other @@ -1033,7 +1035,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { DerivedPointerTable::clear(); #endif - ref_processor()->start_discovery(maximum_heap_compaction); + ref_processor()->start_discovery(clear_all_soft_refs); ClassUnloadingContext ctx(1 /* num_nmethod_unlink_workers */, false /* unregister_nmethods_during_purge */, @@ -1041,9 +1043,7 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { marking_phase(&_gc_tracer); - bool max_on_system_gc = UseMaximumCompactionOnSystemGC - && GCCause::is_user_requested_gc(gc_cause); - summary_phase(maximum_heap_compaction || max_on_system_gc); + summary_phase(); #if COMPILER2_OR_JVMCI assert(DerivedPointerTable::is_active(), "Sanity"); diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.hpp b/src/hotspot/share/gc/parallel/psParallelCompact.hpp index 93ea7aed78e9f..1e04beb8c66f6 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.hpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.hpp @@ -723,10 +723,9 @@ class PSParallelCompact : AllStatic { static void pre_compact(); static void post_compact(); - static bool reassess_maximum_compaction(bool maximum_compaction, - size_t total_live_words, - MutableSpace* const old_space, - HeapWord* full_region_prefix_end); + static bool check_maximum_compaction(size_t total_live_words, + MutableSpace* const old_space, + HeapWord* full_region_prefix_end); // Mark live objects static void marking_phase(ParallelOldTracer *gc_tracer); @@ -739,7 +738,7 @@ class PSParallelCompact : AllStatic { // make the heap parsable. static void fill_dense_prefix_end(SpaceId id); - static void summary_phase(bool maximum_compaction); + static void summary_phase(); static void adjust_pointers(); static void forward_to_new_addr(); diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp index 865bbd170997d..708bb9da48af7 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.cpp +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp @@ -235,7 +235,6 @@ bool PSScavenge::invoke() { assert(!ParallelScavengeHeap::heap()->is_stw_gc_active(), "not reentrant"); ParallelScavengeHeap* const heap = ParallelScavengeHeap::heap(); - PSAdaptiveSizePolicy* policy = heap->size_policy(); IsSTWGCActiveMark mark; const bool scavenge_done = PSScavenge::invoke_no_policy(); @@ -250,8 +249,7 @@ bool PSScavenge::invoke() { if (need_full_gc) { GCCauseSetter gccs(heap, GCCause::_adaptive_size_policy); - SoftRefPolicy* srp = heap->soft_ref_policy(); - const bool clear_all_softrefs = srp->should_clear_all_soft_refs(); + const bool clear_all_softrefs = heap->soft_ref_policy()->should_clear_all_soft_refs(); full_gc_done = PSParallelCompact::invoke_no_policy(clear_all_softrefs); } From c5a668bb653feb3408a9efa3274ceabf9f01a2c7 Mon Sep 17 00:00:00 2001 From: Xiaolong Peng Date: Mon, 8 Jul 2024 10:33:08 +0000 Subject: [PATCH 011/401] 8334231: Optimize MethodData layout Reviewed-by: dholmes, chagedorn, shade --- src/hotspot/share/oops/methodData.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hotspot/share/oops/methodData.hpp b/src/hotspot/share/oops/methodData.hpp index b6e2a1c965212..5071c29f1d774 100644 --- a/src/hotspot/share/oops/methodData.hpp +++ b/src/hotspot/share/oops/methodData.hpp @@ -1946,7 +1946,6 @@ class ciMethodData; class MethodData : public Metadata { friend class VMStructs; friend class JVMCIVMStructs; -private: friend class ProfileData; friend class TypeEntriesAtCall; friend class ciMethodData; @@ -2080,8 +2079,8 @@ class MethodData : public Metadata { #if INCLUDE_JVMCI // Support for HotSpotMethodData.setCompiledIRSize(int) - int _jvmci_ir_size; FailedSpeculation* _failed_speculations; + int _jvmci_ir_size; #endif // Size of _data array in bytes. (Excludes header and extra_data fields.) From c34a1b7013b27a8a214f63387bd528a90342a416 Mon Sep 17 00:00:00 2001 From: Tobias Hartmann Date: Mon, 8 Jul 2024 10:53:03 +0000 Subject: [PATCH 012/401] 8335861: Problem list compiler/vectorization/TestFloat16VectorConvChain.java Reviewed-by: epeter --- 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 d7088408ab887..76dc9f6f033fa 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -69,6 +69,8 @@ compiler/startup/StartupOutput.java 8326615 generic-x64 compiler/codecache/CodeCacheFullCountTest.java 8332954 generic-all +compiler/vectorization/TestFloat16VectorConvChain.java 8335860 generic-all + ############################################################################# # :hotspot_gc From 953c35eb5bff49ec5f7dbb25edd8a324b94318eb Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Mon, 8 Jul 2024 11:44:04 +0000 Subject: [PATCH 013/401] 8335824: Test gc/arguments/TestMinInitialErgonomics.java is timing out Reviewed-by: ayang, kbarrett --- 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 6b03401a563df..6912499e53f00 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 cec222e46065fc15db3f2eb241d3607d605ab580 Mon Sep 17 00:00:00 2001 From: Jorn Vernee Date: Mon, 8 Jul 2024 12:39:33 +0000 Subject: [PATCH 014/401] 8317611: Add a tool like jdeprscan to find usage of restricted methods Reviewed-by: alanb, ihse, mcimadamore, jlahoda, jwaters --- make/modules/jdk.jdeps/Launcher.gmk | 9 + .../javac/platform/JDKPlatformProvider.java | 11 +- .../share/classes/module-info.java | 8 +- .../classes/com/sun/tools/jdeprscan/Main.java | 4 +- .../tools/jnativescan/ClassFileSource.java | 124 +++++++++ .../sun/tools/jnativescan/ClassResolver.java | 163 +++++++++++ .../jnativescan/JNativeScanFatalError.java | 45 ++++ .../tools/jnativescan/JNativeScanTask.java | 195 ++++++++++++++ .../com/sun/tools/jnativescan/Main.java | 234 ++++++++++++++++ .../com/sun/tools/jnativescan/MethodRef.java | 48 ++++ .../tools/jnativescan/NativeMethodFinder.java | 141 ++++++++++ .../sun/tools/jnativescan/RestrictedUse.java | 32 +++ src/jdk.jdeps/share/classes/module-info.java | 23 +- src/jdk.jdeps/share/man/jnativescan.1 | 220 +++++++++++++++ test/jdk/tools/launcher/HelpFlagsTest.java | 1 + test/langtools/TEST.groups | 4 + .../jnativescan/JNativeScanTestBase.java | 86 ++++++ .../tools/jnativescan/TestArrayTypeRefs.java | 56 ++++ .../tools/jnativescan/TestJNativeScan.java | 252 ++++++++++++++++++ .../jnativescan/TestMissingSystemClass.java | 60 +++++ .../tools/jnativescan/TestSubclassRefs.java | 56 ++++ .../jnativescan/cases/classpath/app/App.java | 31 +++ .../cases/classpath/arrayref/App.java | 32 +++ .../jnativescan/cases/classpath/lib/Lib.java | 33 +++ .../cases/classpath/missingsystem/App.java | 32 +++ .../cases/classpath/singlejar/main/Main.java | 34 +++ .../cases/classpath/subclassref/App.java | 32 +++ .../unnamed_package/UnnamedPackage.java | 32 +++ .../cases/modules/org.lib/module-info.java | 26 ++ .../cases/modules/org.lib/org/lib/Lib.java | 34 +++ .../modules/org.lib/org/lib/Service.java | 26 ++ .../cases/modules/org.myapp/module-info.java | 28 ++ .../org.myapp/org/myapp/main/Main.java | 32 +++ .../modules/org.service/module-info.java | 27 ++ .../org.service/org/service/ServiceImpl.java | 35 +++ .../modules/org.singlejar/module-info.java | 25 ++ .../org/singlejar/main/Main.java | 34 +++ 37 files changed, 2250 insertions(+), 15 deletions(-) create mode 100644 src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/ClassFileSource.java create mode 100644 src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/ClassResolver.java create mode 100644 src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/JNativeScanFatalError.java create mode 100644 src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/JNativeScanTask.java create mode 100644 src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/Main.java create mode 100644 src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/MethodRef.java create mode 100644 src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/NativeMethodFinder.java create mode 100644 src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/RestrictedUse.java create mode 100644 src/jdk.jdeps/share/man/jnativescan.1 create mode 100644 test/langtools/tools/jnativescan/JNativeScanTestBase.java create mode 100644 test/langtools/tools/jnativescan/TestArrayTypeRefs.java create mode 100644 test/langtools/tools/jnativescan/TestJNativeScan.java create mode 100644 test/langtools/tools/jnativescan/TestMissingSystemClass.java create mode 100644 test/langtools/tools/jnativescan/TestSubclassRefs.java create mode 100644 test/langtools/tools/jnativescan/cases/classpath/app/App.java create mode 100644 test/langtools/tools/jnativescan/cases/classpath/arrayref/App.java create mode 100644 test/langtools/tools/jnativescan/cases/classpath/lib/Lib.java create mode 100644 test/langtools/tools/jnativescan/cases/classpath/missingsystem/App.java create mode 100644 test/langtools/tools/jnativescan/cases/classpath/singlejar/main/Main.java create mode 100644 test/langtools/tools/jnativescan/cases/classpath/subclassref/App.java create mode 100644 test/langtools/tools/jnativescan/cases/classpath/unnamed_package/UnnamedPackage.java create mode 100644 test/langtools/tools/jnativescan/cases/modules/org.lib/module-info.java create mode 100644 test/langtools/tools/jnativescan/cases/modules/org.lib/org/lib/Lib.java create mode 100644 test/langtools/tools/jnativescan/cases/modules/org.lib/org/lib/Service.java create mode 100644 test/langtools/tools/jnativescan/cases/modules/org.myapp/module-info.java create mode 100644 test/langtools/tools/jnativescan/cases/modules/org.myapp/org/myapp/main/Main.java create mode 100644 test/langtools/tools/jnativescan/cases/modules/org.service/module-info.java create mode 100644 test/langtools/tools/jnativescan/cases/modules/org.service/org/service/ServiceImpl.java create mode 100644 test/langtools/tools/jnativescan/cases/modules/org.singlejar/module-info.java create mode 100644 test/langtools/tools/jnativescan/cases/modules/org.singlejar/org/singlejar/main/Main.java diff --git a/make/modules/jdk.jdeps/Launcher.gmk b/make/modules/jdk.jdeps/Launcher.gmk index ceab793124584..1aa54e16f4564 100644 --- a/make/modules/jdk.jdeps/Launcher.gmk +++ b/make/modules/jdk.jdeps/Launcher.gmk @@ -51,3 +51,12 @@ $(eval $(call SetupBuildLauncher, jdeprscan, \ MAIN_CLASS := com.sun.tools.jdeprscan.Main, \ CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ )) + +################################################################################ +## Build jnativescan +################################################################################ + +$(eval $(call SetupBuildLauncher, jnativescan, \ + MAIN_CLASS := com.sun.tools.jnativescan.Main, \ + CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \ +)) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java index 487fe969f9774..4c24f9892a673 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/platform/JDKPlatformProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -83,7 +83,14 @@ public Iterable getSupportedPlatformNames() { } @Override - public PlatformDescription getPlatform(String platformName, String options) { + public PlatformDescription getPlatform(String platformName, String options) throws PlatformNotSupported { + if (!SUPPORTED_JAVA_PLATFORM_VERSIONS.contains(platformName)) { + throw new PlatformNotSupported(); + } + return getPlatformTrusted(platformName); + } + + public PlatformDescription getPlatformTrusted(String platformName) { return new PlatformDescriptionImpl(platformName); } diff --git a/src/jdk.internal.opt/share/classes/module-info.java b/src/jdk.internal.opt/share/classes/module-info.java index 67ed1410560df..ba6987f1ea93c 100644 --- a/src/jdk.internal.opt/share/classes/module-info.java +++ b/src/jdk.internal.opt/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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,11 +31,13 @@ module jdk.internal.opt { exports jdk.internal.joptsimple to jdk.jlink, - jdk.jshell; + jdk.jshell, + jdk.jdeps; exports jdk.internal.opt to jdk.compiler, jdk.jartool, jdk.javadoc, jdk.jlink, - jdk.jpackage; + jdk.jpackage, + jdk.jdeps; } diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java index c67510de441da..f77d29a8bfa5b 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, 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 @@ -414,7 +414,7 @@ boolean processRelease(String release, Collection classes) throws IOExce .noneMatch(n -> n.equals(release))) { return false; } - JavaFileManager fm = pp.getPlatform(release, "").getFileManager(); + JavaFileManager fm = pp.getPlatformTrusted(release).getFileManager(); List classNames = new ArrayList<>(); for (JavaFileObject fo : fm.list(StandardLocation.PLATFORM_CLASS_PATH, "", diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/ClassFileSource.java b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/ClassFileSource.java new file mode 100644 index 0000000000000..754904c9c7f24 --- /dev/null +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/ClassFileSource.java @@ -0,0 +1,124 @@ +/* + * 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 com.sun.tools.jnativescan; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.lang.module.ModuleReader; +import java.lang.module.ModuleReference; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.jar.JarFile; +import java.util.stream.Stream; +import java.util.zip.ZipFile; + +sealed interface ClassFileSource { + String moduleName(); + Path path(); + + Stream classFiles(Runtime.Version version) throws IOException; + + record Module(ModuleReference reference) implements ClassFileSource { + @Override + public String moduleName() { + return reference.descriptor().name(); + } + + @Override + public Path path() { + URI location = reference.location().orElseThrow(); + return Path.of(location); + } + + @Override + public Stream classFiles(Runtime.Version version) throws IOException { + ModuleReader reader = reference().open(); + return reader.list() + .filter(resourceName -> resourceName.endsWith(".class")) + .map(resourceName -> { + try (InputStream stream = reader.open(resourceName).orElseThrow()) { + return stream.readAllBytes(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }).onClose(() -> { + try { + reader.close(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + } + } + + record ClassPathJar(Path path) implements ClassFileSource { + @Override + public String moduleName() { + return "ALL-UNNAMED"; + } + + @Override + public Stream classFiles(Runtime.Version version) throws IOException { + JarFile jf = new JarFile(path().toFile(), false, ZipFile.OPEN_READ, version); + return jf.versionedStream() + .filter(je -> je.getName().endsWith(".class")) + .map(je -> { + try (InputStream stream = jf.getInputStream(je)){ + return stream.readAllBytes(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }).onClose(() -> { + try { + jf.close(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + } + } + + record ClassPathDirectory(Path path) implements ClassFileSource { + @Override + public String moduleName() { + return "ALL-UNNAMED"; + } + + @Override + public Stream classFiles(Runtime.Version version) throws IOException { + return Files.walk(path) + .filter(file -> Files.isRegularFile(file) && file.toString().endsWith(".class")) + .map(file -> { + try (InputStream stream = Files.newInputStream(file)){ + return stream.readAllBytes(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + } + } +} diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/ClassResolver.java b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/ClassResolver.java new file mode 100644 index 0000000000000..7a267a58aa5a3 --- /dev/null +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/ClassResolver.java @@ -0,0 +1,163 @@ +/* + * 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 com.sun.tools.jnativescan; + +import com.sun.tools.javac.platform.PlatformDescription; +import com.sun.tools.javac.platform.PlatformProvider; + +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.StandardLocation; +import java.io.IOException; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.constant.ClassDesc; +import java.lang.module.ModuleDescriptor; +import java.util.*; +import java.util.function.BiConsumer; +import java.util.stream.Stream; + +abstract class ClassResolver implements AutoCloseable { + + static ClassResolver forClassFileSources(List sources, Runtime.Version version) throws IOException { + Map classMap = new HashMap<>(); + for (ClassFileSource source : sources) { + try (Stream classFiles = source.classFiles(version)) { + classFiles.forEach(bytes -> { + ClassModel model = ClassFile.of().parse(bytes); + ClassDesc desc = model.thisClass().asSymbol(); + classMap.put(desc, new Info(source, model)); + }); + } + } + return new SimpleClassResolver(classMap); + } + + static ClassResolver forSystemModules(Runtime.Version version) { + String platformName = String.valueOf(version.feature()); + PlatformProvider platformProvider = ServiceLoader.load(PlatformProvider.class).findFirst().orElseThrow(); + PlatformDescription platform; + try { + platform = platformProvider.getPlatform(platformName, null); + } catch (PlatformProvider.PlatformNotSupported e) { + throw new JNativeScanFatalError("Release: " + platformName + " not supported", e); + } + JavaFileManager fm = platform.getFileManager(); + return new SystemModuleClassResolver(fm); + } + + record Info(ClassFileSource source, ClassModel model) {} + + public abstract void forEach(BiConsumer action); + public abstract Optional lookup(ClassDesc desc); + + @Override + public abstract void close() throws IOException; + + private static class SimpleClassResolver extends ClassResolver { + + private final Map classMap; + + public SimpleClassResolver(Map classMap) { + this.classMap = classMap; + } + + public void forEach(BiConsumer action) { + classMap.forEach(action); + } + + public Optional lookup(ClassDesc desc) { + return Optional.ofNullable(classMap.get(desc)); + } + + @Override + public void close() {} + } + + private static class SystemModuleClassResolver extends ClassResolver { + + private final JavaFileManager platformFileManager; + private final Map packageToSystemModule; + private final Map cache = new HashMap<>(); + + public SystemModuleClassResolver(JavaFileManager platformFileManager) { + this.platformFileManager = platformFileManager; + this.packageToSystemModule = packageToSystemModule(platformFileManager); + } + + private static Map packageToSystemModule(JavaFileManager platformFileManager) { + try { + Set locations = platformFileManager.listLocationsForModules( + StandardLocation.SYSTEM_MODULES).iterator().next(); + + Map result = new HashMap<>(); + for (JavaFileManager.Location loc : locations) { + JavaFileObject jfo = platformFileManager.getJavaFileForInput(loc, "module-info", JavaFileObject.Kind.CLASS); + ModuleDescriptor descriptor = ModuleDescriptor.read(jfo.openInputStream()); + for (ModuleDescriptor.Exports export : descriptor.exports()) { + if (!export.isQualified()) { + result.put(export.source(), descriptor.name()); + } + } + } + return result; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void forEach(BiConsumer action) { + throw new UnsupportedOperationException("NYI"); + } + + @Override + public Optional lookup(ClassDesc desc) { + return Optional.ofNullable(cache.computeIfAbsent(desc, _ -> { + String qualName = JNativeScanTask.qualName(desc); + String moduleName = packageToSystemModule.get(desc.packageName()); + if (moduleName != null) { + try { + JavaFileManager.Location loc = platformFileManager.getLocationForModule(StandardLocation.SYSTEM_MODULES, moduleName); + JavaFileObject jfo = platformFileManager.getJavaFileForInput(loc, qualName, JavaFileObject.Kind.CLASS); + if (jfo == null) { + throw new JNativeScanFatalError("System class can not be found: " + qualName); + } + ClassModel model = ClassFile.of().parse(jfo.openInputStream().readAllBytes()); + return new Info(null, model); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return null; + })); + } + + @Override + public void close() throws IOException { + platformFileManager.close(); + } + } +} diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/JNativeScanFatalError.java b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/JNativeScanFatalError.java new file mode 100644 index 0000000000000..15cf86e03c333 --- /dev/null +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/JNativeScanFatalError.java @@ -0,0 +1,45 @@ +/* + * 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 com.sun.tools.jnativescan; + +import java.io.Serial; + +// Exception used in case of fatal error that is reasonably expected and handled. +public class JNativeScanFatalError extends RuntimeException { + @Serial + private static final long serialVersionUID = 1L; + + public JNativeScanFatalError(String message) { + super(message); + } + + public JNativeScanFatalError(String message, Throwable cause) { + super(message, cause); + } + + public JNativeScanFatalError(Throwable cause) { + super(cause); + } +} diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/JNativeScanTask.java b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/JNativeScanTask.java new file mode 100644 index 0000000000000..2ff172e9c1b71 --- /dev/null +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/JNativeScanTask.java @@ -0,0 +1,195 @@ +/* + * 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 com.sun.tools.jnativescan; + +import java.io.IOException; +import java.io.PrintWriter; +import java.lang.constant.ClassDesc; +import java.lang.module.Configuration; +import java.lang.module.ModuleFinder; +import java.lang.module.ResolvedModule; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.jar.JarFile; +import java.util.jar.Manifest; +import java.util.stream.Collectors; +import java.util.zip.ZipFile; + +class JNativeScanTask { + + private final PrintWriter out; + private final List classPaths; + private final List modulePaths; + private final List cmdRootModules; + private final Runtime.Version version; + private final Action action; + + public JNativeScanTask(PrintWriter out, List classPaths, List modulePaths, + List cmdRootModules, Runtime.Version version, Action action) { + this.out = out; + this.classPaths = classPaths; + this.modulePaths = modulePaths; + this.version = version; + this.action = action; + this.cmdRootModules = cmdRootModules; + } + + public void run() throws JNativeScanFatalError { + List toScan = new ArrayList<>(findAllClassPathJars()); + + ModuleFinder moduleFinder = ModuleFinder.of(modulePaths.toArray(Path[]::new)); + List rootModules = cmdRootModules; + if (rootModules.contains("ALL-MODULE-PATH")) { + rootModules = allModuleNames(moduleFinder); + } + Configuration config = systemConfiguration().resolveAndBind(ModuleFinder.of(), moduleFinder, rootModules); + for (ResolvedModule m : config.modules()) { + toScan.add(new ClassFileSource.Module(m.reference())); + } + + SortedMap>> allRestrictedMethods; + try(ClassResolver classesToScan = ClassResolver.forClassFileSources(toScan, version); + ClassResolver systemClassResolver = ClassResolver.forSystemModules(version)) { + NativeMethodFinder finder = NativeMethodFinder.create(classesToScan, systemClassResolver); + allRestrictedMethods = finder.findAll(); + } catch (IOException e) { + throw new RuntimeException(e); + } + + switch (action) { + case PRINT -> printNativeAccess(allRestrictedMethods); + case DUMP_ALL -> dumpAll(allRestrictedMethods); + } + } + + private List findAllClassPathJars() throws JNativeScanFatalError { + List result = new ArrayList<>(); + for (Path path : classPaths) { + if (isJarFile(path)) { + Deque jarsToScan = new ArrayDeque<>(); + jarsToScan.offer(path); + + // recursively look for all class path jars, starting at the root jars + // in this.classPaths, and recursively following all Class-Path manifest + // attributes + while (!jarsToScan.isEmpty()) { + Path jar = jarsToScan.poll(); + String[] classPathAttribute = classPathAttribute(jar); + Path parentDir = jar.getParent(); + for (String classPathEntry : classPathAttribute) { + Path otherJar = parentDir != null + ? parentDir.resolve(classPathEntry) + : Path.of(classPathEntry); + if (Files.exists(otherJar)) { + // Class-Path attribute specifies that jars that + // are not found are simply ignored. Do the same here + jarsToScan.offer(otherJar); + } + } + result.add(new ClassFileSource.ClassPathJar(jar)); + } + } else if (Files.isDirectory(path)) { + result.add(new ClassFileSource.ClassPathDirectory(path)); + } else { + throw new JNativeScanFatalError( + "Path does not appear to be a jar file, or directory containing classes: " + path); + } + } + return result; + } + + private String[] classPathAttribute(Path jar) { + try (JarFile jf = new JarFile(jar.toFile(), false, ZipFile.OPEN_READ, version)) { + Manifest manifest = jf.getManifest(); + if (manifest != null) { + String attrib = manifest.getMainAttributes().getValue("Class-Path"); + if (attrib != null) { + return attrib.split("\\s+"); + } + } + return new String[0]; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private Configuration systemConfiguration() { + ModuleFinder systemFinder = ModuleFinder.ofSystem(); + Configuration system = Configuration.resolve(systemFinder, List.of(Configuration.empty()), ModuleFinder.of(), + allModuleNames(systemFinder)); // resolve all of them + return system; + } + + private List allModuleNames(ModuleFinder finder) { + return finder.findAll().stream().map(mr -> mr.descriptor().name()).toList(); + } + + private void printNativeAccess(SortedMap>> allRestrictedMethods) { + String nativeAccess = allRestrictedMethods.keySet().stream() + .map(ClassFileSource::moduleName) + .distinct() + .collect(Collectors.joining(",")); + out.println(nativeAccess); + } + + private void dumpAll(SortedMap>> allRestrictedMethods) { + if (allRestrictedMethods.isEmpty()) { + out.println(" "); + } else { + allRestrictedMethods.forEach((module, perClass) -> { + out.println(module.path() + " (" + module.moduleName() + "):"); + perClass.forEach((classDesc, restrictedUses) -> { + out.println(" " + qualName(classDesc) + ":"); + restrictedUses.forEach(use -> { + switch (use) { + case RestrictedUse.NativeMethodDecl(MethodRef nmd) -> + out.println(" " + nmd + " is a native method declaration"); + case RestrictedUse.RestrictedMethodRefs(MethodRef referent, Set referees) -> { + out.println(" " + referent + " references restricted methods:"); + referees.forEach(referee -> out.println(" " + referee)); + } + } + }); + }); + }); + } + } + + private static boolean isJarFile(Path path) throws JNativeScanFatalError { + return Files.exists(path) && Files.isRegularFile(path) && path.toString().endsWith(".jar"); + } + + public enum Action { + DUMP_ALL, + PRINT + } + + public static String qualName(ClassDesc desc) { + String packagePrefix = desc.packageName().isEmpty() ? "" : desc.packageName() + "."; + return packagePrefix + desc.displayName(); + } +} diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/Main.java b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/Main.java new file mode 100644 index 0000000000000..425a106d599f0 --- /dev/null +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/Main.java @@ -0,0 +1,234 @@ +/* + * 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 com.sun.tools.jnativescan; + +import jdk.internal.joptsimple.*; +import jdk.internal.opt.CommandLine; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.spi.ToolProvider; + +public class Main { + + private static boolean DEBUG = Boolean.getBoolean("com.sun.tools.jnativescan.DEBUG"); + + private static final int SUCCESS_CODE = 0; + private static final int FATAL_ERROR_CODE = 1; + + private final PrintWriter out; + private final PrintWriter err; + + private Main(PrintWriter out, PrintWriter err) { + this.out = out; + this.err = err; + } + + private void printError(String message) { + err.println("ERROR: " + message); + } + + private void printUsage() { + out.print(""" + Use 'jnativescan --help' for help + """); + } + + private void printVersion() { + out.println(System.getProperty("java.version")); + } + + public int run(String[] args) { + if (args.length < 1) { + printUsage(); + return FATAL_ERROR_CODE; + } + + try { + String[] expandedArgs = expandArgFiles(args); + parseOptionsAndRun(expandedArgs); + } catch (JNativeScanFatalError fatalError) { + printError(fatalError.getMessage()); + for (Throwable cause = fatalError.getCause(); + cause instanceof JNativeScanFatalError jNativeScanFatalError; + cause = jNativeScanFatalError.getCause()) { + err.println("CAUSED BY: " + jNativeScanFatalError.getMessage()); + } + if (DEBUG) { + fatalError.printStackTrace(err); + } + return FATAL_ERROR_CODE; + } catch (Throwable e) { + printError("Unexpected exception encountered"); + e.printStackTrace(err); + return FATAL_ERROR_CODE; + } + + return SUCCESS_CODE; + } + + private void parseOptionsAndRun(String[] expandedArgs) throws JNativeScanFatalError { + OptionParser parser = new OptionParser(false); + OptionSpec helpOpt = parser.acceptsAll(List.of("?", "h", "help"), "help").forHelp(); + OptionSpec versionOpt = parser.accepts("version", "Print version information and exit"); + OptionSpec classPathOpt = parser.accepts( + "class-path", + "The class path as used at runtime") + .withRequiredArg() + .withValuesSeparatedBy(File.pathSeparatorChar) + .withValuesConvertedBy(PARSE_PATH); + OptionSpec modulePathOpt = parser.accepts( + "module-path", + "The module path as used at runtime") + .withRequiredArg() + .withValuesSeparatedBy(File.pathSeparatorChar) + .withValuesConvertedBy(PARSE_PATH); + OptionSpec releaseOpt = parser.accepts( + "release", + "The runtime version that will run the application") + .withRequiredArg() + .withValuesConvertedBy(PARSE_VERSION); + OptionSpec addModulesOpt = parser.accepts( + "add-modules", + "List of root modules to scan") + .requiredIf(modulePathOpt) + .withRequiredArg() + .withValuesSeparatedBy(','); + OptionSpec printNativeAccessOpt = parser.accepts( + "print-native-access", + "print a comma separated list of modules that may perform native access operations." + + " ALL-UNNAMED is used to indicate unnamed modules."); + + OptionSet optionSet; + try { + optionSet = parser.parse(expandedArgs); + } catch (OptionException oe) { + throw new JNativeScanFatalError("Parsing options failed: " + oe.getMessage(), oe); + } + + if (optionSet.nonOptionArguments().size() != 0) { + throw new JNativeScanFatalError("jnativescan does not accept positional arguments"); + } + + if (optionSet.has(helpOpt)) { + out.println(""" + The jnativescan tool can be used to find methods that may access native functionality when + run. This includes restricted method calls and 'native' method declarations. + """); + try { + parser.printHelpOn(out); + return; + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + if (optionSet.has(versionOpt)) { + printVersion(); + return; + } + + List classPathJars = optionSet.valuesOf(classPathOpt); + List modulePaths = optionSet.valuesOf(modulePathOpt); + List rootModules = optionSet.valuesOf(addModulesOpt); + Runtime.Version version = Optional.ofNullable(optionSet.valueOf(releaseOpt)).orElse(Runtime.version()); + + JNativeScanTask.Action action = JNativeScanTask.Action.DUMP_ALL; + if (optionSet.has(printNativeAccessOpt)) { + action = JNativeScanTask.Action.PRINT; + } + + new JNativeScanTask(out, classPathJars, modulePaths, rootModules, version, action).run(); + } + + private static String[] expandArgFiles(String[] args) throws JNativeScanFatalError { + try { + return CommandLine.parse(args); + } catch (IOException e) { // file not found + throw new JNativeScanFatalError(e.getMessage(), e); + } + } + + public static void main(String[] args) { + System.exit(new Main.Provider().run(System.out, System.err, args)); + } + + public static class Provider implements ToolProvider { + + @Override + public String name() { + return "jnativescan"; + } + + @Override + public int run(PrintWriter out, PrintWriter err, String... args) { + return new Main(out, err).run(args); + } + } + + // where + private static final ValueConverter PARSE_PATH = new ValueConverter<>() { + @Override + public Path convert(String value) { + return Path.of(value); + } + + @Override + public Class valueType() { + return Path.class; + } + + @Override + public String valuePattern() { + return "Path"; + } + }; + + private static final ValueConverter PARSE_VERSION = new ValueConverter<>() { + @Override + public Runtime.Version convert(String value) { + try { + return Runtime.Version.parse(value); + } catch (IllegalArgumentException e) { + throw new JNativeScanFatalError("Invalid release: " + value + ": " + e.getMessage()); + } + } + + @Override + public Class valueType() { + return Runtime.Version.class; + } + + @Override + public String valuePattern() { + return "Version"; + } + }; +} diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/MethodRef.java b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/MethodRef.java new file mode 100644 index 0000000000000..b19e4e7ec8f2b --- /dev/null +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/MethodRef.java @@ -0,0 +1,48 @@ +/* + * 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 com.sun.tools.jnativescan; + +import java.lang.classfile.MethodModel; +import java.lang.classfile.constantpool.MemberRefEntry; +import java.lang.classfile.instruction.InvokeInstruction; +import java.lang.constant.ClassDesc; +import java.lang.constant.MethodTypeDesc; + +record MethodRef(ClassDesc owner, String name, MethodTypeDesc type) { + public static MethodRef ofModel(MethodModel model) { + return new MethodRef(model.parent().orElseThrow().thisClass().asSymbol(), + model.methodName().stringValue(), model.methodTypeSymbol()); + } + + public static MethodRef ofInvokeInstruction(InvokeInstruction instruction) { + return new MethodRef(instruction.owner().asSymbol(), + instruction.name().stringValue(), instruction.typeSymbol()); + } + + @Override + public String toString() { + return JNativeScanTask.qualName(owner) + "::" + name + type.displayDescriptor(); + } +} diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/NativeMethodFinder.java b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/NativeMethodFinder.java new file mode 100644 index 0000000000000..681b954d4cdd9 --- /dev/null +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/NativeMethodFinder.java @@ -0,0 +1,141 @@ +/* + * 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 com.sun.tools.jnativescan; + +import com.sun.tools.jnativescan.RestrictedUse.NativeMethodDecl; +import com.sun.tools.jnativescan.RestrictedUse.RestrictedMethodRefs; + +import java.io.IOException; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassModel; +import java.lang.classfile.MethodModel; +import java.lang.classfile.instruction.InvokeInstruction; +import java.lang.constant.ClassDesc; +import java.lang.constant.MethodTypeDesc; +import java.lang.reflect.AccessFlag; +import java.util.*; + +class NativeMethodFinder { + + // ct.sym uses this fake name for the restricted annotation instead + // see make/langtools/src/classes/build/tools/symbolgenerator/CreateSymbols.java + private static final String RESTRICTED_NAME = "Ljdk/internal/javac/Restricted+Annotation;"; + + private final Map cache = new HashMap<>(); + private final ClassResolver classesToScan; + private final ClassResolver systemClassResolver; + + private NativeMethodFinder(ClassResolver classesToScan, ClassResolver systemClassResolver) { + this.classesToScan = classesToScan; + this.systemClassResolver = systemClassResolver; + } + + public static NativeMethodFinder create(ClassResolver classesToScan, ClassResolver systemClassResolver) throws JNativeScanFatalError, IOException { + return new NativeMethodFinder(classesToScan, systemClassResolver); + } + + public SortedMap>> findAll() throws JNativeScanFatalError { + SortedMap>> restrictedMethods + = new TreeMap<>(Comparator.comparing(ClassFileSource::path)); + classesToScan.forEach((_, info) -> { + ClassModel classModel = info.model(); + List perClass = new ArrayList<>(); + classModel.methods().forEach(methodModel -> { + if (methodModel.flags().has(AccessFlag.NATIVE)) { + perClass.add(new NativeMethodDecl(MethodRef.ofModel(methodModel))); + } else { + SortedSet perMethod = new TreeSet<>(Comparator.comparing(MethodRef::toString)); + methodModel.code().ifPresent(code -> { + try { + code.forEach(e -> { + switch (e) { + case InvokeInstruction invoke -> { + MethodRef ref = MethodRef.ofInvokeInstruction(invoke); + if (isRestrictedMethod(ref)) { + perMethod.add(ref); + } + } + default -> { + } + } + }); + } catch (JNativeScanFatalError e) { + throw new JNativeScanFatalError("Error while processing method: " + + MethodRef.ofModel(methodModel), e); + } + }); + if (!perMethod.isEmpty()) { + perClass.add(new RestrictedMethodRefs(MethodRef.ofModel(methodModel), perMethod)); + } + } + }); + if (!perClass.isEmpty()) { + restrictedMethods.computeIfAbsent(info.source(), + _ -> new TreeMap<>(Comparator.comparing(JNativeScanTask::qualName))) + .put(classModel.thisClass().asSymbol(), perClass); + } + }); + return restrictedMethods; + } + + private boolean isRestrictedMethod(MethodRef ref) throws JNativeScanFatalError { + return cache.computeIfAbsent(ref, methodRef -> { + if (methodRef.owner().isArray()) { + // no restricted methods in arrays atm, and we can't look them up since they have no class file + return false; + } + Optional info = systemClassResolver.lookup(methodRef.owner()); + if (!info.isPresent()) { + return false; + } + ClassModel classModel = info.get().model(); + Optional methodModel = findMethod(classModel, methodRef.name(), methodRef.type()); + if (!methodModel.isPresent()) { + // If we are here, the method was referenced through a subclass of the class containing the actual + // method declaration. We could implement a method resolver (that needs to be version aware + // as well) to find the method model of the declaration, but it's not really worth it. + // None of the restricted methods (atm) are exposed through more than 1 public type, so it's not + // possible for user code to reference them through a subclass. + return false; + } + + return hasRestrictedAnnotation(methodModel.get()); + }); + } + + private static boolean hasRestrictedAnnotation(MethodModel method) { + return method.findAttribute(Attributes.runtimeVisibleAnnotations()) + .map(rva -> rva.annotations().stream().anyMatch(ann -> + ann.className().stringValue().equals(RESTRICTED_NAME))) + .orElse(false); + } + + private static Optional findMethod(ClassModel classModel, String name, MethodTypeDesc type) { + return classModel.methods().stream() + .filter(m -> m.methodName().stringValue().equals(name) + && m.methodType().stringValue().equals(type.descriptorString())) + .findFirst(); + } +} diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/RestrictedUse.java b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/RestrictedUse.java new file mode 100644 index 0000000000000..58c5798d33f07 --- /dev/null +++ b/src/jdk.jdeps/share/classes/com/sun/tools/jnativescan/RestrictedUse.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 com.sun.tools.jnativescan; + +import java.util.SortedSet; + +sealed interface RestrictedUse { + record RestrictedMethodRefs(MethodRef referent, SortedSet referees) implements RestrictedUse {} + record NativeMethodDecl(MethodRef decl) implements RestrictedUse {} +} diff --git a/src/jdk.jdeps/share/classes/module-info.java b/src/jdk.jdeps/share/classes/module-info.java index e8ad319d70c55..3fdd3ca32d270 100644 --- a/src/jdk.jdeps/share/classes/module-info.java +++ b/src/jdk.jdeps/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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,12 +28,13 @@ /** * Defines tools for analysing dependencies in Java libraries and programs, * including the {@index jdeps jdeps tool}, - * {@index javap javap tool}, and - * {@index jdeprscan jdeprscan tool} tools. + * {@index javap javap tool}, + * {@index jdeprscan jdeprscan tool}, and + * {@index jnativescan jnativescan tool} tools. * *

* This module provides the equivalent of command-line access to the - * javap and jdeps tools via the + * javap, jdeps, and jnativescan tools via the * {@link java.util.spi.ToolProvider ToolProvider} service provider * interface (SPI)

* @@ -49,12 +50,14 @@ * @toolGuide javap * @toolGuide jdeprscan * @toolGuide jdeps + * @toolGuide jnativescan * * @provides java.util.spi.ToolProvider - * Use {@link java.util.spi.ToolProvider#findFirst ToolProvider.findFirst("javap")} - * or {@link java.util.spi.ToolProvider#findFirst ToolProvider.findFirst("jdeps")} + * Use {@link java.util.spi.ToolProvider#findFirst ToolProvider.findFirst("javap")}, + * {@link java.util.spi.ToolProvider#findFirst ToolProvider.findFirst("jdeps")}, + * or {@link java.util.spi.ToolProvider#findFirst ToolProvider.findFirst("jnativescan")} * to obtain an instance of a {@code ToolProvider} that provides the equivalent - * of command-line access to the {@code javap} or {@code jdeps} tool. + * of command-line access to the {@code javap}, {@code jdeps}, {@code jnativescan} tool. * * @moduleGraph * @since 9 @@ -63,10 +66,14 @@ module jdk.jdeps { requires java.compiler; requires jdk.compiler; + requires jdk.internal.opt; + + uses com.sun.tools.javac.platform.PlatformProvider; exports com.sun.tools.classfile to jdk.jlink; provides java.util.spi.ToolProvider with com.sun.tools.javap.Main.JavapToolProvider, - com.sun.tools.jdeps.Main.JDepsToolProvider; + com.sun.tools.jdeps.Main.JDepsToolProvider, + com.sun.tools.jnativescan.Main.Provider; } diff --git a/src/jdk.jdeps/share/man/jnativescan.1 b/src/jdk.jdeps/share/man/jnativescan.1 new file mode 100644 index 0000000000000..ff7f18277f260 --- /dev/null +++ b/src/jdk.jdeps/share/man/jnativescan.1 @@ -0,0 +1,220 @@ +.\" 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. +.\" +.\" Automatically generated by Pandoc 2.19.2 +.\" +.\" Define V font for inline verbatim, using C font in formats +.\" that render this, and otherwise B font. +.ie "\f[CB]x\f[R]"x" \{\ +. ftr V B +. ftr VI BI +. ftr VB B +. ftr VBI BI +.\} +.el \{\ +. ftr V CR +. ftr VI CI +. ftr VB CB +. ftr VBI CBI +.\} +.TH "JNATIVESCAN" "1" "2025" "JDK 24-ea" "JDK Commands" +.hy +.SH NAME +.PP +jnativescan - static analysis tool that scans one or more jar files for +uses of native functionalities, such as restricted method calls or +\f[V]native\f[R] method declarations. +.SH SYNOPSIS +.PP +\f[V]jnativescan\f[R] [\f[I]options\f[R]] +.TP +\f[I]options\f[R] +See \f[B]Options for the jnativescan Command\f[R] +.SH DESCRIPTION +.PP +The \f[V]jnative\f[R] tool is a static analysis tool provided by the JDK +that scans a JAR file for uses of native functionalities, such as +restricted method calls or \f[V]native\f[R] method declarations. +.PP +\f[V]jnativescan\f[R] accepts a runtime class path and module path +configuration, as well as a set of root modules, and a target release. +It scans the jars on the class and module paths, and reports uses of +native functionalities either in a tree like structure, which also +identifies that calling classes and methods, or as a list of module +names when the \f[V]--print-native-access\f[R] flag is specified. +.SH OPTIONS FOR THE JNATIVESCAN COMMAND +.PP +The following options are available: +.TP +\f[V]--class-path\f[R] \f[I]path\f[R] +Used to specify a list of paths pointing to jar files to be scanned. +.PP +All jar files specified through this list will be scanned. +If a jar file contains a \f[V]Class-Path\f[R] attribute in its manifest, +jar files listed there will be scanned as well. +Jar files listed in the \f[V]Class-Path\f[R] manifest attribute that can +not be found are ignored. +All the jar files found are treated as if they belonged to the unnamed +module. +.TP +\f[V]--module-path\f[R] \f[I]path\f[R] +Used to specify a list of paths pointing to jar files or directories +containing jar files, that the tool can use to find modules that need to +be scanned. +The list of jar files that will be scanned depends on the +\f[V]--add-modules\f[R] option. +.RS +.PP +For both the \f[V]--class-path\f[R] and \f[V]--module-path\f[R] options, +\f[I]path\f[R] should be a search path that consists of one or more jar +files, separated by the system-specific path separator. +For example: +.IP \[bu] 2 +\f[B]Linux and macOS:\f[R] +.RS 2 +.RS +.PP +\f[V]--class-path /some/foo.jar:/another/different/bar.jar\f[R] +.RE +.RE +.PP +\f[B]Note:\f[R] +.PP +On Windows, use a semicolon (\f[V];\f[R]) as the separator instead of a +colon (\f[V]:\f[R]). +.IP \[bu] 2 +\f[B]Windows:\f[R] +.RS 2 +.RS +.PP +\f[V]--class-path C:\[rs]some\[rs]foo.jar;C:\[rs]another\[rs]different\[rs]bar.jar\f[R] +.RE +.RE +.RE +.TP +\f[V]--add-modules\f[R] \f[I]module[,module...]\f[R] +Used to specify a comma-separated list of module names that indicate the +root modules to scan. +All the root modules will be scanned, as well as any modules that they +depend on. +This includes dependencies on service implementations specified through +the \f[V]uses\f[R] directive in a module\[aq]s \f[V]module-info\f[R] +file. +All modules found on the module path that provide an implementation of +such a service will be scanned as well. +.TP +\f[V]--release\f[R] \f[I]version\f[R] +Used to specify the Java SE release that specifies the set of restricted +methods to scan for. +For multi-release jar files, this option also indicates the version of +class file that should be loaded from the jar. +This option should be set to the version of the runtime under which the +application is eventually intended to be run. +If this flag is omitted, the version of \f[V]jnativescan\f[R] is used as +release version, which is the same as the version of the JDK that the +tool belongs to. +.TP +\f[V]--print-native-access\f[R] +Print a comma-separated list of module names that use native +functionalities, instead of the default tree structure. +.TP +\f[V]--help\f[R] or \f[V]-h\f[R] +Prints out a full help message. +.TP +\f[V]--version\f[R] +Prints out the abbreviated version string of the tool. +.SH EXAMPLE OF \f[V]jnativescan\f[R] USE +.PP +\f[V]jnativescan\f[R] accepts a runtime configuration in the form of a +class path, module path, set of root modules, and a target release +version. +For the class path, the tool will scan all jar files, including those +found recursively through the \f[V]Class-Path\f[R] manifest attribute. +For the module path, the tool scans all root modules specified through +\f[V]--add-modules\f[R], and any (transitive) dependence of the root +modules, including any modules that contain service implementations that +are used by a scanned module. +.PP +By default, the tool prints out which jars, classes, and methods use +native functionalities, in a tree-like structure. +The following is an example output: +.IP +.nf +\f[CB] +$ jnativescan --class-path app.jar +app.jar (ALL-UNNAMED): + foo.Main: + foo.Main::main(String[])void references restricted methods: + java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment + foo.Main::nativeMethod()void is a native method declaration +\f[R] +.fi +.PP +\f[V]app.jar (ALL-UNNAMED)\f[R] is the path to the jar file, with the +module name in parentheses behind it. +Since in this case the jar file appears on the class path, +\f[V]ALL-UNNAMED\f[R] is printed to indicate the unnamed module. +The second line of the output, \f[V]foo.Main\f[R], indicates that +methods using native functionalities were found in the +\f[V]foo.Main\f[R] class. +The next line: +.IP +.nf +\f[CB] + foo.Main::main(String[])void references restricted methods: +\f[R] +.fi +.PP +Indicates that the \f[V]main(String[])\f[R] method in the +\f[V]foo.Main\f[R] class references a restricted method, which is listed +on the following line as: +.IP +.nf +\f[CB] + java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment +\f[R] +.fi +.PP +Lastly, the text: +.IP +.nf +\f[CB] + foo.Main::nativeMethod()void is a native method declaration +\f[R] +.fi +.PP +Indicates that the \f[V]foo.Main\f[R] class contains a declaration of a +\f[V]native\f[R] method named \f[V]nativeMethod\f[R]. +.PP +If we add \f[V]--print-native-access\f[R] to the example command line, +we instead get a list of the names of modules that contain accesses to +native functionalities: +.IP +.nf +\f[CB] +$ jnativescan --class-path app.jar --print-native-access +ALL-UNNAMED +\f[R] +.fi +.PP +In this case the output consists of just \f[V]ALL-UNNAMED\f[R], which +indicates a jar file on the class path, that is, in the unnamed module, +contains an access to native functionalities. diff --git a/test/jdk/tools/launcher/HelpFlagsTest.java b/test/jdk/tools/launcher/HelpFlagsTest.java index dda649b9f41ba..15c6c101dd0c1 100644 --- a/test/jdk/tools/launcher/HelpFlagsTest.java +++ b/test/jdk/tools/launcher/HelpFlagsTest.java @@ -141,6 +141,7 @@ private static class ToolHelpSpec { new ToolHelpSpec("jlink", 1, 1, 1, 0, 0, 0, 2), // -?, -h, --help new ToolHelpSpec("jmap", 1, 1, 1, 0, 1, 0, 1), // -?, -h, --help, -help accepted but not documented. new ToolHelpSpec("jmod", 1, 1, 1, 0, 1, 0, 2), // -?, -h, --help, -help accepted but not documented. + new ToolHelpSpec("jnativescan", 1, 1, 1, 0, 1, 0, 1), // -?, -h, --help, -help accepted but not documented. new ToolHelpSpec("jps", 1, 1, 1, 0, 1, 1, 1), // -?, -h, --help -help, Documents -help new ToolHelpSpec("jrunscript", 1, 1, 1, 0, 1, 1, 7), // -?, -h, --help -help, Documents -help new ToolHelpSpec("jshell", 1, 1, 1, 0, 1, 0, 1), // -?, -h, --help, -help accepted but not documented. diff --git a/test/langtools/TEST.groups b/test/langtools/TEST.groups index 74503501da9b9..e290a1431a3c5 100644 --- a/test/langtools/TEST.groups +++ b/test/langtools/TEST.groups @@ -63,6 +63,10 @@ langtools_jdeps = \ tools/all \ tools/jdeps +langtools_jnativescan = \ + tools/all \ + tools/jnativescan + langtools_slow = \ jdk/internal/shellsupport/doc/FullJavadocHelperTest.java diff --git a/test/langtools/tools/jnativescan/JNativeScanTestBase.java b/test/langtools/tools/jnativescan/JNativeScanTestBase.java new file mode 100644 index 0000000000000..97c0b21a738a2 --- /dev/null +++ b/test/langtools/tools/jnativescan/JNativeScanTestBase.java @@ -0,0 +1,86 @@ +/* + * 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.PrintWriter; +import java.nio.file.Path; +import java.util.Arrays; + +import java.io.StringWriter; +import java.util.spi.ToolProvider; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.util.JarUtils; + +public class JNativeScanTestBase { + + public static final String MODULE_PATH = "mods"; + + private static final ToolProvider JNATIVESCAN_TOOL = ToolProvider.findFirst("jnativescan") + .orElseThrow(() -> new RuntimeException("jnativescan tool not found")); + + public static OutputAnalyzer jnativescan(String... args) { + return run(JNATIVESCAN_TOOL, args); + } + + private static OutputAnalyzer run(ToolProvider tp, String[] commands) { + int rc; + StringWriter sw = new StringWriter(); + StringWriter esw = new StringWriter(); + + try (PrintWriter pw = new PrintWriter(sw); + PrintWriter epw = new PrintWriter(esw)) { + System.out.println("Running " + tp.name() + ", Command: " + Arrays.toString(commands)); + rc = tp.run(pw, epw, commands); + } + OutputAnalyzer output = new OutputAnalyzer(sw.toString(), esw.toString(), rc); + output.outputTo(System.out); + output.errorTo(System.err); + return output; + } + + public static Path makeModularJar(String moduleName) throws IOException { + Path jarPath = Path.of(MODULE_PATH, moduleName + ".jar"); + Path moduleRoot = moduleRoot(moduleName); + JarUtils.createJarFile(jarPath, moduleRoot); + return jarPath; + } + + public static Path moduleRoot(String name) { + return Path.of(System.getProperty("test.module.path")).resolve(name); + } + + public static OutputAnalyzer assertSuccess(OutputAnalyzer output) { + if (output.getExitValue() != 0) { + throw new IllegalStateException("tool run failed"); + } + return output; + } + + public static OutputAnalyzer assertFailure(OutputAnalyzer output) { + if (output.getExitValue() == 0) { + throw new IllegalStateException("tool run succeeded"); + } + return output; + } +} diff --git a/test/langtools/tools/jnativescan/TestArrayTypeRefs.java b/test/langtools/tools/jnativescan/TestArrayTypeRefs.java new file mode 100644 index 0000000000000..a439fdfdef967 --- /dev/null +++ b/test/langtools/tools/jnativescan/TestArrayTypeRefs.java @@ -0,0 +1,56 @@ +/* + * 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 + * @library /test/lib .. ./cases/modules + * @build JNativeScanTestBase + * cases.classpath.arrayref.App + * @run junit TestArrayTypeRefs + */ + +import jdk.test.lib.util.JarUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.file.Path; + +public class TestArrayTypeRefs extends JNativeScanTestBase { + + static Path ARRAY_REF; + + @BeforeAll + public static void before() throws IOException { + ARRAY_REF = Path.of("arrayref.jar"); + Path testClasses = Path.of(System.getProperty("test.classes", "")); + JarUtils.createJarFile(ARRAY_REF, testClasses, Path.of("arrayref", "App.class")); + } + + @Test + public void testSingleJarClassPath() { + assertSuccess(jnativescan("--class-path", ARRAY_REF.toString())) + .stderrShouldBeEmpty() + .stdoutShouldContain(""); + } +} diff --git a/test/langtools/tools/jnativescan/TestJNativeScan.java b/test/langtools/tools/jnativescan/TestJNativeScan.java new file mode 100644 index 0000000000000..94db492441263 --- /dev/null +++ b/test/langtools/tools/jnativescan/TestJNativeScan.java @@ -0,0 +1,252 @@ +/* + * 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 + * @library /test/lib .. ./cases/modules + * @build JNativeScanTestBase + * org.singlejar/* org.lib/* org.myapp/* org.service/* + * cases.classpath.singlejar.main.Main + * cases.classpath.lib.Lib + * cases.classpath.app.App + * cases.classpath.unnamed_package.UnnamedPackage + * @run junit TestJNativeScan + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.util.JarUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.Set; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class TestJNativeScan extends JNativeScanTestBase { + + static Path TEST_CLASSES; + + static Path CLASS_PATH_APP; + static Path SINGLE_JAR_CLASS_PATH; + static Path SINGLE_JAR_MODULAR; + static Path ORG_MYAPP; + static Path ORG_LIB; + static Path UNNAMED_PACKAGE_JAR; + static Path LIB_JAR; + + @BeforeAll + public static void before() throws IOException { + SINGLE_JAR_CLASS_PATH = Path.of("singleJar.jar"); + TEST_CLASSES = Path.of(System.getProperty("test.classes", "")); + JarUtils.createJarFile(SINGLE_JAR_CLASS_PATH, TEST_CLASSES, Path.of("main", "Main.class")); + + LIB_JAR = Path.of("lib.jar"); + JarUtils.createJarFile(LIB_JAR, TEST_CLASSES, Path.of("lib", "Lib.class")); + Manifest manifest = new Manifest(); + Attributes mainAttrs = manifest.getMainAttributes(); + mainAttrs.put(Attributes.Name.MANIFEST_VERSION, "1.0"); // need version or other attributes will be ignored + mainAttrs.putValue("Class-Path", "lib.jar non-existent.jar"); + CLASS_PATH_APP = Path.of("app.jar"); + JarUtils.createJarFile(CLASS_PATH_APP, manifest, TEST_CLASSES, Path.of("app", "App.class")); + + SINGLE_JAR_MODULAR = makeModularJar("org.singlejar"); + ORG_MYAPP = makeModularJar("org.myapp"); + ORG_LIB = makeModularJar("org.lib"); + makeModularJar("org.service"); + + UNNAMED_PACKAGE_JAR = Path.of("unnamed_package.jar"); + JarUtils.createJarFile(UNNAMED_PACKAGE_JAR, TEST_CLASSES, Path.of("UnnamedPackage.class")); + } + + @Test + public void testSingleJarClassPath() { + assertSuccess(jnativescan("--class-path", SINGLE_JAR_CLASS_PATH.toString())) + .stderrShouldBeEmpty() + .stdoutShouldContain("ALL-UNNAMED") + .stdoutShouldContain("main.Main") + .stdoutShouldContain("main.Main::m()void is a native method declaration") + .stdoutShouldContain("main.Main::main(String[])void references restricted methods") + .stdoutShouldContain("java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment"); + } + + @Test + public void testSingleJarModulePath() { + assertSuccess(jnativescan("--module-path", MODULE_PATH, "--add-modules", "org.singlejar")) + .stderrShouldBeEmpty() + .stdoutShouldContain("org.singlejar") + .stdoutShouldContain("org.singlejar.main.Main") + .stdoutShouldContain("org.singlejar.main.Main::m()void is a native method declaration") + .stdoutShouldContain("org.singlejar.main.Main::main(String[])void references restricted methods") + .stdoutShouldContain("java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment"); + } + + @Test + public void testWithDepModule() { + assertSuccess(jnativescan("--module-path", MODULE_PATH, "--add-modules", "org.myapp")) + .stderrShouldBeEmpty() + .stdoutShouldContain("org.lib") + .stdoutShouldContain("org.lib.Lib") + .stdoutShouldContain("org.lib.Lib::m()void is a native method declaration") + .stdoutShouldContain("org.lib.Lib::doIt()void references restricted methods") + .stdoutShouldContain("java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment") + .stdoutShouldContain("org.service") + .stdoutShouldContain("org.service.ServiceImpl") + .stdoutShouldContain("org.service.ServiceImpl::m()void is a native method declaration") + .stdoutShouldContain("org.service.ServiceImpl::doIt()void references restricted methods") + .stdoutShouldContain("java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment"); + } + + @Test + public void testAllModulePath() { + assertSuccess(jnativescan("--module-path", MODULE_PATH, "--add-modules", "ALL-MODULE-PATH")) + .stderrShouldBeEmpty() + .stdoutShouldContain("org.singlejar") + .stdoutShouldContain("org.lib") + .stdoutShouldContain("org.service"); + } + + @Test + public void testClassPathAttribute() { + assertSuccess(jnativescan("--class-path", CLASS_PATH_APP.toString())) + .stderrShouldBeEmpty() + .stdoutShouldContain("ALL-UNNAMED") + .stdoutShouldContain("lib.Lib") + .stdoutShouldContain("lib.Lib::m()void is a native method declaration") + .stdoutShouldContain("lib.Lib::doIt()void references restricted methods") + .stdoutShouldContain("java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment"); + } + + @Test + public void testInvalidRelease() { + assertFailure(jnativescan("--module-path", MODULE_PATH, "--add-modules", "ALL-MODULE-PATH", "--release", "asdf")) + .stderrShouldContain("Invalid release"); + } + + @Test + public void testReleaseNotSupported() { + assertFailure(jnativescan("--module-path", MODULE_PATH, "--add-modules", "ALL-MODULE-PATH", "--release", "9999999")) + .stderrShouldContain("Release: 9999999 not supported"); + } + + @Test + public void testFileDoesNotExist() { + assertFailure(jnativescan("--class-path", "non-existent.jar")) + .stderrShouldContain("Path does not appear to be a jar file, or directory containing classes"); + } + + @Test + public void testModuleNotAJarFile() { + String modulePath = moduleRoot("org.myapp").toString() + File.pathSeparator + ORG_LIB.toString(); + assertSuccess(jnativescan("--module-path", modulePath, + "--add-modules", "ALL-MODULE-PATH")) + .stdoutShouldContain("lib.Lib") + .stdoutShouldContain("lib.Lib::m()void is a native method declaration") + .stdoutShouldContain("lib.Lib::doIt()void references restricted methods") + .stdoutShouldContain("java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment"); + } + + @Test + public void testPrintNativeAccess() { + assertSuccess(jnativescan("--module-path", MODULE_PATH, + "-add-modules", "org.singlejar,org.myapp", + "--print-native-access")) + .stdoutShouldMatch("org.lib,org.service,org.singlejar"); + } + + @Test + public void testNoDuplicateNames() { + String classPath = SINGLE_JAR_CLASS_PATH + File.pathSeparator + CLASS_PATH_APP; + OutputAnalyzer output = assertSuccess(jnativescan("--class-path", classPath, "--print-native-access")); + String[] moduleNames = output.getStdout().split(","); + Set names = new HashSet<>(); + for (String name : moduleNames) { + assertTrue(names.add(name.strip())); + } + } + + @Test + public void testUnnamedPackage() { + assertSuccess(jnativescan("--class-path", UNNAMED_PACKAGE_JAR.toString())) + .stderrShouldBeEmpty() + .stdoutShouldContain("ALL-UNNAMED") + .stdoutShouldNotContain(".UnnamedPackage") + .stdoutShouldContain("UnnamedPackage") + .stdoutShouldContain("UnnamedPackage::m()void is a native method declaration") + .stdoutShouldContain("UnnamedPackage::main(String[])void references restricted methods") + .stdoutShouldContain("java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment"); + } + + @Test + public void testPositionalArguments() { + assertFailure(jnativescan("foo")) + .stdoutShouldBeEmpty() + .stderrShouldContain("jnativescan does not accept positional arguments"); + } + + @Test + public void testMissingRootModules() { + assertFailure(jnativescan("--module-path", MODULE_PATH)) + .stdoutShouldBeEmpty() + .stderrShouldContain("Missing required option(s) [add-modules]"); + } + + @Test + public void testClassPathDirectory() { + assertSuccess(jnativescan("--class-path", TEST_CLASSES.toString())) + .stderrShouldBeEmpty() + .stdoutShouldContain("ALL-UNNAMED") + .stdoutShouldContain("UnnamedPackage") + .stdoutShouldContain("UnnamedPackage::m()void is a native method declaration") + .stdoutShouldContain("UnnamedPackage::main(String[])void references restricted methods") + .stdoutShouldContain("main.Main") + .stdoutShouldContain("main.Main::m()void is a native method declaration") + .stdoutShouldContain("main.Main::main(String[])void references restricted methods") + .stdoutShouldContain("lib.Lib") + .stdoutShouldContain("lib.Lib::m()void is a native method declaration") + .stdoutShouldContain("lib.Lib::doIt()void references restricted methods") + .stdoutShouldContain("java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment"); + } + + @Test + public void testMultipleClassPathJars() { + // make sure all of these are reported, even when they are all in the ALL-UNNAMED module + String classPath = UNNAMED_PACKAGE_JAR + + File.pathSeparator + SINGLE_JAR_CLASS_PATH + + File.pathSeparator + LIB_JAR; + assertSuccess(jnativescan("--class-path", classPath)) + .stderrShouldBeEmpty() + .stdoutShouldContain("ALL-UNNAMED") + .stdoutShouldContain("UnnamedPackage") + .stdoutShouldContain(UNNAMED_PACKAGE_JAR.toString()) + .stdoutShouldContain("lib.Lib") + .stdoutShouldContain(LIB_JAR.toString()) + .stdoutShouldContain("main.Main") + .stdoutShouldContain(SINGLE_JAR_CLASS_PATH.toString()); + } +} diff --git a/test/langtools/tools/jnativescan/TestMissingSystemClass.java b/test/langtools/tools/jnativescan/TestMissingSystemClass.java new file mode 100644 index 0000000000000..5806590d0e081 --- /dev/null +++ b/test/langtools/tools/jnativescan/TestMissingSystemClass.java @@ -0,0 +1,60 @@ +/* + * 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 + * @library /test/lib .. ./cases/modules + * @build JNativeScanTestBase + * @compile --release 20 cases/classpath/missingsystem/App.java + * @run junit TestMissingSystemClass + */ + +import jdk.test.lib.util.JarUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.file.Path; + +public class TestMissingSystemClass extends JNativeScanTestBase { + + static Path MISSING_SYSTEM; + + @BeforeAll + public static void before() throws IOException { + MISSING_SYSTEM = Path.of("missingsystem.jar"); + Path testClasses = Path.of(System.getProperty("test.classes", "")); + JarUtils.createJarFile(MISSING_SYSTEM, testClasses, Path.of("missingsystem", "App.class")); + } + + @Test + public void testSingleJarClassPath() { + assertFailure(jnativescan("--class-path", MISSING_SYSTEM.toString(), "--release", "21")) + .stdoutShouldBeEmpty() + .stderrShouldContain("Error while processing method") + .stderrShouldContain("missingsystem.App::main(String[])void") + .stderrShouldContain("CAUSED BY:") + .stderrShouldContain("System class can not be found") + .stderrShouldContain("java.lang.Compiler"); + } +} diff --git a/test/langtools/tools/jnativescan/TestSubclassRefs.java b/test/langtools/tools/jnativescan/TestSubclassRefs.java new file mode 100644 index 0000000000000..c8eed0439ee75 --- /dev/null +++ b/test/langtools/tools/jnativescan/TestSubclassRefs.java @@ -0,0 +1,56 @@ +/* + * 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 + * @library /test/lib .. ./cases/modules + * @build JNativeScanTestBase + * cases.classpath.subclassref.App + * @run junit TestSubclassRefs + */ + +import jdk.test.lib.util.JarUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.file.Path; + +public class TestSubclassRefs extends JNativeScanTestBase { + + static Path SUBCLASS_REF; + + @BeforeAll + public static void before() throws IOException { + SUBCLASS_REF = Path.of("subclassref.jar"); + Path testClasses = Path.of(System.getProperty("test.classes", "")); + JarUtils.createJarFile(SUBCLASS_REF, testClasses, Path.of("subclassref", "App.class")); + } + + @Test + public void testSingleJarClassPath() { + assertSuccess(jnativescan("--class-path", SUBCLASS_REF.toString())) + .stderrShouldBeEmpty() + .stdoutShouldContain(""); + } +} diff --git a/test/langtools/tools/jnativescan/cases/classpath/app/App.java b/test/langtools/tools/jnativescan/cases/classpath/app/App.java new file mode 100644 index 0000000000000..f96ab11e5764a --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/classpath/app/App.java @@ -0,0 +1,31 @@ +/* + * 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 app; + +import lib.Lib; + +public class App { + public static void main(String[] args) { + Lib.doIt(); + } +} diff --git a/test/langtools/tools/jnativescan/cases/classpath/arrayref/App.java b/test/langtools/tools/jnativescan/cases/classpath/arrayref/App.java new file mode 100644 index 0000000000000..aa480f392fbf2 --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/classpath/arrayref/App.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. + * + * 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 arrayref; + +public class App { + public static void main(String[] args) { + // reference an array method to see that + // RestrictedMethodFinder correctly handles + // references to array methods + args.clone(); + } +} diff --git a/test/langtools/tools/jnativescan/cases/classpath/lib/Lib.java b/test/langtools/tools/jnativescan/cases/classpath/lib/Lib.java new file mode 100644 index 0000000000000..ec92696364c9d --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/classpath/lib/Lib.java @@ -0,0 +1,33 @@ +/* + * 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 lib; + +import java.lang.foreign.MemorySegment; + +public class Lib { + public static void doIt() { + MemorySegment.ofAddress(1234).reinterpret(10); + } + + private static native void m(); +} diff --git a/test/langtools/tools/jnativescan/cases/classpath/missingsystem/App.java b/test/langtools/tools/jnativescan/cases/classpath/missingsystem/App.java new file mode 100644 index 0000000000000..0e20fe81eecd0 --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/classpath/missingsystem/App.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. + * + * 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 missingsystem; + +public class App { + public static void main(String[] args) { + // this class was present in Java 20, but removed in 21 + // if we compile with --release 20, but run jnativescan + // with --release 21, we should get an error + java.lang.Compiler.enable(); + } +} diff --git a/test/langtools/tools/jnativescan/cases/classpath/singlejar/main/Main.java b/test/langtools/tools/jnativescan/cases/classpath/singlejar/main/Main.java new file mode 100644 index 0000000000000..280e8646f9ff4 --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/classpath/singlejar/main/Main.java @@ -0,0 +1,34 @@ +/* + * 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 main; + +import java.lang.foreign.*; + +public class Main { + public static void main(String[] args) { + MemorySegment.ofAddress(1234).reinterpret(10); + } + + private static native void m(); +} diff --git a/test/langtools/tools/jnativescan/cases/classpath/subclassref/App.java b/test/langtools/tools/jnativescan/cases/classpath/subclassref/App.java new file mode 100644 index 0000000000000..abe9e41265e4c --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/classpath/subclassref/App.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. + * + * 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 subclassref; + +import java.util.List; + +public class App { + public static void main(String[] args) { + List l = List.of(args); + l.stream(); // List does not declare stream() + } +} diff --git a/test/langtools/tools/jnativescan/cases/classpath/unnamed_package/UnnamedPackage.java b/test/langtools/tools/jnativescan/cases/classpath/unnamed_package/UnnamedPackage.java new file mode 100644 index 0000000000000..4e8dfe69b5a19 --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/classpath/unnamed_package/UnnamedPackage.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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.foreign.*; + +public class UnnamedPackage { + public static void main(String[] args) { + MemorySegment.ofAddress(1234).reinterpret(10); + } + + private static native void m(); +} diff --git a/test/langtools/tools/jnativescan/cases/modules/org.lib/module-info.java b/test/langtools/tools/jnativescan/cases/modules/org.lib/module-info.java new file mode 100644 index 0000000000000..8572ed80e431d --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/modules/org.lib/module-info.java @@ -0,0 +1,26 @@ +/* + * 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. + */ + +module org.lib { + exports org.lib; +} diff --git a/test/langtools/tools/jnativescan/cases/modules/org.lib/org/lib/Lib.java b/test/langtools/tools/jnativescan/cases/modules/org.lib/org/lib/Lib.java new file mode 100644 index 0000000000000..3f9ea0e1ada26 --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/modules/org.lib/org/lib/Lib.java @@ -0,0 +1,34 @@ +/* + * 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 org.lib; + +import java.lang.foreign.*; + +public class Lib { + public static void doIt() { + MemorySegment.ofAddress(1234).reinterpret(10); + } + + private static native void m(); +} diff --git a/test/langtools/tools/jnativescan/cases/modules/org.lib/org/lib/Service.java b/test/langtools/tools/jnativescan/cases/modules/org.lib/org/lib/Service.java new file mode 100644 index 0000000000000..2e406d926a662 --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/modules/org.lib/org/lib/Service.java @@ -0,0 +1,26 @@ +/* + * 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 org.lib; + +public interface Service { +} diff --git a/test/langtools/tools/jnativescan/cases/modules/org.myapp/module-info.java b/test/langtools/tools/jnativescan/cases/modules/org.myapp/module-info.java new file mode 100644 index 0000000000000..8155fb5d8f260 --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/modules/org.myapp/module-info.java @@ -0,0 +1,28 @@ +/* + * 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. + */ + +module org.myapp { + requires org.lib; + + uses org.lib.Service; +} diff --git a/test/langtools/tools/jnativescan/cases/modules/org.myapp/org/myapp/main/Main.java b/test/langtools/tools/jnativescan/cases/modules/org.myapp/org/myapp/main/Main.java new file mode 100644 index 0000000000000..c2329b2ceeb2f --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/modules/org.myapp/org/myapp/main/Main.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. + * + * 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.myapp.main; + +import org.lib.Lib; + +public class Main { + public static void main(String[] args) { + Lib.doIt(); + } +} diff --git a/test/langtools/tools/jnativescan/cases/modules/org.service/module-info.java b/test/langtools/tools/jnativescan/cases/modules/org.service/module-info.java new file mode 100644 index 0000000000000..431dd64172dd4 --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/modules/org.service/module-info.java @@ -0,0 +1,27 @@ +/* + * 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. + */ +module org.service { + requires org.lib; + + provides org.lib.Service with org.service.ServiceImpl; +} diff --git a/test/langtools/tools/jnativescan/cases/modules/org.service/org/service/ServiceImpl.java b/test/langtools/tools/jnativescan/cases/modules/org.service/org/service/ServiceImpl.java new file mode 100644 index 0000000000000..6e643f1c649f1 --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/modules/org.service/org/service/ServiceImpl.java @@ -0,0 +1,35 @@ +/* + * 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 org.service; + +import org.lib.Service; + +import java.lang.foreign.MemorySegment; + +public class ServiceImpl implements Service { + public void doIt() { + MemorySegment.ofAddress(1234).reinterpret(10); + } + + private native void m(); +} diff --git a/test/langtools/tools/jnativescan/cases/modules/org.singlejar/module-info.java b/test/langtools/tools/jnativescan/cases/modules/org.singlejar/module-info.java new file mode 100644 index 0000000000000..c9f96e4f77147 --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/modules/org.singlejar/module-info.java @@ -0,0 +1,25 @@ +/* + * 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. + */ +module org.singlejar { + +} diff --git a/test/langtools/tools/jnativescan/cases/modules/org.singlejar/org/singlejar/main/Main.java b/test/langtools/tools/jnativescan/cases/modules/org.singlejar/org/singlejar/main/Main.java new file mode 100644 index 0000000000000..c6925eaf64996 --- /dev/null +++ b/test/langtools/tools/jnativescan/cases/modules/org.singlejar/org/singlejar/main/Main.java @@ -0,0 +1,34 @@ +/* + * 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 org.singlejar.main; + +import java.lang.foreign.*; + +public class Main { + public static void main(String[] args) { + MemorySegment.ofAddress(1234).reinterpret(10); + } + + private static native void m(); +} From be3676f6bbc2d8041e43cf7bcfaee7fb9d864378 Mon Sep 17 00:00:00 2001 From: Matias Saavedra Silva Date: Mon, 8 Jul 2024 14:04:32 +0000 Subject: [PATCH 015/401] 8304484: CDS dynamic dumping incorrectly leads to "Error occurred during initialization of VM" Reviewed-by: ccheung, iklam --- src/hotspot/share/classfile/classLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp index 910cbe48c5c19..e410824e3001c 100644 --- a/src/hotspot/share/classfile/classLoader.cpp +++ b/src/hotspot/share/classfile/classLoader.cpp @@ -470,7 +470,7 @@ bool ClassPathImageEntry::is_modules_image() const { void ClassLoader::exit_with_path_failure(const char* error, const char* message) { assert(CDSConfig::is_dumping_archive(), "sanity"); tty->print_cr("Hint: enable -Xlog:class+path=info to diagnose the failure"); - vm_exit_during_initialization(error, message); + vm_exit_during_cds_dumping(error, message); } #endif From d8c1c6ab0543c986280dcfa1c6c79e010a7b35fb Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Mon, 8 Jul 2024 15:45:26 +0000 Subject: [PATCH 016/401] 8335604: Serial: Inline Generation::contiguous_available Reviewed-by: tschatzl --- src/hotspot/share/gc/serial/defNewGeneration.cpp | 5 ----- src/hotspot/share/gc/serial/defNewGeneration.hpp | 2 -- src/hotspot/share/gc/serial/generation.hpp | 4 ---- src/hotspot/share/gc/serial/tenuredGeneration.cpp | 6 +----- src/hotspot/share/gc/serial/tenuredGeneration.hpp | 2 -- 5 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp index acf7e23910367..715b82fd38d32 100644 --- a/src/hotspot/share/gc/serial/defNewGeneration.cpp +++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp @@ -533,11 +533,6 @@ size_t DefNewGeneration::capacity_before_gc() const { return eden()->capacity(); } -size_t DefNewGeneration::contiguous_available() const { - return eden()->free(); -} - - void DefNewGeneration::object_iterate(ObjectClosure* blk) { eden()->object_iterate(blk); from()->object_iterate(blk); diff --git a/src/hotspot/share/gc/serial/defNewGeneration.hpp b/src/hotspot/share/gc/serial/defNewGeneration.hpp index a7ee555902a25..011b79fdabd6b 100644 --- a/src/hotspot/share/gc/serial/defNewGeneration.hpp +++ b/src/hotspot/share/gc/serial/defNewGeneration.hpp @@ -172,8 +172,6 @@ class DefNewGeneration: public Generation { // heuristic resizing decisions. size_t unsafe_max_alloc_nogc() const; - size_t contiguous_available() const; - size_t max_eden_size() const { return _max_eden_size; } size_t max_survivor_size() const { return _max_survivor_size; } diff --git a/src/hotspot/share/gc/serial/generation.hpp b/src/hotspot/share/gc/serial/generation.hpp index 5e5aad5d0c1b2..a757c97c5cb15 100644 --- a/src/hotspot/share/gc/serial/generation.hpp +++ b/src/hotspot/share/gc/serial/generation.hpp @@ -96,10 +96,6 @@ class Generation: public CHeapObj { // for the allocation of objects. virtual size_t max_capacity() const; - // The largest number of contiguous free bytes in the generation, - // including expansion (Assumes called at a safepoint.) - virtual size_t contiguous_available() const = 0; - MemRegion reserved() const { return _reserved; } /* Returns "TRUE" iff "p" points into the reserved area of the generation. */ diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.cpp b/src/hotspot/share/gc/serial/tenuredGeneration.cpp index f1389b48557f8..b1b7507094771 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.cpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.cpp @@ -377,7 +377,7 @@ void TenuredGeneration::update_counters() { } bool TenuredGeneration::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const { - size_t available = contiguous_available(); + size_t available = _the_space->free() + _virtual_space.uncommitted_size(); size_t av_promo = (size_t)_avg_promoted->padded_average(); bool res = (available >= av_promo) || (available >= max_promotion_in_bytes); @@ -413,10 +413,6 @@ TenuredGeneration::expand_and_allocate(size_t word_size, bool is_tlab) { return allocate(word_size, is_tlab); } -size_t TenuredGeneration::contiguous_available() const { - return _the_space->free() + _virtual_space.uncommitted_size(); -} - void TenuredGeneration::assert_correct_size_change_locking() { assert_locked_or_safepoint(Heap_lock); } diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.hpp b/src/hotspot/share/gc/serial/tenuredGeneration.hpp index bcb2d668213e8..dcec912d4887f 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.hpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.hpp @@ -124,8 +124,6 @@ class TenuredGeneration: public Generation { const char* name() const { return "tenured generation"; } const char* short_name() const { return "Tenured"; } - size_t contiguous_available() const; - // Iteration void object_iterate(ObjectClosure* blk); From a9b7f42f29120a3cca0d341350ff03cae485e68b Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Mon, 8 Jul 2024 16:20:01 +0000 Subject: [PATCH 017/401] 8333826: Update --release 23 symbol information for JDK 23 build 29 Reviewed-by: iris, jlahoda --- src/jdk.compiler/share/data/symbols/java.desktop-N.sym.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/jdk.compiler/share/data/symbols/java.desktop-N.sym.txt b/src/jdk.compiler/share/data/symbols/java.desktop-N.sym.txt index fdc899578cf82..577ff91c7caad 100644 --- a/src/jdk.compiler/share/data/symbols/java.desktop-N.sym.txt +++ b/src/jdk.compiler/share/data/symbols/java.desktop-N.sym.txt @@ -119,6 +119,10 @@ class name javax/swing/JScrollBar method name setMinimumSize descriptor (Ljava/awt/Dimension;)V flags 1 method name setMaximumSize descriptor (Ljava/awt/Dimension;)V flags 1 +class name javax/swing/plaf/basic/BasicSliderUI +-method name descriptor ()V +method name descriptor ()V flags 1 deprecated true runtimeAnnotations @Ljava/lang/Deprecated;(forRemoval=Ztrue,since="23") + class name javax/swing/plaf/synth/SynthTreeUI method name getCollapsedIcon descriptor ()Ljavax/swing/Icon; flags 1 From 284671a1e4fb5bfe15b20b7f41fc24415b1235ed Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Mon, 8 Jul 2024 16:44:22 +0000 Subject: [PATCH 018/401] 8335449: runtime/cds/DeterministicDump.java fails with File content different at byte ... Reviewed-by: matsaave, iklam --- test/hotspot/jtreg/runtime/cds/DeterministicDump.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/runtime/cds/DeterministicDump.java b/test/hotspot/jtreg/runtime/cds/DeterministicDump.java index 8f9bb4a582985..cc8d8c2b1dde9 100644 --- a/test/hotspot/jtreg/runtime/cds/DeterministicDump.java +++ b/test/hotspot/jtreg/runtime/cds/DeterministicDump.java @@ -25,7 +25,7 @@ * @test * @bug 8241071 * @summary The same JDK build should always generate the same archive file (no randomness). - * @requires vm.cds + * @requires vm.cds & vm.flagless * @library /test/lib * @run driver DeterministicDump */ From 3a87eb5c4606ce39970962895315567e8606eba7 Mon Sep 17 00:00:00 2001 From: Kelvin Nilsen Date: Mon, 8 Jul 2024 18:03:19 +0000 Subject: [PATCH 019/401] 8335126: Shenandoah: Improve OOM handling Reviewed-by: shade, ysr, wkemper, rkennke --- .../gc/shenandoah/shenandoahControlThread.cpp | 3 +- .../gc/shenandoah/shenandoahDegeneratedGC.cpp | 1 - .../share/gc/shenandoah/shenandoahHeap.cpp | 48 ++++++++++++------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp index e538ca024678f..95a70de5790e9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp @@ -318,7 +318,8 @@ void ShenandoahControlThread::service_concurrent_normal_cycle(GCCause::Cause cau ShenandoahConcurrentGC gc; if (gc.collect(cause)) { - // Cycle is complete + // Cycle is complete. There were no failed allocation requests and no degeneration, so count this as good progress. + heap->notify_gc_progress(); heap->heuristics()->record_success_concurrent(); heap->shenandoah_policy()->record_success_concurrent(gc.abbreviated()); } else { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp index fb5283bb1d88d..6b597d9b2d7b3 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp @@ -228,7 +228,6 @@ void ShenandoahDegenGC::op_degenerated() { // Check for futility and fail. There is no reason to do several back-to-back Degenerated cycles, // because that probably means the heap is overloaded and/or fragmented. if (!metrics.is_good_progress()) { - heap->notify_gc_no_progress(); heap->cancel_gc(GCCause::_shenandoah_upgrade_to_full_gc); op_degenerated_futile(); } else { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index ee3f4e7d8eb8c..5c5b6f7ebe58d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -945,24 +945,36 @@ HeapWord* ShenandoahHeap::allocate_memory(ShenandoahAllocRequest& req) { return nullptr; } - // Block until control thread reacted, then retry allocation. - // - // It might happen that one of the threads requesting allocation would unblock - // way later after GC happened, only to fail the second allocation, because - // other threads have already depleted the free storage. In this case, a better - // strategy is to try again, as long as GC makes progress (or until at least - // one full GC has completed). - size_t original_count = shenandoah_policy()->full_gc_count(); - while (result == nullptr - && (get_gc_no_progress_count() == 0 || original_count == shenandoah_policy()->full_gc_count())) { - control_thread()->handle_alloc_failure(req, true); - result = allocate_memory_under_lock(req, in_new_region); - } - - if (log_is_enabled(Debug, gc, alloc)) { - ResourceMark rm; - log_debug(gc, alloc)("Thread: %s, Result: " PTR_FORMAT ", Request: %s, Size: " SIZE_FORMAT ", Original: " SIZE_FORMAT ", Latest: " SIZE_FORMAT, - Thread::current()->name(), p2i(result), req.type_string(), req.size(), original_count, get_gc_no_progress_count()); + if (result == nullptr) { + // Block until control thread reacted, then retry allocation. + // + // It might happen that one of the threads requesting allocation would unblock + // way later after GC happened, only to fail the second allocation, because + // other threads have already depleted the free storage. In this case, a better + // strategy is to try again, until at least one full GC has completed. + // + // Stop retrying and return nullptr to cause OOMError exception if our allocation failed even after: + // a) We experienced a GC that had good progress, or + // b) We experienced at least one Full GC (whether or not it had good progress) + // + // TODO: Consider GLOBAL GC rather than Full GC to remediate OOM condition: https://bugs.openjdk.org/browse/JDK-8335910 + + size_t original_count = shenandoah_policy()->full_gc_count(); + while ((result == nullptr) && (original_count == shenandoah_policy()->full_gc_count())) { + control_thread()->handle_alloc_failure(req, true); + result = allocate_memory_under_lock(req, in_new_region); + } + if (result != nullptr) { + // If our allocation request has been satisifed after it initially failed, we count this as good gc progress + notify_gc_progress(); + } + if (log_is_enabled(Debug, gc, alloc)) { + ResourceMark rm; + log_debug(gc, alloc)("Thread: %s, Result: " PTR_FORMAT ", Request: %s, Size: " SIZE_FORMAT + ", Original: " SIZE_FORMAT ", Latest: " SIZE_FORMAT, + Thread::current()->name(), p2i(result), req.type_string(), req.size(), + original_count, get_gc_no_progress_count()); + } } } else { assert(req.is_gc_alloc(), "Can only accept GC allocs here"); From 3733fe3a207078b585421cd2a098e808fafaa817 Mon Sep 17 00:00:00 2001 From: "lawrence.andrews" Date: Mon, 8 Jul 2024 19:14:33 +0000 Subject: [PATCH 020/401] 8335789: [TESTBUG] XparColor.java test fails with Error. Parse Exception: Invalid or unrecognized bugid: @ Reviewed-by: aivanov --- test/jdk/java/awt/print/PrinterJob/XparColor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/awt/print/PrinterJob/XparColor.java b/test/jdk/java/awt/print/PrinterJob/XparColor.java index 9a85a78af558a..30713b1424e53 100644 --- a/test/jdk/java/awt/print/PrinterJob/XparColor.java +++ b/test/jdk/java/awt/print/PrinterJob/XparColor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, 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 @@ -24,7 +24,7 @@ /** * @test * @bug 4179262 - @ @key printer + * @key printer * @summary Confirm that transparent colors are printed correctly. The * printout should show transparent rings with increasing darkness toward * the center. From babf6df7d97e4beedb25e689634d999412c1e950 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 8 Jul 2024 20:09:07 +0000 Subject: [PATCH 021/401] 8334757: AssertionError: Missing type variable in where clause Reviewed-by: jlahoda, vromero --- .../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 e1faa02bd38af..3bc5c671bfda2 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 0000000000000..8d575caec57c2 --- /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 0000000000000..80fa9f2cdd9c9 --- /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 bb1f8a1698553d5962569ac8912edd0d7ef010dd Mon Sep 17 00:00:00 2001 From: Xiaolong Peng Date: Mon, 8 Jul 2024 20:10:27 +0000 Subject: [PATCH 022/401] 8335904: Fix invalid comment in ShenandoahLock Reviewed-by: shade --- src/hotspot/share/gc/shenandoah/shenandoahLock.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp b/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp index 6fc74c53e6390..63c6c9ea88624 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp @@ -44,7 +44,7 @@ void ShenandoahLock::contended_lock(bool allow_block_for_safepoint) { template void ShenandoahLock::contended_lock_internal(JavaThread* java_thread) { assert(!ALLOW_BLOCK || java_thread != nullptr, "Must have a Java thread when allowing block."); - // Spin this much on multi-processor, do not spin on multi-processor. + // Spin this much, but only on multi-processor systems. int ctr = os::is_MP() ? 0xFF : 0; // Apply TTAS to avoid more expensive CAS calls if the lock is still held by other thread. while (Atomic::load(&_state) == locked || From 9c7a6eabb93c570fdb74076edc931576ed6be3e0 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Mon, 8 Jul 2024 20:14:26 +0000 Subject: [PATCH 023/401] 8312125: Refactor CDS enum class handling Reviewed-by: matsaave, ccheung --- src/hotspot/share/cds/cdsEnumKlass.cpp | 136 +++++++++++++++++++++++ src/hotspot/share/cds/cdsEnumKlass.hpp | 50 +++++++++ src/hotspot/share/cds/heapShared.cpp | 94 +--------------- src/hotspot/share/cds/heapShared.hpp | 4 - src/hotspot/share/oops/instanceKlass.cpp | 3 +- 5 files changed, 192 insertions(+), 95 deletions(-) create mode 100644 src/hotspot/share/cds/cdsEnumKlass.cpp create mode 100644 src/hotspot/share/cds/cdsEnumKlass.hpp diff --git a/src/hotspot/share/cds/cdsEnumKlass.cpp b/src/hotspot/share/cds/cdsEnumKlass.cpp new file mode 100644 index 0000000000000..b77f2fd9d16ad --- /dev/null +++ b/src/hotspot/share/cds/cdsEnumKlass.cpp @@ -0,0 +1,136 @@ +/* + * 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 + * 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. + * + */ + +#include "precompiled.hpp" +#include "cds/archiveHeapLoader.hpp" +#include "cds/cdsEnumKlass.hpp" +#include "cds/heapShared.hpp" +#include "classfile/vmClasses.hpp" +#include "classfile/systemDictionaryShared.hpp" +#include "memory/resourceArea.hpp" +#include "oops/fieldStreams.inline.hpp" +#include "oops/oop.inline.hpp" +#include "runtime/fieldDescriptor.inline.hpp" + +#if INCLUDE_CDS_JAVA_HEAP + +bool CDSEnumKlass::is_enum_obj(oop orig_obj) { + Klass* k = orig_obj->klass(); + Klass* buffered_k = ArchiveBuilder::get_buffered_klass(k); + return k->is_instance_klass() && + InstanceKlass::cast(k)->java_super() == vmClasses::Enum_klass(); +} + +// -- Handling of Enum objects +// Java Enum classes have synthetic methods that look like this +// enum MyEnum {FOO, BAR} +// MyEnum:: { +// /*static final MyEnum*/ MyEnum::FOO = new MyEnum("FOO"); +// /*static final MyEnum*/ MyEnum::BAR = new MyEnum("BAR"); +// } +// +// If MyEnum::FOO object is referenced by any of the archived subgraphs, we must +// ensure the archived value equals (in object address) to the runtime value of +// MyEnum::FOO. +// +// However, since MyEnum:: is synthetically generated by javac, there's +// no way of programmatically handling this inside the Java code (as you would handle +// ModuleLayer::EMPTY_LAYER, for example). +// +// Instead, we archive all static field of such Enum classes. At runtime, +// HeapShared::initialize_enum_klass() skips the method and instead pulls +// the static fields out of the archived heap. +void CDSEnumKlass::handle_enum_obj(int level, + KlassSubGraphInfo* subgraph_info, + oop orig_obj) { + assert(level > 1, "must never be called at the first (outermost) level"); + assert(is_enum_obj(orig_obj), "must be"); + + InstanceKlass* ik = InstanceKlass::cast(orig_obj->klass()); + if (ik->has_archived_enum_objs()) { + return; + } + + ik->set_has_archived_enum_objs(); + ArchiveBuilder::get_buffered_klass(ik)->set_has_archived_enum_objs(); + + oop mirror = ik->java_mirror(); + for (JavaFieldStream fs(ik); !fs.done(); fs.next()) { + if (fs.access_flags().is_static()) { + archive_static_field(level, subgraph_info, ik, mirror, fs); + } + } +} + +void CDSEnumKlass::archive_static_field(int level, KlassSubGraphInfo* subgraph_info, + InstanceKlass* ik, oop mirror, JavaFieldStream& fs) { + ResourceMark rm; + fieldDescriptor& fd = fs.field_descriptor(); + if (fd.field_type() != T_OBJECT && fd.field_type() != T_ARRAY) { + guarantee(false, "static field %s::%s must be T_OBJECT or T_ARRAY", + ik->external_name(), fd.name()->as_C_string()); + } + oop oop_field = mirror->obj_field(fd.offset()); + if (oop_field == nullptr) { + guarantee(false, "static field %s::%s must not be null", + ik->external_name(), fd.name()->as_C_string()); + } else if (oop_field->klass() != ik && oop_field->klass() != ik->array_klass_or_null()) { + guarantee(false, "static field %s::%s is of the wrong type", + ik->external_name(), fd.name()->as_C_string()); + } + bool success = HeapShared::archive_reachable_objects_from(level, subgraph_info, oop_field); + assert(success, "VM should have exited with unarchivable objects for _level > 1"); + int root_index = HeapShared::append_root(oop_field); + log_info(cds, heap)("Archived enum obj @%d %s::%s (" INTPTR_FORMAT ")", + root_index, ik->external_name(), fd.name()->as_C_string(), + p2i((oopDesc*)oop_field)); + SystemDictionaryShared::add_enum_klass_static_field(ik, root_index); +} + +bool CDSEnumKlass::initialize_enum_klass(InstanceKlass* k, TRAPS) { + if (!ArchiveHeapLoader::is_in_use()) { + return false; + } + + RunTimeClassInfo* info = RunTimeClassInfo::get_for(k); + assert(info != nullptr, "sanity"); + + if (log_is_enabled(Info, cds, heap)) { + ResourceMark rm; + log_info(cds, heap)("Initializing Enum class: %s", k->external_name()); + } + + oop mirror = k->java_mirror(); + int i = 0; + for (JavaFieldStream fs(k); !fs.done(); fs.next()) { + if (fs.access_flags().is_static()) { + int root_index = info->enum_klass_static_field_root_index_at(i++); + fieldDescriptor& fd = fs.field_descriptor(); + assert(fd.field_type() == T_OBJECT || fd.field_type() == T_ARRAY, "must be"); + mirror->obj_field_put(fd.offset(), HeapShared::get_root(root_index, /*clear=*/true)); + } + } + return true; +} +#endif // INCLUDE_CDS_JAVA_HEAP diff --git a/src/hotspot/share/cds/cdsEnumKlass.hpp b/src/hotspot/share/cds/cdsEnumKlass.hpp new file mode 100644 index 0000000000000..c898bfec60d45 --- /dev/null +++ b/src/hotspot/share/cds/cdsEnumKlass.hpp @@ -0,0 +1,50 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_CDS_CDSENUMKLASS_HPP +#define SHARE_CDS_CDSENUMKLASS_HPP + +#include "memory/allStatic.hpp" +#include "oops/oop.hpp" +#include "utilities/exceptions.hpp" +#include "utilities/macros.hpp" + +class InstanceKlass; +class JavaFieldStream; +class KlassSubGraphInfo; + +class CDSEnumKlass: AllStatic { +public: + static bool is_enum_obj(oop orig_obj); + static void handle_enum_obj(int level, + KlassSubGraphInfo* subgraph_info, + oop orig_obj); + static bool initialize_enum_klass(InstanceKlass* k, TRAPS) NOT_CDS_JAVA_HEAP_RETURN_(false); + +private: + static void archive_static_field(int level, KlassSubGraphInfo* subgraph_info, + InstanceKlass* ik, oop mirror, JavaFieldStream& fs); +}; + +#endif // SHARE_CDS_CDSENUMKLASS_HPP diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index 7b519a57d57cd..ff84ddc13fc6c 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -28,6 +28,7 @@ #include "cds/archiveHeapWriter.hpp" #include "cds/archiveUtils.hpp" #include "cds/cdsConfig.hpp" +#include "cds/cdsEnumKlass.hpp" #include "cds/cdsHeapVerifier.hpp" #include "cds/heapShared.hpp" #include "cds/metaspaceShared.hpp" @@ -451,95 +452,6 @@ void HeapShared::set_has_native_pointers(oop src_obj) { info->set_has_native_pointers(); } -// -- Handling of Enum objects -// Java Enum classes have synthetic methods that look like this -// enum MyEnum {FOO, BAR} -// MyEnum:: { -// /*static final MyEnum*/ MyEnum::FOO = new MyEnum("FOO"); -// /*static final MyEnum*/ MyEnum::BAR = new MyEnum("BAR"); -// } -// -// If MyEnum::FOO object is referenced by any of the archived subgraphs, we must -// ensure the archived value equals (in object address) to the runtime value of -// MyEnum::FOO. -// -// However, since MyEnum:: is synthetically generated by javac, there's -// no way of programmatically handling this inside the Java code (as you would handle -// ModuleLayer::EMPTY_LAYER, for example). -// -// Instead, we archive all static field of such Enum classes. At runtime, -// HeapShared::initialize_enum_klass() will skip the method and pull -// the static fields out of the archived heap. -void HeapShared::check_enum_obj(int level, - KlassSubGraphInfo* subgraph_info, - oop orig_obj) { - assert(level > 1, "must never be called at the first (outermost) level"); - Klass* k = orig_obj->klass(); - Klass* buffered_k = ArchiveBuilder::get_buffered_klass(k); - if (!k->is_instance_klass()) { - return; - } - InstanceKlass* ik = InstanceKlass::cast(k); - if (ik->java_super() == vmClasses::Enum_klass() && !ik->has_archived_enum_objs()) { - ResourceMark rm; - ik->set_has_archived_enum_objs(); - buffered_k->set_has_archived_enum_objs(); - oop mirror = ik->java_mirror(); - - for (JavaFieldStream fs(ik); !fs.done(); fs.next()) { - if (fs.access_flags().is_static()) { - fieldDescriptor& fd = fs.field_descriptor(); - if (fd.field_type() != T_OBJECT && fd.field_type() != T_ARRAY) { - guarantee(false, "static field %s::%s must be T_OBJECT or T_ARRAY", - ik->external_name(), fd.name()->as_C_string()); - } - oop oop_field = mirror->obj_field(fd.offset()); - if (oop_field == nullptr) { - guarantee(false, "static field %s::%s must not be null", - ik->external_name(), fd.name()->as_C_string()); - } else if (oop_field->klass() != ik && oop_field->klass() != ik->array_klass_or_null()) { - guarantee(false, "static field %s::%s is of the wrong type", - ik->external_name(), fd.name()->as_C_string()); - } - bool success = archive_reachable_objects_from(level, subgraph_info, oop_field); - assert(success, "VM should have exited with unarchivable objects for _level > 1"); - int root_index = append_root(oop_field); - log_info(cds, heap)("Archived enum obj @%d %s::%s (" INTPTR_FORMAT ")", - root_index, ik->external_name(), fd.name()->as_C_string(), - p2i((oopDesc*)oop_field)); - SystemDictionaryShared::add_enum_klass_static_field(ik, root_index); - } - } - } -} - -// See comments in HeapShared::check_enum_obj() -bool HeapShared::initialize_enum_klass(InstanceKlass* k, TRAPS) { - if (!ArchiveHeapLoader::is_in_use()) { - return false; - } - - RunTimeClassInfo* info = RunTimeClassInfo::get_for(k); - assert(info != nullptr, "sanity"); - - if (log_is_enabled(Info, cds, heap)) { - ResourceMark rm; - log_info(cds, heap)("Initializing Enum class: %s", k->external_name()); - } - - oop mirror = k->java_mirror(); - int i = 0; - for (JavaFieldStream fs(k); !fs.done(); fs.next()) { - if (fs.access_flags().is_static()) { - int root_index = info->enum_klass_static_field_root_index_at(i++); - fieldDescriptor& fd = fs.field_descriptor(); - assert(fd.field_type() == T_OBJECT || fd.field_type() == T_ARRAY, "must be"); - mirror->obj_field_put(fd.offset(), get_root(root_index, /*clear=*/true)); - } - } - return true; -} - void HeapShared::archive_objects(ArchiveHeapInfo *heap_info) { { NoSafepointVerifier nsv; @@ -1241,7 +1153,9 @@ bool HeapShared::archive_reachable_objects_from(int level, WalkOopAndArchiveClosure walker(level, record_klasses_only, subgraph_info, orig_obj); orig_obj->oop_iterate(&walker); - check_enum_obj(level + 1, subgraph_info, orig_obj); + if (CDSEnumKlass::is_enum_obj(orig_obj)) { + CDSEnumKlass::handle_enum_obj(level + 1, subgraph_info, orig_obj); + } return true; } diff --git a/src/hotspot/share/cds/heapShared.hpp b/src/hotspot/share/cds/heapShared.hpp index aa8c1dd3bc4f9..fa34289a38eda 100644 --- a/src/hotspot/share/cds/heapShared.hpp +++ b/src/hotspot/share/cds/heapShared.hpp @@ -212,9 +212,6 @@ class HeapShared: AllStatic { }; private: - static void check_enum_obj(int level, KlassSubGraphInfo* subgraph_info, - oop orig_obj); - static const int INITIAL_TABLE_SIZE = 15889; // prime number static const int MAX_TABLE_SIZE = 1000000; typedef ResizeableResourceHashtable Date: Tue, 9 Jul 2024 08:10:55 +0000 Subject: [PATCH 024/401] 8335955: JDK-8335742 wrongly used a "JDK-" prefix in the problemlist bug number Reviewed-by: iwalulya --- test/hotspot/jtreg/ProblemList-Virtual.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/ProblemList-Virtual.txt b/test/hotspot/jtreg/ProblemList-Virtual.txt index ac35f60e66153..06110ddcbc1a8 100644 --- a/test/hotspot/jtreg/ProblemList-Virtual.txt +++ b/test/hotspot/jtreg/ProblemList-Virtual.txt @@ -89,7 +89,7 @@ vmTestbase/nsk/jdi/VMOutOfMemoryException/VMOutOfMemoryException001/VMOutOfMemor ### # Fails on Windows because of additional memory allocation. -gc/g1/TestMixedGCLiveThreshold.java#25percent JDK-8334759 windows-x64 +gc/g1/TestMixedGCLiveThreshold.java#25percent 8334759 windows-x64 ########## ## Tests incompatible with with virtual test thread factory. From 2a2964759c73b3b9ab6afaad109383c89952977b Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Tue, 9 Jul 2024 08:25:00 +0000 Subject: [PATCH 025/401] 8334777: Test javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java failed with NullPointerException Reviewed-by: cjplummer, dholmes --- .../remote/mandatory/notif/NotifReconnectDeadlockTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/jdk/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java b/test/jdk/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java index 72ae57663079c..8f8ef54eade22 100644 --- a/test/jdk/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java +++ b/test/jdk/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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,9 @@ * @bug 6199899 * @summary Tests reconnection done by a fetching notif thread. * @author Shanliang JIANG + * @requires vm.compMode != "Xcomp" + * @comment Running with -Xcomp is likely to cause a timeout from ServerCommunicatorAdmin + * before addNotificationListener can complete. * * @run clean NotifReconnectDeadlockTest * @run build NotifReconnectDeadlockTest From 8f62f31dff564289a2422d58e8ecd5062d443b81 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Tue, 9 Jul 2024 08:26:25 +0000 Subject: [PATCH 026/401] 8335906: [s390x] Test Failure: GTestWrapper.java Reviewed-by: stuefe --- src/hotspot/share/runtime/os.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index 7b766707b0d0e..490a04aa6f132 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -959,7 +959,7 @@ static void print_ascii_form(stringStream& ascii_form, uint64_t value, int units uint8_t c[sizeof(v)]; } u = { value }; for (int i = 0; i < unitsize; i++) { - const int idx = LITTLE_ENDIAN_ONLY(i) BIG_ENDIAN_ONLY(sizeof(u.v) - 1 - i); + const int idx = LITTLE_ENDIAN_ONLY(i) BIG_ENDIAN_ONLY(sizeof(u.v) - unitsize + i); const uint8_t c = u.c[idx]; ascii_form.put(isprint(c) && isascii(c) ? c : '.'); } From f3ff4f7427c3c3f5cb2a115a61462bb9d28de1cd Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Tue, 9 Jul 2024 10:21:47 +0000 Subject: [PATCH 027/401] 8335882: platform/cgroup/TestSystemSettings.java fails on Alpine Linux Reviewed-by: stuefe, mbaesken --- test/jdk/jdk/internal/platform/cgroup/TestSystemSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/jdk/internal/platform/cgroup/TestSystemSettings.java b/test/jdk/jdk/internal/platform/cgroup/TestSystemSettings.java index 8d9279e1603c1..0e668b1f969d4 100644 --- a/test/jdk/jdk/internal/platform/cgroup/TestSystemSettings.java +++ b/test/jdk/jdk/internal/platform/cgroup/TestSystemSettings.java @@ -24,7 +24,7 @@ /* * @test * @key cgroups - * @requires os.family == "linux" + * @requires (os.family == "linux" & !vm.musl) * @requires vm.flagless * @library /test/lib * @build TestSystemSettings From 0e0dfca21f64ecfcb3e5ed7cdc2a173834faa509 Mon Sep 17 00:00:00 2001 From: Aleksei Voitylov Date: Tue, 9 Jul 2024 10:27:44 +0000 Subject: [PATCH 028/401] 8330806: test/hotspot/jtreg/compiler/c1/TestLargeMonitorOffset.java fails on ARM32 Reviewed-by: snazarki, dsamersoff --- src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp index 688790f07e548..999f8fe590472 100644 --- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp +++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp @@ -152,8 +152,14 @@ void LIR_Assembler::osr_entry() { int monitor_offset = (method()->max_locals() + 2 * (number_of_locks - 1)) * BytesPerWord; for (int i = 0; i < number_of_locks; i++) { int slot_offset = monitor_offset - (i * 2 * BytesPerWord); - __ ldr(R1, Address(OSR_buf, slot_offset + 0*BytesPerWord)); - __ ldr(R2, Address(OSR_buf, slot_offset + 1*BytesPerWord)); + if (slot_offset >= 4096 - BytesPerWord) { + __ add_slow(R2, OSR_buf, slot_offset); + __ ldr(R1, Address(R2, 0*BytesPerWord)); + __ ldr(R2, Address(R2, 1*BytesPerWord)); + } else { + __ ldr(R1, Address(OSR_buf, slot_offset + 0*BytesPerWord)); + __ ldr(R2, Address(OSR_buf, slot_offset + 1*BytesPerWord)); + } __ str(R1, frame_map()->address_for_monitor_lock(i)); __ str(R2, frame_map()->address_for_monitor_object(i)); } From 531a6d85b00b88688668ab1ced0db6ce0214a5f1 Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Tue, 9 Jul 2024 13:11:07 +0000 Subject: [PATCH 029/401] 8335911: Document ccls indexer in doc/ide.md Reviewed-by: erikj --- doc/ide.html | 11 ++++++----- doc/ide.md | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/ide.html b/doc/ide.html index 0dd16b7b9e6e7..ef6f434013ed1 100644 --- a/doc/ide.html +++ b/doc/ide.html @@ -63,11 +63,12 @@
Alternative indexers

The main vscode-project target configures the default C++ support in Visual Studio Code. There are also other source indexers that can be installed, that may provide additional features. It's -currently possible to generate configuration for two such indexers, clangd and rtags. These can be -configured by appending the name of the indexer to the make target, such -as:

+currently possible to generate configuration for three such indexers, clangd, ccls +and rtags. These can +be configured by appending the name of the indexer to the make target, +such as:

make vscode-project-clangd

Additional instructions for configuring the given indexer will be displayed after the workspace has been generated.

diff --git a/doc/ide.md b/doc/ide.md index 40e3430a43875..d6ebb7b742a61 100644 --- a/doc/ide.md +++ b/doc/ide.md @@ -32,7 +32,8 @@ choose `File -> Open Workspace...` in Visual Studio Code. The main `vscode-project` target configures the default C++ support in Visual Studio Code. There are also other source indexers that can be installed, that may provide additional features. It's currently possible to generate -configuration for two such indexers, [clangd](https://clang.llvm.org/extra/clangd/) +configuration for three such indexers, [clangd](https://clang.llvm.org/extra/clangd/), +[ccls](https://github.com/MaskRay/ccls/wiki/Visual-Studio-Code) and [rtags](https://github.com/Andersbakken/rtags). These can be configured by appending the name of the indexer to the make target, such as: From 7e11fb702696df733ca89d325200f2e9414402d9 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 9 Jul 2024 13:11:20 +0000 Subject: [PATCH 030/401] 8335688: Fix -Wzero-as-null-pointer-constant warnings from fflush calls in jvmti tests Reviewed-by: jwaters, coleenp --- .../libAddModuleUsesAndProvidesTest.c | 6 +- .../GenerateEvents/libGenerateEvents1.cpp | 2 +- .../GenerateEvents/libGenerateEvents2.cpp | 4 +- .../FilteredFields/libFilteredFieldsTest.cpp | 4 +- .../libMissedStackMapFrames.cpp | 2 +- .../libRedefineRetransform.cpp | 2 +- .../FramePop/framepop02/libframepop02.cpp | 4 +- .../thread/GetStackTrace/get_stack_trace.hpp | 2 +- .../SuspendResume1/libSuspendResume1.cpp | 6 +- .../getclfld007/getclfld007.cpp | 6 +- .../followref001/followref001.cpp | 58 ++++++++-------- .../followref002/followref002.cpp | 62 ++++++++--------- .../followref003/followref003.cpp | 68 +++++++++---------- .../followref004/followref004.cpp | 12 ++-- .../followref005/followref005.cpp | 2 +- .../followref006/followref006.cpp | 2 +- .../earlyretbase/earlyretbase.cpp | 12 ++-- .../earlyretfp/earlyretfp.cpp | 18 ++--- .../earlyretint/earlyretint.cpp | 14 ++-- .../earlyretlong/earlyretlong.cpp | 14 ++-- .../earlyretobj/earlyretobj.cpp | 14 ++-- .../earlyretstr/earlyretstr.cpp | 12 ++-- .../earlyretvoid/earlyretvoid.cpp | 12 ++-- .../getallstktr001/getallstktr001.cpp | 6 +- .../getcpool001/getcpool001.cpp | 6 +- 25 files changed, 175 insertions(+), 175 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/jvmti/AddModuleUsesAndProvides/libAddModuleUsesAndProvidesTest.c b/test/hotspot/jtreg/serviceability/jvmti/AddModuleUsesAndProvides/libAddModuleUsesAndProvidesTest.c index 86f9993c70334..a979d1f913e0a 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/AddModuleUsesAndProvides/libAddModuleUsesAndProvidesTest.c +++ b/test/hotspot/jtreg/serviceability/jvmti/AddModuleUsesAndProvides/libAddModuleUsesAndProvidesTest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, 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 @@ -200,7 +200,7 @@ Java_MyPackage_AddModuleUsesAndProvidesTest_checkUses(JNIEnv *env, throw_exc(env, "Check #UC3: service can not be used unexpectedly"); return FAILED; } - fflush(0); + fflush(NULL); return PASSED; } @@ -275,7 +275,7 @@ Java_MyPackage_AddModuleUsesAndProvidesTest_checkProvides(JNIEnv *env, throw_exc(env, "Check #PC2: error in add provides to baseModule with correct service and serviceImpl"); return FAILED; } - fflush(0); + fflush(NULL); return PASSED; } diff --git a/test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/libGenerateEvents1.cpp b/test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/libGenerateEvents1.cpp index fa60c07f8db41..0f040175bf953 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/libGenerateEvents1.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/libGenerateEvents1.cpp @@ -71,7 +71,7 @@ CompiledMethodLoad(jvmtiEnv* jvmti, jmethodID method, check_jvmti_status(env, err, "CompiledMethodLoad: Error in JVMTI GetMethodName"); printf("%s: CompiledMethodLoad: %s%s\n", AGENT_NAME, name, sign); - fflush(0); + fflush(nullptr); } JNIEXPORT jint JNICALL diff --git a/test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/libGenerateEvents2.cpp b/test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/libGenerateEvents2.cpp index 7af061196a157..d582a9648920e 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/libGenerateEvents2.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/libGenerateEvents2.cpp @@ -71,7 +71,7 @@ CompiledMethodLoad(jvmtiEnv* jvmti, jmethodID method, check_jvmti_status(env, err, "CompiledMethodLoad: Error in JVMTI GetMethodName"); printf("%s: CompiledMethodLoad: %s%s\n", AGENT_NAME, name, sign); - fflush(0); + fflush(nullptr); } JNIEXPORT jint JNICALL @@ -132,7 +132,7 @@ Java_MyPackage_GenerateEventsTest_agent2FailStatus(JNIEnv *env, jclass cls) { printf("check2: Unexpected non-zero event count in agent2: %d\n", agent2_event_count); } printf("\n"); - fflush(0); + fflush(nullptr); return fail_status; } diff --git a/test/hotspot/jtreg/serviceability/jvmti/GetClassFields/FilteredFields/libFilteredFieldsTest.cpp b/test/hotspot/jtreg/serviceability/jvmti/GetClassFields/FilteredFields/libFilteredFieldsTest.cpp index 28bfaaa03bd6f..fbefb1219e602 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/GetClassFields/FilteredFields/libFilteredFieldsTest.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/GetClassFields/FilteredFields/libFilteredFieldsTest.cpp @@ -35,7 +35,7 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { jint res = jvm->GetEnv((void **)&jvmti, JVMTI_VERSION_1_1); if (res != JNI_OK || jvmti == nullptr) { printf("Wrong result of a valid call to GetEnv!\n"); - fflush(0); + fflush(nullptr); return JNI_ERR; } return JNI_OK; @@ -72,7 +72,7 @@ Java_FilteredFieldsTest_getJVMTIFieldCount(JNIEnv *env, jclass cls, jclass clazz printf(" [%d]: %s\n", i, name); jvmti->Deallocate((unsigned char *)name); } - fflush(0); + fflush(nullptr); return fcount; } diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/MissedStackMapFrames/libMissedStackMapFrames.cpp b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/MissedStackMapFrames/libMissedStackMapFrames.cpp index 5cebf608c3484..066794d1d6077 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/MissedStackMapFrames/libMissedStackMapFrames.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/MissedStackMapFrames/libMissedStackMapFrames.cpp @@ -31,7 +31,7 @@ static void _log(const char* format, ...) { va_start(args, format); vprintf(format, args); va_end(args); - fflush(0); + fflush(nullptr); } static jvmtiEnv* jvmti = nullptr; diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineRetransform/libRedefineRetransform.cpp b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineRetransform/libRedefineRetransform.cpp index 518e147c94278..450b0f35918b6 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineRetransform/libRedefineRetransform.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineRetransform/libRedefineRetransform.cpp @@ -36,7 +36,7 @@ static void _log(const char* format, ...) { va_start(args, format); vprintf(format, args); va_end(args); - fflush(0); + fflush(nullptr); } static bool isTestClass(const char* name) { diff --git a/test/hotspot/jtreg/serviceability/jvmti/events/FramePop/framepop02/libframepop02.cpp b/test/hotspot/jtreg/serviceability/jvmti/events/FramePop/framepop02/libframepop02.cpp index 61c9a91184bab..93df7f98277bf 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/events/FramePop/framepop02/libframepop02.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/events/FramePop/framepop02/libframepop02.cpp @@ -194,7 +194,7 @@ void JNICALL MethodEntry(jvmtiEnv *jvmti, JNIEnv *jni, { if (printdump == JNI_TRUE) { print_current_time(); - fflush(0); + fflush(nullptr); LOG(">>> %sMethod entry\n>>>", (isNative == JNI_TRUE) ? "Native " : ""); printInfo(jni, jvmti, thr, method, frameCount); } @@ -231,7 +231,7 @@ void JNICALL FramePop(jvmtiEnv *jvmti, JNIEnv *jni, { if (printdump == JNI_TRUE) { print_current_time(); - fflush(0); + fflush(nullptr); LOG(" >>> Frame Pop\n>>>"); printInfo(jni, jvmti, thr, method, frameCount); } diff --git a/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/get_stack_trace.hpp b/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/get_stack_trace.hpp index d7c85704275f2..b8828b0e80f29 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/get_stack_trace.hpp +++ b/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/get_stack_trace.hpp @@ -70,7 +70,7 @@ int compare_stack_trace(jvmtiEnv *jvmti, JNIEnv *jni, jthread thread, int exp_idx = expected_frames_length - 1 - i; printf("expected idx %d\n", exp_idx); - fflush(0); + fflush(nullptr); if (i < expected_frames_length) { // for generated classes don't compare lambda indicies diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/SuspendResume1/libSuspendResume1.cpp b/test/hotspot/jtreg/serviceability/jvmti/vthread/SuspendResume1/libSuspendResume1.cpp index f05e619e0bd7d..93ad399b121ac 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/vthread/SuspendResume1/libSuspendResume1.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/SuspendResume1/libSuspendResume1.cpp @@ -138,7 +138,7 @@ check_suspended_state(JNIEnv* jni, jthread thread, int thr_idx, char* tname, con LOG("## Agent: %s: virtual thread of carrier thread has state: %s (%d)\n", func_name, TranslateState(state), (int)state); - fflush(0); + fflush(nullptr); } set_agent_fail_status(); fatal(jni, "check_resumed_state: expected SUSPENDED flag in thread state"); @@ -169,7 +169,7 @@ check_resumed_state(JNIEnv* jni, jthread thread, int thr_idx, char* tname, const LOG("## Agent: %s: virtual thread of carrier thread has state: %s (%d)\n", func_name, TranslateState(state), (int)state); - fflush(0); + fflush(nullptr); } set_agent_fail_status(); fatal(jni, "check_resumed_state: NOT expected SUSPENDED flag in thread state"); @@ -210,7 +210,7 @@ test_thread_resume(JNIEnv* jni, jthread thread, int thr_idx, char* tname) { LOG("## Agent: test_thread_resume: virtual thread of carrier thread has state: %s (%d)\n", TranslateState(state), (int)state); - fflush(0); + fflush(nullptr); } check_jvmti_status(jni, err, "test_thread_resume: error in JVMTI ResumeThread"); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetClassFields/getclfld007/getclfld007.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetClassFields/getclfld007/getclfld007.cpp index 3cd333843308c..89a62346ca9f0 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetClassFields/getclfld007/getclfld007.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetClassFields/getclfld007/getclfld007.cpp @@ -86,7 +86,7 @@ Java_nsk_jvmti_GetClassFields_getclfld007_check(JNIEnv *env, jclass cls, jclass if (jvmti == nullptr) { printf("JVMTI client was not properly loaded!\n"); - fflush(0); + fflush(nullptr); result = STATUS_FAILED; return; } @@ -98,7 +98,7 @@ Java_nsk_jvmti_GetClassFields_getclfld007_check(JNIEnv *env, jclass cls, jclass if (err != JVMTI_ERROR_NONE) { printf("GetClassFields unexpected error: %s (%d)\n", TranslateError(err), err); - fflush(0); + fflush(nullptr); result = STATUS_FAILED; return; } @@ -132,7 +132,7 @@ Java_nsk_jvmti_GetClassFields_getclfld007_check(JNIEnv *env, jclass cls, jclass jvmti->Deallocate((unsigned char *)name); jvmti->Deallocate((unsigned char *)sig); } - fflush(0); + fflush(nullptr); } JNIEXPORT int JNICALL diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref001/followref001.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref001/followref001.cpp index ff431aa2203e9..b33128b491626 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref001/followref001.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref001/followref001.cpp @@ -137,14 +137,14 @@ static bool initObjectDescList(jvmtiEnv* jvmti, *objectsCount = 1 + 2 * chainLength; printf("Allocate memory for objects list: %d objects\n", *objectsCount); - fflush(0); + fflush(nullptr); if (!NSK_JVMTI_VERIFY(jvmti->Allocate((*objectsCount * sizeof(ObjectDesc)), (unsigned char**) objectDescList))) { nsk_jvmti_setFailStatus(); return false; } printf(" ... allocated array: 0x%p\n", (void*)objectDescList); - fflush(0); + fflush(nullptr); { int k; @@ -179,7 +179,7 @@ static bool getAndTagClasses(jvmtiEnv* jvmti, } printf("\nFound debugee class: 0x%p\n %s\n", (void*) *debugeeClass, DEBUGEE_CLASS_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (*rootObjectClass = jni->FindClass(ROOT_OBJECT_CLASS_NAME)) != nullptr)) { @@ -194,7 +194,7 @@ static bool getAndTagClasses(jvmtiEnv* jvmti, printf("\nFound root object class: 0x%p, tag=%ld\n %s\n", (void*) *rootObjectClass,(long) ROOT_CLASS_TAG, ROOT_OBJECT_CLASS_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (*chainObjectClass = @@ -209,7 +209,7 @@ static bool getAndTagClasses(jvmtiEnv* jvmti, printf("\nFound chain object class: 0x%p, tag=%ld\n %s\n", (void*) *chainObjectClass, (long) CHAIN_CLASS_TAG, CHAIN_OBJECT_CLASS_NAME); - fflush(0); + fflush(nullptr); return true; } /* getAndTagClasses */ @@ -234,7 +234,7 @@ static bool getFieldsAndObjects(jvmtiEnv* jvmti, } printf("\nFound fieldID: 0x%p - \'%s\' static field in debugee class\n", (void*) rootObjectField, OBJECT_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (*reachableChainField = jni->GetFieldID(rootObjectClass, REACHABLE_CHAIN_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != nullptr)) { @@ -243,7 +243,7 @@ static bool getFieldsAndObjects(jvmtiEnv* jvmti, } printf("\nFound fieldID: 0x%p - \'%s\' field in root object class\n", (void*) reachableChainField, REACHABLE_CHAIN_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (*unreachableChainField = jni->GetFieldID(rootObjectClass, UNREACHABLE_CHAIN_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != nullptr)) { @@ -253,7 +253,7 @@ static bool getFieldsAndObjects(jvmtiEnv* jvmti, printf("\nFound fieldID: 0x%p - \'%s\' field in root object class\n", (void*) unreachableChainField, UNREACHABLE_CHAIN_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (*nextField = jni->GetFieldID(chainObjectClass, NEXT_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != nullptr)) { @@ -262,7 +262,7 @@ static bool getFieldsAndObjects(jvmtiEnv* jvmti, } printf("\nFound fieldID: 0x%p - \'%s\' field in chain object class\n", (void*) nextField, NEXT_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (*rootObjectPtr = jni->GetStaticObjectField(debugeeClass, rootObjectField)) != nullptr)) { @@ -270,14 +270,14 @@ static bool getFieldsAndObjects(jvmtiEnv* jvmti, return false; } printf("\nFound root object: 0x%p\n", (void*) *rootObjectPtr); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (*rootObjectPtr = jni->NewGlobalRef(*rootObjectPtr)) != nullptr)) { nsk_jvmti_setFailStatus(); return false; } printf("Created root object global ref: 0x%p\n", (void*)*rootObjectPtr); - fflush(0); + fflush(nullptr); return true; } /* getFieldsAndObjects */ @@ -318,7 +318,7 @@ static bool getAndTagChainObjects( nsk_jvmti_setFailStatus(); } printf(" tag=%-5ld object=0x%p\n", (long)objTag, (void*)nextObj); - fflush(0); + fflush(nullptr); /* To continue traversing objects in the chain */ if (!getAndTagChainObjects(jvmti, @@ -394,7 +394,7 @@ static int getAndTagTestedObjects( (long) ROOT_OBJECT_TAG, (void*) *rootObjectPtr); printf(" reachable objects chain: %d objects\n", chainLength); - fflush(0); + fflush(nullptr); if (!getAndTagChainObjects(jvmti, jni, @@ -453,7 +453,7 @@ static bool checkTestedObjects(jvmtiEnv* jvmti, } printf("\nReachable objects:\n"); - fflush(0); + fflush(nullptr); for (i = 0; i < chainLength; i++) { idx = i + 1; printf("Reachable object:\n" @@ -488,7 +488,7 @@ static bool checkTestedObjects(jvmtiEnv* jvmti, NSK_COMPLAIN0("Unreachable object was iterated\n"); nsk_jvmti_setFailStatus(); } - fflush(0); + fflush(nullptr); } return true; @@ -514,7 +514,7 @@ static void releaseTestedObjects(jvmtiEnv* jvmti, } } - fflush(0); + fflush(nullptr); } /* releaseTestedObjects */ @@ -542,7 +542,7 @@ jint JNICALL heapReferenceCallback( /* ss45998: class_tag=>referrence_class_tag */ printf(" size: %" LL "d, tag_ptr: 0x%p, referrer_tag_ptr: 0x%p, length: %-d\n", size, tag_ptr, referrer_tag_ptr, length); - fflush(0); + fflush(nullptr); if (((uintptr_t) tag_ptr & FULL_32_BIT_MASK) == FULL_32_BIT_MASK) { NSK_COMPLAIN1("wrong tag_ptr passed to " @@ -567,7 +567,7 @@ jint JNICALL heapReferenceCallback( printf(" class_tag=%" LL "d, tag=%" LL "d, size=%" LL "d," " ref_tag=%" LL "d, referrer_index=%d\n\n", class_tag, tag, size, ref_tag, referrer_index); - fflush(0); + fflush(nullptr); if (length != -1) { NSK_COMPLAIN1("wrong length passed to heapReferenceCallback: " @@ -647,7 +647,7 @@ jint JNICALL heapReferenceCallback( case JVMTI_HEAP_REFERENCE_OTHER: { NSK_COMPLAIN1("This reference kind was not expected: %s\n", ref_kind_str[reference_kind]); - fflush(0); + fflush(nullptr); nsk_jvmti_setFailStatus(); return 0; } @@ -674,7 +674,7 @@ jint JNICALL primitiveFieldCallback( (long) class_tag, (long) DEREF(tag_ptr), (int) value_type); - fflush(0); + fflush(nullptr); return 0; } /* primitiveFieldCallback */ @@ -694,7 +694,7 @@ jint JNICALL arrayPrimitiveValueCallback( (long) DEREF(tag_ptr), (int) element_count, (int) element_type); - fflush(0); + fflush(nullptr); return 0; } /* arrayPrimitiveValueCallback */ @@ -711,7 +711,7 @@ jint JNICALL stringPrimitiveValueCallback( (long) class_tag, (long) DEREF(tag_ptr), (int) value_length); - fflush(0); + fflush(nullptr); return 0; } /* stringPrimitiveValueCallback */ @@ -725,14 +725,14 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { jobject rootObject = nullptr; printf("Wait for tested objects created\n"); - fflush(0); + fflush(nullptr); if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) { return; } printf(">>> Obtain and tag tested objects from debugee class\n"); - fflush(0); + fflush(nullptr); if (!NSK_VERIFY(getAndTagTestedObjects(jvmti, jni, @@ -745,7 +745,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf(">>> Let debugee to clean links to unreachable objects\n"); - fflush(0); + fflush(nullptr); if (!NSK_VERIFY(nsk_jvmti_resumeSync())) { return; @@ -755,7 +755,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf(">>> Start iteration from root tested object: 0x%p\n\n", rootObject); - fflush(0); + fflush(nullptr); if (!NSK_JVMTI_VERIFY(jvmti->FollowReferences((jint) 0, /* heap_filter */ (jclass) nullptr, /* class */ @@ -767,19 +767,19 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf(">>> Check if reachable objects were iterated:\n"); - fflush(0); + fflush(nullptr); if (!checkTestedObjects(jvmti, jni, chainLength, objectDescList)) { nsk_jvmti_setFailStatus(); } printf(">>> Clean used data\n"); - fflush(0); + fflush(nullptr); releaseTestedObjects(jvmti, jni, chainLength, objectDescList, rootObject); printf(">>> Let debugee to finish\n"); - fflush(0); + fflush(nullptr); if (!NSK_VERIFY(nsk_jvmti_resumeSync())) { return; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref002/followref002.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref002/followref002.cpp index 6366b430776c9..9ea3a5d0d01c0 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref002/followref002.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref002/followref002.cpp @@ -131,7 +131,7 @@ static int getAndTagChainObjects( nsk_jvmti_setFailStatus(); } printf(" tag=%-5ld object=0x%p\n", (long)objTag, (void*)obj); - fflush(0); + fflush(nullptr); if (!getAndTagChainObjects(jvmti, jni, obj, nextField, nextFieldName, @@ -170,14 +170,14 @@ static int getAndTagTestedObjects( *objectsCount = 1 + 2 * chainLength; printf("Allocate memory for objects list: %d objects\n", *objectsCount); - fflush(0); + fflush(nullptr); if (!NSK_JVMTI_VERIFY(jvmti->Allocate((*objectsCount * sizeof(ObjectDesc)), (unsigned char**)objectDescList))) { nsk_jvmti_setFailStatus(); return NSK_FALSE; } printf(" ... allocated array: 0x%p\n", (void*)objectDescList); - fflush(0); + fflush(nullptr); { int k; @@ -191,7 +191,7 @@ static int getAndTagTestedObjects( (*objectDescList)[0].exp_class_tag = rootClassTag; printf("Find debugee class: %s\n", DEBUGEE_CLASS_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (debugeeClass = jni->FindClass(DEBUGEE_CLASS_NAME)) != nullptr)) { nsk_jvmti_setFailStatus(); return NSK_FALSE; @@ -199,7 +199,7 @@ static int getAndTagTestedObjects( printf(" ... found class: 0x%p\n", (void*)debugeeClass); printf("Find root object class: %s\n", ROOT_OBJECT_CLASS_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (rootObjectClass = jni->FindClass(ROOT_OBJECT_CLASS_NAME)) != nullptr)) { nsk_jvmti_setFailStatus(); return NSK_FALSE; @@ -212,7 +212,7 @@ static int getAndTagTestedObjects( printf(" tag=%-5ld rootClass=0x%p\n", (long)rootClassTag, (void*)rootObjectClass); printf("Find chain object class: %s\n", CHAIN_OBJECT_CLASS_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (chainObjectClass = jni->FindClass(CHAIN_OBJECT_CLASS_NAME)) != nullptr)) { nsk_jvmti_setFailStatus(); @@ -226,7 +226,7 @@ static int getAndTagTestedObjects( printf(" tag=%-5ld chainClass=0x%p\n", (long)chainClassTag, (void*)chainObjectClass); printf("Find static field in debugee class: %s\n", OBJECT_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (objectField = jni->GetStaticFieldID(debugeeClass, OBJECT_FIELD_NAME, ROOT_OBJECT_CLASS_SIG)) != nullptr)) { nsk_jvmti_setFailStatus(); @@ -235,7 +235,7 @@ static int getAndTagTestedObjects( printf(" ... got fieldID: 0x%p\n", (void*)objectField); printf("Find instance field in root object class: %s\n", REACHABLE_CHAIN_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (reachableChainField = jni->GetFieldID(rootObjectClass, REACHABLE_CHAIN_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != nullptr)) { nsk_jvmti_setFailStatus(); @@ -244,7 +244,7 @@ static int getAndTagTestedObjects( printf(" ... got fieldID: 0x%p\n", (void*)reachableChainField); printf("Find instance field in root object class: %s\n", UNREACHABLE_CHAIN_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (unreachableChainField = jni->GetFieldID(rootObjectClass, UNREACHABLE_CHAIN_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != nullptr)) { nsk_jvmti_setFailStatus(); @@ -253,7 +253,7 @@ static int getAndTagTestedObjects( printf(" ... got fieldID: 0x%p\n", (void*)unreachableChainField); printf("Find instance field in chain object class: %s\n", TAIL_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (tailField = jni->GetFieldID(chainObjectClass, TAIL_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != nullptr)) { nsk_jvmti_setFailStatus(); @@ -262,14 +262,14 @@ static int getAndTagTestedObjects( printf(" ... got fieldID: 0x%p\n", (void*)tailField); printf("Get root object from static field: %s\n", OBJECT_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (*rootObject = jni->GetStaticObjectField(debugeeClass, objectField)) != nullptr)) { nsk_jvmti_setFailStatus(); return NSK_FALSE; } printf(" ... got object: 0x%p\n", (void*)*rootObject); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (*rootObject = jni->NewGlobalRef(*rootObject)) != nullptr)) { nsk_jvmti_setFailStatus(); @@ -280,7 +280,7 @@ static int getAndTagTestedObjects( printf("Obtain and tag chain objects:\n"); printf(" root tested object:\n"); - fflush(0); + fflush(nullptr); if (!NSK_JVMTI_VERIFY(jvmti->SetTag(*rootObject, rootObjectTag))) { nsk_jvmti_setFailStatus(); } @@ -295,7 +295,7 @@ static int getAndTagTestedObjects( (*objectDescList)[chainLength].exp_found = 1; printf(" reachable objects chain: %d objects\n", chainLength); - fflush(0); + fflush(nullptr); if (!getAndTagChainObjects(jvmti, jni, *rootObject, reachableChainField, REACHABLE_CHAIN_FIELD_NAME, @@ -348,7 +348,7 @@ static int checkTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, } printf("\nReachable objects:\n"); - fflush(0); + fflush(nullptr); for (i = 0; i < chainLength; i++) { idx = i + 1; printf("Reachable object:\n" @@ -383,7 +383,7 @@ static int checkTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, NSK_COMPLAIN0("Unreachable object was iterated\n"); nsk_jvmti_setFailStatus(); } - fflush(0); + fflush(nullptr); } return NSK_TRUE; @@ -404,7 +404,7 @@ static int releaseTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, } } - fflush(0); + fflush(nullptr); return NSK_TRUE; } /* releaseTestedObjects */ @@ -456,7 +456,7 @@ jint JNICALL heapReferenceCallback( (long) size, (long) ref_tag, (int) referrer_index); - fflush(0); + fflush(nullptr); if (tag_ptr == nullptr) { NSK_COMPLAIN1("null tag_ptr is passed to heapReferenceCallback:" @@ -531,7 +531,7 @@ jint JNICALL heapReferenceCallback( case JVMTI_HEAP_REFERENCE_OTHER: { NSK_COMPLAIN1("This reference kind was not expected: %s\n", ref_kind_str[reference_kind]); - fflush(0); + fflush(nullptr); nsk_jvmti_setFailStatus(); return 0; } @@ -556,7 +556,7 @@ jint JNICALL primitiveFieldCallback( (long) class_tag, (long) DEREF(tag_ptr), (int) value_type); - fflush(0); + fflush(nullptr); return 0; } @@ -574,7 +574,7 @@ jint JNICALL arrayPrimitiveValueCallback( (long) DEREF(tag_ptr), (int) element_count, (int) element_type); - fflush(0); + fflush(nullptr); return 0; } @@ -590,7 +590,7 @@ jint JNICALL stringPrimitiveValueCallback( (long) class_tag, (long) DEREF(tag_ptr), (int) value_length); - fflush(0); + fflush(nullptr); return 0; } @@ -602,13 +602,13 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { jobject rootObject = nullptr; printf("Wait for tested objects created\n"); - fflush(0); + fflush(nullptr); if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) { return; } printf(">>> Obtain and tag tested objects from debugee class\n"); - fflush(0); + fflush(nullptr); { if (!NSK_VERIFY(getAndTagTestedObjects(jvmti, jni, chainLength, &objectsCount, @@ -618,7 +618,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf(">>> Let debugee to clean links to unreachable objects\n"); - fflush(0); + fflush(nullptr); { if (!NSK_VERIFY(nsk_jvmti_resumeSync())) { return; @@ -629,7 +629,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf("\n\n>>> Start 1-st iteration for root tested object: 0x%p\n", rootObject); - fflush(0); + fflush(nullptr); { jint heap_filter = JVMTI_HEAP_FILTER_UNTAGGED | JVMTI_HEAP_FILTER_CLASS_UNTAGGED; if (!NSK_JVMTI_VERIFY(jvmti->FollowReferences(heap_filter, @@ -643,7 +643,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf(">>> Check if reachable objects were iterated\n"); - fflush(0); + fflush(nullptr); { if (!checkTestedObjects(jvmti, jni, chainLength, objectDescList)) { nsk_jvmti_setFailStatus(); @@ -660,7 +660,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf("\n\n>>> Start 2-nd iteration for root tested object: 0x%p\n", rootObject); - fflush(0); + fflush(nullptr); { /* This time everythig is filtered out */ jint heap_filter = JVMTI_HEAP_FILTER_UNTAGGED | JVMTI_HEAP_FILTER_CLASS_UNTAGGED | @@ -676,7 +676,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf(">>> Check if reachable objects were not reported this time\n"); - fflush(0); + fflush(nullptr); { if (!checkTestedObjects(jvmti, jni, chainLength, objectDescList)) { nsk_jvmti_setFailStatus(); @@ -684,7 +684,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf(">>> Clean used data\n"); - fflush(0); + fflush(nullptr); { if (!NSK_VERIFY(releaseTestedObjects(jvmti, jni, chainLength, objectDescList, rootObject))) { return; @@ -692,7 +692,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf("Let debugee to finish\n"); - fflush(0); + fflush(nullptr); if (!NSK_VERIFY(nsk_jvmti_resumeSync())) return; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref003/followref003.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref003/followref003.cpp index cb0385ee6535b..80cbf856f4504 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref003/followref003.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref003/followref003.cpp @@ -146,7 +146,7 @@ static int getChainObjects(jvmtiEnv* jvmti, JNIEnv* jni, jobject firstObject, nsk_jvmti_setFailStatus(); } printf(" tag=%-5ld object=0x%p\n", (long)objTag, (void*)obj); - fflush(0); + fflush(nullptr); if (!getChainObjects(jvmti, jni, obj, nextField, nextFieldName, nextField, nextFieldName, count, objectDescList, tag, reachable)) { @@ -173,14 +173,14 @@ static int getTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, *objectsCount = 1 + 2 * chainLength; printf("Allocate memory for objects list: %d objects\n", *objectsCount); - fflush(0); + fflush(nullptr); if (!NSK_JVMTI_VERIFY(jvmti->Allocate((*objectsCount * sizeof(ObjectDesc)), (unsigned char**)objectDescList))) { nsk_jvmti_setFailStatus(); return NSK_FALSE; } printf(" ... allocated array: 0x%p\n", (void*)objectDescList); - fflush(0); + fflush(nullptr); { int k; @@ -194,7 +194,7 @@ static int getTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, (*objectDescList)[0].exp_class_tag = rootClassTag; printf("Find debugee class: %s\n", DEBUGEE_CLASS_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (debugeeClass = jni->FindClass(DEBUGEE_CLASS_NAME)) != nullptr)) { nsk_jvmti_setFailStatus(); return NSK_FALSE; @@ -202,7 +202,7 @@ static int getTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, printf(" ... found class: 0x%p\n", (void*)debugeeClass); printf("Find root object class: %s\n", ROOT_OBJECT_CLASS_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (rootObjectClass = jni->FindClass(ROOT_OBJECT_CLASS_NAME)) != nullptr)) { nsk_jvmti_setFailStatus(); return NSK_FALSE; @@ -216,7 +216,7 @@ static int getTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, (long)rootClassTag, (void*)rootObjectClass); printf("Find chain object class: %s\n", CHAIN_OBJECT_CLASS_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (chainObjectClass = jni->FindClass(CHAIN_OBJECT_CLASS_NAME)) != nullptr)) { nsk_jvmti_setFailStatus(); @@ -232,7 +232,7 @@ static int getTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, (long)chainClassTag, (void*)chainObjectClass); printf("Find static field in debugee class: %s\n", OBJECT_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (objectField = jni->GetStaticFieldID(debugeeClass, OBJECT_FIELD_NAME, ROOT_OBJECT_CLASS_SIG)) != nullptr)) { nsk_jvmti_setFailStatus(); @@ -241,7 +241,7 @@ static int getTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, printf(" ... got fieldID: 0x%p\n", (void*)objectField); printf("Find instance field in root object class: %s\n", REACHABLE_CHAIN_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (reachableChainField = jni->GetFieldID(rootObjectClass, REACHABLE_CHAIN_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != nullptr)) { nsk_jvmti_setFailStatus(); @@ -250,7 +250,7 @@ static int getTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, printf(" ... got fieldID: 0x%p\n", (void*)reachableChainField); printf("Find instance field in root object class: %s\n", UNREACHABLE_CHAIN_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (unreachableChainField = jni->GetFieldID(rootObjectClass, UNREACHABLE_CHAIN_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != nullptr)) { nsk_jvmti_setFailStatus(); @@ -259,7 +259,7 @@ static int getTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, printf(" ... got fieldID: 0x%p\n", (void*)unreachableChainField); printf("Find instance field in chain object class: %s\n", TAIL_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (tailField = jni->GetFieldID(chainObjectClass, TAIL_FIELD_NAME, CHAIN_OBJECT_CLASS_SIG)) != nullptr)) { nsk_jvmti_setFailStatus(); @@ -268,14 +268,14 @@ static int getTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, printf(" ... got fieldID: 0x%p\n", (void*)tailField); printf("Get root object from static field: %s\n", OBJECT_FIELD_NAME); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (*rootObject = jni->GetStaticObjectField(debugeeClass, objectField)) != nullptr)) { nsk_jvmti_setFailStatus(); return NSK_FALSE; } printf(" ... got object: 0x%p\n", (void*)*rootObject); - fflush(0); + fflush(nullptr); if (!NSK_JNI_VERIFY(jni, (*rootObject = jni->NewGlobalRef(*rootObject)) != nullptr)) { nsk_jvmti_setFailStatus(); @@ -286,7 +286,7 @@ static int getTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, printf("Obtain and tag chain objects:\n"); printf(" root tested object\n"); - fflush(0); + fflush(nullptr); if (!NSK_JVMTI_VERIFY(jvmti->SetTag(*rootObject, rootObjectTag))) { nsk_jvmti_setFailStatus(); } @@ -298,7 +298,7 @@ static int getTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, (*objectDescList)[0].tag = rootObjectTag; printf(" reachable objects chain: %d objects\n", chainLength); - fflush(0); + fflush(nullptr); if (!getChainObjects(jvmti, jni, *rootObject, reachableChainField, REACHABLE_CHAIN_FIELD_NAME, tailField, TAIL_FIELD_NAME, @@ -347,7 +347,7 @@ static int checkTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, } printf("\nReachable objects:\n"); - fflush(0); + fflush(nullptr); for (i = 0; i < chainLength; i++) { idx = i + 1; printf("Reachable object:\n" @@ -382,7 +382,7 @@ static int checkTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, NSK_COMPLAIN0("Unreachable object was iterated\n"); nsk_jvmti_setFailStatus(); } - fflush(0); + fflush(nullptr); } return NSK_TRUE; @@ -403,7 +403,7 @@ static int releaseTestedObjects(jvmtiEnv* jvmti, JNIEnv* jni, int chainLength, } } - fflush(0); + fflush(nullptr); return NSK_TRUE; } @@ -646,7 +646,7 @@ jint JNICALL heapReferenceCallback( (long) size); } - fflush(0); + fflush(nullptr); return 0; } @@ -665,7 +665,7 @@ jint JNICALL heapReferenceCallback( method, (long) location, (int) index); - fflush(0); + fflush(nullptr); if (tag_ptr == nullptr) { NSK_COMPLAIN1("null tag_ptr is passed to heapReferenceCallback:" @@ -748,7 +748,7 @@ jint JNICALL heapReferenceCallback( if (tag != rootObjectTag || class_tag != rootClassTag) { NSK_COMPLAIN1("This reference kind was not expected: %s\n", ref_kind_str[ref_kind]); - fflush(0); + fflush(nullptr); nsk_jvmti_setFailStatus(); } break; @@ -818,7 +818,7 @@ jint JNICALL heapReferenceCallback( default: { NSK_COMPLAIN1("This reference kind was not expected: %s\n\n", ref_kind_str[ref_kind]); - fflush(0); + fflush(nullptr); nsk_jvmti_setFailStatus(); break; } @@ -840,7 +840,7 @@ jint JNICALL primitiveFieldCallback (long) class_tag, (long) DEREF(tag_ptr), (int) value_type); - fflush(0); + fflush(nullptr); return 0; } @@ -853,7 +853,7 @@ jint JNICALL arrayPrimitiveValueCallback (long) DEREF(tag_ptr), (int) element_count, (int) element_type); - fflush(0); + fflush(nullptr); return 0; } @@ -865,7 +865,7 @@ jint JNICALL stringPrimitiveValueCallback (long) class_tag, (long) DEREF(tag_ptr), (int) value_length); - fflush(0); + fflush(nullptr); return 0; } @@ -902,13 +902,13 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { jobject rootObject = nullptr; printf("Wait for tested objects created\n"); - fflush(0); + fflush(nullptr); if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout))) { return; } printf(">>> Obtain and tag tested objects from debugee class\n"); - fflush(0); + fflush(nullptr); { if (!NSK_VERIFY(getTestedObjects(jvmti, jni, chainLength, &objectsCount, &objectDescList, &rootObject))) { @@ -917,7 +917,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf(">>> Let debugee to clean links to unreachable objects\n"); - fflush(0); + fflush(nullptr); { if (!NSK_VERIFY(nsk_jvmti_resumeSync())) { return; @@ -933,7 +933,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf("\n\n>>> Start 1-st iteration starting from the heap root\n"); - fflush(0); + fflush(nullptr); { if (!NSK_JVMTI_VERIFY(jvmti->FollowReferences((jint) 0, /* heap_filter */ (jclass) nullptr, /* class */ @@ -946,7 +946,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf(">>> Check if reachable objects were iterated\n"); - fflush(0); + fflush(nullptr); { if (!checkTestedObjects(jvmti, jni, chainLength, objectDescList)) { nsk_jvmti_setFailStatus(); @@ -968,7 +968,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf("\n\n>>> Start 2-nd iteration starting from the heap root\n"); - fflush(0); + fflush(nullptr); first_followref = 0; { jint heap_filter = JVMTI_HEAP_FILTER_UNTAGGED @@ -985,7 +985,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { printf(">>> Check that both reachable and unreachable " "objects were not iterated\n"); - fflush(0); + fflush(nullptr); { if (!checkTestedObjects(jvmti, jni, chainLength, objectDescList)) { nsk_jvmti_setFailStatus(); @@ -994,7 +994,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { printf(">>> Clean used data\n"); - fflush(0); + fflush(nullptr); { if (!NSK_VERIFY(releaseTestedObjects(jvmti, jni, chainLength, objectDescList, rootObject))) { @@ -1003,7 +1003,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf("Let debugee to finish\n"); - fflush(0); + fflush(nullptr); if (!NSK_VERIFY(nsk_jvmti_resumeSync())) return; } @@ -1047,7 +1047,7 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { info = INFO_HEAPOBJ; else { printf("Unknown option value: info=%s\n", infoOpt); - fflush(0); + fflush(nullptr); return JNI_ERR; } } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref004/followref004.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref004/followref004.cpp index e73534de8b6b4..2446b5f7caf93 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref004/followref004.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref004/followref004.cpp @@ -86,7 +86,7 @@ jint JNICALL primitiveFieldCallback( (long) DEREF(tag_ptr), (int) value_type); - fflush(0); + fflush(nullptr); markTagVisited(DEREF(tag_ptr)); @@ -111,7 +111,7 @@ jint JNICALL arrayPrimitiveValueCallback( (long) DEREF(tag_ptr), (int) element_count, (int) element_type); - fflush(0); + fflush(nullptr); markTagVisited(DEREF(tag_ptr)); @@ -132,7 +132,7 @@ jint JNICALL stringPrimitiveValueCallback( (long) class_tag, (long) DEREF(tag_ptr), (int) value_length); - fflush(0); + fflush(nullptr); markTagVisited(DEREF(tag_ptr)); @@ -168,14 +168,14 @@ static void JNICALL agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) jvmtiError retCode; printf(">>> Sync with Java code\n"); - fflush(0); + fflush(nullptr); if (!NSK_VERIFY(nsk_jvmti_waitForSync(g_timeout))) { return; } printf(">>> Create JNI global references\n"); - fflush(0); + fflush(nullptr); createGlobalRefs(jni); @@ -192,7 +192,7 @@ static void JNICALL agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) checkThatAllTagsVisited(); printf(">>> Let debugee to finish\n"); - fflush(0); + fflush(nullptr); if (!NSK_VERIFY(nsk_jvmti_resumeSync())) { return; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref005/followref005.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref005/followref005.cpp index 333ddcccf831a..d0194feab0288 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref005/followref005.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref005/followref005.cpp @@ -88,7 +88,7 @@ agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) { } printf(">>> Let debugee to finish\n"); - fflush(0); + fflush(nullptr); if (!NSK_VERIFY(nsk_jvmti_waitForSync(g_timeout))) { return; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref006/followref006.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref006/followref006.cpp index 54485fb809ae2..5c5e37803211d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref006/followref006.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/FollowReferences/followref006/followref006.cpp @@ -181,7 +181,7 @@ static void JNICALL agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) checkNoObjIterated(jni, jvmti, JAVA_UTIL_CALENDAR_CLASS_NAME); NSK_DISPLAY0("Let debugee to finish"); - fflush(0); + fflush(nullptr); if (!NSK_VERIFY(nsk_jvmti_waitForSync(g_timeout))) { return; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase/earlyretbase.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase/earlyretbase.cpp index 47b9618d19c88..6c57004fc5f59 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase/earlyretbase.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase/earlyretbase.cpp @@ -33,7 +33,7 @@ extern "C" { #define STATUS_FAILED 2 #define PASSED 0 -#define RETURN_FAILED errCode = STATUS_FAILED; fflush(0); return errCode +#define RETURN_FAILED errCode = STATUS_FAILED; fflush(nullptr); return errCode static jvmtiEnv *jvmti = nullptr; static jvmtiCapabilities caps; @@ -59,7 +59,7 @@ MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr, if (method == midActiveMethod) { printf("#### MethodExit event occurred ####\n"); - fflush(0); + fflush(nullptr); meth_exit_gen_events++; } } @@ -70,7 +70,7 @@ FramePop(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, if (method == midActiveMethod) { printf("#### FramePop event occurred ####\n"); - fflush(0); + fflush(nullptr); pop_frame_gen_events++; } } @@ -120,7 +120,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretbase_resThread(JNIEnv *env, return JNI_ERR; } printf("<<<<<<<< ResumeThread() is successfully done\n"); - fflush(0); + fflush(nullptr); return PASSED; } @@ -176,7 +176,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretbase_doForceEarlyReturn(JNIEnv *env RETURN_FAILED; } printf("Check #1 PASSED: ForceEarlyReturn() is successfully done\n"); - fflush(0); + fflush(nullptr); return(errCode); } @@ -268,7 +268,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretbase_check(JNIEnv *env, jclass cls) "events generated correctly\n"); errCode = PASSED; } - fflush(0); + fflush(nullptr); return errCode; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretfp/earlyretfp.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretfp/earlyretfp.cpp index 9a0ce3d85508b..5e7506a871e3c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretfp/earlyretfp.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretfp/earlyretfp.cpp @@ -33,7 +33,7 @@ extern "C" { #define PASSED 0 #define STATUS_FAILED 2 -#define RETURN_FAILED errCode = STATUS_FAILED; fflush(0); return +#define RETURN_FAILED errCode = STATUS_FAILED; fflush(nullptr); return #define METHCNT 2 static jvmtiEnv *jvmti = nullptr; @@ -175,7 +175,7 @@ void check(jvmtiEnv *jvmti_env, jthread thr, jmethodID mid, printf(" expected: %d\n", framesCount + 1); RETURN_FAILED; } - fflush(0); + fflush(nullptr); } void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -220,7 +220,7 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, TranslateError(err), err); RETURN_FAILED; } - fflush(0); + fflush(nullptr); } void JNICALL SingleStep(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -256,7 +256,7 @@ void JNICALL SingleStep(jvmtiEnv *jvmti_env, JNIEnv *env, RETURN_FAILED; } } - fflush(0); + fflush(nullptr); } void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, @@ -289,7 +289,7 @@ void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, printf("Method was_popped_by_exception unexpectedly\n"); errCode = STATUS_FAILED; } - fflush(0); + fflush(nullptr); } #ifdef STATIC_BUILD @@ -361,7 +361,7 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) { printf("Warning: Breakpoint or SingleStep event are not implemented\n"); } - fflush(0); + fflush(nullptr); return JNI_OK; } @@ -431,7 +431,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretfp_printFloat( JNIEnv *env, jclass cls, jfloat val) { printf("\n>>> Returned value is %8.4f, hex: %#a\n", val, val); - fflush(0); + fflush(nullptr); return; } @@ -440,7 +440,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretfp_printDouble( JNIEnv *env, jclass cls, jdouble val) { printf("\n>>> Returned value is %8.4f, hex: %#a\n", val, val); - fflush(0); + fflush(nullptr); return; } @@ -451,7 +451,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretfp_check(JNIEnv *env, jclass cls) { framesCount, framesExpected); errCode = STATUS_FAILED; } - fflush(0); + fflush(nullptr); return errCode; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretint/earlyretint.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretint/earlyretint.cpp index feb51d5fc407d..16cd4c3856712 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretint/earlyretint.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretint/earlyretint.cpp @@ -33,7 +33,7 @@ extern "C" { #define PASSED 0 #define STATUS_FAILED 2 -#define RETURN_FAILED errCode = STATUS_FAILED; fflush(0); return +#define RETURN_FAILED errCode = STATUS_FAILED; fflush(nullptr); return static jvmtiEnv *jvmti = nullptr; static jvmtiCapabilities caps; @@ -184,7 +184,7 @@ void check(jvmtiEnv *jvmti_env, jthread thr, jmethodID mid, printf(" expected: %d\n", framesCount + 1); RETURN_FAILED; } - fflush(0); + fflush(nullptr); } void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -229,7 +229,7 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, TranslateError(err), err); RETURN_FAILED; } - fflush(0); + fflush(nullptr); } void JNICALL SingleStep(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -270,7 +270,7 @@ void JNICALL SingleStep(jvmtiEnv *jvmti_env, JNIEnv *env, RETURN_FAILED; } } - fflush(0); + fflush(nullptr); } void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, @@ -295,7 +295,7 @@ void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, printf("Method was_popped_by_exception unexpectedly\n"); errCode = STATUS_FAILED; } - fflush(0); + fflush(nullptr); } #ifdef STATIC_BUILD @@ -452,7 +452,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretint_printInt( JNIEnv *env, jclass cls, jint val) { printf("\n>>> Returned value: dec %d, hex: %#x\n", val, val); - fflush(0); + fflush(nullptr); return; } @@ -463,7 +463,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretint_check(JNIEnv *env, jclass cls) framesCount, framesExpected); errCode = STATUS_FAILED; } - fflush(0); + fflush(nullptr); return errCode; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretlong/earlyretlong.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretlong/earlyretlong.cpp index 170d6839bef09..2cb1a318d4492 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretlong/earlyretlong.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretlong/earlyretlong.cpp @@ -34,7 +34,7 @@ extern "C" { #define PASSED 0 #define STATUS_FAILED 2 -#define RETURN_FAILED errCode = STATUS_FAILED; fflush(0); return +#define RETURN_FAILED errCode = STATUS_FAILED; fflush(nullptr); return static jvmtiEnv *jvmti = nullptr; static jvmtiCapabilities caps; @@ -168,7 +168,7 @@ void check(jvmtiEnv *jvmti_env, jthread thr, jmethodID mid, printf(" expected: %d\n", framesCount + 1); RETURN_FAILED; } - fflush(0); + fflush(nullptr); } void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -213,7 +213,7 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, TranslateError(err), err); RETURN_FAILED; } - fflush(0); + fflush(nullptr); } void JNICALL SingleStep(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -251,7 +251,7 @@ void JNICALL SingleStep(jvmtiEnv *jvmti_env, JNIEnv *env, RETURN_FAILED; } } - fflush(0); + fflush(nullptr); } void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, @@ -276,7 +276,7 @@ void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, errCode = STATUS_FAILED; } } - fflush(0); + fflush(nullptr); } #ifdef STATIC_BUILD @@ -412,7 +412,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretlong_printLong( printf("\n>>> Returned value: dec: %" LL "d, hex: %#x %#x\n", val, iptr[0], iptr[1]); - fflush(0); + fflush(nullptr); return; } @@ -423,7 +423,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretlong_check(JNIEnv *env, jclass cls) framesCount, framesExpected); errCode = STATUS_FAILED; } - fflush(0); + fflush(nullptr); return errCode; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretobj/earlyretobj.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretobj/earlyretobj.cpp index 6faf82f9ed90e..ee3b79632d5c2 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretobj/earlyretobj.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretobj/earlyretobj.cpp @@ -34,7 +34,7 @@ extern "C" { #define PASSED 0 #define STATUS_FAILED 2 -#define RETURN_FAILED errCode = STATUS_FAILED; fflush(0); return +#define RETURN_FAILED errCode = STATUS_FAILED; fflush(nullptr); return static jvmtiEnv *jvmti = nullptr; static jvmtiCapabilities caps; @@ -168,7 +168,7 @@ void check(jvmtiEnv *jvmti_env, jthread thr, jmethodID mid, printf(" expected: %d\n", framesCount + 1); RETURN_FAILED; } - fflush(0); + fflush(nullptr); } void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -213,7 +213,7 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, TranslateError(err), err); RETURN_FAILED; } - fflush(0); + fflush(nullptr); } void JNICALL SingleStep(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -251,7 +251,7 @@ void JNICALL SingleStep(jvmtiEnv *jvmti_env, JNIEnv *env, RETURN_FAILED; } } - fflush(0); + fflush(nullptr); } void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, @@ -274,7 +274,7 @@ void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, errCode = STATUS_FAILED; } } - fflush(0); + fflush(nullptr); } #ifdef STATIC_BUILD @@ -410,7 +410,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretobj_check(JNIEnv *env, jclass cls) framesCount, framesExpected); errCode = STATUS_FAILED; } - fflush(0); + fflush(nullptr); return errCode; } @@ -419,7 +419,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretobj_printObject( JNIEnv *env, jclass cls, jobject obj) { printf("\nReturned jobject: %#" PRIxPTR "\n", (uintptr_t)obj); - fflush(0); + fflush(nullptr); return; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretstr/earlyretstr.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretstr/earlyretstr.cpp index 6ebb50026a34a..8465d05f9561a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretstr/earlyretstr.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretstr/earlyretstr.cpp @@ -33,7 +33,7 @@ extern "C" { #define PASSED 0 #define STATUS_FAILED 2 -#define RETURN_FAILED errCode = STATUS_FAILED; fflush(0); return +#define RETURN_FAILED errCode = STATUS_FAILED; fflush(nullptr); return static jvmtiEnv *jvmti = nullptr; static jvmtiCapabilities caps; @@ -167,7 +167,7 @@ void check(jvmtiEnv *jvmti_env, jthread thr, jmethodID mid, printf(" expected: %d\n", framesCount + 1); RETURN_FAILED; } - fflush(0); + fflush(nullptr); } void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -212,7 +212,7 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, TranslateError(err), err); RETURN_FAILED; } - fflush(0); + fflush(nullptr); } void JNICALL SingleStep(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -249,7 +249,7 @@ void JNICALL SingleStep(jvmtiEnv *jvmti_env, JNIEnv *env, RETURN_FAILED; } } - fflush(0); + fflush(nullptr); } void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, @@ -273,7 +273,7 @@ void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, errCode = STATUS_FAILED; } } - fflush(0); + fflush(nullptr); } #ifdef STATIC_BUILD @@ -409,7 +409,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretstr_check(JNIEnv *env, jclass cls) framesCount, framesExpected); errCode = STATUS_FAILED; } - fflush(0); + fflush(nullptr); return errCode; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretvoid/earlyretvoid.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretvoid/earlyretvoid.cpp index 4919d27e9e7c7..e66b9fc97acd6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretvoid/earlyretvoid.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretvoid/earlyretvoid.cpp @@ -33,7 +33,7 @@ extern "C" { #define PASSED 0 #define STATUS_FAILED 2 -#define RETURN_FAILED errCode = STATUS_FAILED; fflush(0); return +#define RETURN_FAILED errCode = STATUS_FAILED; fflush(nullptr); return static jvmtiEnv *jvmti = nullptr; static jvmtiCapabilities caps; @@ -155,7 +155,7 @@ void check(jvmtiEnv *jvmti_env, jthread thr, jmethodID mid, } jvmti_env->Deallocate((unsigned char*)table); } - fflush(0); + fflush(nullptr); } void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -192,7 +192,7 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, TranslateError(err), err); RETURN_FAILED; } - fflush(0); + fflush(nullptr); } void JNICALL SingleStep(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -223,7 +223,7 @@ void JNICALL SingleStep(jvmtiEnv *jvmti_env, JNIEnv *env, RETURN_FAILED; } } - fflush(0); + fflush(nullptr); } #ifdef STATIC_BUILD @@ -339,7 +339,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretvoid_getReady( } else { framesExpected = depth; } - fflush(0); + fflush(nullptr); } JNIEXPORT jint JNICALL @@ -349,7 +349,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretvoid_check(JNIEnv *env, jclass cls) framesCount, framesExpected); errCode = STATUS_FAILED; } - fflush(0); + fflush(nullptr); return errCode; } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetAllStackTraces/getallstktr001/getallstktr001.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetAllStackTraces/getallstktr001/getallstktr001.cpp index c1f0443186f20..8916186531d58 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetAllStackTraces/getallstktr001/getallstktr001.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetAllStackTraces/getallstktr001/getallstktr001.cpp @@ -179,7 +179,7 @@ void compare_all_frames(int ti, int frames_count, printf("thr #%d: compare frame #%d: fields are the same: " " method: 0x%p, location: %#" LL "x\n", ti, fi, fr1->method, fr1->location); - fflush(0); + fflush(nullptr); } } @@ -225,7 +225,7 @@ void compare_one_stack_trace(int ti, " jthread: 0x%p, state: %d, frame_count: %d\n", ti, stk1->thread, stk1->state, stk1->frame_count); - fflush(0); + fflush(nullptr); compare_all_frames(ti, stk1->frame_count, stk1->frame_buffer, @@ -291,7 +291,7 @@ Java_nsk_jvmti_unit_GetAllStackTraces_getallstktr001_GetThreadsInfo( iGlobalStatus = STATUS_FAILED; } printf("GetThreadInfo %d: thread: %s\n", ti, thread_info[ti].name); - fflush(0); + fflush(nullptr); } } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetConstantPool/getcpool001/getcpool001.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetConstantPool/getcpool001/getcpool001.cpp index 997e6c667e60a..d3905ad65ebcf 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetConstantPool/getcpool001/getcpool001.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/GetConstantPool/getcpool001/getcpool001.cpp @@ -36,7 +36,7 @@ extern "C" { static jvmtiCapabilities caps; static jvmtiEventCallbacks callbacks; -#define RETURN_FAILED errCode = STATUS_FAILED; fflush(0); return +#define RETURN_FAILED errCode = STATUS_FAILED; fflush(nullptr); return static jint errCode = PASSED; static jvmtiEnv *jvmti = nullptr; @@ -63,7 +63,7 @@ Java_nsk_jvmti_unit_GetConstantPool_getcpool001_getCP( /* Print Constant Pool attrs*/ printf("getCP: id = %d, cnt = %03d, bytes_cnt = %04d\n", id, cp_cnt, cp_bytes_cnt); - fflush(0); + fflush(nullptr); } void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, @@ -83,7 +83,7 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, TranslateError(err), err); RETURN_FAILED; } - fflush(0); + fflush(nullptr); } #ifdef STATIC_BUILD From 1472124489c841642996ae984e21c533ffec8091 Mon Sep 17 00:00:00 2001 From: Mark Powers Date: Tue, 9 Jul 2024 20:38:09 +0000 Subject: [PATCH 031/401] 8333364: Minor cleanup could be done in com.sun.crypto.provider Reviewed-by: mullan, valeriep --- .../sun/crypto/provider/AESKeyGenerator.java | 12 +- .../com/sun/crypto/provider/AESKeyWrap.java | 30 ++--- .../sun/crypto/provider/AESKeyWrapPadded.java | 34 ++--- .../sun/crypto/provider/ARCFOURCipher.java | 8 +- .../sun/crypto/provider/ChaCha20Cipher.java | 35 +++-- .../provider/ChaCha20Poly1305Parameters.java | 7 +- .../crypto/provider/CipherBlockChaining.java | 4 +- .../com/sun/crypto/provider/CipherCore.java | 21 ++- .../crypto/provider/CipherTextStealing.java | 5 +- .../sun/crypto/provider/ConstructKeys.java | 6 +- .../com/sun/crypto/provider/DESCrypt.java | 126 +++++++++--------- .../sun/crypto/provider/DESKeyFactory.java | 4 +- .../sun/crypto/provider/DESedeKeyFactory.java | 4 +- .../crypto/provider/DESedeKeyGenerator.java | 4 +- .../sun/crypto/provider/DESedeWrapCipher.java | 15 +-- .../com/sun/crypto/provider/DHKEM.java | 20 +-- .../sun/crypto/provider/DHKeyAgreement.java | 30 ++--- .../crypto/provider/DHKeyPairGenerator.java | 5 +- .../crypto/provider/ElectronicCodeBook.java | 6 +- .../sun/crypto/provider/FeedbackCipher.java | 6 +- .../classes/com/sun/crypto/provider/GCTR.java | 5 +- .../com/sun/crypto/provider/GHASH.java | 7 +- .../crypto/provider/GaloisCounterMode.java | 34 ++--- .../com/sun/crypto/provider/HmacCore.java | 27 ++-- .../com/sun/crypto/provider/HmacMD5.java | 9 +- .../crypto/provider/HmacMD5KeyGenerator.java | 5 +- .../com/sun/crypto/provider/HmacSHA1.java | 9 +- .../crypto/provider/HmacSHA1KeyGenerator.java | 5 +- .../sun/crypto/provider/ISO10126Padding.java | 5 +- .../com/sun/crypto/provider/JceKeyStore.java | 14 +- .../com/sun/crypto/provider/KWUtil.java | 10 +- .../com/sun/crypto/provider/KeyProtector.java | 6 +- .../sun/crypto/provider/KeyWrapCipher.java | 20 +-- .../sun/crypto/provider/OAEPParameters.java | 12 +- .../sun/crypto/provider/OutputFeedback.java | 4 +- .../sun/crypto/provider/PBEKeyFactory.java | 4 +- .../com/sun/crypto/provider/PBES1Core.java | 6 +- .../sun/crypto/provider/PBES2Parameters.java | 20 ++- .../sun/crypto/provider/PBKDF2KeyImpl.java | 21 +-- .../com/sun/crypto/provider/PBMAC1Core.java | 4 +- .../com/sun/crypto/provider/PKCS5Padding.java | 5 +- .../com/sun/crypto/provider/Poly1305.java | 12 +- .../com/sun/crypto/provider/RC2Crypt.java | 4 +- .../com/sun/crypto/provider/RSACipher.java | 7 +- .../com/sun/crypto/provider/SslMacCore.java | 23 ++-- .../provider/TlsKeyMaterialGenerator.java | 12 +- .../sun/crypto/provider/TlsPrfGenerator.java | 8 +- 47 files changed, 313 insertions(+), 367 deletions(-) diff --git a/src/java.base/share/classes/com/sun/crypto/provider/AESKeyGenerator.java b/src/java.base/share/classes/com/sun/crypto/provider/AESKeyGenerator.java index 2672807aaddae..51671fdf25d0a 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/AESKeyGenerator.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/AESKeyGenerator.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 @@ -25,19 +25,19 @@ package com.sun.crypto.provider; -import java.security.SecureRandom; -import java.security.InvalidParameterException; import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; +import java.security.InvalidParameterException; +import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.util.Arrays; import javax.crypto.KeyGeneratorSpi; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; + import sun.security.util.SecurityProviderConstants; /** - * This class generates a AES key. + * This class generates an AES key. * * @author Valerie Peng * @@ -105,7 +105,7 @@ protected void engineInit(int keysize, SecureRandom random) { * @return the new AES key */ protected SecretKey engineGenerateKey() { - SecretKeySpec aesKey = null; + SecretKeySpec aesKey; if (this.random == null) { this.random = SunJCE.getRandom(); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/AESKeyWrap.java b/src/java.base/share/classes/com/sun/crypto/provider/AESKeyWrap.java index 9cb338996406e..7fad0b84d0715 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/AESKeyWrap.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/AESKeyWrap.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 @@ -25,11 +25,11 @@ package com.sun.crypto.provider; -import java.util.Arrays; -import java.security.*; -import java.security.spec.*; -import javax.crypto.*; -import javax.crypto.spec.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import javax.crypto.IllegalBlockSizeException; + import static com.sun.crypto.provider.KWUtil.*; /** @@ -66,7 +66,7 @@ String getFeedback() { @Override void save() { throw new UnsupportedOperationException("save not supported"); - }; + } /** * Restores the content of this cipher to the previous saved one. @@ -74,7 +74,7 @@ void save() { @Override void restore() { throw new UnsupportedOperationException("restore not supported"); - }; + } /** * Initializes the cipher in the specified mode with the given key @@ -112,20 +112,20 @@ void init(boolean decrypting, String algorithm, byte[] key, byte[] iv) @Override void reset() { throw new UnsupportedOperationException("reset not supported"); - }; + } - // no support for multi-part encryption + // no support for multipart encryption @Override int encrypt(byte[] pt, int ptOfs, int ptLen, byte[] ct, int ctOfs) { - throw new UnsupportedOperationException("multi-part not supported"); - }; + throw new UnsupportedOperationException("multipart not supported"); + } - // no support for multi-part decryption + // no support for multipart decryption @Override int decrypt(byte[] ct, int ctOfs, int ctLen, byte[] pt, int ptOfs) { - throw new UnsupportedOperationException("multi-part not supported"); - }; + throw new UnsupportedOperationException("multipart not supported"); + } /** * Performs single-part encryption operation. diff --git a/src/java.base/share/classes/com/sun/crypto/provider/AESKeyWrapPadded.java b/src/java.base/share/classes/com/sun/crypto/provider/AESKeyWrapPadded.java index 4ae96acbca853..1e4e7236c8cae 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/AESKeyWrapPadded.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/AESKeyWrapPadded.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 @@ -25,12 +25,12 @@ package com.sun.crypto.provider; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; import java.util.Arrays; import java.util.HexFormat; -import java.security.*; -import java.security.spec.*; -import javax.crypto.*; -import javax.crypto.spec.*; +import javax.crypto.IllegalBlockSizeException; + import static com.sun.crypto.provider.KWUtil.*; /** @@ -49,7 +49,7 @@ class AESKeyWrapPadded extends FeedbackCipher { private static final byte[] PAD_BLK = new byte[SEMI_BLKSIZE - 1]; - // set the first semiblock of dest with iv and inLen + // set the first semi-block of dest with iv and inLen private static void setIvAndLen(byte[] dest, byte[] iv, int inLen) { assert(dest.length >= SEMI_BLKSIZE) : "buffer needs at least 8 bytes"; @@ -60,7 +60,7 @@ private static void setIvAndLen(byte[] dest, byte[] iv, int inLen) { dest[7] = (byte) (inLen & 0xFF); } - // validate the recovered internal ivAndLen semiblock against iv and + // validate the recovered internal ivAndLen semi-block against iv and // return the recovered input length private static int validateIV(byte[] ivAndLen, byte[] iv) throws IllegalBlockSizeException { @@ -103,7 +103,7 @@ String getFeedback() { @Override void save() { throw new UnsupportedOperationException("save not supported"); - }; + } /** * Restores the content of this cipher to the previous saved one. @@ -111,7 +111,7 @@ void save() { @Override void restore() { throw new UnsupportedOperationException("restore not supported"); - }; + } /** * Initializes the cipher in the specified mode with the given key @@ -151,19 +151,19 @@ void init(boolean decrypting, String algorithm, byte[] key, byte[] iv) @Override void reset() { throw new UnsupportedOperationException("reset not supported"); - }; + } - // no support for multi-part encryption + // no support for multipart encryption @Override int encrypt(byte[] pt, int ptOfs, int ptLen, byte[] ct, int ctOfs) { - throw new UnsupportedOperationException("multi-part not supported"); - }; + throw new UnsupportedOperationException("multipart not supported"); + } - // no support for multi-part decryption + // no support for multipart decryption @Override int decrypt(byte[] ct, int ctOfs, int ctLen, byte[] pt, int ptOfs) { - throw new UnsupportedOperationException("multi-part not supported"); - }; + throw new UnsupportedOperationException("multipart not supported"); + } /** * Performs single-part encryption operation. @@ -199,7 +199,7 @@ int encryptFinal(byte[] pt, int dummy1, int ptLen, byte[] dummy2, } if (ptLen <= BLKSIZE) { - // overwrite the first semiblock with iv and input length + // overwrite the first semi-block with iv and input length setIvAndLen(pt, iv, actualLen); embeddedCipher.encryptBlock(pt, 0, pt, 0); } else { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ARCFOURCipher.java b/src/java.base/share/classes/com/sun/crypto/provider/ARCFOURCipher.java index 09d5a8cddebfb..d7c0f3dd35dae 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/ARCFOURCipher.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/ARCFOURCipher.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 @@ -114,7 +114,7 @@ private void crypt(byte[] in, int inOfs, int inLen, byte[] out, // Modes do not make sense with stream ciphers, but allow ECB // see JCE spec. protected void engineSetMode(String mode) throws NoSuchAlgorithmException { - if (mode.equalsIgnoreCase("ECB") == false) { + if (!mode.equalsIgnoreCase("ECB")) { throw new NoSuchAlgorithmException("Unsupported mode " + mode); } } @@ -123,7 +123,7 @@ protected void engineSetMode(String mode) throws NoSuchAlgorithmException { // see JCE spec. protected void engineSetPadding(String padding) throws NoSuchPaddingException { - if (padding.equalsIgnoreCase("NoPadding") == false) { + if (!padding.equalsIgnoreCase("NoPadding")) { throw new NoSuchPaddingException("Padding must be NoPadding"); } } @@ -201,7 +201,7 @@ private static byte[] getEncodedKey(Key key) throws InvalidKeyException { if (!keyAlg.equals("RC4") && !keyAlg.equals("ARCFOUR")) { throw new InvalidKeyException("Not an ARCFOUR key: " + keyAlg); } - if ("RAW".equals(key.getFormat()) == false) { + if (!"RAW".equals(key.getFormat())) { throw new InvalidKeyException("Key encoding format must be RAW"); } byte[] encodedKey = key.getEncoded(); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java b/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java index ed2fda5bf0086..fc39b4ed63480 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -156,7 +156,7 @@ protected ChaCha20Cipher() { } */ @Override protected void engineSetMode(String mode) throws NoSuchAlgorithmException { - if (mode.equalsIgnoreCase("None") == false) { + if (!mode.equalsIgnoreCase("None")) { throw new NoSuchAlgorithmException("Mode must be None"); } } @@ -174,7 +174,7 @@ protected void engineSetMode(String mode) throws NoSuchAlgorithmException { @Override protected void engineSetPadding(String padding) throws NoSuchPaddingException { - if (padding.equalsIgnoreCase("NoPadding") == false) { + if (!padding.equalsIgnoreCase("NoPadding")) { throw new NoSuchPaddingException("Padding must be NoPadding"); } } @@ -326,7 +326,7 @@ protected void engineInit(int opmode, Key key, // We will ignore the secure random implementation and use the nonce // from the AlgorithmParameterSpec instead. - byte[] newNonce = null; + byte[] newNonce; switch (mode) { case MODE_NONE: if (!(params instanceof ChaCha20ParameterSpec)) { @@ -360,7 +360,7 @@ protected void engineInit(int opmode, Key key, /** * Initialize the engine using the {@code AlgorithmParameter} initialization - * format. This cipher does supports initialization with + * format. This cipher supports initialization with * {@code AlgorithmParameter} objects for ChaCha20-Poly1305 but not for * ChaCha20 as a simple stream cipher. In the latter case, it will throw * an {@code InvalidAlgorithmParameterException} if the value is non-null. @@ -618,7 +618,7 @@ private void checkKeyAndNonce(byte[] newKeyBytes, byte[] newNonce) * or if the key encoding format is not {@code RAW}. */ private static byte[] getEncodedKey(Key key) throws InvalidKeyException { - if ("RAW".equals(key.getFormat()) == false) { + if (!"RAW".equals(key.getFormat())) { throw new InvalidKeyException("Key encoding format must be RAW"); } byte[] encodedKey = key.getEncoded(); @@ -675,7 +675,7 @@ protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) { @Override protected int engineUpdate(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) throws ShortBufferException { - int bytesUpdated = 0; + int bytesUpdated; try { bytesUpdated = engine.doUpdate(in, inOfs, inLen, out, outOfs); } catch (KeyException ke) { @@ -691,10 +691,10 @@ protected int engineUpdate(byte[] in, int inOfs, int inLen, * @param output ByteBuffer that will hold the resulting data. This * must be large enough to hold the resulting data. * - * @return the length in bytes of the data written into the {@code out} + * @return the length in bytes of the data written into the {@code output} * buffer. * - * @throws ShortBufferException if the buffer {@code out} does not have + * @throws ShortBufferException if the buffer {@code output} does not have * enough space to hold the resulting data. */ @Override @@ -763,7 +763,7 @@ protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen) protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) throws ShortBufferException, AEADBadTagException { - int bytesUpdated = 0; + int bytesUpdated; try { bytesUpdated = engine.doFinal(in, inOfs, inLen, out, outOfs); } catch (KeyException ke) { @@ -785,6 +785,9 @@ protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out, * * @return the resulting plaintext or ciphertext bytes. * + * @throws ShortBufferException if the buffer {@code output} does not have + * enough space to hold the resulting data. + * * @throws AEADBadTagException if, during decryption, the provided tag * does not match the calculated tag. */ @@ -947,12 +950,8 @@ protected int engineGetKeySize(Key key) throws InvalidKeyException { * key and nonce into their proper locations. The counter field is not * set here. * - * @throws IllegalArgumentException if the key or nonce are not in - * their proper lengths (32 bytes for the key, 12 bytes for the - * nonce). - * @throws InvalidKeyException if the key does not support an encoded form. */ - private void setInitialState() throws InvalidKeyException { + private void setInitialState() { // Apply constants to first 4 words startState[0] = STATE_CONST_0; startState[1] = STATE_CONST_1; @@ -1257,11 +1256,11 @@ private int authUpdate(byte[] data, int offset, int length) { * @param out the array to write the resulting tag into * @param outOff the offset to begin writing the data. * - * @throws ShortBufferException if there is insufficient room to + * @throws ProviderException if there is insufficient room to * write the tag. */ private void authFinalizeData(byte[] data, int dataOff, int length, - byte[] out, int outOff) throws ShortBufferException { + byte[] out, int outOff) { // Update with the final chunk of ciphertext, then pad to a // multiple of 16. if (data != null) { @@ -1300,7 +1299,7 @@ private void authPad16(long dataLen) { * @param dLen the length of the application data. * @param buf the buffer to write the two lengths into. * - * @note it is the caller's responsibility to provide an array large + * @implNote it is the caller's responsibility to provide an array large * enough to hold the two longs. */ private void authWriteLengths(long aLen, long dLen, byte[] buf) { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Poly1305Parameters.java b/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Poly1305Parameters.java index 762827d0152ff..ab9d4a23e6098 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Poly1305Parameters.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Poly1305Parameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -206,8 +206,7 @@ protected byte[] engineGetEncoded(String encodingMethod) protected String engineToString() { String LINE_SEP = System.lineSeparator(); HexDumpEncoder encoder = new HexDumpEncoder(); - StringBuilder sb = new StringBuilder(LINE_SEP + "nonce:" + - LINE_SEP + "[" + encoder.encodeBuffer(nonce) + "]"); - return sb.toString(); + return LINE_SEP + "nonce:" + + LINE_SEP + "[" + encoder.encodeBuffer(nonce) + "]"; } } diff --git a/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java b/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java index 5d756e2684746..4bd7faea72257 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -180,7 +180,7 @@ private int implEncrypt(byte[] plain, int plainOffset, int plainLen, * *

It is also the application's responsibility to make sure that * init has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + * (This check is omitted here, to avoid double-checking.) * * @param cipher the buffer with the input data to be decrypted * @param cipherOffset the offset in cipherOffset diff --git a/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java b/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java index 2555448e3c011..c808756fa1d7a 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, 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 @@ -67,7 +67,7 @@ final class CipherCore { /* * unit size (number of input bytes that can be processed at a time) */ - private int unitBytes = 0; + private int unitBytes; /* * index of the content size left in the buffer @@ -91,17 +91,17 @@ final class CipherCore { * input bytes that are processed at a time is different from the block * size) */ - private int diffBlocksize = 0; + private int diffBlocksize; /* * padding class */ - private Padding padding = null; + private Padding padding; /* * internal cipher engine */ - private FeedbackCipher cipher = null; + private FeedbackCipher cipher; /* * the cipher mode @@ -136,7 +136,7 @@ final class CipherCore { /* * The buffer should be usable for all cipher mode and padding * schemes. Thus, it has to be at least (blockSize+1) for CTS. - * In decryption mode, it also hold the possible padding block. + * In decryption mode, it also holds the possible padding block. */ buffer = new byte[blockSize*2]; @@ -334,7 +334,7 @@ AlgorithmParameters getParameters(String algName) { if (cipherMode == ECB_MODE) { return null; } - AlgorithmParameters params = null; + AlgorithmParameters params; AlgorithmParameterSpec spec; byte[] iv = getIV(); if (iv == null) { @@ -545,7 +545,7 @@ static byte[] getKeyBytes(Key key) throws InvalidKeyException { */ byte[] update(byte[] input, int inputOffset, int inputLen) { - byte[] output = null; + byte[] output; try { output = new byte[getOutputSizeByOperation(inputLen, false)]; int len = update(input, inputOffset, inputLen, output, @@ -930,8 +930,7 @@ private byte[] prepareInputBuffer(byte[] input, int inputOffset, private int fillOutputBuffer(byte[] finalBuf, int finalOffset, byte[] output, int outOfs, int finalBufLen, byte[] input) - throws ShortBufferException, BadPaddingException, - IllegalBlockSizeException { + throws BadPaddingException, IllegalBlockSizeException { int len; try { @@ -967,7 +966,7 @@ private int checkOutputCapacity(byte[] output, int outputOffset, private int finalNoPadding(byte[] in, int inOfs, byte[] out, int outOfs, int len) - throws IllegalBlockSizeException, ShortBufferException { + throws IllegalBlockSizeException { if (in == null || len == 0) { return 0; diff --git a/src/java.base/share/classes/com/sun/crypto/provider/CipherTextStealing.java b/src/java.base/share/classes/com/sun/crypto/provider/CipherTextStealing.java index 630f8707fdeb7..da46f220825a5 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/CipherTextStealing.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/CipherTextStealing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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,6 @@ package com.sun.crypto.provider; import javax.crypto.IllegalBlockSizeException; -import javax.crypto.ShortBufferException; /** * This class represents ciphers in cipher text stealing (CTS) mode. @@ -153,7 +152,7 @@ int encryptFinal(byte[] plain, int plainOffset, int plainLen, * *

It is also the application's responsibility to make sure that * init has been called before this method is called. - * (This check is omitted here, to avoid double checking.) + * (This check is omitted here, to avoid double-checking.) * * @param cipher the buffer with the input data to be decrypted * @param cipherOffset the offset in cipherOffset diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ConstructKeys.java b/src/java.base/share/classes/com/sun/crypto/provider/ConstructKeys.java index e8375d1eb8182..2019104941efd 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/ConstructKeys.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/ConstructKeys.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, 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 @@ -54,7 +54,7 @@ final class ConstructKeys { private static final PublicKey constructPublicKey(byte[] encodedKey, int ofs, int len, String encodedKeyAlgorithm) throws InvalidKeyException, NoSuchAlgorithmException { - PublicKey key = null; + PublicKey key; byte[] keyBytes = (ofs == 0 && encodedKey.length == len) ? encodedKey : Arrays.copyOfRange(encodedKey, ofs, ofs + len); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); @@ -88,7 +88,7 @@ private static final PublicKey constructPublicKey(byte[] encodedKey, private static final PrivateKey constructPrivateKey(byte[] encodedKey, int ofs, int len, String encodedKeyAlgorithm) throws InvalidKeyException, NoSuchAlgorithmException { - PrivateKey key = null; + PrivateKey key; byte[] keyBytes = (ofs == 0 && encodedKey.length == len) ? encodedKey : Arrays.copyOfRange(encodedKey, ofs, ofs + len); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DESCrypt.java b/src/java.base/share/classes/com/sun/crypto/provider/DESCrypt.java index acbde75cd8426..29a5ba2540860 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/DESCrypt.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/DESCrypt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -40,7 +40,7 @@ */ class DESCrypt extends SymmetricCipher implements DESConstants { - private static final int s0p[] = { + private static final int[] s0p = { 0x00410100, 0x00010000, 0x40400000, 0x40410100, 0x00400000, 0x40010100, 0x40010000, 0x40400000, 0x40010100, 0x00410100, 0x00410000, 0x40000100, 0x40400100, 0x00400000, 0x00000000, @@ -56,7 +56,7 @@ class DESCrypt extends SymmetricCipher implements DESConstants { 0x40000000, 0x40410000, 0x00000100, 0x40010100, }; - private static final int s1p[] = { + private static final int[] s1p = { 0x08021002, 0x00000000, 0x00021000, 0x08020000, 0x08000002, 0x00001002, 0x08001000, 0x00021000, 0x00001000, 0x08020002, 0x00000002, 0x08001000, 0x00020002, 0x08021000, 0x08020000, @@ -72,7 +72,7 @@ class DESCrypt extends SymmetricCipher implements DESConstants { 0x08001002, 0x00000002, 0x08020000, 0x00021000, }; - private static final int s2p[] = { + private static final int[] s2p = { 0x20800000, 0x00808020, 0x00000020, 0x20800020, 0x20008000, 0x00800000, 0x20800020, 0x00008020, 0x00800020, 0x00008000, 0x00808000, 0x20000000, 0x20808020, 0x20000020, 0x20000000, @@ -88,7 +88,7 @@ class DESCrypt extends SymmetricCipher implements DESConstants { 0x20800000, 0x20008020, 0x00000020, 0x00808000, }; - private static final int s3p[] = { + private static final int[] s3p = { 0x00080201, 0x02000200, 0x00000001, 0x02080201, 0x00000000, 0x02080000, 0x02000201, 0x00080001, 0x02080200, 0x02000001, 0x02000000, 0x00000201, 0x02000001, 0x00080201, 0x00080000, @@ -104,7 +104,7 @@ class DESCrypt extends SymmetricCipher implements DESConstants { 0x00000201, 0x02000000, 0x02000001, 0x02080200, }; - private static final int s4p[] = { + private static final int[] s4p = { 0x01000000, 0x00002000, 0x00000080, 0x01002084, 0x01002004, 0x01000080, 0x00002084, 0x01002000, 0x00002000, 0x00000004, 0x01000004, 0x00002080, 0x01000084, 0x01002004, 0x01002080, @@ -120,7 +120,7 @@ class DESCrypt extends SymmetricCipher implements DESConstants { 0x00000004, 0x00002084, 0x01002000, 0x01000004, }; - private static final int s5p[] = { + private static final int[] s5p = { 0x10000008, 0x00040008, 0x00000000, 0x10040400, 0x00040008, 0x00000400, 0x10000408, 0x00040000, 0x00000408, 0x10040408, 0x00040400, 0x10000000, 0x10000400, 0x10000008, 0x10040000, @@ -136,7 +136,7 @@ class DESCrypt extends SymmetricCipher implements DESConstants { 0x10040000, 0x00000408, 0x00000008, 0x10040008, }; - private static final int s6p[] = { + private static final int[] s6p = { 0x00000800, 0x00000040, 0x00200040, 0x80200000, 0x80200840, 0x80000800, 0x00000840, 0x00000000, 0x00200000, 0x80200040, 0x80000040, 0x00200800, 0x80000000, 0x00200840, 0x00200800, @@ -152,7 +152,7 @@ class DESCrypt extends SymmetricCipher implements DESConstants { 0x80200000, 0x00200840, 0x00200800, 0x80000800, }; - private static final int s7p[] = { + private static final int[] s7p = { 0x04100010, 0x04104000, 0x00004010, 0x00000000, 0x04004000, 0x00100010, 0x04100000, 0x04104010, 0x00000010, 0x04000000, 0x00104000, 0x00004010, 0x00104010, 0x04004010, 0x04000010, @@ -168,112 +168,112 @@ class DESCrypt extends SymmetricCipher implements DESConstants { 0x04000000, 0x04100010, 0x00004000, 0x00104010, }; - private static final int permRight0[] = { + private static final int[] permRight0 = { 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, 0x40404040, }; - private static final int permLeft1[] = { + private static final int[] permLeft1 = { 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00004000, 0x40004000, 0x00404000, 0x40404000, 0x00000040, 0x40000040, 0x00400040, 0x40400040, 0x00004040, 0x40004040, 0x00404040, 0x40404040, }; - private static final int permRight2[] = { + private static final int[] permRight2 = { 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, 0x10101010, }; - private static final int permLeft3[] = { + private static final int[] permLeft3 = { 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00001000, 0x10001000, 0x00101000, 0x10101000, 0x00000010, 0x10000010, 0x00100010, 0x10100010, 0x00001010, 0x10001010, 0x00101010, 0x10101010, }; - private static final int permRight4[] = { + private static final int[] permRight4 = { 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404, }; - private static final int permLeft5[] = { + private static final int[] permLeft5 = { 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00000400, 0x04000400, 0x00040400, 0x04040400, 0x00000004, 0x04000004, 0x00040004, 0x04040004, 0x00000404, 0x04000404, 0x00040404, 0x04040404, }; - private static final int permRight6[] = { + private static final int[] permRight6 = { 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101, }; - private static final int permLeft7[] = { + private static final int[] permLeft7 = { 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00000100, 0x01000100, 0x00010100, 0x01010100, 0x00000001, 0x01000001, 0x00010001, 0x01010001, 0x00000101, 0x01000101, 0x00010101, 0x01010101, }; - private static final int permRight8[] = { + private static final int[] permRight8 = { 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080, }; - private static final int permLeft9[] = { + private static final int[] permLeft9 = { 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00008000, 0x80008000, 0x00808000, 0x80808000, 0x00000080, 0x80000080, 0x00800080, 0x80800080, 0x00008080, 0x80008080, 0x00808080, 0x80808080, }; - private static final int permRightA[] = { + private static final int[] permRightA = { 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, 0x20202020, }; - private static final int permLeftB[] = { + private static final int[] permLeftB = { 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00002000, 0x20002000, 0x00202000, 0x20202000, 0x00000020, 0x20000020, 0x00200020, 0x20200020, 0x00002020, 0x20002020, 0x00202020, 0x20202020, }; - private static final int permRightC[] = { + private static final int[] permRightC = { 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, 0x08080808, }; - private static final int permLeftD[] = { + private static final int[] permLeftD = { 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00000800, 0x08000800, 0x00080800, 0x08080800, 0x00000008, 0x08000008, 0x00080008, 0x08080008, 0x00000808, 0x08000808, 0x00080808, 0x08080808, }; - private static final int permRightE[] = { + private static final int[] permRightE = { 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, 0x02020202, }; - private static final int permLeftF[] = { + private static final int[] permLeftF = { 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, 0x02000202, 0x00020202, @@ -283,224 +283,224 @@ class DESCrypt extends SymmetricCipher implements DESConstants { /* * Initial Permutation */ - private static final int initPermLeft0[] = { + private static final int[] initPermLeft0 = { 0x00000000, 0x00008000, 0x00000000, 0x00008000, 0x00000080, 0x00008080, 0x00000080, 0x00008080, 0x00000000, 0x00008000, 0x00000000, 0x00008000, 0x00000080, 0x00008080, 0x00000080, 0x00008080, }; - private static final int initPermRight0[] = { + private static final int[] initPermRight0 = { 0x00000000, 0x00000000, 0x00008000, 0x00008000, 0x00000000, 0x00000000, 0x00008000, 0x00008000, 0x00000080, 0x00000080, 0x00008080, 0x00008080, 0x00000080, 0x00000080, 0x00008080, 0x00008080, }; - private static final int initPermLeft1[] = { + private static final int[] initPermLeft1 = { 0x00000000, 0x80000000, 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00800000, 0x80800000, 0x00000000, 0x80000000, 0x00000000, 0x80000000, 0x00800000, 0x80800000, 0x00800000, 0x80800000, }; - private static final int initPermRight1[] = { + private static final int[] initPermRight1 = { 0x00000000, 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x80000000, 0x80000000, 0x00800000, 0x00800000, 0x80800000, 0x80800000, 0x00800000, 0x00800000, 0x80800000, 0x80800000, }; - private static final int initPermLeft2[] = { + private static final int[] initPermLeft2 = { 0x00000000, 0x00004000, 0x00000000, 0x00004000, 0x00000040, 0x00004040, 0x00000040, 0x00004040, 0x00000000, 0x00004000, 0x00000000, 0x00004000, 0x00000040, 0x00004040, 0x00000040, 0x00004040, }; - private static final int initPermRight2[] = { + private static final int[] initPermRight2 = { 0x00000000, 0x00000000, 0x00004000, 0x00004000, 0x00000000, 0x00000000, 0x00004000, 0x00004000, 0x00000040, 0x00000040, 0x00004040, 0x00004040, 0x00000040, 0x00000040, 0x00004040, 0x00004040, }; - private static final int initPermLeft3[] = { + private static final int[] initPermLeft3 = { 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00400000, 0x40400000, 0x00000000, 0x40000000, 0x00000000, 0x40000000, 0x00400000, 0x40400000, 0x00400000, 0x40400000, }; - private static final int initPermRight3[] = { + private static final int[] initPermRight3 = { 0x00000000, 0x00000000, 0x40000000, 0x40000000, 0x00000000, 0x00000000, 0x40000000, 0x40000000, 0x00400000, 0x00400000, 0x40400000, 0x40400000, 0x00400000, 0x00400000, 0x40400000, 0x40400000, }; - private static final int initPermLeft4[] = { + private static final int[] initPermLeft4 = { 0x00000000, 0x00002000, 0x00000000, 0x00002000, 0x00000020, 0x00002020, 0x00000020, 0x00002020, 0x00000000, 0x00002000, 0x00000000, 0x00002000, 0x00000020, 0x00002020, 0x00000020, 0x00002020, }; - private static final int initPermRight4[] = { + private static final int[] initPermRight4 = { 0x00000000, 0x00000000, 0x00002000, 0x00002000, 0x00000000, 0x00000000, 0x00002000, 0x00002000, 0x00000020, 0x00000020, 0x00002020, 0x00002020, 0x00000020, 0x00000020, 0x00002020, 0x00002020, }; - private static final int initPermLeft5[] = { + private static final int[] initPermLeft5 = { 0x00000000, 0x20000000, 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00200000, 0x20200000, 0x00000000, 0x20000000, 0x00000000, 0x20000000, 0x00200000, 0x20200000, 0x00200000, 0x20200000, }; - private static final int initPermRight5[] = { + private static final int[] initPermRight5 = { 0x00000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x20000000, 0x20000000, 0x00200000, 0x00200000, 0x20200000, 0x20200000, 0x00200000, 0x00200000, 0x20200000, 0x20200000, }; - private static final int initPermLeft6[] = { + private static final int[] initPermLeft6 = { 0x00000000, 0x00001000, 0x00000000, 0x00001000, 0x00000010, 0x00001010, 0x00000010, 0x00001010, 0x00000000, 0x00001000, 0x00000000, 0x00001000, 0x00000010, 0x00001010, 0x00000010, 0x00001010, }; - private static final int initPermRight6[] = { + private static final int[] initPermRight6 = { 0x00000000, 0x00000000, 0x00001000, 0x00001000, 0x00000000, 0x00000000, 0x00001000, 0x00001000, 0x00000010, 0x00000010, 0x00001010, 0x00001010, 0x00000010, 0x00000010, 0x00001010, 0x00001010, }; - private static final int initPermLeft7[] = { + private static final int[] initPermLeft7 = { 0x00000000, 0x10000000, 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00100000, 0x10100000, 0x00000000, 0x10000000, 0x00000000, 0x10000000, 0x00100000, 0x10100000, 0x00100000, 0x10100000, }; - private static final int initPermRight7[] = { + private static final int[] initPermRight7 = { 0x00000000, 0x00000000, 0x10000000, 0x10000000, 0x00000000, 0x00000000, 0x10000000, 0x10000000, 0x00100000, 0x00100000, 0x10100000, 0x10100000, 0x00100000, 0x00100000, 0x10100000, 0x10100000, }; - private static final int initPermLeft8[] = { + private static final int[] initPermLeft8 = { 0x00000000, 0x00000800, 0x00000000, 0x00000800, 0x00000008, 0x00000808, 0x00000008, 0x00000808, 0x00000000, 0x00000800, 0x00000000, 0x00000800, 0x00000008, 0x00000808, 0x00000008, 0x00000808, }; - private static final int initPermRight8[] = { + private static final int[] initPermRight8 = { 0x00000000, 0x00000000, 0x00000800, 0x00000800, 0x00000000, 0x00000000, 0x00000800, 0x00000800, 0x00000008, 0x00000008, 0x00000808, 0x00000808, 0x00000008, 0x00000008, 0x00000808, 0x00000808, }; - private static final int initPermLeft9[] = { + private static final int[] initPermLeft9 = { 0x00000000, 0x08000000, 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00080000, 0x08080000, 0x00000000, 0x08000000, 0x00000000, 0x08000000, 0x00080000, 0x08080000, 0x00080000, 0x08080000, }; - private static final int initPermRight9[] = { + private static final int[] initPermRight9 = { 0x00000000, 0x00000000, 0x08000000, 0x08000000, 0x00000000, 0x00000000, 0x08000000, 0x08000000, 0x00080000, 0x00080000, 0x08080000, 0x08080000, 0x00080000, 0x00080000, 0x08080000, 0x08080000, }; - private static final int initPermLeftA[] = { + private static final int[] initPermLeftA = { 0x00000000, 0x00000400, 0x00000000, 0x00000400, 0x00000004, 0x00000404, 0x00000004, 0x00000404, 0x00000000, 0x00000400, 0x00000000, 0x00000400, 0x00000004, 0x00000404, 0x00000004, 0x00000404, }; - private static final int initPermRightA[] = { + private static final int[] initPermRightA = { 0x00000000, 0x00000000, 0x00000400, 0x00000400, 0x00000000, 0x00000000, 0x00000400, 0x00000400, 0x00000004, 0x00000004, 0x00000404, 0x00000404, 0x00000004, 0x00000004, 0x00000404, 0x00000404, }; - private static final int initPermLeftB[] = { + private static final int[] initPermLeftB = { 0x00000000, 0x04000000, 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00040000, 0x04040000, 0x00000000, 0x04000000, 0x00000000, 0x04000000, 0x00040000, 0x04040000, 0x00040000, 0x04040000, }; - private static final int initPermRightB[] = { + private static final int[] initPermRightB = { 0x00000000, 0x00000000, 0x04000000, 0x04000000, 0x00000000, 0x00000000, 0x04000000, 0x04000000, 0x00040000, 0x00040000, 0x04040000, 0x04040000, 0x00040000, 0x00040000, 0x04040000, 0x04040000, }; - private static final int initPermLeftC[] = { + private static final int[] initPermLeftC = { 0x00000000, 0x00000200, 0x00000000, 0x00000200, 0x00000002, 0x00000202, 0x00000002, 0x00000202, 0x00000000, 0x00000200, 0x00000000, 0x00000200, 0x00000002, 0x00000202, 0x00000002, 0x00000202, }; - private static final int initPermRightC[] = { + private static final int[] initPermRightC = { 0x00000000, 0x00000000, 0x00000200, 0x00000200, 0x00000000, 0x00000000, 0x00000200, 0x00000200, 0x00000002, 0x00000002, 0x00000202, 0x00000202, 0x00000002, 0x00000002, 0x00000202, 0x00000202, }; - private static final int initPermLeftD[] = { + private static final int[] initPermLeftD = { 0x00000000, 0x02000000, 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00020000, 0x02020000, 0x00000000, 0x02000000, 0x00000000, 0x02000000, 0x00020000, 0x02020000, 0x00020000, 0x02020000, }; - private static final int initPermRightD[] = { + private static final int[] initPermRightD = { 0x00000000, 0x00000000, 0x02000000, 0x02000000, 0x00000000, 0x00000000, 0x02000000, 0x02000000, 0x00020000, 0x00020000, 0x02020000, 0x02020000, 0x00020000, 0x00020000, 0x02020000, 0x02020000, }; - private static final int initPermLeftE[] = { + private static final int[] initPermLeftE = { 0x00000000, 0x00000100, 0x00000000, 0x00000100, 0x00000001, 0x00000101, 0x00000001, 0x00000101, 0x00000000, 0x00000100, 0x00000000, 0x00000100, 0x00000001, 0x00000101, 0x00000001, 0x00000101, }; - private static final int initPermRightE[] = { + private static final int[] initPermRightE = { 0x00000000, 0x00000000, 0x00000100, 0x00000100, 0x00000000, 0x00000000, 0x00000100, 0x00000100, 0x00000001, 0x00000001, 0x00000101, 0x00000101, 0x00000001, 0x00000001, 0x00000101, 0x00000101, }; - private static final int initPermLeftF[] = { + private static final int[] initPermLeftF = { 0x00000000, 0x01000000, 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00010000, 0x01010000, 0x00000000, 0x01000000, 0x00000000, 0x01000000, 0x00010000, 0x01010000, 0x00010000, 0x01010000, }; - private static final int initPermRightF[] = { + private static final int[] initPermRightF = { 0x00000000, 0x00000000, 0x01000000, 0x01000000, 0x00000000, 0x00000000, 0x01000000, 0x01000000, 0x00010000, 0x00010000, 0x01010000, 0x01010000, 0x00010000, 0x00010000, 0x01010000, @@ -586,7 +586,7 @@ void decryptBlock(byte[] cipher, int cipherOffset, void cipherBlock(byte[] in, int inOffset, byte[] out, int outOffset) { - byte key[]; + byte[] key; int temp; int i, j; int offset; @@ -638,7 +638,7 @@ void cipherBlock(byte[] in, int inOffset, byte[] out, int outOffset) { } private static void perm(int left, int right, - byte out[], int offset) { + byte[] out, int offset) { int low, high, temp; temp = left; @@ -687,7 +687,7 @@ private static void perm(int left, int right, } - private static int initialPermutationLeft(byte block[], int offset) { + private static int initialPermutationLeft(byte[] block, int offset) { int l; l = initPermLeft1[block[offset] & 0xf]; @@ -709,7 +709,7 @@ private static int initialPermutationLeft(byte block[], int offset) { return l; } - private static int initialPermutationRight(byte block[], int offset) { + private static int initialPermutationRight(byte[] block, int offset) { int l; l = initPermRight1[block[offset] & 0xf]; @@ -731,9 +731,9 @@ private static int initialPermutationRight(byte block[], int offset) { return l; } - void expandKey(byte key[]) { + void expandKey(byte[] key) { int octet; - byte ek[] = new byte[128]; + byte[] ek = new byte[128]; octet = key[0]; if ((octet & 0x80) != 0) { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DESKeyFactory.java b/src/java.base/share/classes/com/sun/crypto/provider/DESKeyFactory.java index fa06797abc293..fd3320b070d54 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/DESKeyFactory.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/DESKeyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -104,7 +104,7 @@ protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec) try { - if ((key instanceof SecretKey) + if ((key != null) && (key.getAlgorithm().equalsIgnoreCase("DES")) && (key.getFormat().equalsIgnoreCase("RAW"))) { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DESedeKeyFactory.java b/src/java.base/share/classes/com/sun/crypto/provider/DESedeKeyFactory.java index fd20415bb2d4a..b769aab417b22 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/DESedeKeyFactory.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/DESedeKeyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -103,7 +103,7 @@ protected KeySpec engineGetKeySpec(SecretKey key, Class keySpec) throws InvalidKeySpecException { try { - if ((key instanceof SecretKey) + if ((key != null) && (key.getAlgorithm().equalsIgnoreCase("DESede")) && (key.getFormat().equalsIgnoreCase("RAW"))) { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DESedeKeyGenerator.java b/src/java.base/share/classes/com/sun/crypto/provider/DESedeKeyGenerator.java index 28684b0f9e7af..325c0588777d1 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/DESedeKeyGenerator.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/DESedeKeyGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -130,7 +130,7 @@ protected SecretKey engineGenerateKey() { java.util.Arrays.fill(tmpkey, (byte)0x00); } - DESedeKey desEdeKey = null; + DESedeKey desEdeKey; try { desEdeKey = new DESedeKey(rawkey); } catch (InvalidKeyException ike) { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java b/src/java.base/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java index 92d25b57a7e50..f9281ae929536 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -137,13 +137,13 @@ protected int engineGetBlockSize() { */ protected int engineGetOutputSize(int inputLen) { // can only return an upper-limit if not initialized yet. - int result = 0; + int result; if (decrypting) { result = inputLen - 16; // CHECKSUM_LEN + IV_LEN; } else { result = Math.addExact(inputLen, 16); } - return (result < 0? 0:result); + return (Math.max(result, 0)); } /** @@ -210,7 +210,7 @@ protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { - byte[] currIv = null; + byte[] currIv; if (opmode == Cipher.WRAP_MODE) { decrypting = false; if (params == null) { @@ -380,7 +380,7 @@ protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, /** * Returns the parameters used with this cipher. * Note that null maybe returned if this cipher does not use any - * parameters or when it has not be set, e.g. initialized with + * parameters or when it has not been set, e.g. initialized with * UNWRAP_MODE but wrapped key data has not been given. * * @return the parameters used with this cipher; can be null. @@ -556,9 +556,8 @@ protected Key engineUnwrap(byte[] wrappedKey, buffer2, 0); int keyValLen = buffer2.length - CHECKSUM_LEN; byte[] cks = getChecksum(buffer2, 0, keyValLen); - int offset = keyValLen; for (int i = 0; i < CHECKSUM_LEN; i++) { - if (buffer2[offset + i] != cks[i]) { + if (buffer2[keyValLen + i] != cks[i]) { throw new InvalidKeyException("Checksum comparison failed"); } } @@ -588,7 +587,7 @@ private static final byte[] getChecksum(byte[] in) { return getChecksum(in, 0, in.length); } private static final byte[] getChecksum(byte[] in, int offset, int len) { - MessageDigest md = null; + MessageDigest md; try { md = MessageDigest.getInstance("SHA1"); } catch (NoSuchAlgorithmException nsae) { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DHKEM.java b/src/java.base/share/classes/com/sun/crypto/provider/DHKEM.java index bd1c3f7c38053..3fa6b14762ac2 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/DHKEM.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/DHKEM.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 @@ -24,21 +24,23 @@ */ package com.sun.crypto.provider; -import sun.security.jca.JCAUtil; -import sun.security.ssl.HKDF; -import sun.security.util.*; - -import javax.crypto.*; -import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; -import java.nio.charset.StandardCharsets; import java.security.*; -import java.security.interfaces.*; +import java.security.interfaces.ECKey; +import java.security.interfaces.ECPublicKey; +import java.security.interfaces.XECKey; +import java.security.interfaces.XECPublicKey; import java.security.spec.*; import java.util.Arrays; import java.util.Objects; +import javax.crypto.*; +import javax.crypto.spec.SecretKeySpec; + +import sun.security.jca.JCAUtil; +import sun.security.ssl.HKDF; +import sun.security.util.*; // Implementing DHKEM defined inside https://www.rfc-editor.org/rfc/rfc9180.html, // without the AuthEncap and AuthDecap functions diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DHKeyAgreement.java b/src/java.base/share/classes/com/sun/crypto/provider/DHKeyAgreement.java index 01f978fff615f..5eebf98acc3d8 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/DHKeyAgreement.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/DHKeyAgreement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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,23 +25,15 @@ package com.sun.crypto.provider; -import java.util.*; -import java.lang.*; import java.math.BigInteger; -import java.security.AccessController; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.PrivilegedAction; -import java.security.ProviderException; +import java.security.*; import java.security.spec.AlgorithmParameterSpec; -import java.security.spec.InvalidKeySpecException; +import java.util.Arrays; import javax.crypto.KeyAgreementSpi; -import javax.crypto.ShortBufferException; import javax.crypto.SecretKey; -import javax.crypto.spec.*; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.DHParameterSpec; +import javax.crypto.spec.SecretKeySpec; import sun.security.util.KeyUtil; @@ -180,7 +172,7 @@ protected void engineInit(Key key, AlgorithmParameterSpec params, * @param key the key for this phase. For example, in the case of * Diffie-Hellman between 2 parties, this would be the other party's * Diffie-Hellman public key. - * @param lastPhase flag which indicates whether or not this is the last + * @param lastPhase flag which indicates if this is the last * phase of this key agreement. * * @return the (intermediate) key resulting from this phase, or null if @@ -227,7 +219,7 @@ protected Key engineDoPhase(Key key, boolean lastPhase) // intermediate secret, in which case we wrap it into a // Diffie-Hellman public key object and return it. generateSecret = true; - if (lastPhase == false) { + if (!lastPhase) { byte[] intermediate = engineGenerateSecret(); return new DHPublicKey(new BigInteger(1, intermediate), init_p, init_g); @@ -293,7 +285,7 @@ protected byte[] engineGenerateSecret() protected int engineGenerateSecret(byte[] sharedSecret, int offset) throws IllegalStateException, ShortBufferException { - if (generateSecret == false) { + if (!generateSecret) { throw new IllegalStateException ("Key agreement has not been completed yet"); } @@ -413,9 +405,7 @@ protected SecretKey engineGenerateSecret(String algorithm) int keysize = secret.length; if (keysize >= BlowfishConstants.BLOWFISH_MAX_KEYSIZE) keysize = BlowfishConstants.BLOWFISH_MAX_KEYSIZE; - SecretKeySpec skey = new SecretKeySpec(secret, 0, keysize, - "Blowfish"); - return skey; + return new SecretKeySpec(secret, 0, keysize, "Blowfish"); } else if (algorithm.equalsIgnoreCase("AES")) { // AES int keysize = secret.length; diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java b/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java index 4cc979cb29a89..89d4fcfc402cb 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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,11 +28,10 @@ import java.math.BigInteger; import java.security.*; import java.security.spec.AlgorithmParameterSpec; -import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.DHParameterSpec; -import javax.crypto.spec.DHGenParameterSpec; import sun.security.provider.ParameterCache; + import static sun.security.util.SecurityProviderConstants.DEF_DH_KEY_SIZE; import static sun.security.util.SecurityProviderConstants.getDefDHPrivateExpSize; diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java b/src/java.base/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java index c2085816453d5..ba8a564be11f8 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/ElectronicCodeBook.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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,9 +27,9 @@ import java.security.InvalidKeyException; import java.security.ProviderException; -import sun.security.util.ArrayUtil; -import java.util.Objects; + import jdk.internal.vm.annotation.IntrinsicCandidate; +import sun.security.util.ArrayUtil; /** * This class represents ciphers in electronic codebook (ECB) mode. diff --git a/src/java.base/share/classes/com/sun/crypto/provider/FeedbackCipher.java b/src/java.base/share/classes/com/sun/crypto/provider/FeedbackCipher.java index 6c0e10eb6d0a4..985c1b81f4393 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/FeedbackCipher.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/FeedbackCipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -157,7 +157,7 @@ abstract int encrypt(byte[] plain, int plainOffset, int plainLen, */ int encryptFinal(byte[] plain, int plainOffset, int plainLen, byte[] cipher, int cipherOffset) - throws IllegalBlockSizeException, ShortBufferException { + throws IllegalBlockSizeException { return encrypt(plain, plainOffset, plainLen, cipher, cipherOffset); } /** @@ -199,7 +199,7 @@ abstract int decrypt(byte[] cipher, int cipherOffset, int cipherLen, */ int decryptFinal(byte[] cipher, int cipherOffset, int cipherLen, byte[] plain, int plainOffset) - throws IllegalBlockSizeException, ShortBufferException { + throws IllegalBlockSizeException { return decrypt(cipher, cipherOffset, cipherLen, plain, plainOffset); } } diff --git a/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java b/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java index 7aaec3d6c1ae1..926a56c140b66 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, 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 @@ -79,8 +79,7 @@ private long blocksUntilRollover() { ByteBuffer buf = ByteBuffer.wrap(counter, counter.length - 4, 4); buf.order(ByteOrder.BIG_ENDIAN); long ctr32 = 0xFFFFFFFFL & buf.getInt(); - long blocksLeft = (1L << 32) - ctr32; - return blocksLeft; + return (1L << 32) - ctr32; } private void checkBlock() { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java b/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java index b7aaf6059d535..6b8c2e9c1a965 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, 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 @@ -190,9 +190,8 @@ int update(ByteBuffer ct, int inLen) { // If ct is a direct bytebuffer, send it directly to the intrinsic if (ct.isDirect()) { - int processed = inLen; processBlocksDirect(ct, inLen); - return processed; + return inLen; } else if (!ct.isReadOnly()) { // If a non-read only heap bytebuffer, use the array update method int processed = update(ct.array(), @@ -273,7 +272,7 @@ private static void ghashRangeCheck(byte[] in, int inOfs, int inLen, /* * This is an intrinsified method. The method's argument list must match * the hotspot signature. This method and methods called by it, cannot - * throw exceptions or allocate arrays as it will breaking intrinsics + * throw exceptions or allocate arrays as it will break intrinsics. */ @IntrinsicCandidate private static void processBlocks(byte[] data, int inOfs, int blocks, diff --git a/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java b/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java index 8cfd7d13f12b2..44cfb76d1628e 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, 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 @@ -25,38 +25,24 @@ package com.sun.crypto.provider; -import jdk.internal.access.JavaNioAccess; -import jdk.internal.access.SharedSecrets; -import jdk.internal.misc.Unsafe; -import sun.nio.ch.DirectBuffer; -import sun.security.jca.JCAUtil; -import sun.security.util.ArrayUtil; - -import javax.crypto.AEADBadTagException; -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.CipherSpi; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.ShortBufferException; -import javax.crypto.spec.GCMParameterSpec; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.security.AlgorithmParameters; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.ProviderException; -import java.security.SecureRandom; +import java.security.*; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import java.util.Arrays; +import javax.crypto.*; +import javax.crypto.spec.GCMParameterSpec; +import jdk.internal.access.JavaNioAccess; +import jdk.internal.access.SharedSecrets; +import jdk.internal.misc.Unsafe; import jdk.internal.vm.annotation.IntrinsicCandidate; +import sun.nio.ch.DirectBuffer; +import sun.security.jca.JCAUtil; +import sun.security.util.ArrayUtil; /** * This class represents ciphers in GaloisCounter (GCM) mode. diff --git a/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java b/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java index fecc30a5a085d..c6707fb994113 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/HmacCore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -25,16 +25,12 @@ package com.sun.crypto.provider; -import java.util.Arrays; - import java.nio.ByteBuffer; - +import java.security.*; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Arrays; import javax.crypto.MacSpi; import javax.crypto.SecretKey; -import java.security.*; -import java.security.spec.*; - -import sun.security.x509.AlgorithmId; /** * This class constitutes the core of HMAC- algorithms, where @@ -87,8 +83,7 @@ abstract class HmacCore extends MacSpi implements Cloneable { break; } } - } catch (NoSuchAlgorithmException nsae) { - continue; + } catch (NoSuchAlgorithmException ignored) { } } if (md == null) { @@ -169,7 +164,7 @@ protected void engineInit(Key key, AlgorithmParameterSpec params) * @param input the input byte to be processed. */ protected void engineUpdate(byte input) { - if (first == true) { + if (first) { // compute digest for 1st pass; start with inner pad md.update(k_ipad); first = false; @@ -187,8 +182,8 @@ protected void engineUpdate(byte input) { * @param offset the offset in input where the input starts. * @param len the number of bytes to process. */ - protected void engineUpdate(byte input[], int offset, int len) { - if (first == true) { + protected void engineUpdate(byte[] input, int offset, int len) { + if (first) { // compute digest for 1st pass; start with inner pad md.update(k_ipad); first = false; @@ -205,7 +200,7 @@ protected void engineUpdate(byte input[], int offset, int len) { * @param input the input byte buffer. */ protected void engineUpdate(ByteBuffer input) { - if (first == true) { + if (first) { // compute digest for 1st pass; start with inner pad md.update(k_ipad); first = false; @@ -221,7 +216,7 @@ protected void engineUpdate(ByteBuffer input) { * @return the HMAC result. */ protected byte[] engineDoFinal() { - if (first == true) { + if (first) { // compute digest for 1st pass; start with inner pad md.update(k_ipad); } else { @@ -250,7 +245,7 @@ protected byte[] engineDoFinal() { * HMAC was initialized with. */ protected void engineReset() { - if (first == false) { + if (!first) { md.reset(); first = true; } diff --git a/src/java.base/share/classes/com/sun/crypto/provider/HmacMD5.java b/src/java.base/share/classes/com/sun/crypto/provider/HmacMD5.java index ccf85561db9ec..3e85ad51bb3bd 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/HmacMD5.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/HmacMD5.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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,12 +25,7 @@ package com.sun.crypto.provider; -import java.nio.ByteBuffer; - -import javax.crypto.MacSpi; -import javax.crypto.SecretKey; -import java.security.*; -import java.security.spec.*; +import java.security.NoSuchAlgorithmException; /** * This is an implementation of the HMAC-MD5 algorithm. diff --git a/src/java.base/share/classes/com/sun/crypto/provider/HmacMD5KeyGenerator.java b/src/java.base/share/classes/com/sun/crypto/provider/HmacMD5KeyGenerator.java index ba29e3c74793e..2634128dd286a 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/HmacMD5KeyGenerator.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/HmacMD5KeyGenerator.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 @@ -25,9 +25,8 @@ package com.sun.crypto.provider; -import java.security.SecureRandom; -import java.security.InvalidParameterException; import java.security.InvalidAlgorithmParameterException; +import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.util.Arrays; import javax.crypto.KeyGeneratorSpi; diff --git a/src/java.base/share/classes/com/sun/crypto/provider/HmacSHA1.java b/src/java.base/share/classes/com/sun/crypto/provider/HmacSHA1.java index b79dc9d96584c..0a17cad0ea397 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/HmacSHA1.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/HmacSHA1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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,12 +25,7 @@ package com.sun.crypto.provider; -import java.nio.ByteBuffer; - -import javax.crypto.MacSpi; -import javax.crypto.SecretKey; -import java.security.*; -import java.security.spec.*; +import java.security.NoSuchAlgorithmException; /** * This is an implementation of the HMAC-SHA1 algorithm. diff --git a/src/java.base/share/classes/com/sun/crypto/provider/HmacSHA1KeyGenerator.java b/src/java.base/share/classes/com/sun/crypto/provider/HmacSHA1KeyGenerator.java index 9d92d60ae3656..1997777750348 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/HmacSHA1KeyGenerator.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/HmacSHA1KeyGenerator.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 @@ -25,9 +25,8 @@ package com.sun.crypto.provider; -import java.security.SecureRandom; -import java.security.InvalidParameterException; import java.security.InvalidAlgorithmParameterException; +import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.util.Arrays; import javax.crypto.KeyGeneratorSpi; diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java b/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java index a86f313e2c9e1..43f153422849b 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/ISO10126Padding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -119,7 +119,6 @@ public int unpad(byte[] in, int off, int len) { * @return the length of the padding */ public int padLength(int len) { - int paddingOctet = blockSize - (len % blockSize); - return paddingOctet; + return blockSize - (len % blockSize); } } diff --git a/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java b/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java index fcc450387af9c..ab8f2d7097b04 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ private static final class PrivateKeyEntry { Date date; // the creation date of this entry byte[] protectedKey; Certificate[] chain; - }; + } // Secret key private static final class SecretKeyEntry { @@ -93,7 +93,7 @@ private static final class SecretKeyEntry { private static final class TrustedCertEntry { Date date; // the creation date of this entry Certificate cert; - }; + } /** * Private keys and certificates are stored in a hashtable. @@ -119,7 +119,7 @@ private static final class TrustedCertEntry { public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException { - Key key = null; + Key key; Object entry = entries.get(alias.toLowerCase(Locale.ENGLISH)); @@ -652,7 +652,7 @@ public void engineStore(OutputStream stream, char[] password) * the keystore (such as deleting or modifying key or * certificate entries). */ - byte digest[] = md.digest(); + byte[] digest = md.digest(); dos.write(digest); dos.flush(); @@ -691,8 +691,8 @@ public void engineLoad(InputStream stream, char[] password) MessageDigest md = null; CertificateFactory cf = null; Hashtable cfs = null; - ByteArrayInputStream bais = null; - byte[] encoded = null; + ByteArrayInputStream bais; + byte[] encoded; int trustedKeyCount = 0, privateKeyCount = 0, secretKeyCount = 0; if (stream == null) diff --git a/src/java.base/share/classes/com/sun/crypto/provider/KWUtil.java b/src/java.base/share/classes/com/sun/crypto/provider/KWUtil.java index 7892ca198a8e6..e5dc892032694 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/KWUtil.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/KWUtil.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,10 +26,6 @@ package com.sun.crypto.provider; import java.util.Arrays; -import java.security.*; -import java.security.spec.*; -import javax.crypto.*; -import javax.crypto.spec.*; /** * This class acts as the base class for AES KeyWrap algorithms as defined @@ -58,7 +54,7 @@ static final int W(byte[] icvIn, byte[] in, int inLen, ("Invalid data length for W: " + inLen); assert(icvIn.length == SEMI_BLKSIZE) : "Invalid ICV buffer size"; - // overwrite the first block of in with the icv semiblock + // overwrite the first block of in with the icv semi-block System.arraycopy(icvIn, 0, in, 0, SEMI_BLKSIZE); int n = inLen / SEMI_BLKSIZE - 1; @@ -93,7 +89,7 @@ static final int W(byte[] icvIn, byte[] in, int inLen, * data until the initial value and padding bytes are verified. * @param in input bytes, i.e. the to-be-processed data * @param inLen length of the to-be-processed bytes - * @param ivOut buffer for holding the recovered ICV semiblock + * @param ivOut buffer for holding the recovered ICV semi-block * @param cipher the initialized cipher object used * @return the recovered data length, i.e. {@code (inLen - icvOut.length)} */ diff --git a/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java b/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java index eadc032b36ac6..f2d3efd685c06 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/KeyProtector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -98,7 +98,7 @@ final class KeyProtector { iterationCount > MAX_ITERATION_COUNT) { iterationCount = DEFAULT_ITERATION_COUNT; } - } catch (NumberFormatException e) {} + } catch (NumberFormatException ignored) {} } ITERATION_COUNT = iterationCount; } @@ -369,7 +369,7 @@ Key unseal(SealedObject so, int maxLength) sKey = new PBEKey(pbeKeySpec, "PBEWithMD5AndTripleDES"); pbeKeySpec.clearPassword(); - SealedObjectForKeyProtector soForKeyProtector = null; + SealedObjectForKeyProtector soForKeyProtector; if (!(so instanceof SealedObjectForKeyProtector)) { soForKeyProtector = new SealedObjectForKeyProtector(so); } else { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/KeyWrapCipher.java b/src/java.base/share/classes/com/sun/crypto/provider/KeyWrapCipher.java index dfd2ec2b04bb5..fb69a27c62d51 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/KeyWrapCipher.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/KeyWrapCipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -285,7 +285,7 @@ protected int engineGetOutputSize(int inLen) { padLen = SEMI_BLKSIZE - n; } } - // then add the first semiblock and padLen to result + // then add the first semi-block and padLen to result result = Math.addExact(result, SEMI_BLKSIZE + padLen); } else { result = inLen - SEMI_BLKSIZE; @@ -339,7 +339,7 @@ private void implInit(int opmode, Key key, byte[] iv, SecureRandom random) protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException { try { - implInit(opmode, key, (byte[])null, random); + implInit(opmode, key, null, random); } catch (InvalidAlgorithmParameterException iae) { // should never happen throw new AssertionError(iae); @@ -394,9 +394,9 @@ protected void engineInit(int opmode, Key key, AlgorithmParameters params, byte[] iv = null; if (params != null) { try { - AlgorithmParameterSpec spec = + IvParameterSpec spec = params.getParameterSpec(IvParameterSpec.class); - iv = ((IvParameterSpec)spec).getIV(); + iv = spec.getIV(); } catch (InvalidParameterSpecException ispe) { throw new InvalidAlgorithmParameterException( "Only IvParameterSpec is accepted"); @@ -462,7 +462,7 @@ private void implUpdate(byte[] in, int inOfs, int inLen) { if (inLen <= 0) return; if (opmode == Cipher.ENCRYPT_MODE && dataIdx == 0) { - // the first semiblock is for iv, store data after it + // the first semi-block is for iv, store data after it dataIdx = SEMI_BLKSIZE; } store(in, inOfs, inLen); @@ -595,8 +595,8 @@ private int implDoFinal(byte[] in, int inOfs, int inLen, byte[] out) } // helper routine for in-place encryption. - // 'inBuf' = semiblock | plain text | extra bytes if padding is used - // 'inLen' = semiblock length + plain text length + // 'inBuf' = semi-block | plain text | extra bytes if padding is used + // 'inLen' = semi-block length + plain text length private int helperEncrypt(byte[] inBuf, int inLen) throws IllegalBlockSizeException, ShortBufferException { @@ -646,7 +646,7 @@ private int helperDecrypt(byte[] inBuf, int inLen) */ @Override protected AlgorithmParameters engineGetParameters() { - AlgorithmParameters params = null; + AlgorithmParameters params; byte[] iv = cipher.getIV(); if (iv == null) { @@ -711,7 +711,7 @@ protected byte[] engineWrap(Key key) // output size is known, allocate output buffer byte[] out = new byte[engineGetOutputSize(encoded.length)]; - // reserve the first semiblock and do not write data + // reserve the first semi-block and do not write data int len = SEMI_BLKSIZE; System.arraycopy(encoded, 0, out, len, encoded.length); len += encoded.length; diff --git a/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java b/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java index 9d72472889357..3b826aa38f283 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/OAEPParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -225,11 +225,9 @@ protected byte[] engineGetEncoded(String encodingMethod) } protected String engineToString() { - StringBuilder sb = new StringBuilder(); - sb.append("MD: " + mdName + "\n"); - sb.append("MGF: MGF1" + mgfSpec.getDigestAlgorithm() + "\n"); - sb.append("PSource: PSpecified " + - (p.length==0? "":Debug.toHexString(new BigInteger(p))) + "\n"); - return sb.toString(); + return "MD: " + mdName + "\n" + + "MGF: MGF1" + mgfSpec.getDigestAlgorithm() + "\n" + + "PSource: PSpecified " + + (p.length == 0 ? "" : Debug.toHexString(new BigInteger(p))) + "\n"; } } diff --git a/src/java.base/share/classes/com/sun/crypto/provider/OutputFeedback.java b/src/java.base/share/classes/com/sun/crypto/provider/OutputFeedback.java index aa56144f09052..414659fcf3d40 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/OutputFeedback.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/OutputFeedback.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -53,7 +53,7 @@ final class OutputFeedback extends FeedbackCipher { private final byte[] register; /* - * number of bytes for each stream unit, defaults to the blocksize + * number of bytes for each stream unit, defaults to the block size * of the embedded cipher */ private final int numBytes; diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PBEKeyFactory.java b/src/java.base/share/classes/com/sun/crypto/provider/PBEKeyFactory.java index 02451e536c677..da73d0bc7ce95 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/PBEKeyFactory.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/PBEKeyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -261,7 +261,7 @@ protected SecretKey engineGenerateSecret(KeySpec keySpec) */ protected KeySpec engineGetKeySpec(SecretKey key, Class keySpecCl) throws InvalidKeySpecException { - if ((key instanceof SecretKey) + if ((key != null) && (validTypes.contains(key.getAlgorithm().toUpperCase(Locale.ENGLISH))) && (key.getFormat().equalsIgnoreCase("RAW"))) { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PBES1Core.java b/src/java.base/share/classes/com/sun/crypto/provider/PBES1Core.java index 68b1771d7d967..e10b0b1a7cfb5 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/PBES1Core.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/PBES1Core.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, 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 @@ -161,7 +161,7 @@ byte[] getIV() { * does not use any parameters. */ AlgorithmParameters getParameters() { - AlgorithmParameters params = null; + AlgorithmParameters params; if (salt == null) { salt = new byte[8]; SunJCE.getRandom().nextBytes(salt); @@ -303,7 +303,7 @@ private byte[] deriveCipherKey(byte[] passwdBytes) { // Concatenate the output from each digest round with the // password, and use the result as the input to the next digest // operation. - byte[] toBeHashed = null; + byte[] toBeHashed; result = new byte[DESedeKeySpec.DES_EDE_KEY_LEN + DESConstants.DES_BLOCK_SIZE]; for (i = 0; i < 2; i++) { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java b/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java index fb3dfa00148e0..d6b7d00d360df 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -131,8 +131,8 @@ abstract class PBES2Parameters extends AlgorithmParametersSpi { PBES2Parameters(String pbes2AlgorithmName) throws NoSuchAlgorithmException { int and; - String kdfAlgo = null; - String cipherAlgo = null; + String kdfAlgo; + String cipherAlgo; // Extract the KDF and encryption algorithm names this.pbes2AlgorithmName = pbes2AlgorithmName; @@ -210,9 +210,6 @@ protected void engineInit(AlgorithmParameterSpec paramSpec) protected void engineInit(byte[] encoded) throws IOException { - String kdfAlgo = null; - String cipherAlgo = null; - DerValue pBES2_params = new DerValue(encoded); if (pBES2_params.tag != DerValue.tag_Sequence) { throw new IOException("PBE parameter parsing error: " @@ -231,16 +228,15 @@ protected void engineInit(byte[] encoded) kdf = pBES2_params.data.getDerValue(); } - kdfAlgo = parseKDF(kdf); + String kdfAlgo = parseKDF(kdf); if (pBES2_params.tag != DerValue.tag_Sequence) { throw new IOException("PBE parameter parsing error: " + "not an ASN.1 SEQUENCE tag"); } - cipherAlgo = parseES(pBES2_params.data.getDerValue()); + String cipherAlgo = parseES(pBES2_params.data.getDerValue()); - this.pbes2AlgorithmName = new StringBuilder().append("PBEWith") - .append(kdfAlgo).append("And").append(cipherAlgo).toString(); + this.pbes2AlgorithmName = "PBEWith" + kdfAlgo + "And" + cipherAlgo; } @SuppressWarnings("deprecation") @@ -305,7 +301,7 @@ private String parseKDF(DerValue keyDerivationFunc) throws IOException { @SuppressWarnings("deprecation") private String parseES(DerValue encryptionScheme) throws IOException { - String cipherAlgo = null; + String cipherAlgo; cipherAlgo_OID = encryptionScheme.data.getOID(); if (aes128CBC_OID.equals(cipherAlgo_OID)) { @@ -399,7 +395,7 @@ protected byte[] engineGetEncoded(String encodingMethod) /* * Returns a formatted string describing the parameters. * - * The algorithn name pattern is: "PBEWithAnd" + * The algorithm name pattern is: "PBEWithAnd" * where is one of: HmacSHA1, HmacSHA224, HmacSHA256, HmacSHA384, * HmacSHA512, HmacSHA512/224, or HmacSHA512/256 and is * AES with a keysize suffix. diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java b/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java index a02ce2d15511a..c8b9c392a4b49 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, 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 @@ -25,26 +25,29 @@ package com.sun.crypto.provider; -import java.io.*; -import java.lang.ref.Reference; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputStream; +import java.io.ObjectStreamException; import java.lang.ref.Cleaner; +import java.lang.ref.Reference; import java.nio.ByteBuffer; import java.nio.CharBuffer; -import java.util.Arrays; -import java.util.Locale; -import java.security.MessageDigest; -import java.security.KeyRep; import java.security.GeneralSecurityException; +import java.security.KeyRep; +import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; +import java.util.Arrays; +import java.util.Locale; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.PBEKeySpec; -import static java.nio.charset.StandardCharsets.UTF_8; - import jdk.internal.ref.CleanerFactory; +import static java.nio.charset.StandardCharsets.UTF_8; + /** * This class represents a PBE key derived using PBKDF2 defined * in PKCS#5 v2.0. meaning that diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PBMAC1Core.java b/src/java.base/share/classes/com/sun/crypto/provider/PBMAC1Core.java index 56059a89264a7..146999e35ce7d 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/PBMAC1Core.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/PBMAC1Core.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -61,7 +61,7 @@ abstract class PBMAC1Core extends HmacCore { } private static PBKDF2Core getKDFImpl(String algo) { - PBKDF2Core kdf = null; + PBKDF2Core kdf; switch(algo) { case "HmacSHA1": kdf = new PBKDF2Core.HmacSHA1(); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java b/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java index af072c6f5d708..a8ba711d658c3 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/PKCS5Padding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -120,7 +120,6 @@ public int unpad(byte[] in, int off, int len) { * @return the length of the padding */ public int padLength(int len) { - int paddingOctet = blockSize - (len % blockSize); - return paddingOctet; + return blockSize - (len % blockSize); } } diff --git a/src/java.base/share/classes/com/sun/crypto/provider/Poly1305.java b/src/java.base/share/classes/com/sun/crypto/provider/Poly1305.java index 1752bb8ddddfd..1473cf4aba147 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/Poly1305.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/Poly1305.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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,16 +26,18 @@ package com.sun.crypto.provider; import java.nio.ByteBuffer; -import java.security.Key; import java.security.InvalidKeyException; +import java.security.Key; import java.security.spec.AlgorithmParameterSpec; import java.util.Arrays; import java.util.Objects; -import sun.security.util.math.*; -import sun.security.util.math.intpoly.*; -import jdk.internal.vm.annotation.IntrinsicCandidate; import jdk.internal.vm.annotation.ForceInline; +import jdk.internal.vm.annotation.IntrinsicCandidate; +import sun.security.util.math.IntegerFieldModuloP; +import sun.security.util.math.IntegerModuloP; +import sun.security.util.math.MutableIntegerModuloP; +import sun.security.util.math.intpoly.IntegerPolynomial1305; /** * This class represents the Poly1305 function defined in RFC 7539. diff --git a/src/java.base/share/classes/com/sun/crypto/provider/RC2Crypt.java b/src/java.base/share/classes/com/sun/crypto/provider/RC2Crypt.java index aa3100c1b7d10..78f25f33b2df8 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/RC2Crypt.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/RC2Crypt.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2007, 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 @@ -108,7 +108,7 @@ void initEffectiveKeyBits(int effectiveKeyBits) { static void checkKey(String algorithm, int keyLength) throws InvalidKeyException { - if (algorithm.equals("RC2") == false) { + if (!algorithm.equals("RC2")) { throw new InvalidKeyException("Key algorithm must be RC2"); } if ((keyLength < 5) || (keyLength > 128)) { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java b/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java index df76f78bfb5e0..b48917e755713 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/RSACipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -33,6 +33,7 @@ import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import java.security.spec.MGF1ParameterSpec; +import java.util.Objects; import javax.crypto.*; import javax.crypto.spec.PSource; @@ -126,7 +127,7 @@ public RSACipher() { // modes do not make sense for RSA, but allow ECB // see JCE spec protected void engineSetMode(String mode) throws NoSuchAlgorithmException { - if (mode.equalsIgnoreCase("ECB") == false) { + if (!mode.equalsIgnoreCase("ECB")) { throw new NoSuchAlgorithmException("Unsupported mode " + mode); } } @@ -468,7 +469,7 @@ protected Key engineUnwrap(byte[] wrappedKey, String algorithm, boolean isTlsRsaPremasterSecret = algorithm.equals("TlsRsaPremasterSecret"); - byte[] encoded = null; + byte[] encoded; update(wrappedKey, 0, wrappedKey.length); try { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/SslMacCore.java b/src/java.base/share/classes/com/sun/crypto/provider/SslMacCore.java index 057c139b5945c..0d25c0064c4f1 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/SslMacCore.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/SslMacCore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2009, 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 @@ -26,11 +26,10 @@ package com.sun.crypto.provider; import java.nio.ByteBuffer; - -import javax.crypto.MacSpi; -import javax.crypto.SecretKey; import java.security.*; import java.security.spec.AlgorithmParameterSpec; +import javax.crypto.MacSpi; +import javax.crypto.SecretKey; import static com.sun.crypto.provider.TlsPrfGenerator.genPad; @@ -109,7 +108,7 @@ void init(Key key, AlgorithmParameterSpec params) * @param input the input byte to be processed. */ void update(byte input) { - if (first == true) { + if (first) { // compute digest for 1st pass; start with inner pad md.update(secret); md.update(pad1); @@ -128,8 +127,8 @@ void update(byte input) { * @param offset the offset in input where the input starts. * @param len the number of bytes to process. */ - void update(byte input[], int offset, int len) { - if (first == true) { + void update(byte[] input, int offset, int len) { + if (first) { // compute digest for 1st pass; start with inner pad md.update(secret); md.update(pad1); @@ -141,7 +140,7 @@ void update(byte input[], int offset, int len) { } void update(ByteBuffer input) { - if (first == true) { + if (first) { // compute digest for 1st pass; start with inner pad md.update(secret); md.update(pad1); @@ -158,7 +157,7 @@ void update(ByteBuffer input) { * @return the Mac result. */ byte[] doFinal() { - if (first == true) { + if (first) { // compute digest for 1st pass; start with inner pad md.update(secret); md.update(pad1); @@ -189,7 +188,7 @@ byte[] doFinal() { * Mac was initialized with. */ void reset() { - if (first == false) { + if (!first) { md.reset(); first = true; } @@ -211,7 +210,7 @@ protected void engineInit(Key key, AlgorithmParameterSpec params) protected void engineUpdate(byte input) { core.update(input); } - protected void engineUpdate(byte input[], int offset, int len) { + protected void engineUpdate(byte[] input, int offset, int len) { core.update(input, offset, len); } protected void engineUpdate(ByteBuffer input) { @@ -244,7 +243,7 @@ protected void engineInit(Key key, AlgorithmParameterSpec params) protected void engineUpdate(byte input) { core.update(input); } - protected void engineUpdate(byte input[], int offset, int len) { + protected void engineUpdate(byte[] input, int offset, int len) { core.update(input, offset, len); } protected void engineUpdate(ByteBuffer input) { diff --git a/src/java.base/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java b/src/java.base/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java index 56e4dd976632a..2440b45a2ae60 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, 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 @@ -62,11 +62,11 @@ protected void engineInit(SecureRandom random) { @SuppressWarnings("deprecation") protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { - if (params instanceof TlsKeyMaterialParameterSpec == false) { + if (!(params instanceof TlsKeyMaterialParameterSpec)) { throw new InvalidAlgorithmParameterException(MSG); } this.spec = (TlsKeyMaterialParameterSpec)params; - if ("RAW".equals(spec.getMasterSecret().getFormat()) == false) { + if (!"RAW".equals(spec.getMasterSecret().getFormat())) { throw new InvalidAlgorithmParameterException( "Key format must be RAW"); } @@ -105,8 +105,6 @@ private SecretKey engineGenerateKey0(byte[] masterSecret) throws GeneralSecurity SecretKey clientMacKey = null; SecretKey serverMacKey = null; - SecretKey clientCipherKey = null; - SecretKey serverCipherKey = null; IvParameterSpec clientIv = null; IvParameterSpec serverIv = null; @@ -194,8 +192,10 @@ private SecretKey engineGenerateKey0(byte[] masterSecret) throws GeneralSecurity System.arraycopy(keyBlock, ofs, serverKeyBytes, 0, keyLength); ofs += keyLength; + SecretKey clientCipherKey; + SecretKey serverCipherKey; try { - if (isExportable == false) { + if (!isExportable) { // cipher keys clientCipherKey = new SecretKeySpec(clientKeyBytes, alg); serverCipherKey = new SecretKeySpec(serverKeyBytes, alg); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java b/src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java index 1102f4b94ee1a..f8f733b6d2f74 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, 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 @@ -132,12 +132,12 @@ protected void engineInit(SecureRandom random) { @SuppressWarnings("deprecation") protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { - if (params instanceof TlsPrfParameterSpec == false) { + if (!(params instanceof TlsPrfParameterSpec)) { throw new InvalidAlgorithmParameterException(MSG); } this.spec = (TlsPrfParameterSpec)params; SecretKey key = spec.getSecret(); - if ((key != null) && ("RAW".equals(key.getFormat()) == false)) { + if ((key != null) && (!"RAW".equals(key.getFormat()))) { throw new InvalidAlgorithmParameterException( "Key encoding format must be RAW"); } @@ -378,7 +378,7 @@ private static void expand(MessageDigest digest, int hmacSize, * TLS 1.2 uses a different hash algorithm than 1.0/1.1 for the PRF * calculations. As of 2010, there is no PKCS11-level support for TLS * 1.2 PRF calculations, and no known OS's have an internal variant - * we could use. Therefore for TLS 1.2, we are updating JSSE to request + * we could use. Therefore, for TLS 1.2, we are updating JSSE to request * a different provider algorithm: "SunTls12Prf". If we reused the * name "SunTlsPrf", the PKCS11 provider would need be updated to * fail correctly when presented with the wrong version number From dcf4e0d51f392afe2711223484e932e3826e8864 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Wed, 10 Jul 2024 03:30:19 +0000 Subject: [PATCH 032/401] 8335966: Remove incorrect problem listing of java/lang/instrument/NativeMethodPrefixAgent.java in ProblemList-Virtual.txt Reviewed-by: kevinw, amenkov --- 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 c45353e65edb7..d7692b578cd04 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 b5909cabeef22954f4d9c642b1cbf288b3454562 Mon Sep 17 00:00:00 2001 From: Koichi Sakata Date: Wed, 10 Jul 2024 05:57:11 +0000 Subject: [PATCH 033/401] 8323242: Remove vestigial DONT_USE_REGISTER_DEFINES Reviewed-by: gli, kvn --- src/hotspot/cpu/zero/register_zero.hpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hotspot/cpu/zero/register_zero.hpp b/src/hotspot/cpu/zero/register_zero.hpp index 1b6f52879ef16..fd30f2067623c 100644 --- a/src/hotspot/cpu/zero/register_zero.hpp +++ b/src/hotspot/cpu/zero/register_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright 2007 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -114,8 +114,6 @@ class ConcreteRegisterImpl : public AbstractRegisterImpl { }; CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1)); -#ifndef DONT_USE_REGISTER_DEFINES #define noreg ((Register)(noreg_RegisterEnumValue)) -#endif #endif // CPU_ZERO_REGISTER_ZERO_HPP From a44b60c8c14ad998e51239f48e64779304aaac50 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Wed, 10 Jul 2024 07:53:52 +0000 Subject: [PATCH 034/401] 8335778: runtime/ClassInitErrors/TestStackOverflowDuringInit.java fails on ppc64 platforms after JDK-8334545 Reviewed-by: dholmes, asteiner --- .../runtime/ClassInitErrors/TestStackOverflowDuringInit.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/runtime/ClassInitErrors/TestStackOverflowDuringInit.java b/test/hotspot/jtreg/runtime/ClassInitErrors/TestStackOverflowDuringInit.java index 3917abe85ad57..180dc539795fa 100644 --- a/test/hotspot/jtreg/runtime/ClassInitErrors/TestStackOverflowDuringInit.java +++ b/test/hotspot/jtreg/runtime/ClassInitErrors/TestStackOverflowDuringInit.java @@ -31,7 +31,7 @@ * @requires vm.flagless * @comment Run with the smallest stack possible to limit the execution time. * This is the smallest stack that is supported by all platforms. - * @run main/othervm -Xss240K -Xint TestStackOverflowDuringInit + * @run main/othervm -Xss384K -Xint TestStackOverflowDuringInit */ import java.io.ByteArrayOutputStream; From 537d20afbff255489a7b1bdb0410b9d1aba715b7 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Wed, 10 Jul 2024 09:55:56 +0000 Subject: [PATCH 035/401] 8335766: Switch case with pattern matching and guard clause compiles inconsistently Reviewed-by: abimpoudis --- .../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 ef2d71831dc59..f570ad54c58e8 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 ef4d065f91295..d6180c1810f90 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 e0fb949460d0c7e2ab1697a6466e7d4831a20a33 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Wed, 10 Jul 2024 14:28:20 +0000 Subject: [PATCH 036/401] 8335779: JFR: Hide sleep events Reviewed-by: mgronlun --- .../share/jfr/support/jfrIntrinsics.hpp | 2 +- src/hotspot/share/runtime/objectMonitor.cpp | 2 +- .../share/classes/jdk/jfr/internal/JVM.java | 1 + .../classes/jdk/jfr/internal/JVMSupport.java | 4 +- .../jdk/jfr/internal/MetadataRepository.java | 4 +- .../jfr/internal/consumer/OngoingStream.java | 16 ++-- .../jfr/internal/consumer/RecordingInput.java | 7 +- .../internal/consumer/RepositoryFiles.java | 19 ++-- .../internal/{ => management}/HiddenWait.java | 12 ++- .../internal/management/StreamBarrier.java | 48 ++++++---- .../classes/jdk/jfr/internal/util/Utils.java | 23 +---- .../jdk/management/jfr/DownLoadThread.java | 14 +-- .../classes/jdk/management/jfr/FileDump.java | 52 ++++++----- test/jdk/jdk/jfr/jvm/TestHiddenWait.java | 88 +++++++++++++++++++ 14 files changed, 192 insertions(+), 100 deletions(-) rename src/jdk.jfr/share/classes/jdk/jfr/internal/{ => management}/HiddenWait.java (82%) create mode 100644 test/jdk/jdk/jfr/jvm/TestHiddenWait.java diff --git a/src/hotspot/share/jfr/support/jfrIntrinsics.hpp b/src/hotspot/share/jfr/support/jfrIntrinsics.hpp index 6520f3cb00ca0..77affc69926f0 100644 --- a/src/hotspot/share/jfr/support/jfrIntrinsics.hpp +++ b/src/hotspot/share/jfr/support/jfrIntrinsics.hpp @@ -47,7 +47,7 @@ class JfrIntrinsicSupport : AllStatic { #define JFR_HAVE_INTRINSICS #define JFR_TEMPLATES(template) \ - template(jdk_jfr_internal_HiddenWait, "jdk/jfr/internal/HiddenWait") \ + template(jdk_jfr_internal_management_HiddenWait, "jdk/jfr/internal/management/HiddenWait") \ template(jdk_jfr_internal_JVM, "jdk/jfr/internal/JVM") \ template(jdk_jfr_internal_event_EventWriterFactory, "jdk/jfr/internal/event/EventWriterFactory") \ template(jdk_jfr_internal_event_EventConfiguration_signature, "Ljdk/jfr/internal/event/EventConfiguration;") \ diff --git a/src/hotspot/share/runtime/objectMonitor.cpp b/src/hotspot/share/runtime/objectMonitor.cpp index ba463231592c5..c509ed691cdb8 100644 --- a/src/hotspot/share/runtime/objectMonitor.cpp +++ b/src/hotspot/share/runtime/objectMonitor.cpp @@ -1442,7 +1442,7 @@ bool ObjectMonitor::check_owner(TRAPS) { static inline bool is_excluded(const Klass* monitor_klass) { assert(monitor_klass != nullptr, "invariant"); NOT_JFR_RETURN_(false); - JFR_ONLY(return vmSymbols::jdk_jfr_internal_HiddenWait() == monitor_klass->name();) + JFR_ONLY(return vmSymbols::jdk_jfr_internal_management_HiddenWait() == monitor_klass->name();) } static void post_monitor_wait_event(EventJavaMonitorWait* event, 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 2e600c8c02974..cc0ee05a948a5 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java @@ -31,6 +31,7 @@ import jdk.jfr.Event; import jdk.jfr.internal.event.EventConfiguration; import jdk.jfr.internal.event.EventWriter; +import jdk.jfr.internal.management.HiddenWait; /** * Interface against the JVM. 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 114052ecea250..7fde28a3d21fc 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVMSupport.java @@ -30,6 +30,7 @@ import jdk.jfr.Recording; import jdk.jfr.internal.event.EventConfiguration; +import jdk.jfr.internal.management.HiddenWait; import jdk.jfr.internal.util.Utils; import jdk.jfr.internal.util.ValueFormatter; @@ -118,7 +119,8 @@ private static void awaitUniqueTimestamp() { lastTimestamp = time; return; } - Utils.takeNap(1); + HiddenWait hiddenWait = new HiddenWait(); + hiddenWait.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 4a7bc734d7571..49afd0082d8a9 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/MetadataRepository.java @@ -47,6 +47,7 @@ import jdk.jfr.ValueDescriptor; import jdk.jfr.internal.consumer.RepositoryFiles; import jdk.jfr.internal.event.EventConfiguration; +import jdk.jfr.internal.management.HiddenWait; import jdk.jfr.internal.periodic.PeriodicEvents; import jdk.jfr.internal.util.Utils; @@ -57,6 +58,7 @@ public final class MetadataRepository { private final Map nativeEventTypes = LinkedHashMap.newHashMap(150); private final Map nativeControls = LinkedHashMap.newHashMap(150); private final SettingsManager settingsManager = new SettingsManager(); + private final HiddenWait threadSleeper = new HiddenWait(); private Constructor cachedEventConfigurationConstructor; private boolean staleMetadata = true; private boolean unregistered; @@ -341,7 +343,7 @@ private void awaitEpochMilliShift() { lastMillis = millis; return; } - Utils.takeNap(1); + threadSleeper.takeNap(1); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/OngoingStream.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/OngoingStream.java index 1816d00f345a7..e0dd7fa2ad8d5 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/OngoingStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/OngoingStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, 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 @@ -33,6 +33,7 @@ import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.SecuritySupport.SafePath; import jdk.jfr.internal.management.EventByteStream; +import jdk.jfr.internal.management.HiddenWait; import jdk.jfr.internal.management.ManagementSupport; public final class OngoingStream extends EventByteStream { @@ -44,6 +45,7 @@ public final class OngoingStream extends EventByteStream { private final RepositoryFiles repositoryFiles; private final Recording recording; + private final HiddenWait threadSleeper = new HiddenWait(); private final int blockSize; private final long endTimeNanos; private final byte[] headerBytes = new byte[HEADER_SIZE]; @@ -195,19 +197,13 @@ private byte[] readWithHeader(int size) throws IOException { return bytes; } } - takeNap(); + if (!threadSleeper.takeNap(10)) { + throw new IOException("Read operation interrupted"); + } } return EMPTY_ARRAY; } - private void takeNap() throws IOException { - try { - Thread.sleep(10); - } catch (InterruptedException ie) { - throw new IOException("Read operation interrupted", ie); - } - } - private boolean ensureInput() throws IOException { if (input == null) { if (SecuritySupport.getFileSize(new SafePath(path)) < HEADER_SIZE) { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java index 90a03130f4990..69ec73f57fd6f 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RecordingInput.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 @@ -31,6 +31,8 @@ import java.io.IOException; import java.io.RandomAccessFile; import java.nio.file.Path; + +import jdk.jfr.internal.management.HiddenWait; import jdk.jfr.internal.util.Utils; public final class RecordingInput implements DataInput, AutoCloseable { @@ -67,6 +69,7 @@ public void reset() { } private final int blockSize; private final FileAccess fileAccess; + private final HiddenWait threadSleeper = new HiddenWait(); private long pollCount = 1000; private RandomAccessFile file; private String filename; @@ -453,6 +456,6 @@ public void pollWait() throws IOException { if (pollCount < 0) { throw new IOException("Recording file is stuck in locked stream state."); } - Utils.takeNap(1); + threadSleeper.takeNap(1); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java index 6ef88ecad3750..3f0611f998173 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/consumer/RepositoryFiles.java @@ -46,9 +46,10 @@ import jdk.jfr.internal.Logger; import jdk.jfr.internal.Repository; import jdk.jfr.internal.SecuritySupport.SafePath; +import jdk.jfr.internal.management.HiddenWait;; public final class RepositoryFiles { - private static final Object WAIT_OBJECT = new Object(); + private static final HiddenWait WAIT_OBJECT = new HiddenWait(); private static final String DIRECTORY_PATTERN = "DDDD_DD_DD_DD_DD_DD_"; public static void notifyNewFile() { synchronized (WAIT_OBJECT) { @@ -59,7 +60,7 @@ public static void notifyNewFile() { private final FileAccess fileAccess; private final NavigableMap pathSet = new TreeMap<>(); private final Map pathLookup = new HashMap<>(); - private final Object waitObject; + private final HiddenWait waitObject; private boolean allowSubDirectory; private volatile boolean closed; private Path repository; @@ -67,7 +68,7 @@ public static void notifyNewFile() { public RepositoryFiles(FileAccess fileAccess, Path repository, boolean allowSubDirectory) { this.repository = repository; this.fileAccess = fileAccess; - this.waitObject = repository == null ? WAIT_OBJECT : new Object(); + this.waitObject = repository == null ? WAIT_OBJECT : new HiddenWait(); this.allowSubDirectory = allowSubDirectory; } @@ -108,7 +109,7 @@ private boolean updatePaths(boolean wait) { // was accessed. Just ignore, and retry later. } if (wait) { - nap(); + waitObject.takeNap(1000); } else { return pathLookup.size() > beforeSize; } @@ -157,16 +158,6 @@ private Path path(long timestamp, boolean wait) { } } - private void nap() { - try { - synchronized (waitObject) { - waitObject.wait(1000); - } - } catch (InterruptedException e) { - // ignore - } - } - private boolean updatePaths() throws IOException, DirectoryIteratorException { boolean foundNew = false; Path repoPath = repository; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/HiddenWait.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/HiddenWait.java similarity index 82% rename from src/jdk.jfr/share/classes/jdk/jfr/internal/HiddenWait.java rename to src/jdk.jfr/share/classes/jdk/jfr/internal/management/HiddenWait.java index 26505990332c9..9070faad5a658 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/HiddenWait.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/HiddenWait.java @@ -22,11 +22,21 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.jfr.internal; +package jdk.jfr.internal.management; /** * 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 { + + public synchronized boolean takeNap(long timeoutMillis) { + try { + this.wait(timeoutMillis); + return true; + } catch (InterruptedException e) { + // Ok, ignore + 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 0b3132da2178b..7f1db163b4e3d 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 @@ -39,45 +39,57 @@ * processing should not continue. */ public final class StreamBarrier implements Closeable { - + private final HiddenWait lock = new HiddenWait(); private boolean activated = false; private boolean used = false; private long end = Long.MAX_VALUE; // Blocks thread until barrier is deactivated - public synchronized void check() { - while (activated) { - try { - this.wait(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); + public void check() { + synchronized (lock) { + while (activated) { + try { + lock.wait(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } } } } - public synchronized void setStreamEnd(long timestamp) { - end = timestamp; + public void setStreamEnd(long timestamp) { + synchronized(lock) { + end = timestamp; + } } - public synchronized long getStreamEnd() { - return end; + public long getStreamEnd() { + synchronized(lock) { + return end; + } } - public synchronized void activate() { - activated = true; - used = true; + public void activate() { + synchronized (lock) { + activated = true; + used = true; + } } @Override public synchronized void close() throws IOException { - activated = false; - this.notifyAll(); + synchronized (lock) { + activated = false; + lock.notifyAll(); + } } /** * Returns {@code true) if barrier is, or has been, in active state, {@code false) otherwise. */ - public synchronized boolean used() { - return used; + public boolean used() { + synchronized (lock) { + 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 5e04a25fe7ddf..ae83727096a2a 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,19 +48,19 @@ 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; import jdk.jfr.internal.MirrorEvent; import jdk.jfr.internal.SecuritySupport; import jdk.jfr.internal.Type; +import jdk.jfr.internal.management.HiddenWait; import jdk.jfr.internal.settings.PeriodSetting; import jdk.jfr.internal.settings.StackTraceSetting; import jdk.jfr.internal.settings.ThresholdSetting; public final class Utils { - private static final Object flushObject = new Object(); + private static final HiddenWait flushObject = new HiddenWait(); private static final String LEGACY_EVENT_NAME_PREFIX = "com.oracle.jdk."; /** @@ -351,17 +351,6 @@ private static boolean isSupportedType(Class type) { return Type.isValidJavaFieldType(type.getName()); } - public static void takeNap(long millis) { - HiddenWait hiddenWait = new HiddenWait(); - try { - synchronized(hiddenWait) { - hiddenWait.wait(millis); - } - } catch (InterruptedException e) { - // ok - } - } - public static void notifyFlush() { synchronized (flushObject) { flushObject.notifyAll(); @@ -369,13 +358,7 @@ public static void notifyFlush() { } public static void waitFlush(long timeOut) { - synchronized (flushObject) { - try { - flushObject.wait(timeOut); - } catch (InterruptedException e) { - // OK - } - } + flushObject.takeNap(timeOut); } public static Instant epochNanosToInstant(long epochNanos) { diff --git a/src/jdk.management.jfr/share/classes/jdk/management/jfr/DownLoadThread.java b/src/jdk.management.jfr/share/classes/jdk/management/jfr/DownLoadThread.java index 5ce66692537cb..05895f0f4a99b 100644 --- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/DownLoadThread.java +++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/DownLoadThread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 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 @@ -30,12 +30,14 @@ import java.util.Map; import jdk.jfr.internal.management.ManagementSupport; +import jdk.jfr.internal.management.HiddenWait; final class DownLoadThread extends Thread { private final RemoteRecordingStream stream; private final Instant startTime; private final Instant endTime; private final DiskRepository diskRepository; + private final HiddenWait threadSleeper = new HiddenWait(); DownLoadThread(RemoteRecordingStream stream, String name) { super(name); @@ -64,7 +66,7 @@ public void run() { if (bytes.length != 0) { diskRepository.write(bytes); } else { - takeNap(); + threadSleeper.takeNap(1000); } } } catch (IOException ioe) { @@ -73,12 +75,4 @@ public void run() { diskRepository.complete(); } } - - private void takeNap() { - try { - Thread.sleep(1000); - } catch (InterruptedException ie) { - // ignore - } - } } diff --git a/src/jdk.management.jfr/share/classes/jdk/management/jfr/FileDump.java b/src/jdk.management.jfr/share/classes/jdk/management/jfr/FileDump.java index 7da0fe351c450..37ba296732635 100644 --- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/FileDump.java +++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/FileDump.java @@ -32,8 +32,10 @@ import java.util.Deque; import jdk.management.jfr.DiskRepository.DiskChunk; +import jdk.jfr.internal.management.HiddenWait; final class FileDump { + private final HiddenWait lock = new HiddenWait(); private final Deque chunks = new ArrayDeque<>(); private final long stopTimeMillis; private boolean complete; @@ -42,45 +44,53 @@ final class FileDump { this.stopTimeMillis = stopTimeMillis; } - public synchronized void add(DiskChunk dc) { - if (isComplete()) { - return; - } - dc.acquire(); - chunks.addFirst(dc); - long endMillis = dc.endTimeNanos / 1_000_000; - if (endMillis >= stopTimeMillis) { - setComplete(); + public void add(DiskChunk dc) { + synchronized (lock) { + if (isComplete()) { + return; + } + dc.acquire(); + chunks.addFirst(dc); + long endMillis = dc.endTimeNanos / 1_000_000; + if (endMillis >= stopTimeMillis) { + setComplete(); + } } } - public synchronized boolean isComplete() { - return complete; + public boolean isComplete() { + synchronized (lock) { + return complete; + } } - public synchronized void setComplete() { - complete = true; - this.notifyAll(); + public void setComplete() { + synchronized (lock) { + complete = true; + lock.notifyAll(); + } } - public synchronized void close() { - for (DiskChunk dc : chunks) { - dc.release(); + public void close() { + synchronized (lock) { + for (DiskChunk dc : chunks) { + dc.release(); + } + chunks.clear(); + complete = true; } - chunks.clear(); - complete = true; } private DiskChunk oldestChunk() throws InterruptedException { while (true) { - synchronized (this) { + synchronized (lock) { if (!chunks.isEmpty()) { return chunks.pollLast(); } if (complete) { return null; } - this.wait(); + lock.wait(); } } } diff --git a/test/jdk/jdk/jfr/jvm/TestHiddenWait.java b/test/jdk/jdk/jfr/jvm/TestHiddenWait.java new file mode 100644 index 0000000000000..f4b810f192e48 --- /dev/null +++ b/test/jdk/jdk/jfr/jvm/TestHiddenWait.java @@ -0,0 +1,88 @@ +/* + * 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 jdk.jfr.jvm; + +import java.nio.file.Path; +import java.time.Duration; +import java.util.List; +import java.util.concurrent.atomic.AtomicLong; + +import jdk.jfr.Recording; +import jdk.jfr.Name; +import jdk.jfr.Event; +import jdk.jfr.FlightRecorder; +import jdk.jfr.consumer.RecordedEvent; +import jdk.jfr.consumer.RecordingStream; +import jdk.test.lib.jfr.Events; + +/** + * @test TestHiddenWait + * @key jfr + * @summary Checks that JFR code don't emit noise in the form of ThreadSleep and JavaMonitorWait events. + * @requires vm.hasJFR + * @library /test/lib + * @run main/othervm jdk.jfr.jvm.TestHiddenWait + */ +public class TestHiddenWait { + static final String PERIODIC_EVENT_NAME = "test.Periodic"; + + @Name(PERIODIC_EVENT_NAME) + public static class PeriodicEvent extends Event { + } + + public static void main(String... args) throws Exception { + FlightRecorder.addPeriodicEvent(PeriodicEvent.class, () -> { + PeriodicEvent event = new PeriodicEvent(); + event.commit(); + }); + try (Recording r = new Recording()) { + AtomicLong counter = new AtomicLong(); + r.enable("jdk.ThreadSleep").withoutThreshold(); + r.enable("jdk.JavaMonitorWait").withoutThreshold(); + r.enable(PERIODIC_EVENT_NAME).withPeriod(Duration.ofMillis(100)); + r.start(); + // Triggers Object.wait() in stream barrier + try (RecordingStream b = new RecordingStream()) { + b.startAsync(); + b.stop(); + } + // Wait for for periodic events + try (RecordingStream s = new RecordingStream()) { + s.onEvent(PERIODIC_EVENT_NAME, e -> { + if (counter.incrementAndGet() >= 2) { + s.close(); + } + }); + s.start(); + } + List events = Events.fromRecording(r); + for (RecordedEvent event : events) { + if (!event.getEventType().getName().equals(PERIODIC_EVENT_NAME)) { + System.out.println(event); + throw new Exception("Didn't expect ThreadSleep or JavaMonitorWait events"); + } + } + } + } +} From e6c5aa7a6cb54c647d261facdcffa6a410849627 Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Wed, 10 Jul 2024 15:12:49 +0000 Subject: [PATCH 037/401] 8336012: Fix usages of jtreg-reserved properties Reviewed-by: jjg --- test/jdk/java/lang/invoke/PrivateInvokeTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/jdk/java/lang/invoke/PrivateInvokeTest.java b/test/jdk/java/lang/invoke/PrivateInvokeTest.java index 12edf8e326316..8ae78d96713c6 100644 --- a/test/jdk/java/lang/invoke/PrivateInvokeTest.java +++ b/test/jdk/java/lang/invoke/PrivateInvokeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -67,8 +67,6 @@ public class PrivateInvokeTest { String vstr = System.getProperty(THIS_CLASS.getSimpleName()+".verbose"); if (vstr == null) vstr = System.getProperty(THIS_CLASS.getName()+".verbose"); - if (vstr == null) - vstr = System.getProperty("test.verbose"); if (vstr != null) verbose = Integer.parseInt(vstr); } private static int referenceKind(Method m) { From fb9a227e02ebf826edb762283e15dd7e402f8433 Mon Sep 17 00:00:00 2001 From: Doug Simon Date: Wed, 10 Jul 2024 15:34:27 +0000 Subject: [PATCH 038/401] 8313909: [JVMCI] assert(cp->tag_at(index).is_unresolved_klass()) in lookupKlassInPool Reviewed-by: yzheng, never --- src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index d92d193017362..68168c56b9aac 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -897,7 +897,9 @@ C2V_VMENTRY_NULL(jobject, lookupKlassInPool, (JNIEnv* env, jobject, ARGUMENT_PAI } else if (tag.is_symbol()) { symbol = cp->symbol_at(index); } else { - assert(cp->tag_at(index).is_unresolved_klass(), "wrong tag"); + if (!tag.is_unresolved_klass()) { + JVMCI_THROW_MSG_NULL(InternalError, err_msg("Expected %d at index %d, got %d", JVM_CONSTANT_UnresolvedClassInError, index, tag.value())); + } symbol = cp->klass_name_at(index); } } From fb66716a1bc914db194c5b0b833cc2317704f166 Mon Sep 17 00:00:00 2001 From: Axel Boldt-Christmas Date: Wed, 10 Jul 2024 16:12:40 +0000 Subject: [PATCH 039/401] 8331725: ubsan: pc may not always be the entry point for a VtableStub Reviewed-by: kvn, mbaesken --- src/hotspot/share/code/vtableStubs.cpp | 24 ++++++++++++++++++++---- src/hotspot/share/code/vtableStubs.hpp | 23 +++++++++++++---------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/hotspot/share/code/vtableStubs.cpp b/src/hotspot/share/code/vtableStubs.cpp index 5a54426d6a420..a65852e247fae 100644 --- a/src/hotspot/share/code/vtableStubs.cpp +++ b/src/hotspot/share/code/vtableStubs.cpp @@ -255,6 +255,19 @@ inline uint VtableStubs::hash(bool is_vtable_stub, int vtable_index){ } +inline uint VtableStubs::unsafe_hash(address entry_point) { + // The entrypoint may or may not be a VtableStub. Generate a hash as if it was. + address vtable_stub_addr = entry_point - VtableStub::entry_offset(); + assert(CodeCache::contains(vtable_stub_addr), "assumed to always be the case"); + address vtable_type_addr = vtable_stub_addr + offset_of(VtableStub, _type); + address vtable_index_addr = vtable_stub_addr + offset_of(VtableStub, _index); + bool is_vtable_stub = *vtable_type_addr == static_cast(VtableStub::Type::vtable_stub); + int vtable_index; + memcpy(&vtable_index, vtable_index_addr, sizeof(vtable_index)); + return hash(is_vtable_stub, vtable_index); +} + + VtableStub* VtableStubs::lookup(bool is_vtable_stub, int vtable_index) { assert_lock_strong(VtableStubs_lock); unsigned hash = VtableStubs::hash(is_vtable_stub, vtable_index); @@ -275,12 +288,15 @@ void VtableStubs::enter(bool is_vtable_stub, int vtable_index, VtableStub* s) { } VtableStub* VtableStubs::entry_point(address pc) { + // The pc may or may not be the entry point for a VtableStub. Use unsafe_hash + // to generate the hash that would have been used if it was. The lookup in the + // _table will only succeed if there is a VtableStub with an entry point at + // the pc. MutexLocker ml(VtableStubs_lock, Mutex::_no_safepoint_check_flag); - VtableStub* stub = (VtableStub*)(pc - VtableStub::entry_offset()); - uint hash = VtableStubs::hash(stub->is_vtable_stub(), stub->index()); + uint hash = VtableStubs::unsafe_hash(pc); VtableStub* s; - for (s = Atomic::load(&_table[hash]); s != nullptr && s != stub; s = s->next()) {} - return (s == stub) ? s : nullptr; + for (s = Atomic::load(&_table[hash]); s != nullptr && s->entry_point() != pc; s = s->next()) {} + return (s != nullptr && s->entry_point() == pc) ? s : nullptr; } bool VtableStubs::contains(address pc) { diff --git a/src/hotspot/share/code/vtableStubs.hpp b/src/hotspot/share/code/vtableStubs.hpp index 426753ef00813..06acd8f25b921 100644 --- a/src/hotspot/share/code/vtableStubs.hpp +++ b/src/hotspot/share/code/vtableStubs.hpp @@ -28,7 +28,6 @@ #include "asm/macroAssembler.hpp" #include "code/vmreg.hpp" #include "memory/allStatic.hpp" -#include "sanitizers/ub.hpp" #include "utilities/checkedCast.hpp" // A VtableStub holds an individual code stub for a pair (vtable index, #args) for either itables or vtables @@ -94,6 +93,7 @@ class VtableStubs : AllStatic { static VtableStub* lookup (bool is_vtable_stub, int vtable_index); static void enter (bool is_vtable_stub, int vtable_index, VtableStub* s); static inline uint hash (bool is_vtable_stub, int vtable_index); + static inline uint unsafe_hash (address entry_point); static address find_stub (bool is_vtable_stub, int vtable_index); static void bookkeeping(MacroAssembler* masm, outputStream* out, VtableStub* s, address npe_addr, address ame_addr, bool is_vtable_stub, @@ -119,6 +119,12 @@ class VtableStub { private: friend class VtableStubs; + enum class Type : uint8_t { + itable_stub, + vtable_stub, + }; + + static address _chunk; // For allocation static address _chunk_end; // For allocation static VMReg _receiver_location; // Where to find receiver @@ -127,14 +133,14 @@ class VtableStub { const short _index; // vtable index short _ame_offset; // Where an AbstractMethodError might occur short _npe_offset; // Where a NullPointerException might occur - bool _is_vtable_stub; // True if vtable stub, false, is itable stub + Type _type; // Type, either vtable stub or itable stub /* code follows here */ // The vtableStub code void* operator new(size_t size, int code_size) throw(); VtableStub(bool is_vtable_stub, short index) : _next(nullptr), _index(index), _ame_offset(-1), _npe_offset(-1), - _is_vtable_stub(is_vtable_stub) {} + _type(is_vtable_stub ? Type::vtable_stub : Type::itable_stub) {} VtableStub* next() const { return _next; } int index() const { return _index; } static VMReg receiver_location() { return _receiver_location; } @@ -142,12 +148,12 @@ class VtableStub { public: address code_begin() const { return (address)(this + 1); } - address code_end() const { return code_begin() + VtableStubs::code_size_limit(_is_vtable_stub); } + address code_end() const { return code_begin() + VtableStubs::code_size_limit(is_vtable_stub()); } address entry_point() const { return code_begin(); } static int entry_offset() { return sizeof(class VtableStub); } bool matches(bool is_vtable_stub, int index) const { - return _index == index && _is_vtable_stub == is_vtable_stub; + return _index == index && this->is_vtable_stub() == is_vtable_stub; } bool contains(address pc) const { return code_begin() <= pc && pc < code_end(); } @@ -173,11 +179,8 @@ class VtableStub { public: // Query - bool is_itable_stub() { return !_is_vtable_stub; } - // We reinterpret arbitrary memory as VtableStub. This does not cause failures because the lookup/equality - // check will reject false objects. Disabling UBSan is a temporary workaround until JDK-8331725 is fixed. - ATTRIBUTE_NO_UBSAN - bool is_vtable_stub() { return _is_vtable_stub; } + bool is_itable_stub() const { return _type == Type::itable_stub; } + bool is_vtable_stub() const { return _type == Type::vtable_stub; } bool is_abstract_method_error(address epc) { return epc == code_begin()+_ame_offset; } bool is_null_pointer_exception(address epc) { return epc == code_begin()+_npe_offset; } From 7ab96c74e2c39f430a5c2f65a981da7314a2385b Mon Sep 17 00:00:00 2001 From: Patricio Chilano Mateo Date: Wed, 10 Jul 2024 16:26:16 +0000 Subject: [PATCH 040/401] 8335409: Can't allocate and retain memory from resource area in frame::oops_interpreted_do oop closure after 8329665 Reviewed-by: dholmes, stuefe, coleenp, shade --- src/hotspot/share/interpreter/oopMapCache.cpp | 60 ++++++++----------- src/hotspot/share/interpreter/oopMapCache.hpp | 23 ++++--- src/hotspot/share/runtime/frame.cpp | 1 - 3 files changed, 35 insertions(+), 49 deletions(-) diff --git a/src/hotspot/share/interpreter/oopMapCache.cpp b/src/hotspot/share/interpreter/oopMapCache.cpp index a10f8c439eaa4..87b124e9d7968 100644 --- a/src/hotspot/share/interpreter/oopMapCache.cpp +++ b/src/hotspot/share/interpreter/oopMapCache.cpp @@ -66,9 +66,6 @@ class OopMapCacheEntry: private InterpreterOopMap { public: OopMapCacheEntry() : InterpreterOopMap() { _next = nullptr; -#ifdef ASSERT - _resource_allocate_bit_mask = false; -#endif } }; @@ -177,9 +174,13 @@ class VerifyClosure : public OffsetClosure { InterpreterOopMap::InterpreterOopMap() { initialize(); -#ifdef ASSERT - _resource_allocate_bit_mask = true; -#endif +} + +InterpreterOopMap::~InterpreterOopMap() { + if (has_valid_mask() && mask_size() > small_mask_limit) { + assert(_bit_mask[0] != 0, "should have pointer to C heap"); + FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0]); + } } bool InterpreterOopMap::is_empty() const { @@ -399,37 +400,24 @@ void OopMapCacheEntry::deallocate(OopMapCacheEntry* const entry) { // Implementation of OopMapCache -void InterpreterOopMap::resource_copy(OopMapCacheEntry* from) { - assert(_resource_allocate_bit_mask, - "Should not resource allocate the _bit_mask"); - assert(from->has_valid_mask(), - "Cannot copy entry with an invalid mask"); +void InterpreterOopMap::copy_from(const OopMapCacheEntry* src) { + // The expectation is that this InterpreterOopMap is recently created + // and empty. It is used to get a copy of a cached entry. + assert(!has_valid_mask(), "InterpreterOopMap object can only be filled once"); + assert(src->has_valid_mask(), "Cannot copy entry with an invalid mask"); - set_method(from->method()); - set_bci(from->bci()); - set_mask_size(from->mask_size()); - set_expression_stack_size(from->expression_stack_size()); - _num_oops = from->num_oops(); + set_method(src->method()); + set_bci(src->bci()); + set_mask_size(src->mask_size()); + set_expression_stack_size(src->expression_stack_size()); + _num_oops = src->num_oops(); // Is the bit mask contained in the entry? - if (from->mask_size() <= small_mask_limit) { - memcpy((void *)_bit_mask, (void *)from->_bit_mask, - mask_word_size() * BytesPerWord); + if (src->mask_size() <= small_mask_limit) { + memcpy(_bit_mask, src->_bit_mask, mask_word_size() * BytesPerWord); } else { - // The expectation is that this InterpreterOopMap is a recently created - // and empty. It is used to get a copy of a cached entry. - // If the bit mask has a value, it should be in the - // resource area. - assert(_bit_mask[0] == 0 || - Thread::current()->resource_area()->contains((void*)_bit_mask[0]), - "The bit mask should have been allocated from a resource area"); - // Allocate the bit_mask from a Resource area for performance. Allocating - // from the C heap as is done for OopMapCache has a significant - // performance impact. - _bit_mask[0] = (uintptr_t) NEW_RESOURCE_ARRAY(uintptr_t, mask_word_size()); - assert(_bit_mask[0] != 0, "bit mask was not allocated"); - memcpy((void*) _bit_mask[0], (void*) from->_bit_mask[0], - mask_word_size() * BytesPerWord); + _bit_mask[0] = (uintptr_t) NEW_C_HEAP_ARRAY(uintptr_t, mask_word_size(), mtClass); + memcpy((void*) _bit_mask[0], (void*) src->_bit_mask[0], mask_word_size() * BytesPerWord); } } @@ -512,7 +500,7 @@ void OopMapCache::lookup(const methodHandle& method, for (int i = 0; i < probe_depth; i++) { OopMapCacheEntry *entry = entry_at(probe + i); if (entry != nullptr && !entry->is_empty() && entry->match(method, bci)) { - entry_for->resource_copy(entry); + entry_for->copy_from(entry); assert(!entry_for->is_empty(), "A non-empty oop map should be returned"); log_debug(interpreter, oopmap)("- found at hash %d", probe + i); return; @@ -526,7 +514,7 @@ void OopMapCache::lookup(const methodHandle& method, OopMapCacheEntry* tmp = NEW_C_HEAP_OBJ(OopMapCacheEntry, mtClass); tmp->initialize(); tmp->fill(method, bci); - entry_for->resource_copy(tmp); + entry_for->copy_from(tmp); if (method->should_not_be_cached()) { // It is either not safe or not a good idea to cache this Method* @@ -627,7 +615,7 @@ void OopMapCache::compute_one_oop_map(const methodHandle& method, int bci, Inter tmp->initialize(); tmp->fill(method, bci); if (tmp->has_valid_mask()) { - entry->resource_copy(tmp); + entry->copy_from(tmp); } OopMapCacheEntry::deallocate(tmp); } diff --git a/src/hotspot/share/interpreter/oopMapCache.hpp b/src/hotspot/share/interpreter/oopMapCache.hpp index 7037b2c7d1fcf..062b4178ce06e 100644 --- a/src/hotspot/share/interpreter/oopMapCache.hpp +++ b/src/hotspot/share/interpreter/oopMapCache.hpp @@ -36,13 +36,14 @@ // OopMapCache's are allocated lazily per InstanceKlass. // The oopMap (InterpreterOopMap) is stored as a bit mask. If the -// bit_mask can fit into two words it is stored in +// bit_mask can fit into four words it is stored in // the _bit_mask array, otherwise it is allocated on the heap. // For OopMapCacheEntry the bit_mask is allocated in the C heap // because these entries persist between garbage collections. -// For InterpreterOopMap the bit_mask is allocated in -// a resource area for better performance. InterpreterOopMap -// should only be created and deleted during same garbage collection. +// For InterpreterOopMap the bit_mask is allocated in the C heap +// to avoid issues with allocations from the resource area that have +// to live accross the oop closure. InterpreterOopMap should only be +// created and deleted during the same garbage collection. // // If ENABBLE_ZAP_DEAD_LOCALS is defined, two bits are used // per entry instead of one. In all cases, @@ -88,9 +89,6 @@ class InterpreterOopMap: ResourceObj { unsigned short _bci; // the bci for which the mask is valid protected: -#ifdef ASSERT - bool _resource_allocate_bit_mask; -#endif int _num_oops; intptr_t _bit_mask[N]; // the bit mask if // mask_size <= small_mask_limit, @@ -128,12 +126,13 @@ class InterpreterOopMap: ResourceObj { public: InterpreterOopMap(); + ~InterpreterOopMap(); - // Copy the OopMapCacheEntry in parameter "from" into this - // InterpreterOopMap. If the _bit_mask[0] in "from" points to - // allocated space (i.e., the bit mask was to large to hold - // in-line), allocate the space from a Resource area. - void resource_copy(OopMapCacheEntry* from); + // Copy the OopMapCacheEntry in parameter "src" into this + // InterpreterOopMap. If the _bit_mask[0] in "src" points to + // allocated space (i.e., the bit mask was too large to hold + // in-line), allocate the space from the C heap. + void copy_from(const OopMapCacheEntry* src); void iterate_oop(OffsetClosure* oop_closure) const; void print() const; diff --git a/src/hotspot/share/runtime/frame.cpp b/src/hotspot/share/runtime/frame.cpp index 8f5d2ad4acbf1..1aed46d58804f 100644 --- a/src/hotspot/share/runtime/frame.cpp +++ b/src/hotspot/share/runtime/frame.cpp @@ -947,7 +947,6 @@ void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool quer InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f); // process locals & expression stack - ResourceMark rm(thread); InterpreterOopMap mask; if (query_oop_map_cache) { m->mask_for(m, bci, &mask); From 66db71563c3ebd715a1192a9b399b618d7bdb8d0 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 10 Jul 2024 16:36:39 +0000 Subject: [PATCH 041/401] 8335637: Add explicit non-null return value expectations to Object.toString() Reviewed-by: jpai, alanb, smarks, prappo --- 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 b8bfdc3e3f9bf..d9813df57a4f0 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 242f1133f8e1b373de3714cefc7f6701c39707fe Mon Sep 17 00:00:00 2001 From: Yudi Zheng Date: Wed, 10 Jul 2024 19:42:23 +0000 Subject: [PATCH 042/401] 8334481: [JVMCI] add LINK_TO_NATIVE to MethodHandleAccessProvider.IntrinsicMethod Reviewed-by: dnsimon --- src/hotspot/share/jvmci/vmStructs_jvmci.cpp | 1 + .../jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java | 2 ++ .../share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java | 1 + .../classes/jdk/vm/ci/meta/MethodHandleAccessProvider.java | 4 +++- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index 8f83d483bcf4b..f55c7bf91a9b6 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -778,6 +778,7 @@ declare_constant(vmIntrinsics::_linkToStatic) \ declare_constant(vmIntrinsics::_linkToSpecial) \ declare_constant(vmIntrinsics::_linkToInterface) \ + declare_constant(vmIntrinsics::_linkToNative) \ \ declare_constant(vmSymbols::FIRST_SID) \ declare_constant(vmSymbols::SID_LIMIT) \ diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java index 7e47196a42b89..3d3d140b1ca79 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java @@ -146,6 +146,8 @@ public static IntrinsicMethod getMethodHandleIntrinsic(int intrinsicId) { return IntrinsicMethod.LINK_TO_STATIC; } else if (intrinsicId == config.vmIntrinsicLinkToVirtual) { return IntrinsicMethod.LINK_TO_VIRTUAL; + } else if (intrinsicId == config.vmIntrinsicLinkToNative) { + return IntrinsicMethod.LINK_TO_NATIVE; } return null; } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java index c49f24efed51e..57f9473c90209 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java @@ -342,6 +342,7 @@ final int baseVtableLength() { final int vmIntrinsicLinkToStatic = getConstant("vmIntrinsics::_linkToStatic", Integer.class); final int vmIntrinsicLinkToSpecial = getConstant("vmIntrinsics::_linkToSpecial", Integer.class); final int vmIntrinsicLinkToInterface = getConstant("vmIntrinsics::_linkToInterface", Integer.class); + final int vmIntrinsicLinkToNative = getConstant("vmIntrinsics::_linkToNative", Integer.class); final int codeInstallResultOk = getConstant("JVMCI::ok", Integer.class); final int codeInstallResultDependenciesFailed = getConstant("JVMCI::dependencies_failed", Integer.class); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MethodHandleAccessProvider.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MethodHandleAccessProvider.java index f053905b160c9..eb8b9721d49ce 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MethodHandleAccessProvider.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/MethodHandleAccessProvider.java @@ -45,7 +45,9 @@ enum IntrinsicMethod { /** The method {@code MethodHandle.linkToVirtual}. */ LINK_TO_VIRTUAL, /** The method {@code MethodHandle.linkToInterface}. */ - LINK_TO_INTERFACE + LINK_TO_INTERFACE, + /** The method {@code MethodHandle.linkToNative}. */ + LINK_TO_NATIVE } /** From cad68e06ecad1e19091d1af9c0f9b8145d6842fb Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Wed, 10 Jul 2024 21:06:39 +0000 Subject: [PATCH 043/401] 8335935: Chained builders not sending transformed models to next transforms Reviewed-by: asotona --- .../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 cffa560bef305..a166637509174 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; /** @@ -192,7 +192,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 ffe1a2bd6160f..66e974b4a51b6 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 60e73cdd987c0..8603c77ab8b2a 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 cc19bf9d31c8d..b33d192f9b355 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 38850aec10978..866dda2c5bc53 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 b961a12031f59..0b6549a82da9e 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 e17adcbcf121f..749abbed23b6d 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 e13b09b0a4d0d..6e3ca516bf480 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 4ffc75d3edc82..0000000000000 --- 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 1df7b73bda56a..0cc1dafdf3274 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.transformClass(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.transformClass(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.transformClass(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.transformClass(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

"x&#178;=5"
* - * + * *
"x²=5"
* - * + * *
"x&#178;=5"
* * * - * Built-in - * character entity - * + * Built-in character entity + * *
"y&lt;6"
* - * + * *
"y<6"
* - * + * *
"y&lt;6"
* * * - * Literal newline between - * - *
- * "x=5&#10;y=6"
+ * Literal newline between + * + *
"x=5&#10;y=6"
* - * + * *
"x=5 y=6"
* - * + * *
"x=5&#10;y=6"
* * * - * Normalized newline between - * + * Normalized newline between + * *
"x=5
  * y=6"
* - * + * *
"x=5 y=6"
* - * + * *
"x=5 y=6"
* * * - * Entity e with literal newline - * + * Entity e with literal newline + * *
  * <!ENTITY e '...&#10;...'> [...]> "x=5&e;y=6"
* - * Dependent on Implementation and Load Options - * Dependent on Implementation and Load/Save Options + * Dependent on Implementation and Load Options + * Dependent on Implementation and Load/Save Options * * * From 5100303c6c5e4224d2c41f90719139bb5f4e236e Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Thu, 11 Jul 2024 18:40:40 +0000 Subject: [PATCH 057/401] 8335668: NumberFormat integer only parsing should throw exception for edge case Reviewed-by: naoto --- .../classes/java/text/DecimalFormat.java | 14 +++++--- .../Format/NumberFormat/LenientParseTest.java | 30 ++++++++++++++-- .../Format/NumberFormat/StrictParseTest.java | 34 ++++++++++++++++--- 3 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/java.base/share/classes/java/text/DecimalFormat.java b/src/java.base/share/classes/java/text/DecimalFormat.java index 1f249888a28f5..04acca1ceb51d 100644 --- a/src/java.base/share/classes/java/text/DecimalFormat.java +++ b/src/java.base/share/classes/java/text/DecimalFormat.java @@ -2379,8 +2379,8 @@ private final boolean subparse(String text, ParsePosition parsePosition, NumericPosition pos = subparseNumber(text, position, digits, true, isExponent, status); position = pos.fullPos; - // First character after the prefix was un-parseable, should - // fail regardless if lenient or strict. + // First character after the prefix was un-parseable or parsing integer + // only with no integer portion. Should fail regardless if lenient or strict. if (position == -1) { parsePosition.index = oldStart; parsePosition.errorIndex = oldStart; @@ -2421,8 +2421,8 @@ private final boolean subparse(String text, ParsePosition parsePosition, } // When parsing integer only, index should be int pos - // If intPos is 0, the entire value was integer - if (isParseIntegerOnly() && pos.intPos > 0) { + // If intPos is -1, the entire value was integer and index should be full pos + if (isParseIntegerOnly() && pos.intPos != -1) { parsePosition.index = pos.intPos; } else { // increment the index by the suffix @@ -2474,7 +2474,7 @@ NumericPosition subparseNumber(String text, int position, boolean isExponent, boolean[] status) { // process digits or Inf, find decimal position status[STATUS_INFINITE] = false; - int intIndex = 0; + int intIndex = -1; if (!isExponent && text.regionMatches(position, symbols.getInfinity(), 0, symbols.getInfinity().length())) { position += symbols.getInfinity().length(); @@ -2570,6 +2570,10 @@ NumericPosition subparseNumber(String text, int position, // Cancel out backup setting (see grouping handler below) backup = -1; } else if (!isExponent && ch == decimal) { + if (isParseIntegerOnly() && startPos == position) { + // Parsing int only with no integer portion, fail + return new NumericPosition(-1, intIndex); + } // Check grouping size on decimal separator if (parseStrict && isGroupingViolation(position, prevSeparatorIndex)) { return new NumericPosition( diff --git a/test/jdk/java/text/Format/NumberFormat/LenientParseTest.java b/test/jdk/java/text/Format/NumberFormat/LenientParseTest.java index 41f8961ff32e2..c85fe0f6cbb59 100644 --- a/test/jdk/java/text/Format/NumberFormat/LenientParseTest.java +++ b/test/jdk/java/text/Format/NumberFormat/LenientParseTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8327640 8331485 8333456 + * @bug 8327640 8331485 8333456 8335668 * @summary Test suite for NumberFormat parsing when lenient. * @run junit/othervm -Duser.language=en -Duser.country=US LenientParseTest * @run junit/othervm -Duser.language=ja -Duser.country=JP LenientParseTest @@ -128,6 +128,28 @@ public void numFmtStrictIntegerOnlyUsed(String toParse, int expectedValue, int e dFmt.setParseIntegerOnly(false); } + // 8335668: Parsing with integer only against String with no integer portion + // should fail, not return 0. Expected error index should be 0 + @Test + public void integerParseOnlyFractionOnlyTest() { + var fmt = NumberFormat.getIntegerInstance(); + failParse(fmt, localizeText("."), 0); + failParse(fmt, localizeText(".0"), 0); + failParse(fmt, localizeText(".55"), 0); + } + + // 8335668: Parsing with integer only against String with no integer portion + // should fail, not return 0. Expected error index should be 0 + @Test // Non-localized, run once + @EnabledIfSystemProperty(named = "user.language", matches = "en") + public void compactIntegerParseOnlyFractionOnlyTest() { + var fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT); + fmt.setParseIntegerOnly(true); + failParse(fmt, ".K", 0); + failParse(fmt, ".0K", 0); + failParse(fmt, ".55K", 0); + } + @Test // Non-localized, only run once @EnabledIfSystemProperty(named = "user.language", matches = "en") public void badExponentParseNumberFormatTest() { @@ -313,7 +335,11 @@ private static Stream validFullParseStrings() { Arguments.of("10000", 10000d), Arguments.of("100,000", 100000d), Arguments.of("1,000,000", 1000000d), - Arguments.of("10,000,000", 10000000d)) + Arguments.of("10,000,000", 10000000d), + // Smaller value cases (w/ decimal) + Arguments.of(".1", .1d), + Arguments.of("1.1", 1.1d), + Arguments.of("11.1", 11.1d)) .map(args -> Arguments.of( localizeText(String.valueOf(args.get()[0])), args.get()[1])); } diff --git a/test/jdk/java/text/Format/NumberFormat/StrictParseTest.java b/test/jdk/java/text/Format/NumberFormat/StrictParseTest.java index 333bc1b050637..3e90ccb39ceaf 100644 --- a/test/jdk/java/text/Format/NumberFormat/StrictParseTest.java +++ b/test/jdk/java/text/Format/NumberFormat/StrictParseTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8327640 8331485 8333755 + * @bug 8327640 8331485 8333755 8335668 * @summary Test suite for NumberFormat parsing with strict leniency * @run junit/othervm -Duser.language=en -Duser.country=US StrictParseTest * @run junit/othervm -Duser.language=ja -Duser.country=JP StrictParseTest @@ -203,6 +203,28 @@ public void numFmtStrictIntegerOnlyUsedTest(String toParse, Number expVal) { } } + // 8335668: Parsing with integer only against String with no integer portion + // should fail, not return 0. Expected error index should be 0 + @Test + public void integerParseOnlyFractionOnlyTest() { + var fmt = NumberFormat.getIntegerInstance(); + failParse(fmt, localizeText("."), 0); + failParse(fmt, localizeText(".0"), 0); + failParse(fmt, localizeText(".55"), 0); + } + + // 8335668: Parsing with integer only against String with no integer portion + // should fail, not return 0. Expected error index should be 0 + @Test // Non-localized, run once + @EnabledIfSystemProperty(named = "user.language", matches = "en") + public void compactIntegerParseOnlyFractionOnlyTest() { + var fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT); + fmt.setParseIntegerOnly(true); + failParse(fmt, ".K", 0); + failParse(fmt, ".0K", 0); + failParse(fmt, ".55K", 0); + } + // 8333755: Parsing behavior should follow normal strict behavior // when it comes to failures. @ParameterizedTest @@ -426,8 +448,8 @@ private static Stream badParseStrings() { Arguments.of("1,234a", 5), Arguments.of("1,.a", 2), Arguments.of("1.a", 2), - Arguments.of(".22a", 3), - Arguments.of(".1a1", 2), + Arguments.of("1.22a", 4), + Arguments.of("1.1a1", 3), Arguments.of("1,234,a", 5), // Double decimal Arguments.of("1,234..5", 5)) @@ -453,7 +475,11 @@ private static Stream validParseStrings() { Arguments.of("10000", 10000d), Arguments.of("100,000", 100000d), Arguments.of("1,000,000", 1000000d), - Arguments.of("10,000,000", 10000000d)) + Arguments.of("10,000,000", 10000000d), + // Smaller value cases (w/ decimal) + Arguments.of(".1", .1d), + Arguments.of("1.1", 1.1d), + Arguments.of("11.1", 11.1d)) .map(args -> Arguments.of( localizeText(String.valueOf(args.get()[0])), args.get()[1])); } From 9eb611e7f07ebb6eb0cbcca32d644abf8352c991 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Thu, 11 Jul 2024 19:53:52 +0000 Subject: [PATCH 058/401] 8334055: Unhelpful 'required: reference' diagnostics after JDK-8043226 Reviewed-by: vromero --- .../classes/com/sun/tools/javac/comp/Attr.java | 9 +-------- .../failures/CantAnnotateMissingSymbol.java | 16 ++++++++++++++++ .../failures/CantAnnotateMissingSymbol.out | 2 ++ .../failures/CantAnnotatePackages.java | 2 +- .../failures/CantAnnotatePackages.out | 6 +++--- .../failures/CantAnnotateScoping.java | 2 +- .../failures/CantAnnotateScoping.out | 9 ++++----- 7 files changed, 28 insertions(+), 18 deletions(-) create mode 100644 test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateMissingSymbol.java create mode 100644 test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateMissingSymbol.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 f58319496e968..9b79846ba40df 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 @@ -5241,14 +5241,7 @@ public void visitModifiers(JCModifiers tree) { public void visitAnnotatedType(JCAnnotatedType tree) { attribAnnotationTypes(tree.annotations, env); - Type underlyingType = - attribTree(tree.underlyingType, env, new ResultInfo(KindSelector.TYP_PCK, Type.noType)); - if (underlyingType.hasTag(PACKAGE)) { - // Type annotations are not admissible on packages, but we handle packages here to - // report better diagnostics later in validateAnnotatedType. - result = tree.type = underlyingType; - return; - } + Type underlyingType = attribType(tree.underlyingType, env); Type annotatedType = underlyingType.preannotatedType(); if (!env.info.isNewClass) diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateMissingSymbol.java b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateMissingSymbol.java new file mode 100644 index 0000000000000..469cffa37a61f --- /dev/null +++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateMissingSymbol.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8026564 8043226 + * @summary 8334055 + * @compile/fail/ref=CantAnnotateMissingSymbol.out -XDrawDiagnostics CantAnnotateMissingSymbol.java + */ + +import java.lang.annotation.*; +import java.util.List; + +class CantAnnotateMissingSymbol { + List<@TA NoSuch> x; +} + +@Target(ElementType.TYPE_USE) +@interface TA { } diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateMissingSymbol.out b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateMissingSymbol.out new file mode 100644 index 0000000000000..b875cd2be7b80 --- /dev/null +++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateMissingSymbol.out @@ -0,0 +1,2 @@ +CantAnnotateMissingSymbol.java:12:14: compiler.err.cant.resolve.location: kindname.class, NoSuch, , , (compiler.misc.location: kindname.class, CantAnnotateMissingSymbol, null) +1 error diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.java b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.java index d7587dfcf5fc2..d35351b6f4084 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.java @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8026564 8043226 + * @bug 8026564 8043226 8334055 * @summary The parts of a fully-qualified type can't be annotated. * @author Werner Dietl * @compile/fail/ref=CantAnnotatePackages.out -XDrawDiagnostics CantAnnotatePackages.java diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.out b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.out index 6e2b9cb93b0e2..b91d65828b97b 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.out +++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotatePackages.out @@ -1,5 +1,5 @@ +CantAnnotatePackages.java:16:14: compiler.err.cant.resolve.location: kindname.class, java, , , (compiler.misc.location: kindname.class, CantAnnotatePackages, null) +CantAnnotatePackages.java:17:9: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null) +CantAnnotatePackages.java:18:14: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null) CantAnnotatePackages.java:14:18: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @TA), java.lang, @TA java.lang.Object -CantAnnotatePackages.java:16:14: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @TA), java.lang, @TA java.lang.Object -CantAnnotatePackages.java:17:9: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @TA), java.lang, @TA java.lang.Object -CantAnnotatePackages.java:18:14: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @TA), java.lang, @TA java.lang.Object 4 errors diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.java b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.java index aec691c913dd6..4bdd791909c27 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.java @@ -1,6 +1,6 @@ /* * @test /nodynamiccopyright/ - * @bug 8006733 8006775 8043226 + * @bug 8006733 8006775 8043226 8334055 * @summary Ensure behavior for nested types is correct. * @author Werner Dietl * @compile/fail/ref=CantAnnotateScoping.out -XDrawDiagnostics CantAnnotateScoping.java diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.out b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.out index 2ae736ad315d4..ade5333a446fa 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.out +++ b/test/langtools/tools/javac/annotations/typeAnnotations/failures/CantAnnotateScoping.out @@ -1,13 +1,12 @@ -CantAnnotateScoping.java:68:18: compiler.err.doesnt.exist: java.XXX +CantAnnotateScoping.java:63:9: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null) +CantAnnotateScoping.java:68:9: compiler.err.cant.resolve.location: kindname.class, XXX, , , (compiler.misc.location: kindname.package, java, null) +CantAnnotateScoping.java:71:9: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null) CantAnnotateScoping.java:38:14: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @TA), Test.Outer, @TA Test.Outer.SInner CantAnnotateScoping.java:51:18: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @TA), java.lang, @TA java.lang.Object CantAnnotateScoping.java:60:37: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation: @TA,@TA2), java.lang, @DTA @TA @TA2 java.lang.Object CantAnnotateScoping.java:40:14: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @TA), Test.Outer, @TA Test.Outer.SInner -CantAnnotateScoping.java:63:11: compiler.err.annotation.type.not.applicable.to.type: DA -CantAnnotateScoping.java:68:11: compiler.err.annotation.type.not.applicable.to.type: DA -CantAnnotateScoping.java:71:9: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @TA), java.lang, @TA java.lang.Object CantAnnotateScoping.java:44:34: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation: @TA,@TA2), Test.Outer, @TA @TA2 Test.Outer.SInner CantAnnotateScoping.java:44:25: compiler.err.annotation.type.not.applicable.to.type: DA CantAnnotateScoping.java:48:38: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @TA), Test.Outer, @TA Test.Outer.SInner CantAnnotateScoping.java:48:34: compiler.err.annotation.type.not.applicable.to.type: DA -12 errors +11 errors From 73e3e0edeb20c6f701b213423476f92fb05dd262 Mon Sep 17 00:00:00 2001 From: Dean Long Date: Thu, 11 Jul 2024 20:18:16 +0000 Subject: [PATCH 059/401] 8321509: False positive in get_trampoline fast path causes crash Reviewed-by: kvn, adinn, thartmann --- .../cpu/aarch64/globalDefinitions_aarch64.hpp | 4 +- .../cpu/aarch64/nativeInst_aarch64.cpp | 39 +++++++++---------- .../cpu/aarch64/nativeInst_aarch64.hpp | 7 ++-- src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp | 33 ++++++++++------ src/hotspot/share/code/relocInfo.cpp | 8 ++++ src/hotspot/share/code/relocInfo.hpp | 5 +++ 6 files changed, 58 insertions(+), 38 deletions(-) diff --git a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp index 63f6c9491c8de..faf635dc33282 100644 --- a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -76,4 +76,6 @@ const bool CCallingConventionRequiresIntsAsLongs = false; #define USE_POINTERS_TO_REGISTER_IMPL_ARRAY +#define USE_TRAMPOLINE_STUB_FIX_OWNER + #endif // CPU_AARCH64_GLOBALDEFINITIONS_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp index c88705618e63d..5a3f9d228ca89 100644 --- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -51,13 +51,18 @@ void NativeInstruction::wrote(int offset) { } address NativeCall::destination() const { - address addr = (address)this; - address destination = instruction_address() + displacement(); + address addr = instruction_address(); + address destination = addr + displacement(); + + // Performance optimization: no need to call find_blob() if it is a self-call + if (destination == addr) { + return destination; + } // Do we use a trampoline stub for this call? CodeBlob* cb = CodeCache::find_blob(addr); - assert(cb && cb->is_nmethod(), "sanity"); - nmethod *nm = (nmethod *)cb; + assert(cb != nullptr && cb->is_nmethod(), "nmethod expected"); + nmethod *nm = cb->as_nmethod(); if (nm->stub_contains(destination) && is_NativeCallTrampolineStub_at(destination)) { // Yes we do, so get the destination from the trampoline stub. const address trampoline_stub_addr = destination; @@ -72,12 +77,8 @@ address NativeCall::destination() const { // call instruction at all times. // // Used in the runtime linkage of calls; see class CompiledIC. -// -// Add parameter assert_lock to switch off assertion -// during code generation, where no patching lock is needed. -void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) { - assert(!assert_lock || - (Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) || +void NativeCall::set_destination_mt_safe(address dest) { + assert((Patching_lock->is_locked() || SafepointSynchronize::is_at_safepoint()) || CompiledICLocker::is_safe(addr_at(0)), "concurrent code patching"); @@ -104,22 +105,18 @@ void NativeCall::set_destination_mt_safe(address dest, bool assert_lock) { } address NativeCall::get_trampoline() { - address call_addr = addr_at(0); + address call_addr = instruction_address(); CodeBlob *code = CodeCache::find_blob(call_addr); - assert(code != nullptr, "Could not find the containing code blob"); + assert(code != nullptr && code->is_nmethod(), "nmethod expected"); + nmethod* nm = code->as_nmethod(); - address bl_destination - = MacroAssembler::pd_call_destination(call_addr); - if (code->contains(bl_destination) && + address bl_destination = call_addr + displacement(); + if (nm->stub_contains(bl_destination) && is_NativeCallTrampolineStub_at(bl_destination)) return bl_destination; - if (code->is_nmethod()) { - return trampoline_stub_Relocation::get_trampoline_for(call_addr, (nmethod*)code); - } - - return nullptr; + return trampoline_stub_Relocation::get_trampoline_for(call_addr, nm); } // Inserts a native call instruction at a given pc diff --git a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp index 974214d985b5d..0eb5ff815be1d 100644 --- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2108, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -174,6 +174,7 @@ class NativeCall: public NativeInstruction { int displacement() const { return (int_at(displacement_offset) << 6) >> 4; } address displacement_address() const { return addr_at(displacement_offset); } address return_address() const { return addr_at(return_address_offset); } + address raw_destination() const { return instruction_address() + displacement(); } address destination() const; void set_destination(address dest) { @@ -213,9 +214,7 @@ class NativeCall: public NativeInstruction { // // Used in the runtime linkage of calls; see class CompiledIC. // (Cf. 4506997 and 4479829, where threads witnessed garbage displacements.) - - // The parameter assert_lock disables the assertion during code generation. - void set_destination_mt_safe(address dest, bool assert_lock = true); + void set_destination_mt_safe(address dest); address get_trampoline(); #if INCLUDE_JVMCI diff --git a/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp b/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp index 332f24996930f..c4c8648d552d0 100644 --- a/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/relocInfo_aarch64.cpp @@ -60,13 +60,12 @@ void Relocation::pd_set_data_value(address x, bool verify_only) { address Relocation::pd_call_destination(address orig_addr) { assert(is_call(), "should be a call here"); - if (NativeCall::is_call_at(addr())) { - address trampoline = nativeCall_at(addr())->get_trampoline(); - if (trampoline) { - return nativeCallTrampolineStub_at(trampoline)->destination(); + if (orig_addr == nullptr) { + if (NativeCall::is_call_at(addr())) { + NativeCall* call = nativeCall_at(addr()); + return call->destination(); } - } - if (orig_addr != nullptr) { + } else { address new_addr = MacroAssembler::pd_call_destination(orig_addr); // If call is branch to self, don't try to relocate it, just leave it // as branch to self. This happens during code generation if the code @@ -82,16 +81,26 @@ address Relocation::pd_call_destination(address orig_addr) { void Relocation::pd_set_call_destination(address x) { assert(is_call(), "should be a call here"); if (NativeCall::is_call_at(addr())) { - address trampoline = nativeCall_at(addr())->get_trampoline(); - if (trampoline) { - nativeCall_at(addr())->set_destination_mt_safe(x, /* assert_lock */false); - return; - } + NativeCall* call = nativeCall_at(addr()); + call->set_destination(x); + } else { + MacroAssembler::pd_patch_instruction(addr(), x); } - MacroAssembler::pd_patch_instruction(addr(), x); assert(pd_call_destination(addr()) == x, "fail in reloc"); } +void trampoline_stub_Relocation::pd_fix_owner_after_move() { + NativeCall* call = nativeCall_at(owner()); + assert(call->raw_destination() == owner(), "destination should be empty"); + address trampoline = addr(); + address dest = nativeCallTrampolineStub_at(trampoline)->destination(); + if (!Assembler::reachable_from_branch_at(owner(), dest)) { + dest = trampoline; + } + call->set_destination(dest); +} + + address* Relocation::pd_address_in_code() { return (address*)(addr() + 8); } diff --git a/src/hotspot/share/code/relocInfo.cpp b/src/hotspot/share/code/relocInfo.cpp index 3b19b63f24469..a379f88ddc180 100644 --- a/src/hotspot/share/code/relocInfo.cpp +++ b/src/hotspot/share/code/relocInfo.cpp @@ -373,6 +373,14 @@ void CallRelocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer } +#ifdef USE_TRAMPOLINE_STUB_FIX_OWNER +void trampoline_stub_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { + // Finalize owner destination only for nmethods + if (dest->blob() != nullptr) return; + pd_fix_owner_after_move(); +} +#endif + //// pack/unpack methods void oop_Relocation::pack_data_to(CodeSection* dest) { diff --git a/src/hotspot/share/code/relocInfo.hpp b/src/hotspot/share/code/relocInfo.hpp index 6d0907d97dedc..25cca49e50bb8 100644 --- a/src/hotspot/share/code/relocInfo.hpp +++ b/src/hotspot/share/code/relocInfo.hpp @@ -1258,6 +1258,11 @@ class runtime_call_w_cp_Relocation : public CallRelocation { // in the code, it can patch it to jump to the trampoline where is // sufficient space for a far branch. Needed on PPC. class trampoline_stub_Relocation : public Relocation { +#ifdef USE_TRAMPOLINE_STUB_FIX_OWNER + void pd_fix_owner_after_move(); + void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) override; +#endif + public: static RelocationHolder spec(address static_call) { return RelocationHolder::construct(static_call); From 889055713ea83f899ebd7bf640dcf3c3e1a82ebe Mon Sep 17 00:00:00 2001 From: Nizar Benalla Date: Thu, 11 Jul 2024 20:44:21 +0000 Subject: [PATCH 060/401] 8335623: Clean up HtmlTag.HtmlTag and make the ARIA role attribute global Reviewed-by: liach --- .../jdk/javadoc/internal/doclint/HtmlTag.java | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/HtmlTag.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/HtmlTag.java index 0c820dae91392..fa9d3ea578dd4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/HtmlTag.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/HtmlTag.java @@ -507,7 +507,7 @@ public enum Attr { PROFILE, REV, REVERSED, - ROLE, + ROLE(true), ROWSPAN, RULES, SCHEME, @@ -606,26 +606,6 @@ private static class AttrMap extends EnumMap { this.attrs = new EnumMap<>(Attr.class); for (Map m: attrMaps) this.attrs.putAll(m); - attrs.put(Attr.CLASS, AttrKind.OK); - attrs.put(Attr.ID, AttrKind.OK); - attrs.put(Attr.STYLE, AttrKind.OK); - attrs.put(Attr.ROLE, AttrKind.OK); - // for now, assume that all ARIA attributes are allowed on all tags. - attrs.put(Attr.ARIA_ACTIVEDESCENDANT, AttrKind.OK); - attrs.put(Attr.ARIA_CONTROLS, AttrKind.OK); - attrs.put(Attr.ARIA_DESCRIBEDBY, AttrKind.OK); - attrs.put(Attr.ARIA_EXPANDED, AttrKind.OK); - attrs.put(Attr.ARIA_LABEL, AttrKind.OK); - attrs.put(Attr.ARIA_LABELLEDBY, AttrKind.OK); - attrs.put(Attr.ARIA_LEVEL, AttrKind.OK); - attrs.put(Attr.ARIA_MULTISELECTABLE, AttrKind.OK); - attrs.put(Attr.ARIA_OWNS, AttrKind.OK); - attrs.put(Attr.ARIA_POSINSET, AttrKind.OK); - attrs.put(Attr.ARIA_READONLY, AttrKind.OK); - attrs.put(Attr.ARIA_REQUIRED, AttrKind.OK); - attrs.put(Attr.ARIA_SELECTED, AttrKind.OK); - attrs.put(Attr.ARIA_SETSIZE, AttrKind.OK); - attrs.put(Attr.ARIA_SORT, AttrKind.OK); } public boolean accepts(HtmlTag t) { From 687601ebcaedf133fd4d5cecc42c5aadf9c73f3c Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Thu, 11 Jul 2024 20:45:34 +0000 Subject: [PATCH 061/401] 8336257: Additional tests in jmxremote/startstop to match on PID not app name Reviewed-by: cjplummer, alanb, amenkov, dcubed --- .../sun/management/jmxremote/startstop/JMXStartStopTest.java | 5 +++-- .../jmxremote/startstop/JMXStatusPerfCountersTest.java | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/test/jdk/sun/management/jmxremote/startstop/JMXStartStopTest.java b/test/jdk/sun/management/jmxremote/startstop/JMXStartStopTest.java index 13a4f7bea73f0..3d125325449f5 100644 --- a/test/jdk/sun/management/jmxremote/startstop/JMXStartStopTest.java +++ b/test/jdk/sun/management/jmxremote/startstop/JMXStartStopTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -72,7 +72,7 @@ public class JMXStartStopTest { private static final boolean verbose = false; - private static ManagementAgentJcmd jcmd = new ManagementAgentJcmd(TEST_APP_NAME, verbose); + private static ManagementAgentJcmd jcmd; private static void dbg_print(String msg) { if (verbose) { @@ -347,6 +347,7 @@ public synchronized void start() throws InterruptedException, IOException, Timeo "the requested port not being available"); } pid = p.pid(); + jcmd = new ManagementAgentJcmd(p, verbose); } catch (TimeoutException e) { if (p != null) { p.destroy(); diff --git a/test/jdk/sun/management/jmxremote/startstop/JMXStatusPerfCountersTest.java b/test/jdk/sun/management/jmxremote/startstop/JMXStatusPerfCountersTest.java index fc7a0de2d0630..e3703ba8dbc87 100644 --- a/test/jdk/sun/management/jmxremote/startstop/JMXStatusPerfCountersTest.java +++ b/test/jdk/sun/management/jmxremote/startstop/JMXStatusPerfCountersTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -67,7 +67,6 @@ public static void setupClass() throws Exception { @BeforeTest public void setup() { - jcmd = new ManagementAgentJcmd(TEST_APP_NAME, false); } @BeforeMethod @@ -76,6 +75,7 @@ public void startTestApp() throws Exception { TEST_APP_NAME, testAppPb, (Predicate)l->l.trim().equals("main enter") ); + jcmd = new ManagementAgentJcmd(testApp, false); } @AfterMethod From b3ef2a600cfec31723dc78fe552e9cf9976b0337 Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Thu, 11 Jul 2024 20:51:27 +0000 Subject: [PATCH 062/401] 8336036: Synthetic documentation for a record's equals is incorrect for floating-point types Reviewed-by: prappo --- .../doclets/toolkit/resources/doclets.properties | 6 ++++-- .../doclet/testRecordTypes/TestRecordTypes.java | 14 +++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties index 859289ff8bd21..0ee9429ec0c65 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets.properties @@ -319,10 +319,12 @@ doclet.record_equals_doc.fullbody.head=\ doclet.record_equals_doc.fullbody.tail.both=\ Reference components are compared with \ {@link java.util.Objects#equals(Object,Object) Objects::equals(Object,Object)}; \ - primitive components are compared with '=='. + primitive components are compared with the compare method from \ + their corresponding wrapper classes. doclet.record_equals_doc.fullbody.tail.primitive=\ - All components in this record class are compared with '=='. + All components in this record class are compared with the compare \ + method from their corresponding wrapper classes. doclet.record_equals_doc.fullbody.tail.reference=\ All components in this record class are compared with \ diff --git a/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.java b/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.java index c4579c501ec77..f9aa3cfd6fa49 100644 --- a/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.java +++ b/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.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 @@ -237,7 +237,8 @@ public record R(int r1) { }"""); """ Indicates whether some other object is "equal to" this one. The objects are equa\ l if the other object is of the same class and if all the record components are \ - equal. All components in this record class are compared with '=='.""", + equal. All components in this record class are compared with the compare method from their corresponding wrapper classes.""", """ r1""", """ @@ -300,7 +301,8 @@ public record R(int r1) { }"""); """ Indicates whether some other object is "equal to" this one. The objects are equa\ l if the other object is of the same class and if all the record components are \ - equal. All components in this record class are compared with '=='.""", + equal. All components in this record class are compared with the compare method from their corresponding wrapper classes.""", """ r1""", """ @@ -311,7 +313,8 @@ l if the other object is of the same class and if all the record components are @Test public void testGeneratedEqualsPrimitive(Path base) throws IOException { testGeneratedEquals(base, "int a, int b", - "All components in this record class are compared with '=='."); + "All components in this record class are compared with the compare method " + + "from their corresponding wrapper classes."); } @Test @@ -324,7 +327,8 @@ public void testGeneratedEqualsReference(Path base) throws IOException { public void testGeneratedEqualsMixed(Path base) throws IOException { testGeneratedEquals(base, "int a, Object b", "Reference components are compared with Objects::equals(Object,Object); " - + "primitive components are compared with '=='."); + + "primitive components are compared with the compare method from their " + + "corresponding wrapper classes."); } private void testGeneratedEquals(Path base, String comps, String expect) throws IOException { From 81a0d1ba03bbdbe718302b3925cdc207d5d05232 Mon Sep 17 00:00:00 2001 From: Vanitha B P Date: Thu, 11 Jul 2024 21:27:30 +0000 Subject: [PATCH 063/401] 8325525: Create jtreg test case for JDK-8325203 Reviewed-by: asemenyuk, almatvee --- .../apps/ChildProcessAppLauncher.java | 37 ++++++++ .../jpackage/windows/WinChildProcessTest.java | 88 +++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 test/jdk/tools/jpackage/apps/ChildProcessAppLauncher.java create mode 100644 test/jdk/tools/jpackage/windows/WinChildProcessTest.java diff --git a/test/jdk/tools/jpackage/apps/ChildProcessAppLauncher.java b/test/jdk/tools/jpackage/apps/ChildProcessAppLauncher.java new file mode 100644 index 0000000000000..11be90bc45622 --- /dev/null +++ b/test/jdk/tools/jpackage/apps/ChildProcessAppLauncher.java @@ -0,0 +1,37 @@ +/* + * 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.File; +import java.io.IOException; +import java.nio.file.Path; + +public class ChildProcessAppLauncher { + + public static void main(String[] args) throws IOException { + String calcPath = Path.of(System.getenv("SystemRoot"), "system32", "calc.exe").toString(); + ProcessBuilder processBuilder = new ProcessBuilder(calcPath); + Process process = processBuilder.start(); + System.out.println("Calc id=" + process.pid()); + System.exit(0); + } +} diff --git a/test/jdk/tools/jpackage/windows/WinChildProcessTest.java b/test/jdk/tools/jpackage/windows/WinChildProcessTest.java new file mode 100644 index 0000000000000..2928f7f1c5ffe --- /dev/null +++ b/test/jdk/tools/jpackage/windows/WinChildProcessTest.java @@ -0,0 +1,88 @@ +/* + * 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 8325203 + * @summary Test that Jpackage windows executable application kills the launched 3rd party application + * when System.exit(0) is invoked along with terminating java program. + * @library ../helpers + * @library /test/lib + * @requires os.family == "windows" + * @build WinChildProcessTest + * @build jdk.jpackage.test.* + * @build WinChildProcessTest + * @modules jdk.jpackage/jdk.jpackage.internal + * @run main/othervm -Xmx512m jdk.jpackage.test.Main + * --jpt-run=WinChildProcessTest + * + */ + +import java.util.List; +import java.util.Optional; + +import java.nio.file.Path; + +import jdk.jpackage.test.JPackageCommand; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.Executor; +import jdk.jpackage.test.TKit; + +public class WinChildProcessTest { + private static final Path TEST_APP_JAVA = TKit.TEST_SRC_ROOT + .resolve("apps/ChildProcessAppLauncher.java"); + + @Test + public static void test() throws Throwable { + long calcPid = 0; + try { + JPackageCommand cmd = JPackageCommand + .helloAppImage(TEST_APP_JAVA + "*Hello"); + + // Create the image of the third party application launcher + cmd.executeAndAssertImageCreated(); + + // Start the third party application launcher and dump and save the + // output of the application + List output = new Executor().saveOutput().dumpOutput() + .setExecutable(cmd.appLauncherPath().toAbsolutePath()) + .execute(0).getOutput(); + String pidStr = output.get(0); + + // parse calculator PID + calcPid = Long.parseLong(pidStr.split("=", 2)[1]); + + // Check whether the termination of third party application launcher + // also terminating the launched third party application + // If third party application is not terminated the test is + // successful else failure + Optional processHandle = ProcessHandle.of(calcPid); + boolean isAlive = processHandle.isPresent() + && processHandle.get().isAlive(); + System.out.println("Is Alive " + isAlive); + TKit.assertTrue(isAlive, "Check is calculator process is alive"); + } finally { + // Kill only a specific calculator instance + Runtime.getRuntime().exec("taskkill /F /PID " + calcPid); + } + } +} \ No newline at end of file From c703d290425f85a06e61d72c9672ac2adac92db9 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 12 Jul 2024 05:56:53 +0000 Subject: [PATCH 064/401] 8335710: serviceability/dcmd/vm/SystemDumpMapTest.java and SystemMapTest.java fail on Linux Alpine after 8322475 Reviewed-by: stuefe, lucy --- .../jtreg/serviceability/dcmd/vm/SystemMapTestBase.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/dcmd/vm/SystemMapTestBase.java b/test/hotspot/jtreg/serviceability/dcmd/vm/SystemMapTestBase.java index 000e977a590e5..3d1284b09eeee 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/vm/SystemMapTestBase.java +++ b/test/hotspot/jtreg/serviceability/dcmd/vm/SystemMapTestBase.java @@ -49,8 +49,8 @@ public class SystemMapTestBase { regexBase_committed + "/bin/java", // libjvm regexBase_committed + "/lib/.*/libjvm.so", - // vdso library, should be part of all user space apps on all architectures OpenJDK supports. - regexBase_committed + "\\[vdso\\]", + // heap segment, should be part of all user space apps on all architectures OpenJDK supports. + regexBase_committed + "\\[heap\\]", // we should see the hs-perf data file, and it should appear as shared as well as committed regexBase_shared_and_committed + "hsperfdata_.*" }; From 1fe3ada001e188754df5de00bf6804f028ad274b Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Fri, 12 Jul 2024 08:14:56 +0000 Subject: [PATCH 065/401] 8336284: Test TestClhsdbJstackLock.java/TestJhsdbJstackLock.java fails with -Xcomp after JDK-8335743 Reviewed-by: cjplummer, amenkov --- test/hotspot/jtreg/serviceability/sa/TestClhsdbJstackLock.java | 2 +- test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/sa/TestClhsdbJstackLock.java b/test/hotspot/jtreg/serviceability/sa/TestClhsdbJstackLock.java index e4d4361e6512b..266b14167ef4e 100644 --- a/test/hotspot/jtreg/serviceability/sa/TestClhsdbJstackLock.java +++ b/test/hotspot/jtreg/serviceability/sa/TestClhsdbJstackLock.java @@ -59,7 +59,7 @@ public static void main (String... args) throws Exception { "^\\s+- waiting to lock <0x[0-9a-f]+> \\(a java\\.lang\\.Class for LingeredAppWithLock\\)$", "^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Thread\\)$", "^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Class for int\\)$", - "^\\s+- waiting on <0x[0-9a-f]+> \\(a java\\.lang\\.Object\\)$")); + "^\\s+- waiting on (<0x[0-9a-f]+> \\(a java\\.lang\\.Object\\)|)$")); unExpStrMap.put("jstack", List.of( "missing reason for ")); test.run(app.getPid(), cmds, expStrMap, unExpStrMap); diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java index 98c4286609178..d3c7f61103165 100644 --- a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java +++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLock.java @@ -65,7 +65,7 @@ public static void main (String... args) throws Exception { out.shouldMatch("^\\s+- waiting to lock <0x[0-9a-f]+> \\(a java\\.lang\\.Class for LingeredAppWithLock\\)$"); out.shouldMatch("^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Thread\\)$"); out.shouldMatch("^\\s+- locked <0x[0-9a-f]+> \\(a java\\.lang\\.Class for int\\)$"); - out.shouldMatch("^\\s+- waiting on <0x[0-9a-f]+> \\(a java\\.lang\\.Object\\)$"); + out.shouldMatch("^\\s+- waiting on (<0x[0-9a-f]+> \\(a java\\.lang\\.Object\\)|)$"); out.stderrShouldBeEmptyIgnoreDeprecatedWarnings(); From f677b90eb93026d3fdfd4ae19d48415a7d8318e8 Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Fri, 12 Jul 2024 08:19:24 +0000 Subject: [PATCH 066/401] 8267887: RMIConnector_NPETest.java fails after removal of RMI Activation (JDK-8267123) Reviewed-by: cjplummer, sspitsyn --- test/jdk/ProblemList.txt | 2 - .../connection/RMIConnector_NPETest.java | 77 ------------------- 2 files changed, 79 deletions(-) delete mode 100644 test/jdk/javax/management/remote/mandatory/connection/RMIConnector_NPETest.java diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 20dfcef539de3..05e42b4933046 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -528,8 +528,6 @@ javax/management/MBeanServer/OldMBeanServerTest.java 8030957 aix-all javax/management/monitor/DerivedGaugeMonitorTest.java 8042211 generic-all -javax/management/remote/mandatory/connection/RMIConnector_NPETest.java 8267887 generic-all - javax/management/remote/mandatory/connection/BrokenConnectionTest.java 8262312 linux-all ############################################################################ diff --git a/test/jdk/javax/management/remote/mandatory/connection/RMIConnector_NPETest.java b/test/jdk/javax/management/remote/mandatory/connection/RMIConnector_NPETest.java deleted file mode 100644 index 29a91a464c713..0000000000000 --- a/test/jdk/javax/management/remote/mandatory/connection/RMIConnector_NPETest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2010, 2016, 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 - * @summary NPE IN RMIConnector.connect - * @bug 6984520 - * @library /java/rmi/testlibrary - * @modules java.management.rmi - * java.rmi/sun.rmi.registry - * java.rmi/sun.rmi.server - * java.rmi/sun.rmi.transport - * java.rmi/sun.rmi.transport.tcp - * @run clean RMIConnector_NPETest - * @run build TestLibrary RMID - * @run build RMIConnector_NPETest - * @run main RMIConnector_NPETest - */ -import java.io.IOException; -import javax.management.*; -import javax.management.remote.rmi.*; - -public class RMIConnector_NPETest { - public static void main(String argv[]) throws Exception { - RMID rmid = RMID.createRMID(); - Exception failureCause = null; - RMIConnector agent = null; - - try { - rmid.start(); - int rmidPort = rmid.getPort(); - MBeanServer mbs = MBeanServerFactory.createMBeanServer(); - RMIJRMPServerImpl rmiserver = new RMIJRMPServerImpl(rmidPort, null, null, null); - rmiserver.setMBeanServer(mbs); - agent = new RMIConnector(rmiserver, null); - agent.connect(); - } catch (NullPointerException npe) { - failureCause = npe; - } catch (Exception e) { - // OK - } finally { - if (agent != null) { - try { - agent.close(); - } catch (IOException e) { - // ignore - } - } - rmid.destroy(); - } - - if (failureCause != null) { - TestLibrary.bomb("Test failed", failureCause); - } - - } -} From 7a6203296416268f1c3f269d0db2b0c817642a34 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Fri, 12 Jul 2024 09:30:38 +0000 Subject: [PATCH 067/401] 8336081: Fix -Wzero-as-null-pointer-constant warnings in JVMTypedFlagLimit ctors Reviewed-by: dholmes, jwaters --- src/hotspot/share/runtime/flags/jvmFlagLimit.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/runtime/flags/jvmFlagLimit.hpp b/src/hotspot/share/runtime/flags/jvmFlagLimit.hpp index 69df96f226dd8..4a9c9c66d9b37 100644 --- a/src/hotspot/share/runtime/flags/jvmFlagLimit.hpp +++ b/src/hotspot/share/runtime/flags/jvmFlagLimit.hpp @@ -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 @@ -155,7 +155,7 @@ class JVMTypedFlagLimit : public JVMFlagLimit { // dummy - no range or constraint. This object will not be emitted into the .o file // because we declare it as "const" but has no reference to it. constexpr JVMTypedFlagLimit(int type_enum) : - JVMFlagLimit(0, 0, JVMFlagConstraintPhase::AtParse, 0), _min(0), _max(0) {} + JVMFlagLimit(0, 0, JVMFlagConstraintPhase::AtParse, 0), _min(), _max() {} // range only constexpr JVMTypedFlagLimit(int type_enum, T min, T max) : @@ -163,7 +163,7 @@ class JVMTypedFlagLimit : public JVMFlagLimit { // constraint only constexpr JVMTypedFlagLimit(int type_enum, ConstraintMarker dummy2, short func, JVMFlagConstraintPhase phase) : - JVMFlagLimit(type_enum, func, phase, HAS_CONSTRAINT), _min(0), _max(0) {} + JVMFlagLimit(type_enum, func, phase, HAS_CONSTRAINT), _min(), _max() {} // range and constraint constexpr JVMTypedFlagLimit(int type_enum, T min, T max, ConstraintMarker dummy2, short func, JVMFlagConstraintPhase phase) : From 9b6f6c5c9dd6d0fbb056e8d84c3a0888a3320edf Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Fri, 12 Jul 2024 09:33:04 +0000 Subject: [PATCH 068/401] 8336082: Fix -Wzero-as-null-pointer-constant warnings in SimpleCompactHashtable Reviewed-by: coleenp, dholmes --- .../share/classfile/compactHashtable.hpp | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/classfile/compactHashtable.hpp b/src/hotspot/share/classfile/compactHashtable.hpp index e99369cc5c376..6cb689ad20df6 100644 --- a/src/hotspot/share/classfile/compactHashtable.hpp +++ b/src/hotspot/share/classfile/compactHashtable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -204,18 +204,20 @@ class SimpleCompactHashtable { u4* _entries; public: - SimpleCompactHashtable() { - _entry_count = 0; - _bucket_count = 0; - _buckets = 0; - _entries = 0; - } + SimpleCompactHashtable() : + _base_address(nullptr), + _bucket_count(0), + _entry_count(0), + _buckets(nullptr), + _entries(nullptr) + {} void reset() { + _base_address = nullptr; _bucket_count = 0; _entry_count = 0; - _buckets = 0; - _entries = 0; + _buckets = nullptr; + _entries = nullptr; } void init(address base_address, u4 entry_count, u4 bucket_count, u4* buckets, u4* entries); From eec0e155f303ff4bbdab172765ca7c92c2b94cbd Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Fri, 12 Jul 2024 12:09:58 +0000 Subject: [PATCH 069/401] 8335619: Add an @apiNote to j.l.i.ClassFileTransformer to warn about recursive class loading and ClassCircularityErrors Reviewed-by: alanb, stuefe, liach --- .../lang/instrument/ClassFileTransformer.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java b/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java index d4c17f1cfdcf7..ee2037fac5bfb 100644 --- a/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java +++ b/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -155,11 +155,28 @@ * logging or debugging of format corruptions. * *

- * Note the term class file is used as defined in section 3.1 of - * The Java Virtual Machine Specification, to mean a - * sequence of bytes in class file format, whether or not they reside in a + * Note the term class file is used as defined in chapter {@jvms 4} The + * {@code class} File Format of The Java Virtual Machine Specification, + * to mean a sequence of bytes in class file format, whether or not they reside in a * file. * + * @apiNote + * Great care must be taken when transforming core JDK classes which are at the + * same time required during the transformation process as this can lead to class + * circularity or linkage errors. + * + *

+ * If for example the invocation of {@link #transform transform()} for a class + * {@code C} requires loading or resolving the same class {@code C}, + * an error is thrown that is an instance of {@link LinkageError} (or a subclass). + * If the {@link LinkageError} occurs during reference resolution (see section + * {@jvms 5.4.3} Resolution of The Java Virtual Machine Specification) + * for a class {@code D}, the resolution of the corresponding reference in class + * {@code D} will permanently fail with the same error at any subsequent attempt. + * This means that a {@link LinkageError} triggered during transformation of + * {@code C} in a class {@code D} not directly related to {@code C} can repeatedly + * occur later in arbitrary user code which uses {@code D}. + * * @see java.lang.instrument.Instrumentation * @since 1.5 */ From 559826c2922851dbe45ead23ad1d73b1846334ac Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Fri, 12 Jul 2024 12:17:21 +0000 Subject: [PATCH 070/401] 8332474: Tighten up ToolBox' JavacTask to not silently accept javac crash as a failure Reviewed-by: vromero --- .../com/sun/tools/javac/comp/Modules.java | 1 + .../tools/lib/toolbox/AbstractTask.java | 60 ++++++++++++++++--- .../tools/lib/toolbox/JavacTask.java | 20 +++++++ 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java index 1136cb5621a79..3d893252218b5 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java @@ -330,6 +330,7 @@ private void enterModule(JCCompilationUnit toplevel, ClassSymbol c, Set> implements Task { private final Map redirects = new EnumMap<>(OutputKind.class); private final Map envVars = new HashMap<>(); private Expect expect = Expect.SUCCESS; - int expectedExitCode = 0; + //validator for exit codes, first parameter is the exit code + //the second the test name: + private BiConsumer exitCodeValidator = null; /** * Create a task that will execute in the specified mode. @@ -67,7 +70,7 @@ protected AbstractTask(ToolBox tb, Mode mode) { * @return the result of calling {@code run()} */ public Result run(Expect expect) { - expect(expect, Integer.MIN_VALUE); + expect(expect, (_, _) -> {}); return run(); } @@ -83,17 +86,56 @@ public Result run(Expect expect, int exitCode) { return run(); } + /** + * Sets the expected outcome of the task and calls {@code run()}. + * @param expect the expected outcome + * @param exitCodeValidator an exit code validator. The first parameter will + * be the actual exit code, the second test name, + * should throw TaskError if the exit code is not + * as expected. Only used if the expected outcome + * is {@code FAIL} + * @return the result of calling {@code run()} + */ + public Result run(Expect expect, + BiConsumer exitCodeValidator) { + expect(expect, exitCodeValidator); + return run(); + } + + /** + * Sets the expected outcome and expected exit code of the task. + * The exit code will not be checked if the outcome is + * {@code Expect.SUCCESS} or if the exit code is set to + * {@code Integer.MIN_VALUE}. + * @param expect the expected outcome + * @param expectedExitCode the expected exit code + */ + protected void expect(Expect expect, int expectedExitCode) { + expect(expect, (exitCode, testName) -> { + if (expectedExitCode != Integer.MIN_VALUE && + exitCode != expectedExitCode) { + throw new TaskError("Task " + testName + "failed with unexpected exit code " + + exitCode + ", expected " + expectedExitCode); + } + }); + } + /** * Sets the expected outcome and expected exit code of the task. * The exit code will not be checked if the outcome is * {@code Expect.SUCCESS} or if the exit code is set to * {@code Integer.MIN_VALUE}. * @param expect the expected outcome - * @param exitCode the expected exit code + * @param exitCodeValidator an exit code validator. The first parameter will + * be the actual exit code, the second test name, + * should throw TaskError if the exit code is not + * as expected. Only used if the expected outcome + * is {@code FAIL} */ - protected void expect(Expect expect, int exitCode) { + protected void expect(Expect expect, + BiConsumer exitCodeValidator) { this.expect = expect; - this.expectedExitCode = exitCode; + this.exitCodeValidator = exitCodeValidator; } /** @@ -119,11 +161,11 @@ protected Result checkExit(Result result) throws TaskError { throw new TaskError("Task " + name() + " succeeded unexpectedly"); } - if (expectedExitCode != Integer.MIN_VALUE - && result.exitCode != expectedExitCode) { + try { + exitCodeValidator.accept(result.exitCode, name()); + } catch (Throwable t) { result.writeAll(); - throw new TaskError("Task " + name() + "failed with unexpected exit code " - + result.exitCode + ", expected " + expectedExitCode); + throw t; } break; } diff --git a/test/langtools/tools/lib/toolbox/JavacTask.java b/test/langtools/tools/lib/toolbox/JavacTask.java index 5991d9e6063bc..ed056099e84e3 100644 --- a/test/langtools/tools/lib/toolbox/JavacTask.java +++ b/test/langtools/tools/lib/toolbox/JavacTask.java @@ -314,6 +314,26 @@ public String name() { return "javac"; } + @Override + public Result run(Expect expect) { + int expectedExitCode = expect == Expect.SUCCESS ? 0 : 1; + + return run(expect, (exitCode, testName) -> { + if (exitCode == 4) { + throw new TaskError("Task " + testName + " failed due to a javac crash " + + "(exit code 4)"); + } + }); + } + + @Override + public Result run(Expect expect, int exitCode) { + if (exitCode == 4) { + throw new IllegalArgumentException("Disallowed exit code: 4"); + } + return super.run(expect, exitCode); + } + /** * Calls the compiler with the arguments as currently configured. * @return a Result object indicating the outcome of the compilation From 2fc7eb44a018974734832576a0a2631ae747e0cd Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 12 Jul 2024 12:37:58 +0000 Subject: [PATCH 071/401] 8155030: The Menu Mnemonics are always displayed for GTK LAF Hides mnemonics on menus, buttons, and labels for GTK L&F. Moved shared code for hiding mnemonics into sun/swing/MnemonicHandler and AltProcessor to avoid code duplication. Reviewed-by: prr, tr, achung, dnguyen, aivanov --- .../classes/com/apple/laf/AquaButtonUI.java | 7 +- .../classes/com/apple/laf/AquaLabelUI.java | 21 +-- .../com/apple/laf/AquaLookAndFeel.java | 11 +- .../com/apple/laf/AquaMenuPainter.java | 38 ++++-- .../java/swing/plaf/gtk/GTKGraphicsUtils.java | 21 ++- .../java/swing/plaf/gtk/GTKLookAndFeel.java | 70 ++++++++-- .../share/classes/sun/swing/AltProcessor.java | 67 ++++++++++ .../classes/sun/swing/MnemonicHandler.java} | 100 ++++++--------- .../plaf/windows/WindowsGraphicsUtils.java | 75 ++++------- .../swing/plaf/windows/WindowsLabelUI.java | 7 +- .../plaf/windows/WindowsLookAndFeel.java | 42 +----- .../swing/plaf/windows/WindowsMenuBarUI.java | 6 +- .../swing/plaf/windows/WindowsMenuItemUI.java | 5 +- .../plaf/windows/WindowsPopupMenuUI.java | 9 +- .../swing/plaf/windows/WindowsRootPaneUI.java | 36 +++--- .../swing/JMenuBar/TestMenuMnemonic.java | 8 +- .../JMenuBar/TestMenuMnemonicLinuxAndMac.java | 121 ++++++++++++++++++ .../javax/swing/LookAndFeel/bug4736093.java | 12 +- .../plaf/windows/6921687/bug6921687.java | 11 +- 19 files changed, 428 insertions(+), 239 deletions(-) create mode 100644 src/java.desktop/share/classes/sun/swing/AltProcessor.java rename src/java.desktop/{macosx/classes/com/apple/laf/AquaMnemonicHandler.java => share/classes/sun/swing/MnemonicHandler.java} (52%) create mode 100644 test/jdk/javax/swing/JMenuBar/TestMenuMnemonicLinuxAndMac.java diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonUI.java index dab893252cfdb..063923ff80754 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonUI.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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,6 +75,7 @@ import com.apple.laf.AquaUtilControlSize.Sizeable; import com.apple.laf.AquaUtils.RecyclableSingleton; import com.apple.laf.AquaUtils.RecyclableSingletonFromDefaultConstructor; +import sun.swing.MnemonicHandler; import sun.swing.SwingUtilities2; public class AquaButtonUI extends BasicButtonUI implements Sizeable { @@ -487,12 +488,10 @@ protected void paintIcon(final Graphics g, final AbstractButton b, final Rectang * Use the paintText method which takes the AbstractButton argument. */ protected void paintText(final Graphics g, final JComponent c, final Rectangle localTextRect, final String text) { - final Graphics2D g2d = g instanceof Graphics2D ? (Graphics2D)g : null; - final AbstractButton b = (AbstractButton)c; final ButtonModel model = b.getModel(); final FontMetrics fm = g.getFontMetrics(); - final int mnemonicIndex = AquaMnemonicHandler.isMnemonicHidden() ? -1 : b.getDisplayedMnemonicIndex(); + final int mnemonicIndex = MnemonicHandler.isMnemonicHidden() ? -1 : b.getDisplayedMnemonicIndex(); /* Draw the Text */ if (model.isEnabled()) { diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaLabelUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaLabelUI.java index fb5682d05413e..e0f282325e412 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaLabelUI.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaLabelUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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,16 +25,19 @@ package com.apple.laf; -import java.awt.*; +import java.awt.Color; +import java.awt.Graphics; -import javax.swing.*; -import javax.swing.plaf.*; -import javax.swing.plaf.basic.*; - -import sun.swing.SwingUtilities2; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicLabelUI; import com.apple.laf.AquaUtils.RecyclableSingleton; import com.apple.laf.AquaUtils.RecyclableSingletonFromDefaultConstructor; +import sun.swing.MnemonicHandler; +import sun.swing.SwingUtilities2; public class AquaLabelUI extends BasicLabelUI { private static final RecyclableSingleton aquaLabelUI = new RecyclableSingletonFromDefaultConstructor(AquaLabelUI.class); @@ -55,7 +58,7 @@ protected void uninstallListeners(final JLabel c) { protected void paintEnabledText(final JLabel l, final Graphics g, final String s, final int textX, final int textY) { int mnemIndex = l.getDisplayedMnemonicIndex(); - if (AquaMnemonicHandler.isMnemonicHidden()) { + if (MnemonicHandler.isMnemonicHidden()) { mnemIndex = -1; } @@ -72,7 +75,7 @@ protected void paintEnabledText(final JLabel l, final Graphics g, final String s */ protected void paintDisabledText(final JLabel l, final Graphics g, final String s, final int textX, final int textY) { int accChar = l.getDisplayedMnemonicIndex(); - if (AquaMnemonicHandler.isMnemonicHidden()) { + if (MnemonicHandler.isMnemonicHidden()) { accChar = -1; } diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java index d68cd1448eaa9..83604e5d835cd 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -55,6 +55,8 @@ import apple.laf.JRSUIControl; import apple.laf.JRSUIUtils; +import sun.swing.AltProcessor; +import sun.swing.MnemonicHandler; import sun.swing.SwingAccessor; import sun.swing.SwingUtilities2; @@ -174,7 +176,9 @@ public Void run() { spf.setActive(true); PopupFactory.setSharedInstance(spf); - KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor(AquaMnemonicHandler.getInstance()); + KeyboardFocusManager.getCurrentKeyboardFocusManager() + .addKeyEventPostProcessor(AltProcessor.getInstance()); + MnemonicHandler.setMnemonicHidden(true); } /** @@ -185,7 +189,8 @@ public Void run() { * @see #initialize */ public void uninitialize() { - KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventPostProcessor(AquaMnemonicHandler.getInstance()); + KeyboardFocusManager.getCurrentKeyboardFocusManager() + .removeKeyEventPostProcessor(AltProcessor.getInstance()); final PopupFactory popupFactory = PopupFactory.getSharedInstance(); if (popupFactory instanceof ScreenPopupFactory spf) { diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuPainter.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuPainter.java index 5a13822fd5acd..8f1a6799ff6b6 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuPainter.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuPainter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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,21 +25,39 @@ package com.apple.laf; -import java.awt.*; -import java.awt.event.*; - -import javax.swing.*; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; + +import javax.swing.ButtonModel; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.KeyStroke; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.plaf.basic.BasicHTML; import javax.swing.text.View; -import sun.swing.SwingUtilities2; - -import apple.laf.JRSUIConstants.*; - +import apple.laf.JRSUIConstants.State; +import apple.laf.JRSUIConstants.Widget; import com.apple.laf.AquaIcon.InvertableIcon; import com.apple.laf.AquaUtils.RecyclableSingleton; import com.apple.laf.AquaUtils.RecyclableSingletonFromDefaultConstructor; +import sun.swing.MnemonicHandler; +import sun.swing.SwingUtilities2; /** * AquaMenuPainter, implements paintMenuItem to avoid code duplication @@ -287,7 +305,7 @@ protected void paintMenuItem(final Client client, final Graphics g, final JCompo if (v != null) { v.paint(g, textRect); } else { - final int mnemonic = (AquaMnemonicHandler.isMnemonicHidden() ? -1 : model.getMnemonic()); + final int mnemonic = (MnemonicHandler.isMnemonicHidden() ? -1 : model.getMnemonic()); drawString(g, c, text, mnemonic, textRect.x, textRect.y + fm.getAscent(), isEnabled, isSelected); } } diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKGraphicsUtils.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKGraphicsUtils.java index 0ef404593f592..2a0aa7be41c45 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKGraphicsUtils.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKGraphicsUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2017, 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 @@ -24,12 +24,19 @@ */ package com.sun.java.swing.plaf.gtk; -import javax.swing.*; -import javax.swing.plaf.synth.*; import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; +import javax.swing.AbstractButton; +import javax.swing.JComponent; +import javax.swing.plaf.synth.Region; +import javax.swing.plaf.synth.SynthConstants; +import javax.swing.plaf.synth.SynthContext; +import javax.swing.plaf.synth.SynthGraphicsUtils; + +import sun.swing.MnemonicHandler; + /** * @author Joshua Outwater */ @@ -49,6 +56,11 @@ public void paintText(SynthContext context, Graphics g, String text, int componentState = context.getComponentState(); String themeName = GTKLookAndFeel.getGtkThemeName(); + + if (MnemonicHandler.isMnemonicHidden()) { + mnemonicIndex = -1; + } + if (themeName != null && themeName.startsWith("blueprint") && shouldShadowText(context.getRegion(), componentState)) { @@ -115,7 +127,8 @@ public void paintText(SynthContext context, Graphics g, String text, g.setColor(color); } } - super.paintText(context, g, text, bounds, mnemonicIndex); + super.paintText(context, g, text, bounds, + MnemonicHandler.isMnemonicHidden() ? -1 : mnemonicIndex); } private static boolean shouldShadowText(Region id, int state) { diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java index 65f29ea8384fe..93ba22d8dd3da 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java @@ -25,28 +25,50 @@ package com.sun.java.swing.plaf.gtk; -import java.awt.*; -import java.beans.*; -import java.io.File; -import java.lang.ref.*; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Insets; +import java.awt.KeyboardFocusManager; +import java.awt.Toolkit; +import java.awt.Window; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Locale; -import javax.swing.*; -import javax.swing.colorchooser.*; -import javax.swing.plaf.*; -import javax.swing.plaf.synth.*; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.JComponent; +import javax.swing.JTextField; +import javax.swing.LayoutStyle; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.UIDefaults; +import javax.swing.UIManager; +import javax.swing.colorchooser.AbstractColorChooserPanel; +import javax.swing.plaf.BorderUIResource; +import javax.swing.plaf.ColorUIResource; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.DimensionUIResource; +import javax.swing.plaf.InsetsUIResource; +import javax.swing.plaf.synth.Region; +import javax.swing.plaf.synth.SynthConstants; +import javax.swing.plaf.synth.SynthLookAndFeel; +import javax.swing.plaf.synth.SynthStyleFactory; import javax.swing.text.DefaultEditorKit; import com.sun.java.swing.plaf.gtk.GTKConstants.PositionType; import com.sun.java.swing.plaf.gtk.GTKConstants.StateType; -import java.util.HashMap; -import java.util.Map; import sun.awt.SunToolkit; import sun.awt.UNIXToolkit; -import sun.awt.OSInfo; import sun.security.action.GetPropertyAction; +import sun.swing.AltProcessor; import sun.swing.DefaultLayoutStyle; +import sun.swing.MnemonicHandler; import sun.swing.SwingAccessor; import sun.swing.SwingUtilities2; @@ -866,7 +888,6 @@ public Object createValue(UIDefaults table) { "ctrl released ENTER", "release" }, - "ScrollBar.squareButtons", Boolean.FALSE, "ScrollBar.thumbHeight", Integer.valueOf(14), "ScrollBar.width", Integer.valueOf(16), @@ -1414,6 +1435,10 @@ static boolean isLeftToRight(Component c) { return c.getComponentOrientation().isLeftToRight(); } + /** + * {@inheritDoc} + */ + @Override public void initialize() { /* * We need to call loadGTK() to ensure that the native GTK @@ -1456,6 +1481,23 @@ public void initialize() { gtkAAFontSettingsCond = SwingUtilities2.isLocalDisplay(); aaTextInfo = new HashMap<>(2); SwingUtilities2.putAATextInfo(gtkAAFontSettingsCond, aaTextInfo); + + KeyboardFocusManager.getCurrentKeyboardFocusManager() + .addKeyEventPostProcessor(AltProcessor.getInstance()); + + // By default mnemonics are hidden for GTK L&F + MnemonicHandler.setMnemonicHidden(true); + } + + /** + * {@inheritDoc} + */ + @Override + public void uninitialize() { + KeyboardFocusManager.getCurrentKeyboardFocusManager() + .removeKeyEventPostProcessor(AltProcessor.getInstance()); + MnemonicHandler.setMnemonicHidden(false); + super.uninitialize(); } static ReferenceQueue queue = new ReferenceQueue(); diff --git a/src/java.desktop/share/classes/sun/swing/AltProcessor.java b/src/java.desktop/share/classes/sun/swing/AltProcessor.java new file mode 100644 index 0000000000000..c7bb7b3d4102e --- /dev/null +++ b/src/java.desktop/share/classes/sun/swing/AltProcessor.java @@ -0,0 +1,67 @@ +/* + * 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 sun.swing; + +import java.awt.KeyEventPostProcessor; +import java.awt.Window; +import java.awt.event.KeyEvent; + +import javax.swing.JRootPane; +import javax.swing.SwingUtilities; + +public final class AltProcessor implements KeyEventPostProcessor { + + private AltProcessor() {} + + private static final AltProcessor altProcessor = new AltProcessor(); + + public static KeyEventPostProcessor getInstance() { + return altProcessor; + } + + @Override + public boolean postProcessKeyEvent(final KeyEvent ev) { + if (ev.getKeyCode() != KeyEvent.VK_ALT) { + return false; + } + + final JRootPane root = SwingUtilities.getRootPane(ev.getComponent()); + final Window winAncestor = (root == null ? null : SwingUtilities.getWindowAncestor(root)); + + switch (ev.getID()) { + case KeyEvent.KEY_PRESSED: + MnemonicHandler.setMnemonicHidden(false); + break; + case KeyEvent.KEY_RELEASED: + MnemonicHandler.setMnemonicHidden(true); + break; + } + + MnemonicHandler.repaintMnemonicsInWindow(winAncestor); + + return false; + } +} diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaMnemonicHandler.java b/src/java.desktop/share/classes/sun/swing/MnemonicHandler.java similarity index 52% rename from src/java.desktop/macosx/classes/com/apple/laf/AquaMnemonicHandler.java rename to src/java.desktop/share/classes/sun/swing/MnemonicHandler.java index 76c9735882807..b4f0cac7c611a 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaMnemonicHandler.java +++ b/src/java.desktop/share/classes/sun/swing/MnemonicHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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,39 +23,27 @@ * questions. */ -package com.apple.laf; +package sun.swing; -import java.awt.*; -import java.awt.event.KeyEvent; +import java.awt.Component; +import java.awt.Container; +import java.awt.Window; -import javax.swing.*; +import javax.swing.AbstractButton; +import javax.swing.JLabel; +import javax.swing.UIManager; -import com.apple.laf.AquaUtils.RecyclableSingleton; -import com.apple.laf.AquaUtils.RecyclableSingletonFromDefaultConstructor; +public final class MnemonicHandler { -public class AquaMnemonicHandler { - private static final RecyclableSingleton altProcessor = new RecyclableSingletonFromDefaultConstructor(AltProcessor.class); - public static KeyEventPostProcessor getInstance() { - return altProcessor.get(); - } + private static boolean isMnemonicHidden; - protected static boolean isMnemonicHidden = true; // true by default - - public static void setMnemonicHidden(final boolean hide) { - if (UIManager.getBoolean("Button.showMnemonics")) { - // Do not hide mnemonics if the UI defaults do not support this - isMnemonicHidden = false; - } else { - isMnemonicHidden = hide; - } - } + private MnemonicHandler() {} /** - * Gets the state of the hide mnemonic flag. This only has meaning if this feature is supported by the underlying OS. + * Gets the state of the hide mnemonic flag. + * This only has meaning if this feature is supported by the underlying OS. * * @return true if mnemonics are hidden, otherwise, false - * @see #setMnemonicHidden - * @since 1.4 */ public static boolean isMnemonicHidden() { if (UIManager.getBoolean("Button.showMnemonics")) { @@ -65,34 +53,27 @@ public static boolean isMnemonicHidden() { return isMnemonicHidden; } - static class AltProcessor implements KeyEventPostProcessor { - public boolean postProcessKeyEvent(final KeyEvent ev) { - if (ev.getKeyCode() != KeyEvent.VK_ALT) { - return false; - } - - final JRootPane root = SwingUtilities.getRootPane(ev.getComponent()); - final Window winAncestor = (root == null ? null : SwingUtilities.getWindowAncestor(root)); - - switch(ev.getID()) { - case KeyEvent.KEY_PRESSED: - setMnemonicHidden(false); - break; - case KeyEvent.KEY_RELEASED: - setMnemonicHidden(true); - break; - } - - repaintMnemonicsInWindow(winAncestor); - - return false; + /** + * Sets the state of the hide mnemonic flag. This flag is used by the + * component UI delegates to determine if the mnemonic should be rendered. + * This method is a non operation if the underlying operating system + * does not support the mnemonic hiding feature. + * + * @param hide true if mnemonics should be hidden + */ + public static void setMnemonicHidden(final boolean hide) { + if (UIManager.getBoolean("Button.showMnemonics")) { + // Do not hide mnemonics if the UI defaults do not support this + isMnemonicHidden = false; + } else { + isMnemonicHidden = hide; } } - /* + /** * Repaints all the components with the mnemonics in the given window and all its owned windows. */ - static void repaintMnemonicsInWindow(final Window w) { + public static void repaintMnemonicsInWindow(final Window w) { if (w == null || !w.isShowing()) { return; } @@ -105,29 +86,22 @@ static void repaintMnemonicsInWindow(final Window w) { repaintMnemonicsInContainer(w); } - /* + /** * Repaints all the components with the mnemonics in container. * Recursively searches for all the subcomponents. */ - static void repaintMnemonicsInContainer(final Container cont) { - for (int i = 0; i < cont.getComponentCount(); i++) { - final Component c = cont.getComponent(i); + private static void repaintMnemonicsInContainer(final Container cont) { + final Component[] elements = cont.getComponents(); + for (final Component c : elements) { if (c == null || !c.isVisible()) { continue; } - if (c instanceof AbstractButton && ((AbstractButton)c).getMnemonic() != '\0') { - c.repaint(); - continue; - } - - if (c instanceof JLabel && ((JLabel)c).getDisplayedMnemonic() != '\0') { + if ((c instanceof AbstractButton b && b.getMnemonic() != '\0') + || (c instanceof JLabel l && l.getDisplayedMnemonic() != '\0')) { c.repaint(); - continue; - } - - if (c instanceof Container) { - repaintMnemonicsInContainer((Container)c); + } else if (c instanceof Container) { + repaintMnemonicsInContainer((Container) c); } } } diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsGraphicsUtils.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsGraphicsUtils.java index ff38130f728e5..cb4b5caa86de9 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsGraphicsUtils.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsGraphicsUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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,14 +25,31 @@ package com.sun.java.swing.plaf.windows; -import sun.swing.SwingUtilities2; - -import java.awt.*; - -import javax.swing.*; +import java.awt.Color; +import java.awt.Component; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Rectangle; + +import javax.swing.AbstractButton; +import javax.swing.ButtonModel; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JRadioButton; +import javax.swing.JToggleButton; +import javax.swing.UIManager; import javax.swing.plaf.UIResource; -import static com.sun.java.swing.plaf.windows.TMSchema.*; +import sun.swing.MnemonicHandler; +import sun.swing.SwingUtilities2; + +import static com.sun.java.swing.plaf.windows.TMSchema.Part; +import static com.sun.java.swing.plaf.windows.TMSchema.Prop; +import static com.sun.java.swing.plaf.windows.TMSchema.State; +import static com.sun.java.swing.plaf.windows.TMSchema.TypeEnum; /** * A collection of static utility methods used for rendering the Windows look @@ -60,7 +77,7 @@ public static void paintText(Graphics g, AbstractButton b, int mnemIndex = b.getDisplayedMnemonicIndex(); // W2K Feature: Check to see if the Underscore should be rendered. - if (WindowsLookAndFeel.isMnemonicHidden() == true) { + if (MnemonicHandler.isMnemonicHidden()) { mnemIndex = -1; } @@ -191,46 +208,4 @@ static boolean isLeftToRight(Component c) { return c.getComponentOrientation().isLeftToRight(); } - /* - * Repaints all the components with the mnemonics in the given window and - * all its owned windows. - */ - static void repaintMnemonicsInWindow(Window w) { - if(w == null || !w.isShowing()) { - return; - } - - Window[] ownedWindows = w.getOwnedWindows(); - for(int i=0;i

Provides classfile parsing, generation, and transformation library.

* The {@code java.lang.classfile} package contains classes for reading, writing, and - * modifying Java class files, as specified in Chapter {@jvms 4} of the Java - * Java Virtual Machine Specification. + * modifying Java class files, as specified in Chapter {@jvms 4} of the + * Java Virtual Machine Specification. * *

Reading classfiles

* The main class for reading classfiles is {@link java.lang.classfile.ClassModel}; we From 9695f09581bac856ad97943cca15c65dc21d2adf Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Thu, 8 Aug 2024 16:11:08 +0000 Subject: [PATCH 353/401] 8337683: Fix -Wconversion problem with arrayOop.hpp Reviewed-by: stefank, dholmes --- src/hotspot/share/oops/arrayOop.hpp | 18 +++++++++--------- src/hotspot/share/runtime/atomic.hpp | 5 +++-- src/hotspot/share/utilities/byteswap.hpp | 3 ++- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/oops/arrayOop.hpp b/src/hotspot/share/oops/arrayOop.hpp index 0aa26500bd8d2..1ca8a9530a48c 100644 --- a/src/hotspot/share/oops/arrayOop.hpp +++ b/src/hotspot/share/oops/arrayOop.hpp @@ -68,10 +68,10 @@ class arrayOopDesc : public oopDesc { // The header is considered the oop part of this type plus the length. // This is not equivalent to sizeof(arrayOopDesc) which should not appear in the code. static int header_size_in_bytes() { - size_t hs = length_offset_in_bytes() + sizeof(int); + int hs = length_offset_in_bytes() + (int)sizeof(int); #ifdef ASSERT // make sure it isn't called before UseCompressedOops is initialized. - static size_t arrayoopdesc_hs = 0; + static int arrayoopdesc_hs = 0; if (arrayoopdesc_hs == 0) arrayoopdesc_hs = hs; assert(arrayoopdesc_hs == hs, "header size can't change"); #endif // ASSERT @@ -83,13 +83,13 @@ class arrayOopDesc : public oopDesc { // it occupies the second half of the _klass field in oopDesc. static int length_offset_in_bytes() { return UseCompressedClassPointers ? klass_gap_offset_in_bytes() : - sizeof(arrayOopDesc); + (int)sizeof(arrayOopDesc); } // Returns the offset of the first element. static int base_offset_in_bytes(BasicType type) { - size_t hs = header_size_in_bytes(); - return (int)(element_type_should_be_aligned(type) ? align_up(hs, BytesPerLong) : hs); + int hs = header_size_in_bytes(); + return element_type_should_be_aligned(type) ? align_up(hs, BytesPerLong) : hs; } // Returns the address of the first element. The elements in the array will not @@ -134,14 +134,14 @@ class arrayOopDesc : public oopDesc { assert(type < T_CONFLICT, "wrong type"); assert(type2aelembytes(type) != 0, "wrong type"); - size_t hdr_size_in_bytes = base_offset_in_bytes(type); + int hdr_size_in_bytes = base_offset_in_bytes(type); // This is rounded-up and may overlap with the first array elements. - size_t hdr_size_in_words = align_up(hdr_size_in_bytes, HeapWordSize) / HeapWordSize; + int hdr_size_in_words = align_up(hdr_size_in_bytes, HeapWordSize) / HeapWordSize; const size_t max_element_words_per_size_t = - align_down((SIZE_MAX/HeapWordSize - hdr_size_in_words), MinObjAlignment); + align_down((SIZE_MAX/HeapWordSize - (size_t)hdr_size_in_words), MinObjAlignment); const size_t max_elements_per_size_t = - HeapWordSize * max_element_words_per_size_t / type2aelembytes(type); + HeapWordSize * max_element_words_per_size_t / (size_t)type2aelembytes(type); if ((size_t)max_jint < max_elements_per_size_t) { // It should be ok to return max_jint here, but parts of the code // (CollectedHeap, Klass::oop_oop_iterate(), and more) uses an int for diff --git a/src/hotspot/share/runtime/atomic.hpp b/src/hotspot/share/runtime/atomic.hpp index 399a78fd3fce1..bf198b5f5621f 100644 --- a/src/hotspot/share/runtime/atomic.hpp +++ b/src/hotspot/share/runtime/atomic.hpp @@ -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 @@ -31,6 +31,7 @@ #include "runtime/orderAccess.hpp" #include "utilities/align.hpp" #include "utilities/bytes.hpp" +#include "utilities/checkedCast.hpp" #include "utilities/macros.hpp" #include @@ -1118,7 +1119,7 @@ inline T Atomic::CmpxchgByteUsingInt::operator()(T volatile* dest, uint8_t canon_compare_value = compare_value; volatile uint32_t* aligned_dest = reinterpret_cast(align_down(dest, sizeof(uint32_t))); - size_t offset = pointer_delta(dest, aligned_dest, 1); + uint32_t offset = checked_cast(pointer_delta(dest, aligned_dest, 1)); uint32_t idx = (Endian::NATIVE == Endian::BIG) ? (sizeof(uint32_t) - 1 - offset) diff --git a/src/hotspot/share/utilities/byteswap.hpp b/src/hotspot/share/utilities/byteswap.hpp index fba0775cf4992..9c3b53630b39b 100644 --- a/src/hotspot/share/utilities/byteswap.hpp +++ b/src/hotspot/share/utilities/byteswap.hpp @@ -26,6 +26,7 @@ #define SHARE_UTILITIES_BYTESWAP_HPP #include "metaprogramming/enableIf.hpp" +#include "utilities/checkedCast.hpp" #include "utilities/globalDefinitions.hpp" #include @@ -63,7 +64,7 @@ struct ByteswapFallbackImpl; template struct ByteswapFallbackImpl { inline constexpr uint16_t operator()(uint16_t x) const { - return (((x & UINT16_C(0x00ff)) << 8) | ((x & UINT16_C(0xff00)) >> 8)); + return checked_cast(((x & UINT16_C(0x00ff)) << 8) | ((x & UINT16_C(0xff00)) >> 8)); } }; From 53c9f037fb2805aab5ab9729166ce7d5bc7a77f9 Mon Sep 17 00:00:00 2001 From: Jiangli Zhou Date: Thu, 8 Aug 2024 16:31:02 +0000 Subject: [PATCH 354/401] 8336849: Remove .llvm_addrsig section from JDK/VM static libraries (.a files) Reviewed-by: ihse --- make/common/native/Link.gmk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/make/common/native/Link.gmk b/make/common/native/Link.gmk index 2090218ffbb34..ca03c6ee6b12f 100644 --- a/make/common/native/Link.gmk +++ b/make/common/native/Link.gmk @@ -109,6 +109,11 @@ define CreateStaticLibrary $(if $$($1_LINK_OBJS_RELATIVE), $$(CD) $$(OUTPUTDIR) ; ) \ $$($1_LD) $(LDFLAGS_CXX_PARTIAL_LINKING) $$($1_SYSROOT_LDFLAGS) \ -o $$($1_TARGET_RELOCATABLE) $$($1_LD_OBJ_ARG)) + # 'ld -r' might invalidate the .llvm_addrsig section, and this will cause subsequent + # calls to lld (with '-Wl,--icf=safe') to fail when linking with this library, so + # remove that section. + $$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_objcopy_remove_llvm_addrsig_section, \ + $$($1_OBJCOPY) --remove-section=.llvm_addrsig $$($1_TARGET_RELOCATABLE)) endif $$(call ExecuteWithLog, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_run_ar, \ $(if $$($1_LINK_OBJS_RELATIVE), $$(CD) $$(OUTPUTDIR) ; ) \ From bfb75b96266f4c5840e2edea13f9aa2c801518cf Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Thu, 8 Aug 2024 16:53:38 +0000 Subject: [PATCH 355/401] 8336926: jdk/internal/util/ReferencedKeyTest.java can fail with ConcurrentModificationException Reviewed-by: bpb, shade, dfuchs --- .../jdk/internal/util/ReferencedKeyMap.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/util/ReferencedKeyMap.java b/src/java.base/share/classes/jdk/internal/util/ReferencedKeyMap.java index 9c364cd781350..810d43ae38a3a 100644 --- a/src/java.base/share/classes/jdk/internal/util/ReferencedKeyMap.java +++ b/src/java.base/share/classes/jdk/internal/util/ReferencedKeyMap.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 @@ -219,8 +219,14 @@ public boolean containsValue(Object value) { @Override public V get(Object key) { - Objects.requireNonNull(key, "key must not be null"); removeStaleReferences(); + return getNoCheckStale(key); + } + + // Internal get(key) without removing stale references that would modify the keyset. + // Use when iterating or streaming over the keys to avoid ConcurrentModificationException. + private V getNoCheckStale(Object key) { + Objects.requireNonNull(key, "key must not be null"); return map.get(lookupKey(key)); } @@ -291,7 +297,7 @@ public Collection values() { public Set> entrySet() { removeStaleReferences(); return filterKeySet() - .map(k -> new AbstractMap.SimpleEntry<>(k, get(k))) + .map(k -> new AbstractMap.SimpleEntry<>(k, getNoCheckStale(k))) .collect(Collectors.toSet()); } @@ -335,7 +341,7 @@ public V replace(K key, V value) { public String toString() { removeStaleReferences(); return filterKeySet() - .map(k -> k + "=" + get(k)) + .map(k -> k + "=" + getNoCheckStale(k)) .collect(Collectors.joining(", ", "{", "}")); } From e7a0b5b09bcfcd8b09667e51ec588e206f0652ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Thu, 8 Aug 2024 18:45:11 +0000 Subject: [PATCH 356/401] 8334780: Crash: assert(h_array_list.not_null()) failed: invariant Reviewed-by: egahlin, shade --- src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp b/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp index cd47630228931..0c2fb0206ecee 100644 --- a/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp +++ b/src/hotspot/share/jfr/support/jfrJdkJfrEvent.cpp @@ -136,7 +136,9 @@ jobject JdkJfrEvent::get_all_klasses(TRAPS) { transform_klasses_to_local_jni_handles(event_subklasses, THREAD); Handle h_array_list(THREAD, new_java_util_arraylist(THREAD)); - assert(h_array_list.not_null(), "invariant"); + if (h_array_list.is_null()) { + return empty_java_util_arraylist; + } static const char add_method_name[] = "add"; static const char add_method_signature[] = "(Ljava/lang/Object;)Z"; From 9f08a01cb6ebb08f67749aabdff4efaedfaf3228 Mon Sep 17 00:00:00 2001 From: Leonid Mesnik Date: Thu, 8 Aug 2024 19:47:50 +0000 Subject: [PATCH 357/401] 8338010: WB_IsFrameDeoptimized miss ResourceMark Reviewed-by: dholmes, shade --- src/hotspot/share/prims/whitebox.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index 6ee33a6107998..544eeabb5c212 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -799,6 +799,7 @@ WB_END WB_ENTRY(jboolean, WB_IsFrameDeoptimized(JNIEnv* env, jobject o, jint depth)) bool result = false; if (thread->has_last_Java_frame()) { + ResourceMark rm(THREAD); RegisterMap reg_map(thread, RegisterMap::UpdateMap::include, RegisterMap::ProcessFrames::include, From 55c509708e9b89a7609fd41b6e5a271f250bbacd Mon Sep 17 00:00:00 2001 From: Jiawei Tang Date: Fri, 9 Aug 2024 02:29:15 +0000 Subject: [PATCH 358/401] 8337331: crash: pinned virtual thread will lead to jvm crash when running with the javaagent option Reviewed-by: dholmes, sspitsyn --- src/hotspot/share/prims/jvmtiExport.cpp | 10 +-- .../TestPinCaseWithCFLH.java | 77 +++++++++++++++++++ 2 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 test/hotspot/jtreg/serviceability/jvmti/vthread/TestPinCaseWithCFLH/TestPinCaseWithCFLH.java diff --git a/src/hotspot/share/prims/jvmtiExport.cpp b/src/hotspot/share/prims/jvmtiExport.cpp index f79116f5ebeb0..95cc54d93134f 100644 --- a/src/hotspot/share/prims/jvmtiExport.cpp +++ b/src/hotspot/share/prims/jvmtiExport.cpp @@ -929,9 +929,8 @@ class JvmtiClassFileLoadHookPoster : public StackObj { _cached_class_file_ptr = cache_ptr; _has_been_modified = false; - if (_thread->is_in_any_VTMS_transition()) { - return; // no events should be posted if thread is in any VTMS transition - } + assert(!_thread->is_in_any_VTMS_transition(), "CFLH events are not allowed in any VTMS transition"); + _state = JvmtiExport::get_jvmti_thread_state(_thread); if (_state != nullptr) { _class_being_redefined = _state->get_class_being_redefined(); @@ -1091,8 +1090,9 @@ bool JvmtiExport::post_class_file_load_hook(Symbol* h_name, if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) { return false; } - if (JavaThread::current()->is_in_tmp_VTMS_transition()) { - return false; // skip CFLH events in tmp VTMS transition + + if (JavaThread::current()->is_in_any_VTMS_transition()) { + return false; // no events should be posted if thread is in any VTMS transition } JvmtiClassFileLoadHookPoster poster(h_name, class_loader, diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/TestPinCaseWithCFLH/TestPinCaseWithCFLH.java b/test/hotspot/jtreg/serviceability/jvmti/vthread/TestPinCaseWithCFLH/TestPinCaseWithCFLH.java new file mode 100644 index 0000000000000..02755a0289fc1 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/TestPinCaseWithCFLH/TestPinCaseWithCFLH.java @@ -0,0 +1,77 @@ +/* + * 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.lang.instrument.ClassFileTransformer; +import java.lang.instrument.IllegalClassFormatException; +import java.lang.instrument.Instrumentation; +import java.security.ProtectionDomain; +import jdk.test.lib.thread.VThreadPinner; + +/* + * @test + * @summary javaagent + tracePinnedThreads will cause jvm crash/ run into deadlock when the virtual thread is pinned + * @library /test/lib + * @requires vm.continuations + * @requires vm.jvmti + * @modules java.base/java.lang:+open + * @compile TestPinCaseWithCFLH.java + * @build jdk.test.lib.Utils + * @run driver jdk.test.lib.util.JavaAgentBuilder + * TestPinCaseWithCFLH TestPinCaseWithCFLH.jar + * @run main/othervm/timeout=100 -Djdk.virtualThreadScheduler.maxPoolSize=1 + * -Djdk.tracePinnedThreads=full --enable-native-access=ALL-UNNAMED + * -javaagent:TestPinCaseWithCFLH.jar TestPinCaseWithCFLH + */ +public class TestPinCaseWithCFLH { + + public static class TestClassFileTransformer implements ClassFileTransformer { + public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, + ProtectionDomain protectionDomain, byte[] classfileBuffer) + throws IllegalClassFormatException { + return classfileBuffer; + } + } + + // Called when agent is loaded at startup + public static void premain(String agentArgs, Instrumentation instrumentation) throws Exception { + instrumentation.addTransformer(new TestClassFileTransformer()); + } + + private static int result = 0; + + public static void main(String[] args) throws Exception{ + Thread t1 = Thread.ofVirtual().name("vthread-1").start(() -> { + VThreadPinner.runPinned(() -> { + try { + // try yield, will pin, + // javaagent + tracePinnedThreads should not lead to crash + // (because of the class `PinnedThreadPrinter`) + Thread.sleep(500); + } catch (Exception e) { + e.printStackTrace(); + } + }); + }); + t1.join(); + } + +} \ No newline at end of file From 0c1e9111d226b601236b9826e27ecc67a8b625fb Mon Sep 17 00:00:00 2001 From: Gui Cao Date: Fri, 9 Aug 2024 02:59:37 +0000 Subject: [PATCH 359/401] 8338019: Fix simple -Wzero-as-null-pointer-constant warnings in riscv code Reviewed-by: fyang, mli, luhenry --- src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp | 2 +- src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp | 2 +- src/hotspot/cpu/riscv/frame_riscv.cpp | 2 +- src/hotspot/cpu/riscv/nativeInst_riscv.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp index 798679185d3a2..3d146b87707aa 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp @@ -542,7 +542,7 @@ void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmi insn = &MacroAssembler::sw; break; case T_OBJECT: // fall through case T_ARRAY: - assert(c->as_jobject() == 0, "should be"); + assert(c->as_jobject() == nullptr, "should be"); if (UseCompressedOops && !wide) { insn = &MacroAssembler::sw; } else { diff --git a/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp index 9fa8939837a85..e999b703b3e7b 100644 --- a/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_Runtime1_riscv.cpp @@ -1066,4 +1066,4 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { #undef __ -const char *Runtime1::pd_name_for_address(address entry) { Unimplemented(); return 0; } +const char *Runtime1::pd_name_for_address(address entry) { Unimplemented(); } diff --git a/src/hotspot/cpu/riscv/frame_riscv.cpp b/src/hotspot/cpu/riscv/frame_riscv.cpp index 32825a02c5eac..96dca4704ad95 100644 --- a/src/hotspot/cpu/riscv/frame_riscv.cpp +++ b/src/hotspot/cpu/riscv/frame_riscv.cpp @@ -269,7 +269,7 @@ void frame::patch_pc(Thread* thread, address pc) { // Either the return address is the original one or we are going to // patch in the same address that's already there. - assert(_pc == pc_old || pc == pc_old || pc_old == 0, "must be"); + assert(_pc == pc_old || pc == pc_old || pc_old == nullptr, "must be"); DEBUG_ONLY(address old_pc = _pc;) *pc_addr = pc; _pc = pc; // must be set before call to get_deopt_original_pc diff --git a/src/hotspot/cpu/riscv/nativeInst_riscv.cpp b/src/hotspot/cpu/riscv/nativeInst_riscv.cpp index f0357f1cd3029..6c9e0986869b6 100644 --- a/src/hotspot/cpu/riscv/nativeInst_riscv.cpp +++ b/src/hotspot/cpu/riscv/nativeInst_riscv.cpp @@ -685,7 +685,7 @@ address NativeJump::jump_destination() const { // load // return -1 if jump to self or to 0 - if ((dest == (address) this) || dest == 0) { + if ((dest == (address) this) || dest == nullptr) { dest = (address) -1; } @@ -714,7 +714,7 @@ address NativeGeneralJump::jump_destination() const { // a general jump // return -1 if jump to self or to 0 - if ((dest == (address) this) || dest == 0) { + if ((dest == (address) this) || dest == nullptr) { dest = (address) -1; } From 9ab8c6b9ba90ffd12600a250c8704571e9feb78d Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 9 Aug 2024 05:09:27 +0000 Subject: [PATCH 360/401] 8335130: The test "javax/swing/plaf/synth/ComponentsOrientationSupport/5033822/bug5033822.java" fails because the background color of the tabs is displayed incorrectly. Reviewed-by: achung, psadhukhan --- .../sun/java/swing/plaf/gtk/GTKPainter.java | 34 ++++++++-------- .../swing/plaf/nimbus/SynthPainterImpl.java | 39 ++++++++++--------- .../swing/plaf/synth/SynthTabbedPaneUI.java | 8 +--- 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java index 4787696a367eb..ea27a2a6e0d9b 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java @@ -935,25 +935,27 @@ public void paintTabbedPaneTabBackground(SynthContext context, Graphics g, int x, int y, int w, int h, int tabIndex) { - Region id = context.getRegion(); - int state = context.getComponentState(); - int gtkState = ((state & SynthConstants.SELECTED) != 0 ? - SynthConstants.ENABLED : SynthConstants.PRESSED); JTabbedPane pane = (JTabbedPane)context.getComponent(); - int placement = pane.getTabPlacement(); + if (UIManager.getBoolean("TabbedPane.tabsOpaque") || pane.isOpaque()) { + Region id = context.getRegion(); + int state = context.getComponentState(); + int gtkState = ((state & SynthConstants.SELECTED) != 0 ? + SynthConstants.ENABLED : SynthConstants.PRESSED); + int placement = pane.getTabPlacement(); - // Fill the tab rect area - g.fillRect(x, y, w, h); + // Fill the tab rect area + g.fillRect(x, y, w, h); - synchronized (UNIXToolkit.GTK_LOCK) { - if (! ENGINE.paintCachedImage(g, x, y, w, h, - id, gtkState, placement, tabIndex)) { - PositionType side = POSITIONS[placement - 1]; - ENGINE.startPainting(g, x, y, w, h, - id, gtkState, placement, tabIndex); - ENGINE.paintExtension(g, context, id, gtkState, - ShadowType.OUT, "tab", x, y, w, h, side, tabIndex); - ENGINE.finishPainting(); + synchronized (UNIXToolkit.GTK_LOCK) { + if (!ENGINE.paintCachedImage(g, x, y, w, h, + id, gtkState, placement, tabIndex)) { + PositionType side = POSITIONS[placement - 1]; + ENGINE.startPainting(g, x, y, w, h, + id, gtkState, placement, tabIndex); + ENGINE.paintExtension(g, context, id, gtkState, + ShadowType.OUT, "tab", x, y, w, h, side, tabIndex); + ENGINE.finishPainting(); + } } } } diff --git a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java index c990c968ff6fa..9dfd422f6dddb 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java @@ -2098,24 +2098,27 @@ public void paintTabbedPaneTabBackground(SynthContext context, Graphics g, public void paintTabbedPaneTabBackground(SynthContext context, Graphics g, int x, int y, int w, int h, int tabIndex, int orientation) { - if (orientation == JTabbedPane.LEFT) { - AffineTransform transform = new AffineTransform(); - transform.scale(-1, 1); - transform.rotate(Math.toRadians(90)); - paintBackground(context, g, y, x, h, w, transform); - } else if (orientation == JTabbedPane.RIGHT) { - AffineTransform transform = new AffineTransform(); - transform.rotate(Math.toRadians(90)); - transform.translate(0, -(x + w)); - paintBackground(context, g, y, 0, h, w, transform); - } else if (orientation == JTabbedPane.BOTTOM) { - AffineTransform transform = new AffineTransform(); - transform.translate(x,y); - transform.scale(1, -1); - transform.translate(0,-h); - paintBackground(context, g, 0, 0, w, h, transform); - } else { - paintBackground(context, g, x, y, w, h, null); + JTabbedPane pane = (JTabbedPane)context.getComponent(); + if (UIManager.getBoolean("TabbedPane.tabsOpaque") || pane.isOpaque()) { + if (orientation == JTabbedPane.LEFT) { + AffineTransform transform = new AffineTransform(); + transform.scale(-1, 1); + transform.rotate(Math.toRadians(90)); + paintBackground(context, g, y, x, h, w, transform); + } else if (orientation == JTabbedPane.RIGHT) { + AffineTransform transform = new AffineTransform(); + transform.rotate(Math.toRadians(90)); + transform.translate(0, -(x + w)); + paintBackground(context, g, y, 0, h, w, transform); + } else if (orientation == JTabbedPane.BOTTOM) { + AffineTransform transform = new AffineTransform(); + transform.translate(x, y); + transform.scale(1, -1); + transform.translate(0, -h); + paintBackground(context, g, 0, 0, w, h, transform); + } else { + paintBackground(context, g, x, y, w, h, null); + } } } diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java index 837c4d8298f9e..3378ef9e8b3de 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java @@ -127,7 +127,6 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI // Background color for unselected tabs private Color unselectedBackground; private boolean contentOpaque = true; - private boolean tabsOpaque = true; /** * @@ -156,7 +155,6 @@ private boolean scrollableTabLayoutEnabled() { protected void installDefaults() { selectColor = UIManager.getColor("TabbedPane.selected"); contentOpaque = UIManager.getBoolean("TabbedPane.contentOpaque"); - tabsOpaque = UIManager.getBoolean("TabbedPane.tabsOpaque"); unselectedBackground = UIManager.getColor("TabbedPane.unselectedBackground"); updateStyle(tabPane); } @@ -655,10 +653,8 @@ private void paintTab(SynthContext ss, Graphics g, g.setColor(getUnselectedBackgroundAt(tabIndex)); } - if (tabsOpaque || tabPane.isOpaque()) { - tabContext.getPainter().paintTabbedPaneTabBackground(tabContext, g, - x, y, width, height, tabIndex, placement); - } + tabContext.getPainter().paintTabbedPaneTabBackground(tabContext, g, + x, y, width, height, tabIndex, placement); tabContext.getPainter().paintTabbedPaneTabBorder(tabContext, g, x, y, width, height, tabIndex, placement); From 00aac4097abd3c5e6144734cfd44228bc31892fb Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 9 Aug 2024 06:26:22 +0000 Subject: [PATCH 361/401] 8338058: map_or_reserve_memory_aligned Windows enhance remap assertion Reviewed-by: mdoerr, clanger --- src/hotspot/os/windows/os_windows.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 1cc7d9aa33adf..65ba13b0d9e81 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -3463,6 +3463,7 @@ static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int fi } assert(aligned_base != nullptr, "Did not manage to re-map after %d attempts?", max_attempts); + assert(aligned_base != nullptr, "Did not manage to re-map after %d attempts (size %zu, alignment %zu, file descriptor %d)", max_attempts, size, alignment, file_desc); return aligned_base; } From c01f53ac2dab1d4d2cd1e4d45a67f9373d4a9c7e Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Fri, 9 Aug 2024 07:17:59 +0000 Subject: [PATCH 362/401] 8337876: [IR Framework] Add support for IR tests with @Stable Reviewed-by: shade, kvn --- .../jtreg/compiler/lib/ir_framework/README.md | 11 ++- .../lib/ir_framework/TestFramework.java | 13 +++- .../ir_framework/driver/TestVMProcess.java | 15 ++-- .../tests/TestPhaseIRMatching.java | 2 +- .../tests/TestPrivilegedMode.java | 69 +++++++++++++++++++ 5 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPrivilegedMode.java diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md index 3f6e0d4163faa..55d9fcbaecead 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/README.md +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/README.md @@ -157,7 +157,16 @@ The framework allows the use of additional compiler control annotations for help - [@ForceCompile](./ForceCompile.java) - [@ForceCompileClassInitializer](./ForceCompileClassInitializer.java) -### 2.5 Framework Debug and Stress Flags +### 2.5 IR Tests with Privileged Classes +To run tests in a privileged mode (e.g. when using `@Stable`, `@Contended`, `@ReservedStackAccess` etc.), one need to add the test classes to the boot classpath. This can easily be achieved by calling `TestFramework.addTestClassesToBootClassPath()` on the test framework object: +``` +TestFramework testFramework = new TestFramework(); +testFramework + .addTestClassesToBootClassPath() + .start(); +``` + +### 2.6 Framework Debug and Stress Flags The framework provides various stress and debug flags. They should mainly be used as JTreg VM and/or Javaoptions (apart from `VerifyIR`). The following (property) flags are supported: - `-DVerifyIR=false`: Explicitly disable IR verification. This is useful, for example, if some scenarios use VM flags that let `@IR` annotation rules fail and the user does not want to provide separate IR rules or add flag preconditions to the already existing IR rules. diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java index 67fadbc4eac31..d477aa44763fa 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/TestFramework.java @@ -172,6 +172,7 @@ public class TestFramework { private Set scenarioIndices; private List flags; private int defaultWarmup = -1; + private boolean testClassesOnBootClassPath; /* * Public interface methods @@ -323,6 +324,15 @@ public TestFramework addScenarios(Scenario... scenarios) { return this; } + /** + * Add test classes to boot classpath. This adds all classes found on path {@link jdk.test.lib.Utils#TEST_CLASSES} + * to the boot classpath with "-Xbootclasspath/a". This is useful when trying to run tests in a privileged mode. + */ + public TestFramework addTestClassesToBootClassPath() { + this.testClassesOnBootClassPath = true; + return this; + } + /** * Start the testing of the implicitly (by {@link #TestFramework()}) or explicitly (by {@link #TestFramework(Class)}) * set test class. @@ -744,7 +754,8 @@ private boolean onlyWhitelistedJTregVMAndJavaOptsFlags() { } private void runTestVM(List additionalFlags) { - TestVMProcess testVMProcess = new TestVMProcess(additionalFlags, testClass, helperClasses, defaultWarmup); + TestVMProcess testVMProcess = new TestVMProcess(additionalFlags, testClass, helperClasses, defaultWarmup, + testClassesOnBootClassPath); if (shouldVerifyIR) { try { TestClassParser testClassParser = new TestClassParser(testClass); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java index 04f8096d96917..8c168b73260cf 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/driver/TestVMProcess.java @@ -34,6 +34,7 @@ import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; +import java.io.File; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -63,11 +64,12 @@ public class TestVMProcess { private OutputAnalyzer oa; private String irEncoding; - public TestVMProcess(List additionalFlags, Class testClass, Set> helperClasses, int defaultWarmup) { + public TestVMProcess(List additionalFlags, Class testClass, Set> helperClasses, int defaultWarmup, + boolean testClassesOnBootClassPath) { this.cmds = new ArrayList<>(); TestFrameworkSocket socket = new TestFrameworkSocket(); try (socket) { - prepareTestVMFlags(additionalFlags, socket, testClass, helperClasses, defaultWarmup); + prepareTestVMFlags(additionalFlags, socket, testClass, helperClasses, defaultWarmup, testClassesOnBootClassPath); start(); } processSocketOutput(socket); @@ -91,11 +93,16 @@ public static String getLastTestVMOutput() { } private void prepareTestVMFlags(List additionalFlags, TestFrameworkSocket socket, Class testClass, - Set> helperClasses, int defaultWarmup) { + Set> helperClasses, int defaultWarmup, boolean testClassesOnBootClassPath) { // Set java.library.path so JNI tests which rely on jtreg nativepath setting work cmds.add("-Djava.library.path=" + Utils.TEST_NATIVE_PATH); // Need White Box access in test VM. - cmds.add("-Xbootclasspath/a:."); + String bootClassPath = "-Xbootclasspath/a:."; + if (testClassesOnBootClassPath) { + // Add test classes themselves to boot classpath to make them privileged. + bootClassPath += File.pathSeparator + Utils.TEST_CLASSES; + } + cmds.add(bootClassPath); cmds.add("-XX:+UnlockDiagnosticVMOptions"); cmds.add("-XX:+WhiteBoxAPI"); // Ignore CompileCommand flags which have an impact on the profiling information. diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java index 9a39fb5310f35..f0056ebc79da9 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java @@ -66,7 +66,7 @@ private static void run(Class testClass) { List noAdditionalFlags = new ArrayList<>(); FlagVMProcess flagVMProcess = new FlagVMProcess(testClass, noAdditionalFlags); List testVMFlags = flagVMProcess.getTestVMFlags(); - TestVMProcess testVMProcess = new TestVMProcess(testVMFlags, testClass, null, -1); + TestVMProcess testVMProcess = new TestVMProcess(testVMFlags, testClass, null, -1, false); TestClassParser testClassParser = new TestClassParser(testClass); Matchable testClassMatchable = testClassParser.parse(testVMProcess.getHotspotPidFileName(), testVMProcess.getIrEncoding()); diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPrivilegedMode.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPrivilegedMode.java new file mode 100644 index 0000000000000..347b2eb39fbfc --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPrivilegedMode.java @@ -0,0 +1,69 @@ +/* + * 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 ir_framework.tests; + +import compiler.lib.ir_framework.*; +import compiler.lib.ir_framework.driver.irmatching.IRViolationException; + +import jdk.internal.vm.annotation.Stable; +import jdk.test.lib.Asserts; + +/* + * @test + * @requires vm.flagless + * @summary Test that IR framework successfully adds test class to boot classpath in order to run in privileged mode. + * @modules java.base/jdk.internal.vm.annotation + * @library /test/lib / + * @run driver ir_framework.tests.TestPrivilegedMode + */ + +public class TestPrivilegedMode { + static @Stable int iFld; // Treated as constant after first being set. + + public static void main(String[] args) { + try { + TestFramework.run(); + Asserts.fail("should not reach"); + } catch (IRViolationException e) { + // Without adding test class to boot classpath, we fail to replace the field load by a constant. + Asserts.assertTrue(e.getExceptionInfo().contains("Matched forbidden node")); + Asserts.assertTrue(e.getExceptionInfo().contains("LoadI")); + } + + // When adding the test class to the boot classpath, we can replace the field load by a constant. + new TestFramework().addTestClassesToBootClassPath().start(); + } + + @Test + @Arguments(setup = "setup") + @IR(failOn = IRNode.LOAD_I) + public int test() { + return iFld; + } + + @Setup + public void setup() { + iFld = 34; + } +} From 82d5768c1bdccfaf97a41f32a8bfcfd03a0fb378 Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Fri, 9 Aug 2024 07:20:01 +0000 Subject: [PATCH 363/401] 8337840: Remove redundant null check in ObjectOutputStream.writeProxyDesc Reviewed-by: rriggs --- src/java.base/share/classes/java/io/ObjectOutputStream.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/io/ObjectOutputStream.java b/src/java.base/share/classes/java/io/ObjectOutputStream.java index 2dcf174cf5399..3650b10135356 100644 --- a/src/java.base/share/classes/java/io/ObjectOutputStream.java +++ b/src/java.base/share/classes/java/io/ObjectOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -1272,7 +1272,7 @@ private void writeProxyDesc(ObjectStreamClass desc, boolean unshared) } bout.setBlockDataMode(true); - if (cl != null && isCustomSubclass()) { + if (isCustomSubclass()) { ReflectUtil.checkPackageAccess(cl); } annotateProxyClass(cl); From f74109bd178c92a9dff1ca6fce03b25f51a0384f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Sikstr=C3=B6m?= Date: Fri, 9 Aug 2024 07:29:56 +0000 Subject: [PATCH 364/401] 8337939: ZGC: Make assertions and checks less convoluted and explicit Reviewed-by: stefank, ayang, eosterlund --- src/hotspot/share/gc/z/zAddress.cpp | 6 ++-- src/hotspot/share/gc/z/zAddress.inline.hpp | 30 +++++++++++++++---- src/hotspot/share/gc/z/zBarrier.inline.hpp | 6 ++-- src/hotspot/share/gc/z/zBarrierSet.inline.hpp | 4 +-- src/hotspot/share/gc/z/zHeapIterator.cpp | 2 +- src/hotspot/share/gc/z/zMark.cpp | 4 +-- src/hotspot/share/gc/z/zMark.inline.hpp | 4 +-- src/hotspot/share/gc/z/zPage.inline.hpp | 2 +- .../share/gc/z/zReferenceProcessor.cpp | 4 +-- src/hotspot/share/gc/z/zVerify.cpp | 24 +++++++++------ 10 files changed, 55 insertions(+), 31 deletions(-) diff --git a/src/hotspot/share/gc/z/zAddress.cpp b/src/hotspot/share/gc/z/zAddress.cpp index d1c199fad070c..1cd33e44a05d1 100644 --- a/src/hotspot/share/gc/z/zAddress.cpp +++ b/src/hotspot/share/gc/z/zAddress.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -93,9 +93,7 @@ static void initialize_check_oop_function() { #ifdef CHECK_UNHANDLED_OOPS if (ZVerifyOops) { // Enable extra verification of usages of oops in oopsHierarchy.hpp - check_oop_function = [](oopDesc* obj) { - (void)to_zaddress(obj); - }; + check_oop_function = &check_is_valid_zaddress; } #endif } diff --git a/src/hotspot/share/gc/z/zAddress.inline.hpp b/src/hotspot/share/gc/z/zAddress.inline.hpp index 4adbf50bc86c6..bbc92a7e2aaf3 100644 --- a/src/hotspot/share/gc/z/zAddress.inline.hpp +++ b/src/hotspot/share/gc/z/zAddress.inline.hpp @@ -333,10 +333,22 @@ inline void dereferenceable_test(zaddress addr) { } #endif -inline zaddress to_zaddress(uintptr_t value) { - const zaddress addr = zaddress(value); +inline void check_is_valid_zaddress(zaddress addr) { assert_is_valid(addr); DEBUG_ONLY(dereferenceable_test(addr)); +} + +inline void check_is_valid_zaddress(uintptr_t value) { + check_is_valid_zaddress(zaddress(value)); +} + +inline void check_is_valid_zaddress(oopDesc* o) { + check_is_valid_zaddress(uintptr_t(o)); +} + +inline zaddress to_zaddress(uintptr_t value) { + const zaddress addr = zaddress(value); + check_is_valid_zaddress(addr); return addr; } @@ -344,7 +356,7 @@ inline zaddress to_zaddress(oopDesc* o) { return to_zaddress(uintptr_t(o)); } -inline oop to_oop(zaddress addr) { +inline void assert_is_oop_or_null(zaddress addr) { const oop obj = cast_to_oop(addr); assert(!ZVerifyOops || oopDesc::is_oop_or_null(obj), "Broken oop: " PTR_FORMAT " [" PTR_FORMAT " " PTR_FORMAT " " PTR_FORMAT " " PTR_FORMAT "]", p2i(obj), @@ -352,7 +364,16 @@ inline oop to_oop(zaddress addr) { *(uintptr_t*)(untype(addr) + 0x08), *(uintptr_t*)(untype(addr) + 0x10), *(uintptr_t*)(untype(addr) + 0x18)); - return obj; +} + +inline void assert_is_oop(zaddress addr) { + assert(!is_null(addr), "Should not be null"); + assert_is_oop_or_null(addr); +} + +inline oop to_oop(zaddress addr) { + assert_is_oop_or_null(addr); + return cast_to_oop(addr); } inline zaddress operator+(zaddress addr, size_t size) { @@ -378,7 +399,6 @@ inline void assert_is_valid(zaddress_unsafe addr) { DEBUG_ONLY(is_valid(addr, true /* assert_on_failure */);) } - inline uintptr_t untype(zaddress_unsafe addr) { return static_cast(addr); } diff --git a/src/hotspot/share/gc/z/zBarrier.inline.hpp b/src/hotspot/share/gc/z/zBarrier.inline.hpp index b3191e9ae3f7a..a3eb7a9ca67d6 100644 --- a/src/hotspot/share/gc/z/zBarrier.inline.hpp +++ b/src/hotspot/share/gc/z/zBarrier.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -745,7 +745,7 @@ inline void ZBarrier::mark_and_remember(volatile zpointer* p, zaddress addr) { template inline void ZBarrier::mark(zaddress addr) { - assert(!ZVerifyOops || oopDesc::is_oop(to_oop(addr), false), "must be oop"); + assert_is_oop(addr); if (ZHeap::heap()->is_old(addr)) { ZGeneration::old()->mark_object_if_active(addr); @@ -757,7 +757,7 @@ inline void ZBarrier::mark(zaddress addr) { template inline void ZBarrier::mark_young(zaddress addr) { assert(ZGeneration::young()->is_phase_mark(), "Should only be called during marking"); - assert(!ZVerifyOops || oopDesc::is_oop(to_oop(addr), false), "must be oop"); + assert_is_oop(addr); assert(ZHeap::heap()->is_young(addr), "Must be young"); ZGeneration::young()->mark_object(addr); diff --git a/src/hotspot/share/gc/z/zBarrierSet.inline.hpp b/src/hotspot/share/gc/z/zBarrierSet.inline.hpp index d53b69345dd98..174cdfd9e909d 100644 --- a/src/hotspot/share/gc/z/zBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/z/zBarrierSet.inline.hpp @@ -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 @@ -430,7 +430,7 @@ class ZLoadBarrierOopClosure : public BasicOopIterateClosure { template inline void ZBarrierSet::AccessBarrier::clone_in_heap(oop src, oop dst, size_t size) { - assert_is_valid(to_zaddress(src)); + check_is_valid_zaddress(src); if (dst->is_objArray()) { // Cloning an object array is similar to performing array copy. diff --git a/src/hotspot/share/gc/z/zHeapIterator.cpp b/src/hotspot/share/gc/z/zHeapIterator.cpp index 50fc921131fe7..e149a976add92 100644 --- a/src/hotspot/share/gc/z/zHeapIterator.cpp +++ b/src/hotspot/share/gc/z/zHeapIterator.cpp @@ -146,7 +146,7 @@ class ZHeapIteratorUncoloredRootOopClosure : public OopClosure { oop load_oop(oop* p) { const oop o = Atomic::load(p); - assert_is_valid(to_zaddress(o)); + check_is_valid_zaddress(o); return RawAccess<>::oop_load(p); } diff --git a/src/hotspot/share/gc/z/zMark.cpp b/src/hotspot/share/gc/z/zMark.cpp index eb342495f5799..d33b86c83e57c 100644 --- a/src/hotspot/share/gc/z/zMark.cpp +++ b/src/hotspot/share/gc/z/zMark.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -365,7 +365,7 @@ void ZMark::follow_array_object(objArrayOop obj, bool finalizable) { } // Should be convertible to colorless oop - assert_is_valid(to_zaddress(obj)); + check_is_valid_zaddress(obj); zpointer* const addr = (zpointer*)obj->base(); const size_t length = (size_t)obj->length(); diff --git a/src/hotspot/share/gc/z/zMark.inline.hpp b/src/hotspot/share/gc/z/zMark.inline.hpp index b530259361027..9edc57a60002e 100644 --- a/src/hotspot/share/gc/z/zMark.inline.hpp +++ b/src/hotspot/share/gc/z/zMark.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -47,7 +47,7 @@ template inline void ZMark::mark_object(zaddress addr) { - assert(!ZVerifyOops || oopDesc::is_oop(to_oop(addr)), "Should be oop"); + assert_is_oop(addr); ZPage* const page = _page_table->get(addr); if (page->is_allocating()) { diff --git a/src/hotspot/share/gc/z/zPage.inline.hpp b/src/hotspot/share/gc/z/zPage.inline.hpp index fcf69c685f7b6..d8ecad571907c 100644 --- a/src/hotspot/share/gc/z/zPage.inline.hpp +++ b/src/hotspot/share/gc/z/zPage.inline.hpp @@ -311,7 +311,7 @@ inline bool ZPage::mark_object(zaddress addr, bool finalizable, bool& inc_live) assert(is_in(addr), "Invalid address"); // Verify oop - (void)to_oop(addr); + assert_is_oop(addr); // Set mark bit const BitMap::idx_t index = bit_index(addr); diff --git a/src/hotspot/share/gc/z/zReferenceProcessor.cpp b/src/hotspot/share/gc/z/zReferenceProcessor.cpp index df8cb2b0e959f..1252de2ac2723 100644 --- a/src/hotspot/share/gc/z/zReferenceProcessor.cpp +++ b/src/hotspot/share/gc/z/zReferenceProcessor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -143,7 +143,7 @@ bool ZReferenceProcessor::is_inactive(zaddress reference, oop referent, Referenc return !is_null(reference_next(reference)); } else { // Verification - (void)to_zaddress(referent); + check_is_valid_zaddress(referent); // A non-FinalReference is inactive if the referent is null. The referent can only // be null if the application called Reference.enqueue() or Reference.clear(). diff --git a/src/hotspot/share/gc/z/zVerify.cpp b/src/hotspot/share/gc/z/zVerify.cpp index d47886ec7c2fc..b735965e9d49b 100644 --- a/src/hotspot/share/gc/z/zVerify.cpp +++ b/src/hotspot/share/gc/z/zVerify.cpp @@ -111,6 +111,16 @@ static bool z_is_null_relaxed(zpointer o) { return (untype(o) & ~color_mask) == 0; } +static void z_verify_oop_object(zaddress addr, zpointer o, void* p) { + const oop obj = cast_to_oop(addr); + guarantee(oopDesc::is_oop(obj), BAD_OOP_ARG(o, p)); +} + +static void z_verify_root_oop_object(zaddress addr, void* p) { + const oop obj = cast_to_oop(addr); + guarantee(oopDesc::is_oop(obj), BAD_OOP_ARG(addr, p)); +} + static void z_verify_old_oop(zpointer* p) { const zpointer o = *p; assert(o != zpointer::null, "Old should not contain raw null"); @@ -121,7 +131,7 @@ static void z_verify_old_oop(zpointer* p) { // safepoint after reference processing, where we hold the driver lock and // know there is no concurrent remembered set processing in the young generation. const zaddress addr = ZPointer::uncolor(o); - guarantee(oopDesc::is_oop(to_oop(addr)), BAD_OOP_ARG(o, p)); + z_verify_oop_object(addr, o, p); } else { const zaddress addr = ZBarrier::load_barrier_on_oop_field_preloaded(nullptr, o); // Old to young pointers might not be mark good if the young @@ -143,15 +153,11 @@ static void z_verify_young_oop(zpointer* p) { guarantee(ZPointer::is_marked_young(o), BAD_OOP_ARG(o, p)); if (ZPointer::is_load_good(o)) { - guarantee(oopDesc::is_oop(to_oop(ZPointer::uncolor(o))), BAD_OOP_ARG(o, p)); + z_verify_oop_object(ZPointer::uncolor(o), o, p); } } } -static void z_verify_root_oop_object(zaddress o, void* p) { - guarantee(oopDesc::is_oop(to_oop(o)), BAD_OOP_ARG(o, p)); -} - static void z_verify_uncolored_root_oop(zaddress* p) { assert(!ZHeap::heap()->is_in((uintptr_t)p), "Roots shouldn't be in heap"); const zaddress o = *p; @@ -168,7 +174,7 @@ static void z_verify_possibly_weak_oop(zpointer* p) { const zaddress addr = ZBarrier::load_barrier_on_oop_field_preloaded(nullptr, o); guarantee(ZHeap::heap()->is_old(addr) || ZPointer::is_marked_young(o), BAD_OOP_ARG(o, p)); guarantee(ZHeap::heap()->is_young(addr) || ZHeap::heap()->is_object_live(addr), BAD_OOP_ARG(o, p)); - guarantee(oopDesc::is_oop(to_oop(addr)), BAD_OOP_ARG(o, p)); + z_verify_oop_object(addr, o, p); // Verify no missing remset entries. We are holding the driver lock here and that // allows us to more precisely verify the remembered set, as there is no concurrent @@ -211,14 +217,14 @@ class ZVerifyColoredRootClosure : public OopClosure { // Minor collections could have relocated the object; // use load barrier to find correct object. const zaddress addr = ZBarrier::load_barrier_on_oop_field_preloaded(nullptr, o); - z_verify_root_oop_object(addr, p); + z_verify_oop_object(addr, o, p); } else { // Don't know the state of the oop if (is_valid(o)) { // it looks like a valid colored oop; // use load barrier to find correct object. const zaddress addr = ZBarrier::load_barrier_on_oop_field_preloaded(nullptr, o); - z_verify_root_oop_object(addr, p); + z_verify_oop_object(addr, o, p); } } } From 53fce38a3ff8700fef640fffc066efc21ff9c25f Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 9 Aug 2024 07:53:15 +0000 Subject: [PATCH 365/401] 8338062: JFR: Remove TestStartDuration.java and TestStartName.java from ProblemList.txt Reviewed-by: mgronlun --- test/jdk/ProblemList.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 8aedbc7793116..293d9d108d32c 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -745,8 +745,6 @@ jdk/incubator/vector/LoadJsvmlTest.java 8305390 windows- # jdk_jfr jdk/jfr/event/runtime/TestResidentSetSizeEvent.java 8309846 aix-ppc64 -jdk/jfr/startupargs/TestStartName.java 8214685 windows-x64 -jdk/jfr/startupargs/TestStartDuration.java 8214685 windows-x64 jdk/jfr/jvm/TestWaste.java 8282427 generic-all ############################################################################ From 6ebd5d74d57b334e7cf0b1282d7bb469a56fb3d6 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Fri, 9 Aug 2024 08:23:44 +0000 Subject: [PATCH 366/401] 8338036: Serial: Remove Generation::update_counters Reviewed-by: kbarrett --- src/hotspot/share/gc/serial/generation.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hotspot/share/gc/serial/generation.hpp b/src/hotspot/share/gc/serial/generation.hpp index beb29928f4826..c6a9f94a8703a 100644 --- a/src/hotspot/share/gc/serial/generation.hpp +++ b/src/hotspot/share/gc/serial/generation.hpp @@ -114,8 +114,7 @@ class Generation: public CHeapObj { public: // Performance Counter support - virtual void update_counters() = 0; - virtual CollectorCounters* counters() { return _gc_counters; } + CollectorCounters* counters() { return _gc_counters; } GCMemoryManager* gc_manager() const { assert(_gc_manager != nullptr, "not initialized yet"); From c37e8638c98cb4516569304e9a0ab477affb0641 Mon Sep 17 00:00:00 2001 From: Hamlin Li Date: Fri, 9 Aug 2024 09:12:41 +0000 Subject: [PATCH 367/401] 8314125: RISC-V: implement Base64 intrinsic - encoding Reviewed-by: fyang, luhenry --- src/hotspot/cpu/riscv/assembler_riscv.hpp | 13 + src/hotspot/cpu/riscv/stubGenerator_riscv.cpp | 223 ++++++++++++++++++ src/hotspot/cpu/riscv/vm_version_riscv.cpp | 5 + 3 files changed, 241 insertions(+) diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index e4280ab34e1ce..79279be7acc1b 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -1828,6 +1828,19 @@ enum Nf { #undef INSN +#define INSN(NAME, op, width, umop, mop, mew, nf) \ + void NAME(VectorRegister Vd_or_Vs3, Register Rs1, VectorMask vm = unmasked) { \ + patch_VLdSt(op, Vd_or_Vs3, width, Rs1, umop, vm, mop, mew, nf); \ + } + + // Vector Unit-Stride Segment Load Instructions + INSN(vlseg3e8_v, 0b0000111, 0b000, 0b00000, 0b00, 0b0, g3); + + // Vector Unit-Stride Segment Store Instructions + INSN(vsseg4e8_v, 0b0100111, 0b000, 0b00000, 0b00, 0b0, g4); + +#undef INSN + #define INSN(NAME, op, width, mop, mew) \ void NAME(VectorRegister Vd, Register Rs1, VectorRegister Vs2, VectorMask vm = unmasked, Nf nf = g1) { \ patch_VLdSt(op, Vd, width, Rs1, Vs2->raw_encoding(), vm, mop, mew, nf); \ diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 198835d733f79..6a2c6c7d6c9bd 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -5103,6 +5103,225 @@ class StubGenerator: public StubCodeGenerator { return (address) start; } + /** + * vector registers: + * input VectorRegister's: intputV1-V3, for m2 they could be v2, v4, v6, for m1 they could be v1, v2, v3 + * index VectorRegister's: idxV1-V4, for m2 they could be v8, v10, v12, v14, for m1 they could be v4, v5, v6, v7 + * output VectorRegister's: outputV1-V4, for m2 they could be v16, v18, v20, v22, for m1 they could be v8, v9, v10, v11 + * + * NOTE: each field will occupy a vector register group + */ + void base64_vector_encode_round(Register src, Register dst, Register codec, + Register size, Register stepSrc, Register stepDst, + VectorRegister inputV1, VectorRegister inputV2, VectorRegister inputV3, + VectorRegister idxV1, VectorRegister idxV2, VectorRegister idxV3, VectorRegister idxV4, + VectorRegister outputV1, VectorRegister outputV2, VectorRegister outputV3, VectorRegister outputV4, + Assembler::LMUL lmul) { + // set vector register type/len + __ vsetvli(x0, size, Assembler::e8, lmul); + + // segmented load src into v registers: mem(src) => vr(3) + __ vlseg3e8_v(inputV1, src); + + // src = src + register_group_len_bytes * 3 + __ add(src, src, stepSrc); + + // encoding + // 1. compute index into lookup table: vr(3) => vr(4) + __ vsrl_vi(idxV1, inputV1, 2); + + __ vsrl_vi(idxV2, inputV2, 2); + __ vsll_vi(inputV1, inputV1, 6); + __ vor_vv(idxV2, idxV2, inputV1); + __ vsrl_vi(idxV2, idxV2, 2); + + __ vsrl_vi(idxV3, inputV3, 4); + __ vsll_vi(inputV2, inputV2, 4); + __ vor_vv(idxV3, inputV2, idxV3); + __ vsrl_vi(idxV3, idxV3, 2); + + __ vsll_vi(idxV4, inputV3, 2); + __ vsrl_vi(idxV4, idxV4, 2); + + // 2. indexed load: vr(4) => vr(4) + __ vluxei8_v(outputV1, codec, idxV1); + __ vluxei8_v(outputV2, codec, idxV2); + __ vluxei8_v(outputV3, codec, idxV3); + __ vluxei8_v(outputV4, codec, idxV4); + + // segmented store encoded data in v registers back to dst: vr(4) => mem(dst) + __ vsseg4e8_v(outputV1, dst); + + // dst = dst + register_group_len_bytes * 4 + __ add(dst, dst, stepDst); + } + + /** + * void j.u.Base64.Encoder.encodeBlock(byte[] src, int sp, int sl, byte[] dst, int dp, boolean isURL) + * + * Input arguments: + * c_rarg0 - src, source array + * c_rarg1 - sp, src start offset + * c_rarg2 - sl, src end offset + * c_rarg3 - dst, dest array + * c_rarg4 - dp, dst start offset + * c_rarg5 - isURL, Base64 or URL character set + */ + address generate_base64_encodeBlock() { + alignas(64) static const char toBase64[64] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' + }; + + alignas(64) static const char toBase64URL[64] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' + }; + + __ align(CodeEntryAlignment); + StubCodeMark mark(this, "StubRoutines", "encodeBlock"); + address start = __ pc(); + __ enter(); + + Register src = c_rarg0; + Register soff = c_rarg1; + Register send = c_rarg2; + Register dst = c_rarg3; + Register doff = c_rarg4; + Register isURL = c_rarg5; + + Register codec = c_rarg6; + Register length = c_rarg7; // total length of src data in bytes + + Label ProcessData, Exit; + + // length should be multiple of 3 + __ sub(length, send, soff); + // real src/dst to process data + __ add(src, src, soff); + __ add(dst, dst, doff); + + // load the codec base address + __ la(codec, ExternalAddress((address) toBase64)); + __ beqz(isURL, ProcessData); + __ la(codec, ExternalAddress((address) toBase64URL)); + __ BIND(ProcessData); + + // vector version + if (UseRVV) { + Label ProcessM2, ProcessM1, ProcessScalar; + + Register size = soff; + Register stepSrcM1 = send; + Register stepSrcM2 = doff; + Register stepDst = isURL; + + __ mv(size, MaxVectorSize * 2); + __ mv(stepSrcM1, MaxVectorSize * 3); + __ slli(stepSrcM2, stepSrcM1, 1); + __ mv(stepDst, MaxVectorSize * 2 * 4); + + __ blt(length, stepSrcM2, ProcessM1); + + __ BIND(ProcessM2); + base64_vector_encode_round(src, dst, codec, + size, stepSrcM2, stepDst, + v2, v4, v6, // inputs + v8, v10, v12, v14, // indexes + v16, v18, v20, v22, // outputs + Assembler::m2); + + __ sub(length, length, stepSrcM2); + __ bge(length, stepSrcM2, ProcessM2); + + __ BIND(ProcessM1); + __ blt(length, stepSrcM1, ProcessScalar); + + __ srli(size, size, 1); + __ srli(stepDst, stepDst, 1); + base64_vector_encode_round(src, dst, codec, + size, stepSrcM1, stepDst, + v1, v2, v3, // inputs + v4, v5, v6, v7, // indexes + v8, v9, v10, v11, // outputs + Assembler::m1); + __ sub(length, length, stepSrcM1); + + __ BIND(ProcessScalar); + } + + // scalar version + { + Register byte1 = soff, byte0 = send, byte2 = doff; + Register combined24Bits = isURL; + + __ beqz(length, Exit); + + Label ScalarLoop; + __ BIND(ScalarLoop); + { + // plain: [byte0[7:0] : byte1[7:0] : byte2[7:0]] => + // encoded: [byte0[7:2] : byte0[1:0]+byte1[7:4] : byte1[3:0]+byte2[7:6] : byte2[5:0]] + + // load 3 bytes src data + __ lbu(byte0, Address(src, 0)); + __ lbu(byte1, Address(src, 1)); + __ lbu(byte2, Address(src, 2)); + __ addi(src, src, 3); + + // construct 24 bits from 3 bytes + __ slliw(byte0, byte0, 16); + __ slliw(byte1, byte1, 8); + __ orr(combined24Bits, byte0, byte1); + __ orr(combined24Bits, combined24Bits, byte2); + + // get codec index and encode(ie. load from codec by index) + __ slliw(byte0, combined24Bits, 8); + __ srliw(byte0, byte0, 26); + __ add(byte0, codec, byte0); + __ lbu(byte0, byte0); + + __ slliw(byte1, combined24Bits, 14); + __ srliw(byte1, byte1, 26); + __ add(byte1, codec, byte1); + __ lbu(byte1, byte1); + + __ slliw(byte2, combined24Bits, 20); + __ srliw(byte2, byte2, 26); + __ add(byte2, codec, byte2); + __ lbu(byte2, byte2); + + __ andi(combined24Bits, combined24Bits, 0x3f); + __ add(combined24Bits, codec, combined24Bits); + __ lbu(combined24Bits, combined24Bits); + + // store 4 bytes encoded data + __ sb(byte0, Address(dst, 0)); + __ sb(byte1, Address(dst, 1)); + __ sb(byte2, Address(dst, 2)); + __ sb(combined24Bits, Address(dst, 3)); + + __ sub(length, length, 3); + __ addi(dst, dst, 4); + // loop back + __ bnez(length, ScalarLoop); + } + } + + __ BIND(Exit); + + __ leave(); + __ ret(); + + return (address) start; + } + void adler32_process_bytes(Register buff, Register s1, Register s2, VectorRegister vtable, VectorRegister vzero, VectorRegister vbytes, VectorRegister vs1acc, VectorRegister vs2acc, Register temp0, Register temp1, Register temp2, Register temp3, @@ -5996,6 +6215,10 @@ static const int64_t right_3_bits = right_n_bits(3); StubRoutines::_sha1_implCompressMB = generate_sha1_implCompress(true, "sha1_implCompressMB"); } + if (UseBASE64Intrinsics) { + StubRoutines::_base64_encodeBlock = generate_base64_encodeBlock(); + } + if (UseAdler32Intrinsics) { StubRoutines::_updateBytesAdler32 = generate_updateBytesAdler32(); } diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index ac2d6cde1a227..e9c6226f44639 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -265,6 +265,11 @@ void VM_Version::c2_initialize() { // as there are extra checks inside it which could disable UseRVV // in some situations. + // Base64 + if (FLAG_IS_DEFAULT(UseBASE64Intrinsics)) { + FLAG_SET_DEFAULT(UseBASE64Intrinsics, true); + } + if (FLAG_IS_DEFAULT(UseVectorizedHashCodeIntrinsic)) { FLAG_SET_DEFAULT(UseVectorizedHashCodeIntrinsic, true); } From 140716078694a338e2c2f837841761262cee5542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Fri, 9 Aug 2024 09:24:50 +0000 Subject: [PATCH 368/401] 8313931: Javadoc: links to type parameters actually generate links to classes Reviewed-by: jjg --- .../doclets/formats/html/ClassWriter.java | 50 +++++-- .../doclets/formats/html/HtmlIds.java | 16 +++ .../doclets/formats/html/HtmlLinkFactory.java | 13 +- .../formats/html/resources/script.js.template | 18 ++- .../formats/html/resources/stylesheet.css | 22 +++- .../formats/html/taglets/LinkTaglet.java | 24 +++- .../formats/html/taglets/ParamTaglet.java | 6 +- .../doclets/toolkit/util/CommentHelper.java | 6 + .../TestDeprecatedDocs.java | 8 +- .../TestDirectedInheritance.java | 6 +- .../doclet/testErasure/TestErasure.java | 8 +- .../TestGenericMethodLinkTaglet.java | 6 +- .../jdk/javadoc/doclet/testHref/TestHref.java | 5 +- .../doclet/testInterface/TestInterface.java | 36 ++--- .../TestLinkTagletTypeParam.java | 124 ++++++++++++++++++ .../TestMemberInheritance.java | 4 +- .../doclet/testModules/TestModules.java | 2 +- .../TestNewLanguageFeatures.java | 22 ++-- .../testParamTaglet/TestParamTaglet.java | 6 +- .../doclet/testProperty/TestProperty.java | 4 +- .../testRecordTypes/TestRecordTypes.java | 2 +- .../TestSerializedForm.java | 5 +- .../javadoc/doclet/testThrows/TestThrows.java | 4 +- .../testTypeParams/TestTypeParameters.java | 20 ++- .../testTypeParams/pkg/CtorTypeParam.java | 6 + .../doclet/testUnicode/TestUnicode.java | 4 +- 26 files changed, 336 insertions(+), 91 deletions(-) create mode 100644 test/langtools/jdk/javadoc/doclet/testLinkTaglet/TestLinkTagletTypeParam.java diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java index a1fd27fefdd58..8218e5128be3b 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java @@ -37,6 +37,7 @@ import javax.lang.model.element.Name; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; +import javax.lang.model.element.TypeParameterElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.SimpleElementVisitor8; @@ -155,7 +156,7 @@ protected void buildClassTree(Content classContent) { * @param target the content to which the documentation will be added */ protected void buildClassInfo(Content target) { - Content c = HtmlTree.DIV(HtmlStyles.horizontalScroll); + var c = new ContentBuilder(); buildParamInfo(c); buildSuperInterfacesInfo(c); buildImplementedInterfacesInfo(c); @@ -164,11 +165,13 @@ protected void buildClassInfo(Content target) { buildInterfaceUsageInfo(c); buildNestedClassInfo(c); buildFunctionalInterfaceInfo(c); - buildClassSignature(c); - buildDeprecationInfo(c); - buildClassDescription(c); - buildClassTagInfo(c); - + c.add(new HtmlTree(HtmlTag.HR)); + var div = HtmlTree.DIV(HtmlStyles.horizontalScroll); + buildClassSignature(div); + buildDeprecationInfo(div); + buildClassDescription(div); + buildClassTagInfo(div); + c.add(div); target.add(getClassInfo(c)); } @@ -432,12 +435,9 @@ private void setRecordDocumentation(TypeElement elem) { protected Content getHeader(String header) { HtmlTree body = getBody(getWindowTitle(utils.getSimpleName(typeElement))); var div = HtmlTree.DIV(HtmlStyles.header); - HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration, - HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS_AND_BOUNDS, typeElement) - .linkToSelf(false); // Let's not link to ourselves in the header var heading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING, HtmlStyles.title, Text.of(header)); - heading.add(getTypeParameterLinks(linkInfo)); + heading.add(getTypeParameters()); div.add(heading); bodyContents.setHeader(getHeader(PageMode.CLASS, typeElement)) .addMainContent(MarkerComments.START_OF_CLASS_DATA) @@ -445,6 +445,35 @@ protected Content getHeader(String header) { return body; } + // Renders type parameters for the class heading, creating id attributes + // if @param block tags are missing in doc comment. + private Content getTypeParameters() { + var content = new ContentBuilder(); + var typeParams = typeElement.getTypeParameters(); + if (!typeParams.isEmpty()) { + // Generate id attributes if @param tags are missing for type parameters. + // Note that this does not handle the case where some but not all @param tags are missing. + var needsId = !utils.hasBlockTag(typeElement, DocTree.Kind.PARAM); + var linkInfo = new HtmlLinkInfo(configuration, + HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS_AND_BOUNDS, typeElement) + .linkToSelf(false); // Let's not link to ourselves in the header + content.add("<"); + var first = true; + for (TypeParameterElement t : typeParams) { + if (!first) { + content.add(",").add(new HtmlTree(HtmlTag.WBR)); + } + var typeParamLink = getLink(linkInfo.forType(t.asType())); + content.add(needsId + ? HtmlTree.SPAN_ID(htmlIds.forTypeParam(t.getSimpleName().toString(), typeElement), typeParamLink) + : typeParamLink); + first = false; + } + content.add(">"); + } + return content; + } + protected Content getClassContentHeader() { return getContentHeader(); } @@ -473,7 +502,6 @@ public TypeElement getCurrentPageElement() { } protected void addClassSignature(Content classInfo) { - classInfo.add(new HtmlTree(HtmlTag.HR)); classInfo.add(new Signatures.TypeSignature(typeElement, this) .toContent()); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlIds.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlIds.java index 1b9896fafa006..8b48c7a6f2262 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlIds.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlIds.java @@ -462,6 +462,22 @@ public static HtmlId forText(String text, Map counts) { return HtmlId.of(count == 0 ? base : base + "-" + count); } + /** + * Returns an id for text documenting a type parameter of a class or method. + * + * @param paramName the name of the type parameter + * @param owner the enclosing element + * + * @return the id + */ + public HtmlId forTypeParam(String paramName, Element owner) { + if (utils.isExecutableElement(owner)) { + return HtmlId.of(forMember((ExecutableElement) owner).getFirst().name() + + "-type-param-" + paramName); + } + return HtmlId.of("type-param-" + paramName); + } + /** * Returns an id for one of the kinds of section in the pages for item group summaries. * diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java index 22af1e4a0244c..8e0c010dd1ae4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java @@ -162,9 +162,11 @@ public Content visitTypeVariable(TypeVariable type, HtmlLinkInfo linkInfo) { Element owner = typevariable.asElement().getEnclosingElement(); if (linkInfo.linkTypeParameters() && utils.isTypeElement(owner)) { linkInfo.setTypeElement((TypeElement) owner); - Content label = newContent(); - label.add(utils.getTypeName(type, false)); - linkInfo.label(label).skipPreview(true); + if (linkInfo.getLabel() == null || linkInfo.getLabel().isEmpty()) { + Content label = newContent(); + label.add(utils.getTypeName(type, false)); + linkInfo.label(label).skipPreview(true); + } link.add(getClassLink(linkInfo)); } else { // No need to link method type parameters. @@ -242,6 +244,11 @@ protected Content getClassLink(HtmlLinkInfo linkInfo) { boolean isTypeLink = linkInfo.getType() != null && utils.isTypeVariable(utils.getComponentType(linkInfo.getType())); title = getClassToolTip(typeElement, isTypeLink); + if (isTypeLink) { + linkInfo.fragment(m_writer.configuration.htmlIds.forTypeParam( + utils.getTypeName(utils.getComponentType(linkInfo.getType()), false), + typeElement).name()); + } } Content label = linkInfo.getClassLinkLabel(configuration); if (linkInfo.getContext() == HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS_IN_LABEL) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script.js.template b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script.js.template index ef09e6df90fd7..71ef847670822 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script.js.template +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/script.js.template @@ -232,6 +232,20 @@ document.addEventListener("readystatechange", (e) => { }); document.addEventListener("DOMContentLoaded", function(e) { setTopMargin(); + // Reset animation for type parameter target highlight + document.querySelectorAll("a").forEach((link) => { + link.addEventListener("click", (e) => { + const href = e.currentTarget.getAttribute("href"); + if (href && href.startsWith("#") && href.indexOf("type-param-") > -1) { + const target = document.getElementById(decodeURI(href.substring(1))); + if (target) { + target.style.animation = "none"; + void target.offsetHeight; + target.style.removeProperty("animation"); + } + } + }) + }); // Make sure current element is visible in breadcrumb navigation on small displays const subnav = document.querySelector("ol.sub-nav-list"); if (subnav && subnav.lastElementChild) { @@ -286,7 +300,7 @@ document.addEventListener("DOMContentLoaded", function(e) { }); var expanded = false; var windowWidth; - function collapse() { + function collapse(e) { if (expanded) { mainnav.removeAttribute("style"); if (toc) { @@ -336,7 +350,7 @@ document.addEventListener("DOMContentLoaded", function(e) { document.querySelectorAll("h1, h2, h3, h4, h5, h6") .forEach((hdr, idx) => { // Create anchor links for headers with an associated id attribute - var id = hdr.getAttribute("id") || hdr.parentElement.getAttribute("id") + var id = hdr.parentElement.getAttribute("id") || hdr.getAttribute("id") || (hdr.querySelector("a") && hdr.querySelector("a").getAttribute("id")); if (id) { var template = document.createElement('template'); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css index 4e37588f6cda5..1130f14dc35b4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css @@ -63,7 +63,7 @@ --search-input-text-color: #000000; --search-input-placeholder-color: #909090; /* Highlight color for active search tag target */ - --search-tag-highlight-color: #ffff00; + --search-tag-highlight-color: #ffff66; /* Adjustments for icon and active background colors of copy-to-clipboard buttons */ --copy-icon-brightness: 100%; --copy-button-background-color-active: rgba(168, 168, 176, 0.3); @@ -307,7 +307,7 @@ ol.sub-nav-list a.current-selection { */ .title { color:var(--title-color); - margin:10px 0; + margin:10px 0 12px 0; } .sub-title { margin:5px 0 0 0; @@ -988,6 +988,22 @@ input::placeholder { .search-tag-result:target { background-color:var(--search-tag-highlight-color); } +dd > span:target, +h1 > span:target { + animation: 2.4s ease-out highlight; +} +section.class-description dd > span:target, +section.class-description h1 > span:target { + scroll-margin-top: 20em; +} +@keyframes highlight { + from { + background-color: var(--search-tag-highlight-color); + } + 60% { + background-color: var(--search-tag-highlight-color); + } +} details.page-search-details { display: inline-block; } @@ -1040,7 +1056,7 @@ span#page-search-link { z-index: 5; } .inherited-list { - margin: 10px 0 10px 0; + margin: 10px 0; } .horizontal-scroll { overflow: auto hidden; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/taglets/LinkTaglet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/taglets/LinkTaglet.java index e16acd0315ad7..b16a1490b6303 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/taglets/LinkTaglet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/taglets/LinkTaglet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -176,7 +176,7 @@ Content linkSeeReferenceOutput(Element holder, return htmlWriter.getPackageLink(refPackage, labelContent, refFragment); } else { // @see is not referencing an included class, module or package. Check for cross-links. - String refModuleName = ch.getReferencedModuleName(refSignature); + String refModuleName = ch.getReferencedModuleName(refSignature); DocLink elementCrossLink = (refPackage != null) ? htmlWriter.getCrossPackageLink(refPackage) : (config.extern.isModule(refModuleName)) ? htmlWriter.getCrossModuleLink(utils.elementUtils.getModuleElement(refModuleName)) @@ -190,12 +190,28 @@ Content linkSeeReferenceOutput(Element holder, if (!config.isDocLintReferenceGroupEnabled()) { reportWarning.accept( "doclet.link.see.reference_not_found", - new Object[] { refSignature}); + new Object[] {refSignature}); } return htmlWriter.invalidTagOutput(resources.getText("doclet.link.see.reference_invalid"), - Optional.of(labelContent.isEmpty() ? text: labelContent)); + Optional.of(labelContent.isEmpty() ? text : labelContent)); } } + } else if (utils.isTypeParameterElement(ref)) { + // This is a type parameter of a generic class, method or constructor + if (labelContent.isEmpty()) { + labelContent = plainOrCode(isPlain, Text.of(utils.getSimpleName(ref))); + } + if (refMem == null) { + return htmlWriter.getLink( + new HtmlLinkInfo(config, HtmlLinkInfo.Kind.LINK_TYPE_PARAMS, ref.asType()) + .label(labelContent)); + } else { + // HtmlLinkFactory does not render type parameters of generic methods as links, so instead of + // teaching it how to do it (making the code even more complex) just create the link directly. + return htmlWriter.getLink(new HtmlLinkInfo(config, HtmlLinkInfo.Kind.PLAIN, refClass) + .fragment(config.htmlIds.forTypeParam(ref.getSimpleName().toString(), refMem).name()) + .label((labelContent))); + } } else if (refFragment == null) { // Must be a class reference since refClass is not null and refFragment is null. if (labelContent.isEmpty() && refTree != null) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/taglets/ParamTaglet.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/taglets/ParamTaglet.java index ed46e6c5c864f..8a3c47bbfd4b6 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/taglets/ParamTaglet.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/taglets/ParamTaglet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, 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 @@ -278,7 +278,9 @@ private Content paramTagOutput(Element element, ParamTree paramTag, String param body.add(" - "); List description = ch.getDescription(paramTag); body.add(htmlWriter.commentTagsToContent(element, description, context.within(paramTag))); - return HtmlTree.DD(body); + return HtmlTree.DD(paramTag.isTypeParameter() + ? HtmlTree.SPAN_ID(config.htmlIds.forTypeParam(paramName, element), body) + : body); } private record Documentation(ParamTree paramTree, ExecutableElement method) { } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/CommentHelper.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/CommentHelper.java index d7a0bd2d0a070..30aa86aea7196 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/CommentHelper.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/CommentHelper.java @@ -188,6 +188,12 @@ public Element getReferencedMember(Element e) { Utils utils = configuration.utils; if (e == null) { return null; + } else if (utils.isTypeParameterElement(e)) { + // Return the enclosing member for type parameters of generic methods or constructors. + Element encl = e.getEnclosingElement(); + if (utils.isExecutableElement(encl)) { + return encl; + } } return (utils.isExecutableElement(e) || utils.isVariableElement(e)) ? e : null; } diff --git a/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/TestDeprecatedDocs.java b/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/TestDeprecatedDocs.java index 2bd9da5957837..165fadc8e051f 100644 --- a/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/TestDeprecatedDocs.java +++ b/test/langtools/jdk/javadoc/doclet/testDeprecatedDocs/TestDeprecatedDocs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -102,7 +102,6 @@ public void test() { checkOutput("pkg/TestAnnotationType.html", true, """ -
@Deprecated(forRemoval=true) @Documented public @interface
@Deprecated(forRemoval=true) public class TestClass extends java.lang.Object
@@ -212,7 +210,6 @@ public void test() { checkOutput("pkg/TestEnum.html", true, """ -
@Deprecated(forRemoval=true) public enum TestEnum extends java.lang.Enum<
@Deprecated(forRemoval=true) public class TestError extends java.lang.Error
@@ -244,7 +240,6 @@ public void test() { checkOutput("pkg/TestException.html", true, """ -
@Deprecated(forRemoval=true) public class TestException extends java.lang.Exception
@@ -255,7 +250,6 @@ public void test() { checkOutput("pkg/TestInterface.html", true, """ -
@Deprecated(forRemoval=true) public class TestInterface extends java.lang.Object
diff --git a/test/langtools/jdk/javadoc/doclet/testDirectedInheritance/TestDirectedInheritance.java b/test/langtools/jdk/javadoc/doclet/testDirectedInheritance/TestDirectedInheritance.java index 89eb68db1dfdc..0f2b398e626bc 100644 --- a/test/langtools/jdk/javadoc/doclet/testDirectedInheritance/TestDirectedInheritance.java +++ b/test/langtools/jdk/javadoc/doclet/testDirectedInheritance/TestDirectedInheritance.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 @@ -154,8 +154,8 @@ public interface E1 extends I1, I2 {
I2: main description
""", """
Type Parameters:
-
E - I2: first type parameter
-
F - I2: second type parameter
+
E - I2: first type parameter
+
F - I2: second type parameter
Parameters:
eObj - I2: parameter
Returns:
diff --git a/test/langtools/jdk/javadoc/doclet/testErasure/TestErasure.java b/test/langtools/jdk/javadoc/doclet/testErasure/TestErasure.java index f80074c50e250..ee2ec08b884e6 100644 --- a/test/langtools/jdk/javadoc/doclet/testErasure/TestErasure.java +++ b/test/langtools/jdk/javadoc/doclet/testErasure/TestErasure.java @@ -199,7 +199,7 @@ class X { }
 
\ Foo\ - (T arg)
+ (T arg)
 
 <T extends X>
\ @@ -227,10 +227,10 @@ class X { } // methods checkOutput("Foo.html", true, """
abstract T
+ method-summary-table-tab3">abstract T
m\ - (T arg)
+ (T arg)
 
Test Feature
"""); } -} \ No newline at end of file +} diff --git a/test/langtools/jdk/javadoc/doclet/testGenericMethodLinkTaglet/TestGenericMethodLinkTaglet.java b/test/langtools/jdk/javadoc/doclet/testGenericMethodLinkTaglet/TestGenericMethodLinkTaglet.java index a9a4be1b262b9..db23064e9ca8d 100644 --- a/test/langtools/jdk/javadoc/doclet/testGenericMethodLinkTaglet/TestGenericMethodLinkTaglet.java +++ b/test/langtools/jdk/javadoc/doclet/testGenericMethodLinkTaglet/TestGenericMethodLinkTaglet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 8188248 + * @bug 8188248 8313931 * @summary NullPointerException on generic methods * @library /tools/lib ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -67,7 +67,7 @@ public void test(Path base) throws Exception { checkOutput("pkg/A.html", true, """ - A"""); + param T"""); } void createTestClass(Path srcDir) throws Exception { diff --git a/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java b/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java index f21ad223fb459..b9dff5ff2a897 100644 --- a/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java +++ b/test/langtools/jdk/javadoc/doclet/testHref/TestHref.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -75,7 +75,8 @@ public void test() { checkOutput("pkg/C4.html", true, //Header does not link to the page itself. - "Class C4<E extends C4<E>>", + """ + Class C4<E extends C4<E>>""", //Signature does not link to the page itself. """ public abstract class method
 in interface&\ nbsp;Interface<CE>""", + href="#type-param-CE" title="type parameter in Child">CE>""", //Make sure "Overrides" has substituted type parameters. """
Overrides:
method in class Parent<Parent<CE>
"""); checkOutput("pkg/Parent.html", true, @@ -190,7 +190,7 @@ public void test1() {
Overrides:
method1 in class&\ nbsp;GrandParent<<\ - a href="Child.html" title="type parameter in Child">CE>"""); + a href="#type-param-CE" title="type parameter in Child">CE>"""); } @Test @@ -209,17 +209,17 @@ public void test2() { erface in pkg2">Spliterator Spliterator.\ OfDouble, Spliter\ - ator.OfInt<Integer>, Spliterator.OfPrimitive<T,T_C\ - ONS,T,T_C\ + ONS,T_SPLITR extends Spliterator.OfPrimitive<T,<\ - a href="Spliterator.OfPrimitive.html" title="type parameter in Spliterator.OfPri\ - mitive">T_CONS,T,<\ + a href="Spliterator.OfPrimitive.html#type-param-T_CONS" title="type parameter in Spliterator.OfPri\ + mitive">T_CONS,T_SPLITR>>"""); checkOutput("pkg2/Spliterator.html", true, """ @@ -236,21 +236,21 @@ public void test2() {
static interface 
Spliterator.OfInt<Integer&\ + Spliterator.OfInt.html#type-param-Integer" title="type parameter in Spliterator.OfInt">Integer&\ gt;
 
static interface 
Spliterator.OfPrimitive\ - <T,T,T_CONS,T_SPLITR extends <\ + e.html#type-param-T_SPLITR" title="type parameter in Spliterator.OfPrimitive">T_SPLITR extends <\ a href="Spliterator.OfPrimitive.html" title="interface in pkg2">Spliterator.OfPr\ - imitive<T,<T,T_CONS,T_SPLITRT_SPLITR>>
 
"""); diff --git a/test/langtools/jdk/javadoc/doclet/testLinkTaglet/TestLinkTagletTypeParam.java b/test/langtools/jdk/javadoc/doclet/testLinkTaglet/TestLinkTagletTypeParam.java new file mode 100644 index 0000000000000..5cb1f687d452f --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testLinkTaglet/TestLinkTagletTypeParam.java @@ -0,0 +1,124 @@ +/* + * 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 8313931 + * @summary Javadoc: links to type parameters actually generate links to classes + * @library /tools/lib ../../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build toolbox.ToolBox javadoc.tester.* + * @run main TestLinkTagletTypeParam + */ + +import javadoc.tester.JavadocTester; +import toolbox.ToolBox; + +import java.io.IOException; +import java.nio.file.Path; + +public class TestLinkTagletTypeParam extends JavadocTester { + + public static void main(String... args) throws Exception { + var tester = new TestLinkTagletTypeParam(); + tester.runTests(); + } + + ToolBox tb = new ToolBox(); + + @JavadocTester.Test + public void testClassTypeParameterLink(Path base) throws IOException { + Path src = base.resolve("src"); + + tb.writeJavaFiles(src, + """ + /** + * Link to {@link F}. + * + * @param the first type param + * @param an Appendable + * + * @see APND the second type parameter + */ + public class Test { + private Test() {} + } + """); + + javadoc("-Xdoclint:none", + "-d", base.resolve("api").toString(), + "-sourcepath", src.toString(), + src.resolve("Test.java").toString()); + checkExit(JavadocTester.Exit.OK); + + checkOrder("Test.html", + """ +
Type Parameters:
+
F - the first type param
+
APND - an Appendable
""", + """ + Link to
F.""", + """ +
See Also:
+
+ """); + } + + @JavadocTester.Test + public void testMethodTypeParameterLink(Path base) throws IOException { + Path src = base.resolve("src"); + + tb.writeJavaFiles(src, + """ + /** + * Class comment. + */ + public class Test { + /** + * Link to {@link T} and {@linkplain T link with label}. + * + * @param the T + * @param appendable the appendable + */ + public T append(final T appendable) { + return appendable; + } + } + """); + + javadoc("-Xdoclint:reference", + "-d", base.resolve("api").toString(), + "-sourcepath", src.toString(), + src.resolve("Test.java").toString()); + + checkOutput(JavadocTester.Output.OUT, true, + ""); + + checkOutput("Test.html", true, + """ + Link to T and link with label."""); + } +} diff --git a/test/langtools/jdk/javadoc/doclet/testMemberInheritance/TestMemberInheritance.java b/test/langtools/jdk/javadoc/doclet/testMemberInheritance/TestMemberInheritance.java index 705cae327e3a3..559f7b08d3877 100644 --- a/test/langtools/jdk/javadoc/doclet/testMemberInheritance/TestMemberInheritance.java +++ b/test/langtools/jdk/javadoc/doclet/testMemberInheritance/TestMemberInheritance.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, 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 @@ -120,8 +120,8 @@ interface in pkg">BaseInterface
checkOutput("pkg2/DocumentedNonGenericChild.html", true, """
-

+
public abstract class DocumentedNonGenericChild extends java.lang.Object
diff --git a/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java b/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java index 79bad12f95db2..4d3628544f81e 100644 --- a/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java +++ b/test/langtools/jdk/javadoc/doclet/testModules/TestModules.java @@ -1360,8 +1360,8 @@ void checkLinkSource(boolean includePrivate) { checkOutput("moduleA/testpkgmdlA/TestClassInModuleA.html", true, """
-

+
public class TestClassInModuleA diff --git a/test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java b/test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java index a54fbbcff75f0..eafad8c3245f2 100644 --- a/test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java +++ b/test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, 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 @@ -117,7 +117,7 @@ void checkTypeParameters() { // Check class type parameters section. """
Type Parameters:
-
E - the type parameter for this class.""", +
E - the type parameter for this class.
""", // Type parameters in @see/@link """
@@ -130,12 +130,14 @@ void checkTypeParameters() {
""", // Method that uses class type parameter. """ - (E param)""", + (E param)""", // Method type parameter section. """
Type Parameters:
-
T - This is the first type parameter.
-
V - This is the second type parameter.""", +
T - Th\ + is is the first type parameter.
+
V - Th\ + is is the second type parameter.
""", // Signature of method with type parameters """
public E[]
methodThatReturnsTypeParameterA(E[] \ + ref="#type-param-E" title="type parameter in TypeParameters">E[] \ e)""", """
public E[] methodThatReturnsTypePa\ - rameterA((E[] e)
""", """ @@ -176,7 +178,7 @@ void checkTypeParameters() { """
<X extends java.lang.Throwable>
E
\ + href="#type-param-E" title="type parameter in TypeParameters">E
\
Type Parameters: -
T2 - type 2
+
T2 - type 2
Parameters:
t1 - param 1
t3 - param 3
@@ -92,7 +92,7 @@ public void test() { checkOutput("pkg/C.Nested.html", true, """
Type Parameters:
-
T1 - type 1
+
T1 - type 1
"""); } } diff --git a/test/langtools/jdk/javadoc/doclet/testProperty/TestProperty.java b/test/langtools/jdk/javadoc/doclet/testProperty/TestProperty.java index 7ce046c07575c..94ad1a8040f6a 100644 --- a/test/langtools/jdk/javadoc/doclet/testProperty/TestProperty.java +++ b/test/langtools/jdk/javadoc/doclet/testProperty/TestProperty.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 @@ -110,7 +110,7 @@ class in pkg">ObjectProperty
<public final <\ span class="return-type">Obje\ - ctProperty<java.util.List<T>> listProperty<\ /div>
This is an Object property where the Object is a single List<T>.
diff --git a/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.java b/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.java index f9aa3cfd6fa49..3b6a8a4fc72e4 100644 --- a/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.java +++ b/test/langtools/jdk/javadoc/doclet/testRecordTypes/TestRecordTypes.java @@ -175,7 +175,7 @@ public record R(int r1) { }"""); """
Type Parameters:
-
T - This is a type parameter.
+
T - This is a type parameter.
Record Components:
r1 - This is a component.
""", diff --git a/test/langtools/jdk/javadoc/doclet/testSerializedForm/TestSerializedForm.java b/test/langtools/jdk/javadoc/doclet/testSerializedForm/TestSerializedForm.java index 9bf2ac362c611..af3e36aa7d897 100644 --- a/test/langtools/jdk/javadoc/doclet/testSerializedForm/TestSerializedForm.java +++ b/test/langtools/jdk/javadoc/doclet/testSerializedForm/TestSerializedForm.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, 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 @@ -219,6 +219,7 @@ public void test2() { """ Fields[] singleArray""", """ - java.lang.Class<E> someClass"""); + java.lang.Class<E> someClass"""); } } diff --git a/test/langtools/jdk/javadoc/doclet/testThrows/TestThrows.java b/test/langtools/jdk/javadoc/doclet/testThrows/TestThrows.java index ca4592ea5f84c..e4c578578998f 100644 --- a/test/langtools/jdk/javadoc/doclet/testThrows/TestThrows.java +++ b/test/langtools/jdk/javadoc/doclet/testThrows/TestThrows.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 @@ -83,7 +83,7 @@ public interface C { """
Type Parameters:
-
T - the throwable
+
T - the throwable
Throws:
T - if a specific error occurs
java.lang.Exception - if an exception occurs
diff --git a/test/langtools/jdk/javadoc/doclet/testTypeParams/TestTypeParameters.java b/test/langtools/jdk/javadoc/doclet/testTypeParams/TestTypeParameters.java index 0d95ee38cdc94..dad610acb302e 100644 --- a/test/langtools/jdk/javadoc/doclet/testTypeParams/TestTypeParameters.java +++ b/test/langtools/jdk/javadoc/doclet/testTypeParams/TestTypeParameters.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 @@ -23,7 +23,7 @@ /* * @test - * @bug 4927167 4974929 6381729 7010344 8025633 8081854 8182765 8187288 8261976 + * @bug 4927167 4974929 6381729 7010344 8025633 8081854 8182765 8187288 8261976 8313931 * @summary When the type parameters are more than 10 characters in length, * make sure there is a line break between type params and return type * in member summary. Also, test for type parameter links in package-summary and @@ -110,10 +110,22 @@ public void test3() {
 <T extends java.lang.Runnable>
-
 
""", +
+
Generic constructor.
""", """
public\  <T extends java.lang.Runnable>\ -  CtorTypeParam()
"""); +  CtorTypeParam()
""", + """ + T""", + """ +
Type Parameters:
+
T - the type parameter
""", + """ +
See Also:
+
+ """); } } diff --git a/test/langtools/jdk/javadoc/doclet/testTypeParams/pkg/CtorTypeParam.java b/test/langtools/jdk/javadoc/doclet/testTypeParams/pkg/CtorTypeParam.java index a7f2309475d28..690471861dbd9 100644 --- a/test/langtools/jdk/javadoc/doclet/testTypeParams/pkg/CtorTypeParam.java +++ b/test/langtools/jdk/javadoc/doclet/testTypeParams/pkg/CtorTypeParam.java @@ -24,6 +24,12 @@ package pkg; public class CtorTypeParam { + /** + * Generic constructor. {@link T} + * + * @param the type parameter + * @see T link to type parameter + */ public CtorTypeParam() { } } diff --git a/test/langtools/jdk/javadoc/doclet/testUnicode/TestUnicode.java b/test/langtools/jdk/javadoc/doclet/testUnicode/TestUnicode.java index 76008260343ca..cf30488ec7bc2 100644 --- a/test/langtools/jdk/javadoc/doclet/testUnicode/TestUnicode.java +++ b/test/langtools/jdk/javadoc/doclet/testUnicode/TestUnicode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -101,7 +101,7 @@ public class Code<##> { """
Type Parameters:
-
## - the ##
+
## - the ##
""".replaceAll("##", chineseElephant), """ From 2b5aec2aad3883d4d407ec3a572f78755d60190d Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev Date: Fri, 9 Aug 2024 11:28:59 +0000 Subject: [PATCH 369/401] 8338109: java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java duplicate in ProblemList Reviewed-by: aivanov --- test/jdk/ProblemList.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 293d9d108d32c..6cde711138310 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -375,7 +375,7 @@ java/awt/Modal/MultipleDialogs/MultipleDialogs3Test.java 8198665 macosx-all java/awt/Modal/MultipleDialogs/MultipleDialogs4Test.java 8198665 macosx-all java/awt/Modal/MultipleDialogs/MultipleDialogs5Test.java 8198665 macosx-all java/awt/Mouse/EnterExitEvents/DragWindowOutOfFrameTest.java 8177326 macosx-all -java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java 8005021 macosx-all +java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java 8005021,8332158 macosx-all,linux-x64 java/awt/Mouse/EnterExitEvents/FullscreenEnterEventTest.java 8051455 macosx-all java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Standard.java 7124407,8302787 macosx-all,windows-all java/awt/Mouse/RemovedComponentMouseListener/RemovedComponentMouseListener.java 8157170 macosx-all @@ -475,7 +475,6 @@ java/awt/Choice/SelectNewItemTest/SelectNewItemTest.java 8324782 macosx-all # Wayland related -java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java 8332158 linux-x64 java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java 8280991 linux-x64 java/awt/FullScreen/SetFullScreenTest.java 8332155 linux-x64 From 069e0ea69f43960164d3e077d2c7b950cde77927 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Fri, 9 Aug 2024 12:00:15 +0000 Subject: [PATCH 370/401] 8338064: Give better error for ConcurrentHashTable corruption Reviewed-by: dholmes, shade --- .../share/utilities/concurrentHashTable.hpp | 5 ++ .../utilities/concurrentHashTable.inline.hpp | 6 +- .../StringTableCorruptionTest.java | 59 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/runtime/stringtable/StringTableCorruptionTest.java diff --git a/src/hotspot/share/utilities/concurrentHashTable.hpp b/src/hotspot/share/utilities/concurrentHashTable.hpp index 991ea9fe3c609..4e506d5fe84f1 100644 --- a/src/hotspot/share/utilities/concurrentHashTable.hpp +++ b/src/hotspot/share/utilities/concurrentHashTable.hpp @@ -65,6 +65,7 @@ class ConcurrentHashTable : public CHeapObj { // the InternalTable or user-defined memory. class Node { private: + DEBUG_ONLY(size_t _saved_hash); Node * volatile _next; VALUE _value; public: @@ -77,6 +78,10 @@ class ConcurrentHashTable : public CHeapObj { Node* next() const; void set_next(Node* node) { _next = node; } Node* const volatile * next_ptr() { return &_next; } +#ifdef ASSERT + size_t saved_hash() const { return _saved_hash; } + void set_saved_hash(size_t hash) { _saved_hash = hash; } +#endif VALUE* value() { return &_value; } diff --git a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp index 78c7e148bbb3c..f035aeae44847 100644 --- a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp +++ b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp @@ -679,7 +679,9 @@ inline bool ConcurrentHashTable:: // Keep in odd list odd = aux->next_ptr(); } else { - fatal("aux_index does not match even or odd indices"); + const char* msg = "Cannot resize table: Node hash code has changed possibly due to corruption of the contents."; + DEBUG_ONLY(fatal("%s Node hash code changed from " SIZE_FORMAT " to " SIZE_FORMAT, msg, aux->saved_hash(), aux_hash);) + NOT_DEBUG(fatal("%s", msg);) } } aux = aux_next; @@ -892,6 +894,7 @@ inline bool ConcurrentHashTable:: size_t i = 0; uintx hash = lookup_f.get_hash(); Node* new_node = Node::create_node(_context, value, nullptr); + DEBUG_ONLY(new_node->set_saved_hash(hash);) while (true) { { @@ -1117,6 +1120,7 @@ inline bool ConcurrentHashTable:: Bucket* bucket = get_bucket_in(table, hash); assert(!bucket->have_redirect() && !bucket->is_locked(), "bad"); Node* new_node = Node::create_node(_context, value, bucket->first()); + DEBUG_ONLY(new_node->set_saved_hash(hash);) if (!bucket->cas_first(new_node, bucket->first())) { assert(false, "bad"); } diff --git a/test/hotspot/jtreg/runtime/stringtable/StringTableCorruptionTest.java b/test/hotspot/jtreg/runtime/stringtable/StringTableCorruptionTest.java new file mode 100644 index 0000000000000..e4d6a2e5d0f95 --- /dev/null +++ b/test/hotspot/jtreg/runtime/stringtable/StringTableCorruptionTest.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 8333356 + * @summary Verify new error message for corrupting string table contents. + * @requires vm.flagless + * @modules java.base/java.lang:open + * @library /test/lib + * @modules java.base/jdk.internal.misc + * @run driver StringTableCorruptionTest test + */ + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class StringTableCorruptionTest { + public static void main(String[] args) throws Exception { + if (args.length > 0) { + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("--add-opens", "java.base/java.lang=ALL-UNNAMED", + "-XX:-CreateCoredumpOnCrash", "StringTableCorruptionTest"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("Node hash code has changed possibly due to corruption of the contents."); + output.shouldNotHaveExitValue(0); + return; + } + + Field f = String.class.getDeclaredField("value"); + f.setAccessible(true); + f.set("s1".intern(), f.get("s2")); + for (int i = 0; i < 4_000_000; i++) { + ("s_" + i).intern(); + } + } +} From 3cf3f300de1e9d2c8767877ed3a26679e34b7d22 Mon Sep 17 00:00:00 2001 From: Casper Norrbin Date: Fri, 9 Aug 2024 14:32:29 +0000 Subject: [PATCH 371/401] 8330191: Fix typo in precompiled.hpp Reviewed-by: jsjolen, szaldana --- src/hotspot/share/precompiled/precompiled.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/precompiled/precompiled.hpp b/src/hotspot/share/precompiled/precompiled.hpp index c53a78de87bca..07922d129697e 100644 --- a/src/hotspot/share/precompiled/precompiled.hpp +++ b/src/hotspot/share/precompiled/precompiled.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -29,7 +29,7 @@ // These header files are included in at least 130 C++ files, as of // measurements made in November 2018. This list excludes files named -// *.include.hpp, since including them decreased build performance. +// *.inline.hpp, since including them decreased build performance. #include "classfile/classLoaderData.hpp" #include "classfile/javaClasses.hpp" From 60fa08fcfe5c6551ee3120330ade93e45df618c7 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 9 Aug 2024 17:08:19 +0000 Subject: [PATCH 372/401] 8337797: Additional ExternalAddress cleanup Reviewed-by: adinn, thartmann --- src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp | 4 ++-- src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp | 9 ++------- src/hotspot/cpu/x86/assembler_x86.cpp | 1 + src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp | 8 ++++---- src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp | 6 +++--- src/hotspot/cpu/x86/macroAssembler_x86.cpp | 4 ++-- src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp | 4 ++-- src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp | 4 ++-- src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp | 2 +- src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp | 4 ++-- 10 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp b/src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp index e79b93651b072..aea268ea94443 100644 --- a/src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -201,7 +201,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { { __ enter(); - __ lea(rscratch1, ExternalAddress(slow_case_addr)); + __ lea(rscratch1, RuntimeAddress(slow_case_addr)); __ blr(rscratch1); __ leave(); __ ret(lr); diff --git a/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp b/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp index 8423ecad8a3da..f7d702c631069 100644 --- a/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp +++ b/src/hotspot/cpu/riscv/jniFastGetField_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -173,12 +173,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { { __ enter(); - ExternalAddress target(slow_case_addr); - __ relocate(target.rspec(), [&] { - int32_t offset; - __ la(t0, target.target(), offset); - __ jalr(t0, offset); - }); + __ rt_call(slow_case_addr); __ leave(); __ ret(); } diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index 001ff472f40bb..207d3fbb61eba 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -1780,6 +1780,7 @@ void Assembler::call(Register dst) { void Assembler::call(Address adr) { + assert(!adr._rspec.reloc()->is_data(), "should not use ExternalAddress for call"); InstructionMark im(this); prefix(adr); emit_int8((unsigned char)0xFF); diff --git a/src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp b/src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp index 34be2a61b5a47..52e4388c5d249 100644 --- a/src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp +++ b/src/hotspot/cpu/x86/jniFastGetField_x86_32.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -138,7 +138,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { default: ShouldNotReachHere(); } // tail call - __ jump (ExternalAddress(slow_case_addr)); + __ jump (RuntimeAddress(slow_case_addr)); __ flush (); @@ -251,7 +251,7 @@ address JNI_FastGetField::generate_fast_get_long_field() { __ pop (rsi); address slow_case_addr = jni_GetLongField_addr();; // tail call - __ jump (ExternalAddress(slow_case_addr)); + __ jump (RuntimeAddress(slow_case_addr)); __ flush (); @@ -350,7 +350,7 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { default: ShouldNotReachHere(); } // tail call - __ jump (ExternalAddress(slow_case_addr)); + __ jump (RuntimeAddress(slow_case_addr)); __ flush (); diff --git a/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp b/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp index 4506205c259fb..e94b7d12b0b3c 100644 --- a/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp +++ b/src/hotspot/cpu/x86/jniFastGetField_x86_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -118,7 +118,7 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { default: break; } // tail call - __ jump (ExternalAddress(slow_case_addr), rscratch1); + __ jump (RuntimeAddress(slow_case_addr), rscratch1); __ flush (); @@ -206,7 +206,7 @@ address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) { default: break; } // tail call - __ jump (ExternalAddress(slow_case_addr), rscratch1); + __ jump (RuntimeAddress(slow_case_addr), rscratch1); __ flush (); diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index affd18f937ca8..c8234d6b9b88b 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -2329,7 +2329,7 @@ void MacroAssembler::incrementl(Address dst, int value) { void MacroAssembler::jump(AddressLiteral dst, Register rscratch) { assert(rscratch != noreg || always_reachable(dst), "missing"); - + assert(!dst.rspec().reloc()->is_data(), "should not use ExternalAddress for jump"); if (reachable(dst)) { jmp_literal(dst.target(), dst.rspec()); } else { @@ -2340,7 +2340,7 @@ void MacroAssembler::jump(AddressLiteral dst, Register rscratch) { void MacroAssembler::jump_cc(Condition cc, AddressLiteral dst, Register rscratch) { assert(rscratch != noreg || always_reachable(dst), "missing"); - + assert(!dst.rspec().reloc()->is_data(), "should not use ExternalAddress for jump_cc"); if (reachable(dst)) { InstructionMark im(this); relocate(dst.reloc()); diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp index 80be7c7d5b642..d313c1b216a40 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp @@ -704,10 +704,10 @@ static void range_check(MacroAssembler* masm, Register pc_reg, Register temp_reg address code_start, address code_end, Label& L_ok) { Label L_fail; - __ lea(temp_reg, ExternalAddress(code_start)); + __ lea(temp_reg, AddressLiteral(code_start, relocInfo::none)); __ cmpptr(pc_reg, temp_reg); __ jcc(Assembler::belowEqual, L_fail); - __ lea(temp_reg, ExternalAddress(code_end)); + __ lea(temp_reg, AddressLiteral(code_end, relocInfo::none)); __ cmpptr(pc_reg, temp_reg); __ jcc(Assembler::below, L_ok); __ bind(L_fail); diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp index f2488ef4e7445..d27b1d141fc29 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -824,10 +824,10 @@ static void range_check(MacroAssembler* masm, Register pc_reg, Register temp_reg address code_start, address code_end, Label& L_ok) { Label L_fail; - __ lea(temp_reg, ExternalAddress(code_start)); + __ lea(temp_reg, AddressLiteral(code_start, relocInfo::none)); __ cmpptr(pc_reg, temp_reg); __ jcc(Assembler::belowEqual, L_fail); - __ lea(temp_reg, ExternalAddress(code_end)); + __ lea(temp_reg, AddressLiteral(code_end, relocInfo::none)); __ cmpptr(pc_reg, temp_reg); __ jcc(Assembler::below, L_ok); __ bind(L_fail); diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp index d8f7a6b272bc9..5b316881d0346 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp @@ -215,7 +215,7 @@ void StubGenerator::array_overlap_test(address no_overlap_target, Label* NOLp, A __ cmpptr(to, from); __ lea(end_from, Address(from, count, sf, 0)); if (NOLp == nullptr) { - ExternalAddress no_overlap(no_overlap_target); + RuntimeAddress no_overlap(no_overlap_target); __ jump_cc(Assembler::belowEqual, no_overlap); __ cmpptr(to, end_from); __ jump_cc(Assembler::aboveEqual, no_overlap); diff --git a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp index 7e0814c014bec..62022d780a20b 100644 --- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp +++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp @@ -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 @@ -180,7 +180,7 @@ bool os::win32::register_code_area(char *low, char *high) { MacroAssembler* masm = new MacroAssembler(&cb); pDCD = (pDynamicCodeData) masm->pc(); - masm->jump(ExternalAddress((address)&HandleExceptionFromCodeCache), rscratch1); + masm->jump(RuntimeAddress((address)&HandleExceptionFromCodeCache), rscratch1); masm->flush(); // Create an Unwind Structure specifying no unwind info From 358d77dafbe0e35d5b20340fccddc0fb8f3db82a Mon Sep 17 00:00:00 2001 From: Dmitry Chuyko Date: Fri, 9 Aug 2024 17:56:37 +0000 Subject: [PATCH 373/401] 8337657: AArch64: No need for acquire fence in safepoint poll during JNI calls Reviewed-by: phh --- src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp | 12 ++---------- .../aarch64/templateInterpreterGenerator_aarch64.cpp | 11 ++--------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp index 65c026b95abbd..8ce4230baa2b4 100644 --- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp @@ -1883,16 +1883,8 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, // Check for safepoint operation in progress and/or pending suspend requests. { - // We need an acquire here to ensure that any subsequent load of the - // global SafepointSynchronize::_state flag is ordered after this load - // of the thread-local polling word. We don't want this poll to - // return false (i.e. not safepointing) and a later poll of the global - // SafepointSynchronize::_state spuriously to return true. - // - // This is to avoid a race when we're in a native->Java transition - // racing the code which wakes up from a safepoint. - - __ safepoint_poll(safepoint_in_progress, true /* at_return */, true /* acquire */, false /* in_nmethod */); + // No need for acquire as Java threads always disarm themselves. + __ safepoint_poll(safepoint_in_progress, true /* at_return */, false /* acquire */, false /* in_nmethod */); __ ldrw(rscratch1, Address(rthread, JavaThread::suspend_flags_offset())); __ cbnzw(rscratch1, safepoint_in_progress); __ bind(safepoint_in_progress_done); diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index d639d9cf17ee5..ed2450a9110e5 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp @@ -1413,15 +1413,8 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) { { Label L, Continue; - // We need an acquire here to ensure that any subsequent load of the - // global SafepointSynchronize::_state flag is ordered after this load - // of the thread-local polling word. We don't want this poll to - // return false (i.e. not safepointing) and a later poll of the global - // SafepointSynchronize::_state spuriously to return true. - // - // This is to avoid a race when we're in a native->Java transition - // racing the code which wakes up from a safepoint. - __ safepoint_poll(L, true /* at_return */, true /* acquire */, false /* in_nmethod */); + // No need for acquire as Java threads always disarm themselves. + __ safepoint_poll(L, true /* at_return */, false /* acquire */, false /* in_nmethod */); __ ldrw(rscratch2, Address(rthread, JavaThread::suspend_flags_offset())); __ cbz(rscratch2, Continue); __ bind(L); From 6a3d045221c338fefec9bd59245324eae60b156b Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Sun, 11 Aug 2024 18:34:18 +0000 Subject: [PATCH 374/401] 8337709: Use allocated states for chunking large array processing Reviewed-by: iwalulya, tschatzl --- .../share/gc/g1/g1ParScanThreadState.cpp | 90 +++++++---- .../share/gc/g1/g1ParScanThreadState.hpp | 12 +- .../share/gc/shared/partialArrayState.cpp | 152 ++++++++++++++++++ .../share/gc/shared/partialArrayState.hpp | 136 ++++++++++++++++ .../gc/shared/partialArrayTaskStepper.cpp | 6 +- .../gc/shared/partialArrayTaskStepper.hpp | 59 ++++--- .../shared/partialArrayTaskStepper.inline.hpp | 71 +++----- src/hotspot/share/gc/shared/taskqueue.hpp | 21 ++- .../shared/test_partialArrayTaskStepper.cpp | 42 ++--- 9 files changed, 444 insertions(+), 145 deletions(-) create mode 100644 src/hotspot/share/gc/shared/partialArrayState.cpp create mode 100644 src/hotspot/share/gc/shared/partialArrayState.hpp diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp index e4ac20ca7ea92..f81c3241a1a90 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp @@ -35,6 +35,7 @@ #include "gc/g1/g1Trace.hpp" #include "gc/g1/g1YoungGCAllocationFailureInjector.inline.hpp" #include "gc/shared/continuationGCSupport.inline.hpp" +#include "gc/shared/partialArrayState.hpp" #include "gc/shared/partialArrayTaskStepper.inline.hpp" #include "gc/shared/preservedMarks.inline.hpp" #include "gc/shared/stringdedup/stringDedup.hpp" @@ -43,6 +44,7 @@ #include "oops/access.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" +#include "runtime/mutexLocker.hpp" #include "runtime/prefetch.inline.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" @@ -61,7 +63,8 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint worker_id, uint num_workers, G1CollectionSet* collection_set, - G1EvacFailureRegions* evac_failure_regions) + G1EvacFailureRegions* evac_failure_regions, + PartialArrayStateAllocator* pas_allocator) : _g1h(g1h), _task_queue(g1h->task_queue(worker_id)), _rdc_local_qset(rdcqs), @@ -80,8 +83,8 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, _surviving_young_words(nullptr), _surviving_words_length(collection_set->young_region_length() + 1), _old_gen_is_full(false), - _partial_objarray_chunk_size(ParGCArrayScanChunk), - _partial_array_stepper(num_workers), + _partial_array_state_allocator(pas_allocator), + _partial_array_stepper(num_workers, ParGCArrayScanChunk), _string_dedup_requests(), _max_num_optional_regions(collection_set->optional_region_length()), _numa(g1h->numa()), @@ -169,9 +172,9 @@ void G1ParScanThreadState::verify_task(oop* task) const { "task=" PTR_FORMAT " p=" PTR_FORMAT, p2i(task), p2i(p)); } -void G1ParScanThreadState::verify_task(PartialArrayScanTask task) const { +void G1ParScanThreadState::verify_task(PartialArrayState* task) const { // Must be in the collection set--it's already been copied. - oop p = task.to_source_array(); + oop p = task->source(); assert(_g1h->is_in_cset(p), "p=" PTR_FORMAT, p2i(p)); } @@ -180,8 +183,8 @@ void G1ParScanThreadState::verify_task(ScannerTask task) const { verify_task(task.to_narrow_oop_ptr()); } else if (task.is_oop_ptr()) { verify_task(task.to_oop_ptr()); - } else if (task.is_partial_array_task()) { - verify_task(task.to_partial_array_task()); + } else if (task.is_partial_array_state()) { + verify_task(task.to_partial_array_state()); } else { ShouldNotReachHere(); } @@ -223,34 +226,39 @@ void G1ParScanThreadState::do_oop_evac(T* p) { } MAYBE_INLINE_EVACUATION -void G1ParScanThreadState::do_partial_array(PartialArrayScanTask task) { - oop from_obj = task.to_source_array(); +void G1ParScanThreadState::do_partial_array(PartialArrayState* state) { + oop to_obj = state->destination(); +#ifdef ASSERT + oop from_obj = state->source(); assert(_g1h->is_in_reserved(from_obj), "must be in heap."); assert(from_obj->is_objArray(), "must be obj array"); assert(from_obj->is_forwarded(), "must be forwarded"); - - oop to_obj = from_obj->forwardee(); assert(from_obj != to_obj, "should not be chunking self-forwarded objects"); assert(to_obj->is_objArray(), "must be obj array"); +#endif // ASSERT + objArrayOop to_array = objArrayOop(to_obj); - PartialArrayTaskStepper::Step step - = _partial_array_stepper.next(objArrayOop(from_obj), - to_array, - _partial_objarray_chunk_size); - for (uint i = 0; i < step._ncreate; ++i) { - push_on_queue(ScannerTask(PartialArrayScanTask(from_obj))); + // Claim a chunk and get number of additional tasks to enqueue. + PartialArrayTaskStepper::Step step = _partial_array_stepper.next(state); + // Push any additional partial scan tasks needed. Pushed before processing + // the claimed chunk to allow other workers to steal while we're processing. + if (step._ncreate > 0) { + state->add_references(step._ncreate); + for (uint i = 0; i < step._ncreate; ++i) { + push_on_queue(ScannerTask(state)); + } } G1HeapRegionAttr dest_attr = _g1h->region_attr(to_array); G1SkipCardEnqueueSetter x(&_scanner, dest_attr.is_new_survivor()); - // Process claimed task. The length of to_array is not correct, but - // fortunately the iteration ignores the length field and just relies - // on start/end. + // Process claimed task. to_array->oop_iterate_range(&_scanner, - step._index, - step._index + _partial_objarray_chunk_size); + checked_cast(step._index), + checked_cast(step._index + _partial_array_stepper.chunk_size())); + // Release reference to the state, now that we're done with it. + _partial_array_state_allocator->release(_worker_id, state); } MAYBE_INLINE_EVACUATION @@ -260,20 +268,30 @@ void G1ParScanThreadState::start_partial_objarray(G1HeapRegionAttr dest_attr, assert(from_obj->is_objArray(), "precondition"); assert(from_obj->is_forwarded(), "precondition"); assert(from_obj->forwardee() == to_obj, "precondition"); - assert(from_obj != to_obj, "should not be scanning self-forwarded objects"); assert(to_obj->is_objArray(), "precondition"); objArrayOop to_array = objArrayOop(to_obj); - PartialArrayTaskStepper::Step step - = _partial_array_stepper.start(objArrayOop(from_obj), - to_array, - _partial_objarray_chunk_size); + size_t array_length = to_array->length(); + PartialArrayTaskStepper::Step step = _partial_array_stepper.start(array_length); // Push any needed partial scan tasks. Pushed before processing the // initial chunk to allow other workers to steal while we're processing. - for (uint i = 0; i < step._ncreate; ++i) { - push_on_queue(ScannerTask(PartialArrayScanTask(from_obj))); + if (step._ncreate > 0) { + assert(step._index < array_length, "invariant"); + assert(((array_length - step._index) % _partial_array_stepper.chunk_size()) == 0, + "invariant"); + PartialArrayState* state = + _partial_array_state_allocator->allocate(_worker_id, + from_obj, to_obj, + step._index, + array_length, + step._ncreate); + for (uint i = 0; i < step._ncreate; ++i) { + push_on_queue(ScannerTask(state)); + } + } else { + assert(step._index == array_length, "invariant"); } // Skip the card enqueue iff the object (to_array) is in survivor region. @@ -284,9 +302,8 @@ void G1ParScanThreadState::start_partial_objarray(G1HeapRegionAttr dest_attr, G1SkipCardEnqueueSetter x(&_scanner, dest_attr.is_young()); // Process the initial chunk. No need to process the type in the // klass, as it will already be handled by processing the built-in - // module. The length of to_array is not correct, but fortunately - // the iteration ignores that length field and relies on start/end. - to_array->oop_iterate_range(&_scanner, 0, step._index); + // module. + to_array->oop_iterate_range(&_scanner, 0, checked_cast(step._index)); } MAYBE_INLINE_EVACUATION @@ -297,7 +314,7 @@ void G1ParScanThreadState::dispatch_task(ScannerTask task) { } else if (task.is_oop_ptr()) { do_oop_evac(task.to_oop_ptr()); } else { - do_partial_array(task.to_partial_array_task()); + do_partial_array(task.to_partial_array_state()); } } @@ -582,7 +599,8 @@ G1ParScanThreadState* G1ParScanThreadStateSet::state_for_worker(uint worker_id) worker_id, _num_workers, _collection_set, - _evac_failure_regions); + _evac_failure_regions, + &_partial_array_state_allocator); } return _states[worker_id]; } @@ -715,7 +733,9 @@ G1ParScanThreadStateSet::G1ParScanThreadStateSet(G1CollectedHeap* g1h, _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, collection_set->young_region_length() + 1, mtGC)), _num_workers(num_workers), _flushed(false), - _evac_failure_regions(evac_failure_regions) { + _evac_failure_regions(evac_failure_regions), + _partial_array_state_allocator(num_workers) +{ _preserved_marks_set.init(num_workers); for (uint i = 0; i < num_workers; ++i) { _states[i] = nullptr; diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp index 24ca682e14118..1cfd6fca08a6f 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp @@ -32,6 +32,7 @@ #include "gc/shared/ageTable.hpp" #include "gc/shared/copyFailedInfo.hpp" #include "gc/shared/gc_globals.hpp" +#include "gc/shared/partialArrayState.hpp" #include "gc/shared/partialArrayTaskStepper.hpp" #include "gc/shared/preservedMarks.hpp" #include "gc/shared/stringdedup/stringDedup.hpp" @@ -87,7 +88,8 @@ class G1ParScanThreadState : public CHeapObj { // available for allocation. bool _old_gen_is_full; // Size (in elements) of a partial objArray task chunk. - int _partial_objarray_chunk_size; + size_t _partial_objarray_chunk_size; + PartialArrayStateAllocator* _partial_array_state_allocator; PartialArrayTaskStepper _partial_array_stepper; StringDedup::Requests _string_dedup_requests; @@ -129,7 +131,8 @@ class G1ParScanThreadState : public CHeapObj { uint worker_id, uint num_workers, G1CollectionSet* collection_set, - G1EvacFailureRegions* evac_failure_regions); + G1EvacFailureRegions* evac_failure_regions, + PartialArrayStateAllocator* partial_array_state_allocator); virtual ~G1ParScanThreadState(); void set_ref_discoverer(ReferenceDiscoverer* rd) { _scanner.set_ref_discoverer(rd); } @@ -140,7 +143,7 @@ class G1ParScanThreadState : public CHeapObj { void verify_task(narrowOop* task) const NOT_DEBUG_RETURN; void verify_task(oop* task) const NOT_DEBUG_RETURN; - void verify_task(PartialArrayScanTask task) const NOT_DEBUG_RETURN; + void verify_task(PartialArrayState* task) const NOT_DEBUG_RETURN; void verify_task(ScannerTask task) const NOT_DEBUG_RETURN; void push_on_queue(ScannerTask task); @@ -169,7 +172,7 @@ class G1ParScanThreadState : public CHeapObj { size_t flush_stats(size_t* surviving_young_words, uint num_workers, BufferNodeList* buffer_log); private: - void do_partial_array(PartialArrayScanTask task); + void do_partial_array(PartialArrayState* state); void start_partial_objarray(G1HeapRegionAttr dest_dir, oop from, oop to); HeapWord* allocate_copy_slow(G1HeapRegionAttr* dest_attr, @@ -252,6 +255,7 @@ class G1ParScanThreadStateSet : public StackObj { uint _num_workers; bool _flushed; G1EvacFailureRegions* _evac_failure_regions; + PartialArrayStateAllocator _partial_array_state_allocator; public: G1ParScanThreadStateSet(G1CollectedHeap* g1h, diff --git a/src/hotspot/share/gc/shared/partialArrayState.cpp b/src/hotspot/share/gc/shared/partialArrayState.cpp new file mode 100644 index 0000000000000..583c5dede4026 --- /dev/null +++ b/src/hotspot/share/gc/shared/partialArrayState.cpp @@ -0,0 +1,152 @@ +/* + * 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. + * + */ + +#include "precompiled.hpp" +#include "gc/shared/partialArrayState.hpp" +#include "memory/allocation.inline.hpp" +#include "memory/arena.hpp" +#include "nmt/memflags.hpp" +#include "oops/oopsHierarchy.hpp" +#include "runtime/atomic.hpp" +#include "runtime/orderAccess.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/macros.hpp" +#include + +PartialArrayState::PartialArrayState(oop src, oop dst, + size_t index, size_t length, + size_t initial_refcount) + : _source(src), + _destination(dst), + _length(length), + _index(index), + _refcount(initial_refcount) +{ + assert(index <= length, "precondition"); +} + +void PartialArrayState::add_references(size_t count) { + size_t new_count = Atomic::add(&_refcount, count, memory_order_relaxed); + assert(new_count >= count, "reference count overflow"); +} + +class PartialArrayStateAllocator::Impl : public CHeapObj { + struct FreeListEntry; + + Arena* _arenas; + FreeListEntry** _free_lists; + uint _num_workers; + +public: + Impl(uint num_workers); + ~Impl(); + + NONCOPYABLE(Impl); + + PartialArrayState* allocate(uint worker_id, + oop src, oop dst, + size_t index, size_t length, + size_t initial_refcount); + void release(uint worker_id, PartialArrayState* state); +}; + +struct PartialArrayStateAllocator::Impl::FreeListEntry { + FreeListEntry* _next; + + FreeListEntry(FreeListEntry* next) : _next(next) {} + ~FreeListEntry() = default; + + NONCOPYABLE(FreeListEntry); +}; + +PartialArrayStateAllocator::Impl::Impl(uint num_workers) + : _arenas(NEW_C_HEAP_ARRAY(Arena, num_workers, mtGC)), + _free_lists(NEW_C_HEAP_ARRAY(FreeListEntry*, num_workers, mtGC)), + _num_workers(num_workers) +{ + for (uint i = 0; i < _num_workers; ++i) { + ::new (&_arenas[i]) Arena(mtGC); + _free_lists[i] = nullptr; + } +} + +PartialArrayStateAllocator::Impl::~Impl() { + // We don't need to clean up the free lists. Deallocating the entries + // does nothing, since we're using arena allocation. Instead, leave it + // to the arena destructor to release the memory. + FREE_C_HEAP_ARRAY(FreeListEntry*, _free_lists); + for (uint i = 0; i < _num_workers; ++i) { + _arenas[i].~Arena(); + } +} + +PartialArrayState* PartialArrayStateAllocator::Impl::allocate(uint worker_id, + oop src, oop dst, + size_t index, + size_t length, + size_t initial_refcount) { + void* p; + FreeListEntry* head = _free_lists[worker_id]; + if (head == nullptr) { + p = NEW_ARENA_OBJ(&_arenas[worker_id], PartialArrayState); + } else { + _free_lists[worker_id] = head->_next; + head->~FreeListEntry(); + p = head; + } + return ::new (p) PartialArrayState(src, dst, index, length, initial_refcount); +} + +void PartialArrayStateAllocator::Impl::release(uint worker_id, PartialArrayState* state) { + size_t refcount = Atomic::sub(&state->_refcount, size_t(1), memory_order_release); + if (refcount != 0) { + assert(refcount + 1 != 0, "refcount underflow"); + } else { + OrderAccess::acquire(); + state->~PartialArrayState(); + _free_lists[worker_id] = ::new (state) FreeListEntry(_free_lists[worker_id]); + } +} + +PartialArrayStateAllocator::PartialArrayStateAllocator(uint num_workers) + : _impl(new Impl(num_workers)) +{} + +PartialArrayStateAllocator::~PartialArrayStateAllocator() { + delete _impl; +} + +PartialArrayState* PartialArrayStateAllocator::allocate(uint worker_id, + oop src, oop dst, + size_t index, + size_t length, + size_t initial_refcount) { + return _impl->allocate(worker_id, src, dst, index, length, initial_refcount); +} + +void PartialArrayStateAllocator::release(uint worker_id, PartialArrayState* state) { + _impl->release(worker_id, state); +} + diff --git a/src/hotspot/share/gc/shared/partialArrayState.hpp b/src/hotspot/share/gc/shared/partialArrayState.hpp new file mode 100644 index 0000000000000..f3bfc3ed8b859 --- /dev/null +++ b/src/hotspot/share/gc/shared/partialArrayState.hpp @@ -0,0 +1,136 @@ +/* + * 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. + * + */ + +#ifndef SHARE_GC_SHARED_PARTIALARRAYSTATE_HPP +#define SHARE_GC_SHARED_PARTIALARRAYSTATE_HPP + +#include "oops/oopsHierarchy.hpp" +#include "utilities/globalDefinitions.hpp" +#include "utilities/macros.hpp" + +class PartialArrayStateAllocator; + +// Instances of this class are used to represent processing progress for an +// array task in a taskqueue. When a sufficiently large array needs to be +// processed, such that it is desirable to split up the processing into +// parallelizable subtasks, a state object is allocated for the array. +// Multiple tasks referring to the state can then be added to the taskqueue +// for later processing, either by the current thread or by some other thread +// that steals one of those tasks. +// +// Processing a state involves using the state to claim a segment of the +// array, and processing that segment. Claiming is done by atomically +// incrementing the index, thereby claiming the segment from the old to new +// index values. New tasks should also be added as needed to ensure the +// entire array will be processed. A PartialArrayTaskStepper can be used to +// help with this. +// +// States are allocated and released using a PartialArrayStateAllocator. +// States are reference counted to aid in that management. Each task +// referring to a given state that is added to a taskqueue must increase the +// reference count by one. When the processing of a task referring to a state +// is complete, the reference count must be decreased by one. When the +// reference count reaches zero the state should be released to the allocator +// for later reuse. +class PartialArrayState { + oop _source; + oop _destination; + size_t _length; + volatile size_t _index; + volatile size_t _refcount; + + friend class PartialArrayStateAllocator; + + PartialArrayState(oop src, oop dst, + size_t index, size_t length, + size_t initial_refcount); + ~PartialArrayState() = default; + + NONCOPYABLE(PartialArrayState); + +public: + // Add count references, one per referring task being added to a taskqueue. + void add_references(size_t count); + + // The source array oop. + oop source() const { return _source; } + + // The destination array oop. In some circumstances the source and + // destination may be the same. + oop destination() const { return _destination; } + + // The length of the array oop. + size_t length() const { return _length; } + + // A pointer to the start index for the next segment to process, for atomic + // update. + volatile size_t* index_addr() { return &_index; } +}; + +// This class provides memory management for PartialArrayStates. +// +// States are initially allocated from a set of arenas owned by the allocator. +// This allows the entire set of allocated states to be discarded without the +// need to keep track of or find them under some circumstances. For example, +// if G1 concurrent marking is aborted and needs to restart because of a full +// marking queue, the queue doesn't need to be searched for tasks referring to +// states to allow releasing them. Instead the queue contents can just be +// discarded, and the memory for the no longer referenced states will +// eventually be reclaimed when the arenas are reset. +// +// A set of free-lists is placed in front of the arena allocators. This +// causes the maximum number of allocated states to be based on the number of +// in-progress arrays, rather than the total number of arrays that need to be +// processed. The use of free-list allocators is the reason for reference +// counting states. +// +// The arena and free-list to use for an allocation operation is designated by +// the worker_id used in the operation. This avoids locking and such on those +// data structures, at the cost of possibly doing more total arena allocation +// that would be needed with a single shared arena and free-list. +class PartialArrayStateAllocator { + class Impl; + Impl* _impl; + +public: + PartialArrayStateAllocator(uint num_workers); + ~PartialArrayStateAllocator(); + + NONCOPYABLE(PartialArrayStateAllocator); + + // Create a new state, obtaining the memory for it from the free-list or + // arena associated with worker_id. + PartialArrayState* allocate(uint worker_id, + oop src, oop dst, + size_t index, size_t length, + size_t initial_refcount); + + // Decrement the state's refcount. If the new refcount is zero, add the + // state to the free-list associated with worker_id. The state must have + // been allocated by this allocator, but that allocation doesn't need to + // have been associated with worker_id. + void release(uint worker_id, PartialArrayState* state); +}; + +#endif // SHARE_GC_SHARED_PARTIALARRAYSTATE_HPP diff --git a/src/hotspot/share/gc/shared/partialArrayTaskStepper.cpp b/src/hotspot/share/gc/shared/partialArrayTaskStepper.cpp index ed52d7abff18c..6faa162ac7bed 100644 --- a/src/hotspot/share/gc/shared/partialArrayTaskStepper.cpp +++ b/src/hotspot/share/gc/shared/partialArrayTaskStepper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 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 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "gc/shared/partialArrayTaskStepper.hpp" #include "oops/arrayOop.hpp" +#include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/powerOfTwo.hpp" @@ -48,7 +49,8 @@ static uint compute_task_fanout(uint task_limit) { return result; } -PartialArrayTaskStepper::PartialArrayTaskStepper(uint n_workers) : +PartialArrayTaskStepper::PartialArrayTaskStepper(uint n_workers, size_t chunk_size) : + _chunk_size(chunk_size), _task_limit(compute_task_limit(n_workers)), _task_fanout(compute_task_fanout(_task_limit)) {} diff --git a/src/hotspot/share/gc/shared/partialArrayTaskStepper.hpp b/src/hotspot/share/gc/shared/partialArrayTaskStepper.hpp index aec993f907ce6..a68d9bd361209 100644 --- a/src/hotspot/share/gc/shared/partialArrayTaskStepper.hpp +++ b/src/hotspot/share/gc/shared/partialArrayTaskStepper.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 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 @@ -28,55 +28,52 @@ #include "oops/arrayOop.hpp" #include "utilities/globalDefinitions.hpp" -// Helper for handling PartialArrayTasks. +class PartialArrayState; + +// Helper for partial array chunking tasks. // // When an array is large, we want to split it up into chunks that can be -// processed in parallel. Each task (implicitly) represents such a chunk. -// We can enqueue multiple tasks at the same time. We want to enqueue -// enough tasks to benefit from the available parallelism, while not so many -// as to substantially expand the task queues. -// -// A task directly refers to the from-space array. The from-space array's -// forwarding pointer refers to the associated to-space array, and its -// length is the actual length. The to-space array's length field is used to -// indicate processing progress. It is the starting index of the next chunk -// to process, or equals the actual length when there are no more chunks to -// be processed. +// processed in parallel. Each task (implicitly) represents such a chunk. We +// can enqueue multiple tasks at the same time. We want to enqueue enough +// tasks to benefit from the available parallelism, while not so many as to +// substantially expand the task queues. class PartialArrayTaskStepper { public: - PartialArrayTaskStepper(uint n_workers); + PartialArrayTaskStepper(uint n_workers, size_t chunk_size); struct Step { - int _index; // Array index for the step. + size_t _index; // Array index for the step. uint _ncreate; // Number of new tasks to create. }; - // Set to's length to the end of the initial chunk, which is the start of - // the first partial task if the array is large enough to need splitting. - // Returns a Step with _index being that index and _ncreate being the - // initial number of partial tasks to enqueue. - inline Step start(arrayOop from, arrayOop to, int chunk_size) const; + // Called with the length of the array to be processed. Returns a Step with + // _index being the end of the initial chunk, which the caller should + // process. This is also the starting index for the next chunk to process. + // The _ncreate is the number of tasks to enqueue to continue processing the + // array. If _ncreate is zero then _index will be length. + inline Step start(size_t length) const; + + // Atomically increment state's index by chunk_size() to claim the next + // chunk. Returns a Step with _index being the starting index of the + // claimed chunk and _ncreate being the number of additional partial tasks + // to enqueue. + inline Step next(PartialArrayState* state) const; - // Increment to's length by chunk_size to claim the next chunk. Returns a - // Step with _index being the starting index of the claimed chunk and - // _ncreate being the number of additional partial tasks to enqueue. - // precondition: chunk_size must be the same as used to start the task sequence. - inline Step next(arrayOop from, arrayOop to, int chunk_size) const; + // The size of chunks to claim for each task. + inline size_t chunk_size() const; class TestSupport; // For unit tests private: + // Size (number of elements) of a chunk to process. + size_t _chunk_size; // Limit on the number of partial array tasks to create for a given array. uint _task_limit; // Maximum number of new tasks to create when processing an existing task. uint _task_fanout; - // Split start/next into public part dealing with oops and private - // impl dealing with lengths and pointers to lengths, for unit testing. - // length is the actual length obtained from the from-space object. - // to_length_addr is the address of the to-space object's length value. - inline Step start_impl(int length, int* to_length_addr, int chunk_size) const; - inline Step next_impl(int length, int* to_length_addr, int chunk_size) const; + // For unit tests. + inline Step next_impl(size_t length, volatile size_t* index_addr) const; }; #endif // SHARE_GC_SHARED_PARTIALARRAYTASKSTEPPER_HPP diff --git a/src/hotspot/share/gc/shared/partialArrayTaskStepper.inline.hpp b/src/hotspot/share/gc/shared/partialArrayTaskStepper.inline.hpp index aa9a02c49025a..1d43578b5fea5 100644 --- a/src/hotspot/share/gc/shared/partialArrayTaskStepper.inline.hpp +++ b/src/hotspot/share/gc/shared/partialArrayTaskStepper.inline.hpp @@ -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 @@ -25,66 +25,46 @@ #ifndef SHARE_GC_SHARED_PARTIALARRAYTASKSTEPPER_INLINE_HPP #define SHARE_GC_SHARED_PARTIALARRAYTASKSTEPPER_INLINE_HPP +#include "gc/shared/partialArrayState.hpp" #include "gc/shared/partialArrayTaskStepper.hpp" - -#include "oops/arrayOop.hpp" #include "runtime/atomic.hpp" +#include "utilities/checkedCast.hpp" +#include "utilities/debug.hpp" -PartialArrayTaskStepper::Step -PartialArrayTaskStepper::start_impl(int length, - int* to_length_addr, - int chunk_size) const { - assert(chunk_size > 0, "precondition"); - - int end = length % chunk_size; // End of initial chunk. - // Set to's length to end of initial chunk. Partial tasks use that length - // field as the start of the next chunk to process. Must be done before - // enqueuing partial scan tasks, in case other threads steal any of those - // tasks. - // - // The value of end can be 0, either because of a 0-length array or - // because length is a multiple of the chunk size. Both of those are - // relatively rare and handled in the normal course of the iteration, so - // not worth doing anything special about here. - *to_length_addr = end; +size_t PartialArrayTaskStepper::chunk_size() const { + return _chunk_size; +} +PartialArrayTaskStepper::Step +PartialArrayTaskStepper::start(size_t length) const { + size_t end = length % _chunk_size; // End of initial chunk. // If the initial chunk is the complete array, then don't need any partial // tasks. Otherwise, start with just one partial task; see new task // calculation in next(). - Step result = { end, (length > end) ? 1u : 0u }; - return result; + return Step{ end, (length > end) ? 1u : 0u }; } PartialArrayTaskStepper::Step -PartialArrayTaskStepper::start(arrayOop from, arrayOop to, int chunk_size) const { - return start_impl(from->length(), to->length_addr(), chunk_size); -} - -PartialArrayTaskStepper::Step -PartialArrayTaskStepper::next_impl(int length, - int* to_length_addr, - int chunk_size) const { - assert(chunk_size > 0, "precondition"); - - // The start of the next task is in the length field of the to-space object. +PartialArrayTaskStepper::next_impl(size_t length, volatile size_t* index_addr) const { + // The start of the next task is in the state's index. // Atomically increment by the chunk size to claim the associated chunk. // Because we limit the number of enqueued tasks to being no more than the // number of remaining chunks to process, we can use an atomic add for the // claim, rather than a CAS loop. - int start = Atomic::fetch_then_add(to_length_addr, - chunk_size, - memory_order_relaxed); + size_t start = Atomic::fetch_then_add(index_addr, + _chunk_size, + memory_order_relaxed); - assert(start < length, "invariant: start %d, length %d", start, length); - assert(((length - start) % chunk_size) == 0, - "invariant: start %d, length %d, chunk size %d", - start, length, chunk_size); + assert(start < length, "invariant: start %zu, length %zu", start, length); + assert(((length - start) % _chunk_size) == 0, + "invariant: start %zu, length %zu, chunk size %zu", + start, length, _chunk_size); // Determine the number of new tasks to create. // Zero-based index for this partial task. The initial task isn't counted. - uint task_num = (start / chunk_size); + uint task_num = checked_cast(start / _chunk_size); // Number of tasks left to process, including this one. - uint remaining_tasks = (length - start) / chunk_size; + uint remaining_tasks = checked_cast((length - start) / _chunk_size); assert(remaining_tasks > 0, "invariant"); // Compute number of pending tasks, including this one. The maximum number // of tasks is a function of task_num (N) and _task_fanout (F). @@ -106,13 +86,12 @@ PartialArrayTaskStepper::next_impl(int length, // of tasks to add for this task. uint pending = MIN3(max_pending, remaining_tasks, _task_limit); uint ncreate = MIN2(_task_fanout, MIN2(remaining_tasks, _task_limit + 1) - pending); - Step result = { start, ncreate }; - return result; + return Step{ start, ncreate }; } PartialArrayTaskStepper::Step -PartialArrayTaskStepper::next(arrayOop from, arrayOop to, int chunk_size) const { - return next_impl(from->length(), to->length_addr(), chunk_size); +PartialArrayTaskStepper::next(PartialArrayState* state) const { + return next_impl(state->length(), state->index_addr()); } #endif // SHARE_GC_SHARED_PARTIALARRAYTASKSTEPPER_INLINE_HPP diff --git a/src/hotspot/share/gc/shared/taskqueue.hpp b/src/hotspot/share/gc/shared/taskqueue.hpp index 2e21ba33b0bf7..2ea75e1457c48 100644 --- a/src/hotspot/share/gc/shared/taskqueue.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, 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 @@ -576,6 +576,7 @@ class ObjArrayTask // Wrapper over an oop that is a partially scanned array. // Can be converted to a ScannerTask for placement in associated task queues. // Refers to the partially copied source array oop. +// Temporarily retained to support ParallelGC until it adopts PartialArrayState. class PartialArrayScanTask { oop _src; @@ -586,7 +587,9 @@ class PartialArrayScanTask { oop to_source_array() const { return _src; } }; -// Discriminated union over oop*, narrowOop*, and PartialArrayScanTask. +class PartialArrayState; + +// Discriminated union over oop*, narrowOop*, and PartialArrayState. // Uses a low tag in the associated pointer to identify the category. // Used as a task queue element type. class ScannerTask { @@ -624,9 +627,13 @@ class ScannerTask { explicit ScannerTask(narrowOop* p) : _p(encode(p, NarrowOopTag)) {} + // Temporarily retained to support ParallelGC until it adopts PartialArrayState. explicit ScannerTask(PartialArrayScanTask t) : _p(encode(t.to_source_array(), PartialArrayTag)) {} + explicit ScannerTask(PartialArrayState* state) : + _p(encode(state, PartialArrayTag)) {} + // Trivially copyable. // Predicate implementations assume OopTag == 0, others are powers of 2. @@ -639,10 +646,15 @@ class ScannerTask { return (raw_value() & NarrowOopTag) != 0; } + // Temporarily retained to support ParallelGC until it adopts PartialArrayState. bool is_partial_array_task() const { return (raw_value() & PartialArrayTag) != 0; } + bool is_partial_array_state() const { + return (raw_value() & PartialArrayTag) != 0; + } + oop* to_oop_ptr() const { return static_cast(decode(OopTag)); } @@ -651,9 +663,14 @@ class ScannerTask { return static_cast(decode(NarrowOopTag)); } + // Temporarily retained to support ParallelGC until it adopts PartialArrayState. PartialArrayScanTask to_partial_array_task() const { return PartialArrayScanTask(cast_to_oop(decode(PartialArrayTag))); } + + PartialArrayState* to_partial_array_state() const { + return static_cast(decode(PartialArrayTag)); + } }; #endif // SHARE_GC_SHARED_TASKQUEUE_HPP diff --git a/test/hotspot/gtest/gc/shared/test_partialArrayTaskStepper.cpp b/test/hotspot/gtest/gc/shared/test_partialArrayTaskStepper.cpp index fb797ba12c18f..3bb3a74437c8e 100644 --- a/test/hotspot/gtest/gc/shared/test_partialArrayTaskStepper.cpp +++ b/test/hotspot/gtest/gc/shared/test_partialArrayTaskStepper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 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 @@ -32,50 +32,42 @@ using Stepper = PartialArrayTaskStepper; class PartialArrayTaskStepper::TestSupport : AllStatic { public: - static Step start(const Stepper* stepper, - int length, - int* to_length_addr, - uint chunk_size) { - return stepper->start_impl(length, to_length_addr, chunk_size); - } - static Step next(const Stepper* stepper, - int length, - int* to_length_addr, - uint chunk_size) { - return stepper->next_impl(length, to_length_addr, chunk_size); + size_t length, + size_t* to_length_addr) { + return stepper->next_impl(length, to_length_addr); } }; using StepperSupport = PartialArrayTaskStepper::TestSupport; -static int simulate(const Stepper* stepper, - int length, - int* to_length_addr, - uint chunk_size) { - Step init = StepperSupport::start(stepper, length, to_length_addr, chunk_size); +static uint simulate(const Stepper* stepper, + size_t length, + size_t* to_length_addr) { + Step init = stepper->start(length); + *to_length_addr = init._index; uint queue_count = init._ncreate; - int task = 0; + uint task = 0; for ( ; queue_count > 0; ++task) { --queue_count; - Step step = StepperSupport::next(stepper, length, to_length_addr, chunk_size); + Step step = StepperSupport::next(stepper, length, to_length_addr); queue_count += step._ncreate; } return task; } -static void run_test(int length, int chunk_size, uint n_workers) { - const PartialArrayTaskStepper stepper(n_workers); - int to_length; - int tasks = simulate(&stepper, length, &to_length, chunk_size); +static void run_test(size_t length, size_t chunk_size, uint n_workers) { + const PartialArrayTaskStepper stepper(n_workers, chunk_size); + size_t to_length; + uint tasks = simulate(&stepper, length, &to_length); ASSERT_EQ(length, to_length); ASSERT_EQ(tasks, length / chunk_size); } TEST(PartialArrayTaskStepperTest, doit) { - for (int chunk_size = 50; chunk_size <= 500; chunk_size += 50) { + for (size_t chunk_size = 50; chunk_size <= 500; chunk_size += 50) { for (uint n_workers = 1; n_workers <= 256; n_workers = (n_workers * 3 / 2 + 1)) { - for (int length = 0; length <= 1000000; length = (length * 2 + 1)) { + for (size_t length = 0; length <= 1000000; length = (length * 2 + 1)) { run_test(length, chunk_size, n_workers); } // Ensure we hit boundary cases for length % chunk_size == 0. From 0e7c1c1afeaba1c125b70cabe7b1b7a3193ee5c3 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Mon, 12 Aug 2024 06:26:27 +0000 Subject: [PATCH 375/401] 8338112: Test testlibrary_tests/ir_framework/tests/TestPrivilegedMode.java fails with release build Reviewed-by: chagedorn, thartmann --- .../ir_framework/tests/TestPrivilegedMode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPrivilegedMode.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPrivilegedMode.java index 347b2eb39fbfc..2122be83a0ff2 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPrivilegedMode.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPrivilegedMode.java @@ -31,7 +31,7 @@ /* * @test - * @requires vm.flagless + * @requires vm.debug == true & vm.compiler2.enabled & vm.flagless * @summary Test that IR framework successfully adds test class to boot classpath in order to run in privileged mode. * @modules java.base/jdk.internal.vm.annotation * @library /test/lib / From 692f5cbdb9bd94f03e5f18ddf07d56fbb5c0d456 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Mon, 12 Aug 2024 07:32:10 +0000 Subject: [PATCH 376/401] 8338101: remove old remap assertion in map_or_reserve_memory_aligned after JDK-8338058 Reviewed-by: mdoerr, clanger --- src/hotspot/os/windows/os_windows.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 65ba13b0d9e81..cb0fe95269b9f 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -3462,8 +3462,8 @@ static char* map_or_reserve_memory_aligned(size_t size, size_t alignment, int fi os::attempt_reserve_memory_at(aligned_base, size, false, flag); } - assert(aligned_base != nullptr, "Did not manage to re-map after %d attempts?", max_attempts); - assert(aligned_base != nullptr, "Did not manage to re-map after %d attempts (size %zu, alignment %zu, file descriptor %d)", max_attempts, size, alignment, file_desc); + assert(aligned_base != nullptr, + "Did not manage to re-map after %d attempts (size %zu, alignment %zu, file descriptor %d)", max_attempts, size, alignment, file_desc); return aligned_base; } From 03204600c596214895ef86581eba9722f76d39b3 Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Mon, 12 Aug 2024 07:38:43 +0000 Subject: [PATCH 377/401] 8337958: Out-of-bounds array access in secondary_super_cache Reviewed-by: vlivanov, shade --- src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp | 4 ++-- src/hotspot/cpu/riscv/macroAssembler_riscv.cpp | 4 ++-- src/hotspot/cpu/x86/macroAssembler_x86.cpp | 5 ++--- src/hotspot/share/oops/klass.cpp | 13 ++++++++----- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 25dfaca6dca20..9dd4371cf69e2 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -1730,8 +1730,8 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl // The bitmap is full to bursting. // Implicit invariant: BITMAP_FULL implies (length > 0) assert(Klass::SECONDARY_SUPERS_BITMAP_FULL == ~uintx(0), ""); - cmn(r_bitmap, (u1)1); - br(EQ, L_huge); + cmpw(r_array_length, (u1)(Klass::SECONDARY_SUPERS_TABLE_SIZE - 2)); + br(GT, L_huge); // NB! Our caller has checked bits 0 and 1 in the bitmap. The // current slot (at secondary_supers[r_array_index]) has not yet diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index e0b24b7fd66ca..c6624cb45bb4e 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -3973,8 +3973,8 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl // Check if bitmap is SECONDARY_SUPERS_BITMAP_FULL assert(Klass::SECONDARY_SUPERS_BITMAP_FULL == ~uintx(0), "Adjust this code"); - addi(t0, r_bitmap, (u1)1); - beqz(t0, L_bitmap_full); + subw(t0, r_array_length, Klass::SECONDARY_SUPERS_TABLE_SIZE - 2); + bgtz(t0, L_bitmap_full); // NB! Our caller has checked bits 0 and 1 in the bitmap. The // current slot (at secondary_supers[r_array_index]) has not yet diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index c8234d6b9b88b..78bcabb2000b3 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -4945,9 +4945,8 @@ void MacroAssembler::lookup_secondary_supers_table_slow_path(Register r_super_kl // The bitmap is full to bursting. // Implicit invariant: BITMAP_FULL implies (length > 0) - assert(Klass::SECONDARY_SUPERS_BITMAP_FULL == ~uintx(0), ""); - cmpq(r_bitmap, (int32_t)-1); // sign-extends immediate to 64-bit value - jcc(Assembler::equal, L_huge); + cmpl(r_array_length, (int32_t)Klass::SECONDARY_SUPERS_TABLE_SIZE - 2); + jcc(Assembler::greater, L_huge); // NB! Our caller has checked bits 0 and 1 in the bitmap. The // current slot (at secondary_supers[r_array_index]) has not yet diff --git a/src/hotspot/share/oops/klass.cpp b/src/hotspot/share/oops/klass.cpp index 1fed317a86016..964bb030b960e 100644 --- a/src/hotspot/share/oops/klass.cpp +++ b/src/hotspot/share/oops/klass.cpp @@ -306,6 +306,7 @@ void Klass::set_secondary_supers(Array* secondaries, uintx bitmap) { if (UseSecondarySupersTable && secondaries != nullptr) { uintx real_bitmap = compute_secondary_supers_bitmap(secondaries); assert(bitmap == real_bitmap, "must be"); + assert(secondaries->length() >= (int)population_count(bitmap), "must be"); } #endif _bitmap = bitmap; @@ -344,11 +345,12 @@ uintx Klass::hash_secondary_supers(Array* secondaries, bool rewrite) { return uintx(1) << hash_slot; } - // For performance reasons we don't use a hashed table unless there - // are at least two empty slots in it. If there were only one empty - // slot it'd take a long time to create the table and the resulting - // search would be no faster than linear probing. - if (length > SECONDARY_SUPERS_TABLE_SIZE - 2) { + // Invariant: _secondary_supers.length >= population_count(_secondary_supers_bitmap) + + // Don't attempt to hash a table that's completely full, because in + // the case of an absent interface linear probing would not + // terminate. + if (length >= SECONDARY_SUPERS_TABLE_SIZE) { return SECONDARY_SUPERS_BITMAP_FULL; } @@ -788,6 +790,7 @@ void Klass::remove_java_mirror() { void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) { assert(is_klass(), "ensure C++ vtable is restored"); assert(is_shared(), "must be set"); + assert(secondary_supers()->length() >= (int)population_count(_bitmap), "must be"); JFR_ONLY(RESTORE_ID(this);) if (log_is_enabled(Trace, cds, unshareable)) { ResourceMark rm(THREAD); From a6c0630737bbf2f2e6c64863ff9b43c50c4742b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Sikstr=C3=B6m?= Date: Mon, 12 Aug 2024 10:58:05 +0000 Subject: [PATCH 378/401] 8337938: ZUtils::alloc_aligned allocates without reporting to NMT Reviewed-by: stefank, kbarrett --- src/hotspot/os/posix/gc/z/zUtils_posix.cpp | 43 ------------------- .../os/windows/gc/z/zUtils_windows.cpp | 40 ----------------- src/hotspot/share/gc/z/zStat.cpp | 4 +- src/hotspot/share/gc/z/zUtils.hpp | 4 +- src/hotspot/share/gc/z/zUtils.inline.hpp | 15 ++++++- src/hotspot/share/gc/z/zValue.inline.hpp | 6 +-- 6 files changed, 21 insertions(+), 91 deletions(-) delete mode 100644 src/hotspot/os/posix/gc/z/zUtils_posix.cpp delete mode 100644 src/hotspot/os/windows/gc/z/zUtils_windows.cpp diff --git a/src/hotspot/os/posix/gc/z/zUtils_posix.cpp b/src/hotspot/os/posix/gc/z/zUtils_posix.cpp deleted file mode 100644 index dc5af2b973a25..0000000000000 --- a/src/hotspot/os/posix/gc/z/zUtils_posix.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -#include "precompiled.hpp" -#include "gc/z/zUtils.hpp" -#include "utilities/debug.hpp" -#include "utilities/globalDefinitions.hpp" - -#include - -uintptr_t ZUtils::alloc_aligned(size_t alignment, size_t size) { - void* res = nullptr; - - // Use raw posix_memalign as long as we have no wrapper for it - ALLOW_C_FUNCTION(::posix_memalign, int rc = posix_memalign(&res, alignment, size);) - if (rc != 0) { - fatal("posix_memalign() failed"); - } - - memset(res, 0, size); - - return (uintptr_t)res; -} diff --git a/src/hotspot/os/windows/gc/z/zUtils_windows.cpp b/src/hotspot/os/windows/gc/z/zUtils_windows.cpp deleted file mode 100644 index 29f7f55e2d145..0000000000000 --- a/src/hotspot/os/windows/gc/z/zUtils_windows.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2019, 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. - */ - -#include "precompiled.hpp" -#include "gc/z/zUtils.hpp" -#include "utilities/debug.hpp" - -#include - -uintptr_t ZUtils::alloc_aligned(size_t alignment, size_t size) { - void* const res = _aligned_malloc(size, alignment); - - if (res == nullptr) { - fatal("_aligned_malloc failed"); - } - - memset(res, 0, size); - - return (uintptr_t)res; -} diff --git a/src/hotspot/share/gc/z/zStat.cpp b/src/hotspot/share/gc/z/zStat.cpp index 613f7b2740b43..c2a7a23c04f53 100644 --- a/src/hotspot/share/gc/z/zStat.cpp +++ b/src/hotspot/share/gc/z/zStat.cpp @@ -35,7 +35,7 @@ #include "gc/z/zRelocationSetSelector.inline.hpp" #include "gc/z/zStat.hpp" #include "gc/z/zTracer.inline.hpp" -#include "gc/z/zUtils.hpp" +#include "gc/z/zUtils.inline.hpp" #include "memory/metaspaceUtils.hpp" #include "memory/resourceArea.hpp" #include "runtime/atomic.hpp" @@ -364,7 +364,7 @@ void ZStatValue::initialize() { // Allocation aligned memory const size_t size = _cpu_offset * ZCPU::count(); - _base = ZUtils::alloc_aligned(ZCacheLineSize, size); + _base = ZUtils::alloc_aligned_unfreeable(ZCacheLineSize, size); } const char* ZStatValue::group() const { diff --git a/src/hotspot/share/gc/z/zUtils.hpp b/src/hotspot/share/gc/z/zUtils.hpp index f82ef06235c82..59e789d5b380f 100644 --- a/src/hotspot/share/gc/z/zUtils.hpp +++ b/src/hotspot/share/gc/z/zUtils.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -34,7 +34,7 @@ class ZUtils : public AllStatic { static const char* thread_name(); // Allocation - static uintptr_t alloc_aligned(size_t alignment, size_t size); + static uintptr_t alloc_aligned_unfreeable(size_t alignment, size_t size); // Size conversion static size_t bytes_to_words(size_t size_in_words); diff --git a/src/hotspot/share/gc/z/zUtils.inline.hpp b/src/hotspot/share/gc/z/zUtils.inline.hpp index eda9fca9398a7..b6acf12df3020 100644 --- a/src/hotspot/share/gc/z/zUtils.inline.hpp +++ b/src/hotspot/share/gc/z/zUtils.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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,11 +28,24 @@ #include "gc/z/zAddress.inline.hpp" #include "oops/oop.inline.hpp" +#include "runtime/os.hpp" #include "utilities/align.hpp" #include "utilities/copy.hpp" #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" +inline uintptr_t ZUtils::alloc_aligned_unfreeable(size_t alignment, size_t size) { + const size_t padded_size = size + (alignment - 1); + void* const addr = os::malloc(padded_size, mtGC); + void* const aligned_addr = align_up(addr, alignment); + + memset(aligned_addr, 0, size); + + // Since free expects pointers returned by malloc, aligned_addr cannot be + // freed since it is most likely not the same as addr after alignment. + return (uintptr_t)aligned_addr; +} + inline size_t ZUtils::bytes_to_words(size_t size_in_bytes) { assert(is_aligned(size_in_bytes, BytesPerWord), "Size not word aligned"); return size_in_bytes >> LogBytesPerWord; diff --git a/src/hotspot/share/gc/z/zValue.inline.hpp b/src/hotspot/share/gc/z/zValue.inline.hpp index b8c86cdd5c540..2367bac0f0aab 100644 --- a/src/hotspot/share/gc/z/zValue.inline.hpp +++ b/src/hotspot/share/gc/z/zValue.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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,7 @@ #include "gc/z/zCPU.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zNUMA.hpp" -#include "gc/z/zUtils.hpp" +#include "gc/z/zUtils.inline.hpp" #include "runtime/globals.hpp" #include "utilities/align.hpp" @@ -58,7 +58,7 @@ uintptr_t ZValueStorage::alloc(size_t size) { // Allocate new block of memory const size_t block_alignment = offset; const size_t block_size = offset * S::count(); - _top = ZUtils::alloc_aligned(block_alignment, block_size); + _top = ZUtils::alloc_aligned_unfreeable(block_alignment, block_size); _end = _top + offset; // Retry allocation From 89a15f1414f89d2dd32eac791e9155fcb4207e56 Mon Sep 17 00:00:00 2001 From: Daniel Gredler Date: Mon, 12 Aug 2024 12:09:22 +0000 Subject: [PATCH 379/401] 8337681: PNGImageWriter uses much more memory than necessary Reviewed-by: prr, lbourges --- .../imageio/plugins/png/PNGImageWriter.java | 22 ++- .../plugins/png/RasterReuseWriteTest.java | 182 ++++++++++++++++++ 2 files changed, 199 insertions(+), 5 deletions(-) create mode 100644 test/jdk/javax/imageio/plugins/png/RasterReuseWriteTest.java diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java index 27707613f76ee..ca9ba7631ca03 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java @@ -26,6 +26,7 @@ package com.sun.imageio.plugins.png; import java.awt.Rectangle; +import java.awt.image.BufferedImage; import java.awt.image.IndexColorModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; @@ -919,17 +920,28 @@ private void encodePass(ImageOutputStream os, int bitDepth = metadata.IHDR_bitDepth; for (int row = minY + yOffset; row < minY + height; row += ySkip) { - Rectangle rect = new Rectangle(minX, row, width, 1); - Raster ras = image.getData(rect); + Raster ras; + if (image instanceof BufferedImage bi) { + // Use the raster directly (no copy). + ras = bi.getRaster(); + } else if (image.getNumXTiles() == 1 && image.getNumYTiles() == 1 && + image.getTileWidth() == width && image.getTileHeight() == height) { + // Use the single tile directly (no copy). + ras = image.getTile(image.getMinTileX(), image.getMinTileY()); + } else { + // Make a copy of the raster data. + Rectangle rect = new Rectangle(minX, row, width, 1); + ras = image.getData(rect); + } + if (sourceBands != null) { - ras = ras.createChild(minX, row, width, 1, minX, row, - sourceBands); + ras = ras.createChild(minX, row, width, 1, minX, row, sourceBands); } ras.getPixels(minX, row, width, 1, samples); if (image.getColorModel().isAlphaPremultiplied()) { - WritableRaster wr = ras.createCompatibleWritableRaster(); + WritableRaster wr = ras.createCompatibleWritableRaster(minX, row, width, 1); wr.setPixels(wr.getMinX(), wr.getMinY(), wr.getWidth(), wr.getHeight(), samples); diff --git a/test/jdk/javax/imageio/plugins/png/RasterReuseWriteTest.java b/test/jdk/javax/imageio/plugins/png/RasterReuseWriteTest.java new file mode 100644 index 0000000000000..64adaa6d196d2 --- /dev/null +++ b/test/jdk/javax/imageio/plugins/png/RasterReuseWriteTest.java @@ -0,0 +1,182 @@ +/* + * 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 8337681 + * @summary Test that raster use optimization does not cause any regressions. + */ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.RenderedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.ImageOutputStream; +import javax.imageio.stream.MemoryCacheImageOutputStream; + +public class RasterReuseWriteTest { + + public static void main(String[] args) throws Exception { + test(BufferedImage.TYPE_INT_RGB); + test(BufferedImage.TYPE_INT_ARGB); + test(BufferedImage.TYPE_INT_ARGB_PRE); + test(BufferedImage.TYPE_4BYTE_ABGR); + test(BufferedImage.TYPE_4BYTE_ABGR_PRE); + } + + private static void test(int type) throws Exception { + + // swaps blue and red + int bands = (type == BufferedImage.TYPE_INT_RGB ? 3 : 4); + int[] sourceBands = bands == 3 ? new int[] { 2, 1, 0 } : + new int[] { 2, 1, 0, 3 }; + + // test writing a BufferedImage without source bands + BufferedImage img1 = createImage(256, 256, type); + byte[] bytes1 = writePng(img1, null); + BufferedImage img2 = ImageIO.read(new ByteArrayInputStream(bytes1)); + compare(img1, img2, false); + + // test writing a BufferedImage with source bands + BufferedImage img3 = createImage(256, 256, type); + byte[] bytes3 = writePng(img3, sourceBands); + BufferedImage img4 = ImageIO.read(new ByteArrayInputStream(bytes3)); + compare(img3, img4, true); + + // test writing a non-BufferedImage with source bands and one tile + RenderedImage img5 = toTiledImage(img1, 256); + byte[] bytes5 = writePng(img5, sourceBands); + BufferedImage img6 = ImageIO.read(new ByteArrayInputStream(bytes5)); + compare(img5, img6, true); + + // test writing a non-BufferedImage with source bands and multiple tiles + RenderedImage img7 = toTiledImage(img1, 128); + byte[] bytes7 = writePng(img7, sourceBands); + BufferedImage img8 = ImageIO.read(new ByteArrayInputStream(bytes7)); + compare(img7, img8, true); + } + + private static BufferedImage createImage(int w, int h, int type) throws Exception { + BufferedImage img = new BufferedImage(w, h, type); + Graphics2D g2d = img.createGraphics(); + g2d.setColor(Color.WHITE); + g2d.fillRect(0, 0, w, h); + g2d.setColor(Color.GREEN); + g2d.drawRect(20, 20, 100, 50); + g2d.setColor(Color.RED); + g2d.drawRect(80, 10, 100, 40); + g2d.setColor(Color.BLUE); + g2d.fillRect(40, 60, 120, 30); + g2d.dispose(); + return img; + } + + private static byte[] writePng(RenderedImage img, int[] sourceBands) throws Exception { + ImageWriter writer = ImageIO.getImageWritersByFormatName("png").next(); + ImageWriteParam param = writer.getDefaultWriteParam(); + param.setSourceBands(sourceBands); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageOutputStream stream = new MemoryCacheImageOutputStream(baos); + writer.setOutput(stream); + writer.write(null, new IIOImage(img, null, null), param); + writer.dispose(); + stream.flush(); + return baos.toByteArray(); + } + + private static void compare(RenderedImage img1, RenderedImage img2, boolean blueAndRedSwapped) { + int[] pixels1 = getRgbPixels(img1); + int[] pixels2 = getRgbPixels(img2); + for (int i = 0; i < pixels1.length; i++) { + int expected; + if (blueAndRedSwapped && pixels1[i] == 0xFFFF0000) { + expected = 0xFF0000FF; // red -> blue + } else if (blueAndRedSwapped && pixels1[i] == 0xFF0000FF) { + expected = 0xFFFF0000; // blue -> red + } else { + expected = pixels1[i]; // no change + } + int actual = pixels2[i]; + if (actual != expected) { + throw new RuntimeException("Pixel " + i + ": expected " + + Integer.toHexString(expected) + ", but got " + + Integer.toHexString(actual)); + } + } + } + + private static int[] getRgbPixels(RenderedImage img) { + int w = img.getWidth(); + int h = img.getHeight(); + if (img instanceof BufferedImage bi) { + return bi.getRGB(0, 0, w, h, null, 0, w); + } else { + BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = bi.createGraphics(); + g2d.drawRenderedImage(img, new AffineTransform()); + g2d.dispose(); + return bi.getRGB(0, 0, w, h, null, 0, w); + } + } + + private static RenderedImage toTiledImage(BufferedImage img, int tileSize) throws Exception { + + // write to TIFF + ImageWriter writer = ImageIO.getImageWritersByFormatName("tiff").next(); + ImageWriteParam param = writer.getDefaultWriteParam(); + param.setTilingMode(ImageWriteParam.MODE_EXPLICIT); + param.setTiling(tileSize, tileSize, 0, 0); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageOutputStream stream = new MemoryCacheImageOutputStream(baos); + writer.setOutput(stream); + writer.write(null, new IIOImage(img, null, null), param); + writer.dispose(); + stream.flush(); + byte[] bytes = baos.toByteArray(); + + // read from TIFF + ImageReader reader = ImageIO.getImageReadersByFormatName("tiff").next(); + ImageInputStream input = ImageIO.createImageInputStream(new ByteArrayInputStream(bytes)); + reader.setInput(input); + RenderedImage ri = reader.readAsRenderedImage(0, null); + if (ri instanceof BufferedImage) { + throw new RuntimeException("Unexpected BufferedImage"); + } + int tw = ri.getTileWidth(); + int th = ri.getTileHeight(); + if (tw != tileSize || th != tileSize) { + throw new RuntimeException("Expected tile size " + tileSize + + ", but found " + tw + "x" + th); + } + return ri; + } +} From 61d1dc59535a3dc186bc1986a04efdb4e5a8fa18 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Mon, 12 Aug 2024 13:52:57 +0000 Subject: [PATCH 380/401] 8334466: Ambiguous method call with generics may cause FunctionDescriptorLookupError Reviewed-by: jlahoda --- .../com/sun/tools/javac/comp/Resolve.java | 14 ++++++++--- ...WithFunctionDescriptorLookupErrorTest.java | 25 +++++++++++++++++++ ...hWithFunctionDescriptorLookupErrorTest.out | 2 ++ 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 test/langtools/tools/javac/lambda/CrashWithFunctionDescriptorLookupErrorTest.java create mode 100644 test/langtools/tools/javac/lambda/CrashWithFunctionDescriptorLookupErrorTest.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 c71b6d341dc12..5bf1bc0ead149 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 @@ -1219,9 +1219,17 @@ private boolean unrelatedInterfaces(Type t, Type s) { /** Parameters {@code t} and {@code s} are unrelated functional interface types. */ private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) { - Type tDesc = types.findDescriptorType(types.capture(t)); - Type tDescNoCapture = types.findDescriptorType(t); - Type sDesc = types.findDescriptorType(s); + Type tDesc; + Type tDescNoCapture; + Type sDesc; + try { + tDesc = types.findDescriptorType(types.capture(t)); + tDescNoCapture = types.findDescriptorType(t); + sDesc = types.findDescriptorType(s); + } catch (Types.FunctionDescriptorLookupError ex) { + // don't report, a more meaningful error should be reported upstream + return false; + } final List tTypeParams = tDesc.getTypeArguments(); final List tTypeParamsNoCapture = tDescNoCapture.getTypeArguments(); final List sTypeParams = sDesc.getTypeArguments(); diff --git a/test/langtools/tools/javac/lambda/CrashWithFunctionDescriptorLookupErrorTest.java b/test/langtools/tools/javac/lambda/CrashWithFunctionDescriptorLookupErrorTest.java new file mode 100644 index 0000000000000..bfdfc30609de4 --- /dev/null +++ b/test/langtools/tools/javac/lambda/CrashWithFunctionDescriptorLookupErrorTest.java @@ -0,0 +1,25 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8334466 + * @summary Ambiguous method call with generics may cause FunctionDescriptorLookupError + * @compile/fail/ref=CrashWithFunctionDescriptorLookupErrorTest.out -XDrawDiagnostics CrashWithFunctionDescriptorLookupErrorTest.java + */ + +import java.util.List; + +class CrashWithFunctionDescriptorLookupErrorTest { + void m() { + List list = List.of(new X()); + test(list.get(0)); + } + + void test(A a) { } + void test(B b) { } + + interface A> { T a(); } + interface B> { T b(); } + class X implements A, B { + public X a() { return null; } + public X b() { return null; } + } +} diff --git a/test/langtools/tools/javac/lambda/CrashWithFunctionDescriptorLookupErrorTest.out b/test/langtools/tools/javac/lambda/CrashWithFunctionDescriptorLookupErrorTest.out new file mode 100644 index 0000000000000..06afbc8bc18a6 --- /dev/null +++ b/test/langtools/tools/javac/lambda/CrashWithFunctionDescriptorLookupErrorTest.out @@ -0,0 +1,2 @@ +CrashWithFunctionDescriptorLookupErrorTest.java:13:9: compiler.err.ref.ambiguous: test, kindname.method, test(CrashWithFunctionDescriptorLookupErrorTest.A), CrashWithFunctionDescriptorLookupErrorTest, kindname.method, test(CrashWithFunctionDescriptorLookupErrorTest.B), CrashWithFunctionDescriptorLookupErrorTest +1 error From a36fb368e1a3630d32908884f4abdc3382eb9aaa Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Mon, 12 Aug 2024 15:33:31 +0000 Subject: [PATCH 381/401] 8338108: Give better error message in configure if a full XCode is missing Reviewed-by: jwaters, erikj, shade --- make/autoconf/toolchain.m4 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/make/autoconf/toolchain.m4 b/make/autoconf/toolchain.m4 index 57064df1ed75f..12d450cc708cd 100644 --- a/make/autoconf/toolchain.m4 +++ b/make/autoconf/toolchain.m4 @@ -678,6 +678,9 @@ AC_DEFUN_ONCE([TOOLCHAIN_DETECT_TOOLCHAIN_EXTRA], test_metal=`$METAL --version 2>&1` if test $? -ne 0; then AC_MSG_RESULT([no]) + AC_MSG_NOTICE([A full XCode is required to build the JDK (not only command line tools)]) + AC_MSG_NOTICE([If you have XCode installed, you might need to reset the Xcode active developer directory]) + AC_MSG_NOTICE([using 'sudo xcode-select -r']) AC_MSG_ERROR([XCode tool 'metal' neither found in path nor with xcrun]) else AC_MSG_RESULT([yes, will be using '$METAL']) From 04b146a31f55825e2c8e3c8e42310b3b3337ae95 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Mon, 12 Aug 2024 15:43:40 +0000 Subject: [PATCH 382/401] 8337334: Test tools/javac/7142086/T7142086.java timeout with fastdebug binary Reviewed-by: vromero --- test/langtools/TEST.ROOT | 3 ++- test/langtools/tools/javac/7142086/T7142086.java | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/test/langtools/TEST.ROOT b/test/langtools/TEST.ROOT index 11daad5244f31..d816d5b096b79 100644 --- a/test/langtools/TEST.ROOT +++ b/test/langtools/TEST.ROOT @@ -42,4 +42,5 @@ requires.extraPropDefns.vmOpts = \ -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI \ --add-exports java.base/jdk.internal.foreign=ALL-UNNAMED requires.properties= \ - vm.continuations + vm.continuations \ + vm.debug diff --git a/test/langtools/tools/javac/7142086/T7142086.java b/test/langtools/tools/javac/7142086/T7142086.java index bc8260bd486f6..b6521b7ffbc05 100644 --- a/test/langtools/tools/javac/7142086/T7142086.java +++ b/test/langtools/tools/javac/7142086/T7142086.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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,12 +23,20 @@ /* * @test - * @bug 7142086 + * @bug 7142086 8337334 + * @requires vm.debug == false * @summary performance problem in Check.checkOverrideClashes(...) * @modules jdk.compiler * @run main/timeout=10 T7142086 */ +/* + * @test + * @requires vm.debug == true + * @modules jdk.compiler + * @run main/timeout=20 T7142086 + */ + import com.sun.source.util.JavacTask; import java.net.URI; import java.util.List; From f84240bca80d2ff01e198bb67931ad4725a5b334 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Mon, 12 Aug 2024 16:03:41 +0000 Subject: [PATCH 383/401] 8338011: CDS archived heap object support for 64-bit Windows Reviewed-by: stuefe, shade, ccheung --- src/hotspot/share/cds/filemap.cpp | 42 +++++++++++++++++--------- src/hotspot/share/cds/heapShared.cpp | 1 - src/hotspot/share/utilities/macros.hpp | 4 +-- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 96c826fb67e82..c5a9d5cceed53 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -2178,21 +2178,35 @@ bool FileMapInfo::map_heap_region_impl() { // Map the archived heap data. No need to call MemTracker::record_virtual_memory_type() // for mapped region as it is part of the reserved java heap, which is already recorded. char* addr = (char*)_mapped_heap_memregion.start(); - char* base = map_memory(_fd, _full_path, r->file_offset(), - addr, _mapped_heap_memregion.byte_size(), r->read_only(), - r->allow_exec()); - if (base == nullptr || base != addr) { - dealloc_heap_region(); - log_info(cds)("UseSharedSpaces: Unable to map at required address in java heap. " - INTPTR_FORMAT ", size = " SIZE_FORMAT " bytes", - p2i(addr), _mapped_heap_memregion.byte_size()); - return false; - } + char* base; - if (VerifySharedSpaces && !r->check_region_crc(base)) { - dealloc_heap_region(); - log_info(cds)("UseSharedSpaces: mapped heap region is corrupt"); - return false; + if (MetaspaceShared::use_windows_memory_mapping()) { + if (!read_region(MetaspaceShared::hp, addr, + align_up(_mapped_heap_memregion.byte_size(), os::vm_page_size()), + /* do_commit = */ true)) { + dealloc_heap_region(); + log_error(cds)("Failed to read archived heap region into " INTPTR_FORMAT, p2i(addr)); + return false; + } + // Checks for VerifySharedSpaces is already done inside read_region() + base = addr; + } else { + base = map_memory(_fd, _full_path, r->file_offset(), + addr, _mapped_heap_memregion.byte_size(), r->read_only(), + r->allow_exec()); + if (base == nullptr || base != addr) { + dealloc_heap_region(); + log_info(cds)("UseSharedSpaces: Unable to map at required address in java heap. " + INTPTR_FORMAT ", size = " SIZE_FORMAT " bytes", + p2i(addr), _mapped_heap_memregion.byte_size()); + return false; + } + + if (VerifySharedSpaces && !r->check_region_crc(base)) { + dealloc_heap_region(); + log_info(cds)("UseSharedSpaces: mapped heap region is corrupt"); + return false; + } } r->set_mapped_base(base); diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index ff84ddc13fc6c..0a0dc56c894a4 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -1554,7 +1554,6 @@ void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[], // by any of these static fields. // At runtime, these classes are initialized before X's archived fields // are restored by HeapShared::initialize_from_archived_subgraph(). - int i; for (int i = 0; fields[i].valid(); ) { ArchivableStaticFieldInfo* info = &fields[i]; const char* klass_name = info->klass_name; diff --git a/src/hotspot/share/utilities/macros.hpp b/src/hotspot/share/utilities/macros.hpp index 244b18ecdd422..1034dec0d9aaa 100644 --- a/src/hotspot/share/utilities/macros.hpp +++ b/src/hotspot/share/utilities/macros.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -621,7 +621,7 @@ #define COMPILER_HEADER(basename) XSTR(COMPILER_HEADER_STEM(basename).hpp) #define COMPILER_HEADER_INLINE(basename) XSTR(COMPILER_HEADER_STEM(basename).inline.hpp) -#if INCLUDE_CDS && INCLUDE_G1GC && defined(_LP64) && !defined(_WINDOWS) +#if INCLUDE_CDS && INCLUDE_G1GC && defined(_LP64) #define INCLUDE_CDS_JAVA_HEAP 1 #define CDS_JAVA_HEAP_ONLY(x) x #define NOT_CDS_JAVA_HEAP(x) From 8d0831478338e9b084b2c47f46eba9faae3a5eb6 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Mon, 12 Aug 2024 17:15:39 +0000 Subject: [PATCH 384/401] 8337795: Type annotation attached to incorrect type during class reading Reviewed-by: vromero --- .../com/sun/tools/javac/jvm/ClassReader.java | 145 ++++++++---------- .../processing/model/type/BasicAnnoTests.java | 4 + 2 files changed, 65 insertions(+), 84 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java index dba5fb6a1975c..fcc1efda8dcc0 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java @@ -36,9 +36,9 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.function.BiFunction; import java.util.function.IntFunction; import java.util.function.Predicate; +import java.util.stream.IntStream; import javax.lang.model.element.Modifier; import javax.lang.model.element.NestingKind; @@ -2461,13 +2461,8 @@ private Type addTypeAnnotations(Type type, Predicate fil .add(attribute); } - // Search the structure of the type to find the contained types at each type path - Map> attributesByType = new HashMap<>(); - new TypeAnnotationLocator(attributesByPath, attributesByType).visit(type, List.nil()); - // Rewrite the type and add the annotations - type = new TypeAnnotationTypeMapping(attributesByType).visit(type, null); - Assert.check(attributesByType.isEmpty(), "Failed to apply annotations to types"); + type = new TypeAnnotationStructuralTypeMapping(attributesByPath).visit(type, List.nil()); return type; } @@ -2495,120 +2490,102 @@ private static Predicate classExtends(int index) { } /** - * Visit all contained types, assembling a type path to represent the current location, and - * record the types at each type path that need to be annotated. + * A type mapping that rewrites the type to include type annotations. + * + *

This logic is similar to {@link Type.StructuralTypeMapping}, but also tracks the path to + * the contained types being rewritten, and so cannot easily share the existing logic. */ - private static class TypeAnnotationLocator - extends Types.DefaultTypeVisitor> { + private static final class TypeAnnotationStructuralTypeMapping + extends Types.TypeMapping> { + private final Map, - ListBuffer> attributesByPath; - private final Map> attributesByType; + ListBuffer> attributesByPath; - private TypeAnnotationLocator( + private TypeAnnotationStructuralTypeMapping( Map, ListBuffer> - attributesByPath, - Map> attributesByType) { + attributesByPath) { this.attributesByPath = attributesByPath; - this.attributesByType = attributesByType; } + @Override - public Void visitClassType(ClassType t, List path) { + public Type visitClassType(ClassType t, List path) { // As described in JVMS 4.7.20.2, type annotations on nested types are located with // 'left-to-right' steps starting on 'the outermost part of the type for which a type // annotation is admissible'. So the current path represents the outermost containing // type of the type being visited, and we add type path steps for every contained nested // type. - List enclosing = List.nil(); - for (Type curr = t; - curr != null && curr != Type.noType; + Type outer = t.getEnclosingType(); + Type outer1 = outer != Type.noType ? visit(outer, path) : outer; + for (Type curr = t.getEnclosingType(); + curr != Type.noType; curr = curr.getEnclosingType()) { - enclosing = enclosing.prepend((ClassType) curr); - } - for (ClassType te : enclosing) { - if (te.typarams_field != null) { - int i = 0; - for (Type typaram : te.typarams_field) { - visit(typaram, path.append(new TypeAnnotationPosition.TypePathEntry( - TypeAnnotationPosition.TypePathEntryKind.TYPE_ARGUMENT, i++))); - } - } - visitType(te, path); path = path.append(TypeAnnotationPosition.TypePathEntry.INNER_TYPE); } - return null; + List typarams = t.getTypeArguments(); + List typarams1 = rewriteTypeParams(path, typarams); + if (outer1 != outer || typarams != typarams1) { + t = new ClassType(outer1, typarams1, t.tsym, t.getMetadata()); + } + return reannotate(t, path); } - @Override - public Void visitWildcardType( - WildcardType t, List path) { - visit(t.type, path.append(TypeAnnotationPosition.TypePathEntry.WILDCARD)); - return super.visitWildcardType(t, path); + private List rewriteTypeParams( + List path, List typarams) { + var i = IntStream.iterate(0, x -> x + 1).iterator(); + return typarams.map(typaram -> visit(typaram, + path.append(new TypeAnnotationPosition.TypePathEntry( + TypeAnnotationPosition.TypePathEntryKind.TYPE_ARGUMENT, i.nextInt())))); } @Override - public Void visitArrayType(ArrayType t, List path) { - visit(t.elemtype, path.append(TypeAnnotationPosition.TypePathEntry.ARRAY)); - return super.visitArrayType(t, path); + public Type visitWildcardType( + WildcardType wt, List path) { + Type t = wt.type; + if (t != null) { + t = visit(t, path.append(TypeAnnotationPosition.TypePathEntry.WILDCARD)); + } + if (t != wt.type) { + wt = new WildcardType(t, wt.kind, wt.tsym, wt.bound, wt.getMetadata()); + } + return reannotate(wt, path); } @Override - public Void visitType(Type t, List path) { - ListBuffer attributes = attributesByPath.remove(path); - if (attributes != null) { - attributesByType.put(t, attributes.toList()); + public Type visitArrayType(ArrayType t, List path) { + Type elemtype = t.elemtype; + Type elemtype1 = + visit(elemtype, path.append(TypeAnnotationPosition.TypePathEntry.ARRAY)); + if (elemtype1 != elemtype) { + t = new ArrayType(elemtype1, t.tsym, t.getMetadata()); } - return null; + return reannotate(t, path); } - } - - /** A type mapping that rewrites the type to include type annotations. */ - private static class TypeAnnotationTypeMapping extends Type.StructuralTypeMapping { - private final Map> attributesByType; - - private TypeAnnotationTypeMapping( - Map> attributesByType) { - this.attributesByType = attributesByType; + @Override + public Type visitType(Type t, List path) { + return reannotate(t, path); } - private Type reannotate(T t, BiFunction f) { - // We're relying on object identify of Type instances to record where the annotations - // need to be added, so we have to retrieve the annotations for each type before - // rewriting it, and then add them after its contained types have been rewritten. - List attributes = attributesByType.remove(t); - Type mapped = f.apply(t, null); - if (attributes == null) { - return mapped; + Type reannotate(Type type, List path) { + List attributes = attributesForPath(path); + if (attributes.isEmpty()) { + return type; } // Runtime-visible and -invisible annotations are completed separately, so if the same // type has annotations from both it will get annotated twice. - TypeMetadata.Annotations existing = mapped.getMetadata(TypeMetadata.Annotations.class); + TypeMetadata.Annotations existing = type.getMetadata(TypeMetadata.Annotations.class); if (existing != null) { existing.annotationBuffer().addAll(attributes); - return mapped; + return type; } - return mapped.annotatedType(attributes); + return type.annotatedType(attributes); } - @Override - public Type visitClassType(ClassType t, Void unused) { - return reannotate(t, super::visitClassType); - } - - @Override - public Type visitWildcardType(WildcardType t, Void unused) { - return reannotate(t, super::visitWildcardType); - } - - @Override - public Type visitArrayType(ArrayType t, Void unused) { - return reannotate(t, super::visitArrayType); - } - - @Override - public Type visitType(Type t, Void unused) { - return reannotate(t, (x, u) -> x); + List attributesForPath( + List path) { + ListBuffer attributes = attributesByPath.remove(path); + return attributes != null ? attributes.toList() : List.nil(); } } diff --git a/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java b/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java index d45edc8e3d6e3..acd91eac8c785 100644 --- a/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java +++ b/test/langtools/tools/javac/processing/model/type/BasicAnnoTests.java @@ -717,4 +717,8 @@ private class GenericNested { GenericNested(@TA(120) GenericInner120 GenericInner120.this) {} } } + + @Test(posn=1, annoType=TA.class, expect="130") + @Test(posn=23, annoType=TA.class, expect="131") + public Map<@TA(130) String, @TA(131) String> f130; } From 99edb4a45d6a4a871dec9c07b41b3ab66b89a4b6 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Mon, 12 Aug 2024 17:20:20 +0000 Subject: [PATCH 385/401] 8337702: Use new ForwardExceptionNode to call StubRoutines::forward_exception_entry() Reviewed-by: thartmann --- src/hotspot/cpu/aarch64/aarch64.ad | 13 ++++++++ src/hotspot/cpu/arm/arm.ad | 14 +++++++++ src/hotspot/cpu/ppc/ppc.ad | 15 +++++++++ src/hotspot/cpu/riscv/riscv.ad | 16 ++++++++++ src/hotspot/cpu/s390/s390.ad | 14 +++++++++ src/hotspot/cpu/x86/x86_32.ad | 12 ++++++++ src/hotspot/cpu/x86/x86_64.ad | 12 ++++++++ src/hotspot/share/adlc/formssel.cpp | 34 ++++++++++++--------- src/hotspot/share/opto/callnode.hpp | 11 +++++++ src/hotspot/share/opto/classes.hpp | 1 + src/hotspot/share/opto/domgraph.cpp | 1 + src/hotspot/share/opto/gcm.cpp | 5 ++- src/hotspot/share/opto/generateOptoStub.cpp | 14 ++++----- src/hotspot/share/opto/matcher.cpp | 15 ++++++++- src/hotspot/share/runtime/vmStructs.cpp | 1 + 15 files changed, 153 insertions(+), 25 deletions(-) diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index d8db75961d8af..66a24a61f29c2 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -16184,6 +16184,19 @@ instruct TailjmpInd(iRegPNoSpNoRfp jump_target, iRegP_R0 ex_oop) ins_pipe(pipe_class_call); %} +// Forward exception. +instruct ForwardExceptionjmp() +%{ + match(ForwardException); + ins_cost(CALL_COST); + + format %{ "b forward_exception_stub" %} + ins_encode %{ + __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry())); + %} + ins_pipe(pipe_class_call); +%} + // Create exception oop: created by stack-crawling runtime code. // Created exception is now available to this handler, and is setup // just prior to jumping to this handler. No code emitted. diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad index 638c48ad5aa31..2c7de0a58a204 100644 --- a/src/hotspot/cpu/arm/arm.ad +++ b/src/hotspot/cpu/arm/arm.ad @@ -8953,6 +8953,20 @@ instruct tailjmpInd(IPRegP jump_target, RExceptionRegP ex_oop) %{ ins_pipe(tail_call); %} +// Forward exception. +instruct ForwardExceptionjmp() +%{ + match(ForwardException); + ins_cost(CALL_COST); + + format %{ "b forward_exception_stub" %} + ins_encode %{ + // OK to trash Rtemp, because Rtemp is used by stub + __ jump(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type, Rtemp); + %} + ins_pipe(tail_call); +%} + // Create exception oop: created by stack-crawling runtime code. // Created exception is now available to this handler, and is setup // just prior to jumping to this handler. No code emitted. diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad index 38485da958132..b34d3ef150140 100644 --- a/src/hotspot/cpu/ppc/ppc.ad +++ b/src/hotspot/cpu/ppc/ppc.ad @@ -14534,6 +14534,21 @@ instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{ ins_pipe(pipe_class_call); %} +// Forward exception. +instruct ForwardExceptionjmp() +%{ + match(ForwardException); + ins_cost(CALL_COST); + + format %{ "Jmp forward_exception_stub" %} + ins_encode %{ + __ set_inst_mark(); + __ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type); + __ clear_inst_mark(); + %} + ins_pipe(pipe_class_call); +%} + // Create exception oop: created by stack-crawling runtime code. // Created exception is now available to this handler, and is setup // just prior to jumping to this handler. No code emitted. diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index 1e26c2bf14202..d3e2b0549e9ea 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -10617,6 +10617,22 @@ instruct TailjmpInd(iRegPNoSpNoFp jump_target, iRegP_R10 ex_oop) ins_pipe(pipe_class_call); %} +// Forward exception. +instruct ForwardExceptionjmp() +%{ + match(ForwardException); + + ins_cost(BRANCH_COST); + + format %{ "j forward_exception_stub\t#@ForwardException" %} + + ins_encode %{ + __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry())); + %} + + ins_pipe(pipe_class_call); +%} + // Create exception oop: created by stack-crawling runtime code. // Created exception is now available to this handler, and is setup // just prior to jumping to this handler. No code emitted. diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad index e3dcfdb8759da..4de1a4e7b7f35 100644 --- a/src/hotspot/cpu/s390/s390.ad +++ b/src/hotspot/cpu/s390/s390.ad @@ -9517,6 +9517,20 @@ instruct tailjmpInd(iRegP jump_target, rarg1RegP ex_oop) %{ ins_pipe(pipe_class_dummy); %} +// Forward exception. +instruct ForwardExceptionjmp() %{ + match(ForwardException); + ins_cost(CALL_COST); + format %{ "Jmp forward_exception_stub" %} + ins_encode %{ + __ set_inst_mark(); + __ load_const_optimized(Z_R1_scratch, (address)StubRoutines::forward_exception_entry()); + __ z_br(Z_R1_scratch); + __ clear_inst_mark(); + %} + ins_pipe(pipe_class_dummy); +%} + // Create exception oop: created by stack-crawling runtime code. // Created exception is now available to this handler, and is setup // just prior to jumping to this handler. No code emitted. diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad index 49a3cad37df2f..7aa4f6a29a116 100644 --- a/src/hotspot/cpu/x86/x86_32.ad +++ b/src/hotspot/cpu/x86/x86_32.ad @@ -13583,6 +13583,18 @@ instruct tailjmpInd(eRegP_no_EBP jump_target, eAXRegP ex_oop) %{ ins_pipe( pipe_jmp ); %} +// Forward exception. +instruct ForwardExceptionjmp() +%{ + match(ForwardException); + + format %{ "JMP forward_exception_stub" %} + ins_encode %{ + __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); + %} + ins_pipe(pipe_jmp); +%} + // Create exception oop: created by stack-crawling runtime code. // Created exception is now available to this handler, and is setup // just prior to jumping to this handler. No code emitted. diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index 1490cfa60b34f..3bc4cac2f06a7 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -12592,6 +12592,18 @@ instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) ins_pipe(pipe_jmp); %} +// Forward exception. +instruct ForwardExceptionjmp() +%{ + match(ForwardException); + + format %{ "jmp forward_exception_stub" %} + ins_encode %{ + __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); + %} + ins_pipe(pipe_jmp); +%} + // Create exception oop: created by stack-crawling runtime code. // Created exception is now available to this handler, and is setup // just prior to jumping to this handler. No code emitted. diff --git a/src/hotspot/share/adlc/formssel.cpp b/src/hotspot/share/adlc/formssel.cpp index be97547f8ce11..e7df38ff221a9 100644 --- a/src/hotspot/share/adlc/formssel.cpp +++ b/src/hotspot/share/adlc/formssel.cpp @@ -210,15 +210,16 @@ bool InstructForm::is_pinned(FormDict &globals) { if ( ! _matrule) return false; int index = 0; - if (_matrule->find_type("Goto", index)) return true; - if (_matrule->find_type("If", index)) return true; - if (_matrule->find_type("CountedLoopEnd",index)) return true; - if (_matrule->find_type("Return", index)) return true; - if (_matrule->find_type("Rethrow", index)) return true; - if (_matrule->find_type("TailCall", index)) return true; - if (_matrule->find_type("TailJump", index)) return true; - if (_matrule->find_type("Halt", index)) return true; - if (_matrule->find_type("Jump", index)) return true; + if (_matrule->find_type("Goto", index)) return true; + if (_matrule->find_type("If", index)) return true; + if (_matrule->find_type("CountedLoopEnd", index)) return true; + if (_matrule->find_type("Return", index)) return true; + if (_matrule->find_type("Rethrow", index)) return true; + if (_matrule->find_type("TailCall", index)) return true; + if (_matrule->find_type("TailJump", index)) return true; + if (_matrule->find_type("ForwardException", index)) return true; + if (_matrule->find_type("Halt", index)) return true; + if (_matrule->find_type("Jump", index)) return true; return is_parm(globals); } @@ -228,12 +229,13 @@ bool InstructForm::is_projection(FormDict &globals) { if ( ! _matrule) return false; int index = 0; - if (_matrule->find_type("Goto", index)) return true; - if (_matrule->find_type("Return", index)) return true; - if (_matrule->find_type("Rethrow", index)) return true; - if (_matrule->find_type("TailCall",index)) return true; - if (_matrule->find_type("TailJump",index)) return true; - if (_matrule->find_type("Halt", index)) return true; + if (_matrule->find_type("Goto", index)) return true; + if (_matrule->find_type("Return", index)) return true; + if (_matrule->find_type("Rethrow", index)) return true; + if (_matrule->find_type("TailCall", index)) return true; + if (_matrule->find_type("TailJump", index)) return true; + if (_matrule->find_type("ForwardException", index)) return true; + if (_matrule->find_type("Halt", index)) return true; return false; } @@ -376,6 +378,7 @@ bool InstructForm::is_ideal_return() const { if (_matrule->find_type("Rethrow",index)) return true; if (_matrule->find_type("TailCall",index)) return true; if (_matrule->find_type("TailJump",index)) return true; + if (_matrule->find_type("ForwardException", index)) return true; return false; } @@ -894,6 +897,7 @@ uint InstructForm::oper_input_base(FormDict &globals) { strcmp(_matrule->_opType,"Rethrow" )==0 || strcmp(_matrule->_opType,"TailCall" )==0 || strcmp(_matrule->_opType,"TailJump" )==0 || + strcmp(_matrule->_opType,"ForwardException")==0 || strcmp(_matrule->_opType,"SafePoint" )==0 || strcmp(_matrule->_opType,"Halt" )==0 ) return AdlcVMDeps::Parms; // Skip the machine-state edges diff --git a/src/hotspot/share/opto/callnode.hpp b/src/hotspot/share/opto/callnode.hpp index 120bb112ec56b..2d3835b71ad42 100644 --- a/src/hotspot/share/opto/callnode.hpp +++ b/src/hotspot/share/opto/callnode.hpp @@ -152,6 +152,17 @@ class RethrowNode : public Node { }; +//------------------------------ForwardExceptionNode--------------------------- +// Pop stack frame and jump to StubRoutines::forward_exception_entry() +class ForwardExceptionNode : public ReturnNode { +public: + ForwardExceptionNode(Node* cntrl, Node* i_o, Node* memory, Node* frameptr, Node* retadr) + : ReturnNode(TypeFunc::Parms, cntrl, i_o, memory, frameptr, retadr) { + } + + virtual int Opcode() const; +}; + //------------------------------TailCallNode----------------------------------- // Pop stack frame and jump indirect class TailCallNode : public ReturnNode { diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp index dc61377687302..8bee6279446ef 100644 --- a/src/hotspot/share/opto/classes.hpp +++ b/src/hotspot/share/opto/classes.hpp @@ -184,6 +184,7 @@ macro(FastLock) macro(FastUnlock) macro(FmaD) macro(FmaF) +macro(ForwardException) macro(Goto) macro(Halt) macro(CountPositives) diff --git a/src/hotspot/share/opto/domgraph.cpp b/src/hotspot/share/opto/domgraph.cpp index 363005d1181c2..84f83ef131bbd 100644 --- a/src/hotspot/share/opto/domgraph.cpp +++ b/src/hotspot/share/opto/domgraph.cpp @@ -239,6 +239,7 @@ uint Block_Stack::most_frequent_successor( Block *b ) { break; case Op_TailCall: case Op_TailJump: + case Op_ForwardException: case Op_Return: case Op_Halt: case Op_Rethrow: diff --git a/src/hotspot/share/opto/gcm.cpp b/src/hotspot/share/opto/gcm.cpp index 23ae8cbcb6b08..3880bea07d711 100644 --- a/src/hotspot/share/opto/gcm.cpp +++ b/src/hotspot/share/opto/gcm.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -2031,6 +2031,7 @@ float Block::succ_prob(uint i) { case Op_TailCall: case Op_TailJump: + case Op_ForwardException: case Op_Return: case Op_Halt: case Op_Rethrow: @@ -2084,6 +2085,7 @@ int Block::num_fall_throughs() { case Op_NeverBranch: case Op_TailCall: case Op_TailJump: + case Op_ForwardException: case Op_Return: case Op_Halt: case Op_Rethrow: @@ -2129,6 +2131,7 @@ bool Block::succ_fall_through(uint i) { case Op_NeverBranch: case Op_TailCall: case Op_TailJump: + case Op_ForwardException: case Op_Return: case Op_Halt: case Op_Rethrow: diff --git a/src/hotspot/share/opto/generateOptoStub.cpp b/src/hotspot/share/opto/generateOptoStub.cpp index 9bd7d42a3f9d7..e22f484c17955 100644 --- a/src/hotspot/share/opto/generateOptoStub.cpp +++ b/src/hotspot/share/opto/generateOptoStub.cpp @@ -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 @@ -255,13 +255,11 @@ void GraphKit::gen_stub(address C_function, Node* if_not_null = _gvn.transform( new IfTrueNode(iff) ); assert (StubRoutines::forward_exception_entry() != nullptr, "must be generated before"); - Node *exc_target = makecon(TypeRawPtr::make( StubRoutines::forward_exception_entry() )); - Node *to_exc = new TailCallNode(if_not_null, - i_o(), - exit_memory, - frameptr(), - returnadr(), - exc_target, null()); + Node *to_exc = new ForwardExceptionNode(if_not_null, + i_o(), + exit_memory, + frameptr(), + returnadr()); root()->add_req(_gvn.transform(to_exc)); // bind to root to keep live C->init_start(start); diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp index 4e2306602e6f7..bf773d43d3d39 100644 --- a/src/hotspot/share/opto/matcher.cpp +++ b/src/hotspot/share/opto/matcher.cpp @@ -804,6 +804,10 @@ void Matcher::Fixup_Save_On_Entry( ) { if (ret_edge_cnt > TypeFunc::Parms) ret_rms[TypeFunc::Parms+0] = _return_value_mask; + // Input RegMask array shared by all ForwardExceptions + uint forw_exc_edge_cnt = TypeFunc::Parms; + RegMask* forw_exc_rms = init_input_masks( forw_exc_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask ); + // Input RegMask array shared by all Rethrows. uint reth_edge_cnt = TypeFunc::Parms+1; RegMask *reth_rms = init_input_masks( reth_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask ); @@ -863,6 +867,7 @@ void Matcher::Fixup_Save_On_Entry( ) { case Op_Rethrow : exit->_in_rms = reth_rms; break; case Op_TailCall : exit->_in_rms = tail_call_rms; break; case Op_TailJump : exit->_in_rms = tail_jump_rms; break; + case Op_ForwardException: exit->_in_rms = forw_exc_rms; break; case Op_Halt : exit->_in_rms = halt_rms; break; default : ShouldNotReachHere(); } @@ -882,6 +887,7 @@ void Matcher::Fixup_Save_On_Entry( ) { reth_rms [ reth_edge_cnt] = mreg2regmask[i]; tail_call_rms[tail_call_edge_cnt] = mreg2regmask[i]; tail_jump_rms[tail_jump_edge_cnt] = mreg2regmask[i]; + forw_exc_rms [ forw_exc_edge_cnt] = mreg2regmask[i]; // Halts need the SOE registers, but only in the stack as debug info. // A just-prior uncommon-trap or deoptimization will use the SOE regs. halt_rms [ halt_edge_cnt] = *idealreg2spillmask[_register_save_type[i]]; @@ -899,6 +905,7 @@ void Matcher::Fixup_Save_On_Entry( ) { reth_rms [ reth_edge_cnt].Insert(OptoReg::Name(i+1)); tail_call_rms[tail_call_edge_cnt].Insert(OptoReg::Name(i+1)); tail_jump_rms[tail_jump_edge_cnt].Insert(OptoReg::Name(i+1)); + forw_exc_rms [ forw_exc_edge_cnt].Insert(OptoReg::Name(i+1)); halt_rms [ halt_edge_cnt].Insert(OptoReg::Name(i+1)); mproj = new MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegD ); proj_cnt += 2; // Skip 2 for doubles @@ -911,6 +918,7 @@ void Matcher::Fixup_Save_On_Entry( ) { reth_rms [ reth_edge_cnt] = RegMask::Empty; tail_call_rms[tail_call_edge_cnt] = RegMask::Empty; tail_jump_rms[tail_jump_edge_cnt] = RegMask::Empty; + forw_exc_rms [ forw_exc_edge_cnt] = RegMask::Empty; halt_rms [ halt_edge_cnt] = RegMask::Empty; mproj = C->top(); } @@ -925,6 +933,7 @@ void Matcher::Fixup_Save_On_Entry( ) { reth_rms [ reth_edge_cnt].Insert(OptoReg::Name(i+1)); tail_call_rms[tail_call_edge_cnt].Insert(OptoReg::Name(i+1)); tail_jump_rms[tail_jump_edge_cnt].Insert(OptoReg::Name(i+1)); + forw_exc_rms [ forw_exc_edge_cnt].Insert(OptoReg::Name(i+1)); halt_rms [ halt_edge_cnt].Insert(OptoReg::Name(i+1)); mproj = new MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegL ); proj_cnt += 2; // Skip 2 for longs @@ -937,6 +946,7 @@ void Matcher::Fixup_Save_On_Entry( ) { reth_rms [ reth_edge_cnt] = RegMask::Empty; tail_call_rms[tail_call_edge_cnt] = RegMask::Empty; tail_jump_rms[tail_jump_edge_cnt] = RegMask::Empty; + forw_exc_rms [ forw_exc_edge_cnt] = RegMask::Empty; halt_rms [ halt_edge_cnt] = RegMask::Empty; mproj = C->top(); } else { @@ -948,11 +958,13 @@ void Matcher::Fixup_Save_On_Entry( ) { reth_edge_cnt ++; tail_call_edge_cnt ++; tail_jump_edge_cnt ++; + forw_exc_edge_cnt++; halt_edge_cnt ++; // Add a use of the SOE register to all exit paths - for( uint j=1; j < root->req(); j++ ) + for (uint j=1; j < root->req(); j++) { root->in(j)->add_req(mproj); + } } // End of if a save-on-entry register } // End of for all machine registers } @@ -1070,6 +1082,7 @@ static void match_alias_type(Compile* C, Node* n, Node* m) { case Op_Halt: case Op_TailCall: case Op_TailJump: + case Op_ForwardException: nidx = Compile::AliasIdxBot; nat = TypePtr::BOTTOM; break; diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 4b6381bd05ebd..27dc10d2adb17 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -1422,6 +1422,7 @@ declare_c2_type(RethrowNode, Node) \ declare_c2_type(TailCallNode, ReturnNode) \ declare_c2_type(TailJumpNode, ReturnNode) \ + declare_c2_type(ForwardExceptionNode, ReturnNode) \ declare_c2_type(SafePointNode, MultiNode) \ declare_c2_type(CallNode, SafePointNode) \ declare_c2_type(CallJavaNode, CallNode) \ From 2ca136a7adb6defaea3b7a69d30e6c36bda66e6a Mon Sep 17 00:00:00 2001 From: Ben Taylor Date: Mon, 12 Aug 2024 17:26:51 +0000 Subject: [PATCH 386/401] 8337815: Relax G1EvacStats atomic operations Reviewed-by: kbarrett, tschatzl, shade --- src/hotspot/share/gc/g1/g1EvacStats.inline.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1EvacStats.inline.hpp b/src/hotspot/share/gc/g1/g1EvacStats.inline.hpp index 4b4c6e104b7e3..d4cae1f983652 100644 --- a/src/hotspot/share/gc/g1/g1EvacStats.inline.hpp +++ b/src/hotspot/share/gc/g1/g1EvacStats.inline.hpp @@ -30,25 +30,25 @@ #include "runtime/atomic.hpp" inline void G1EvacStats::add_direct_allocated(size_t value) { - Atomic::add(&_direct_allocated, value); + Atomic::add(&_direct_allocated, value, memory_order_relaxed); } inline void G1EvacStats::add_num_plab_filled(size_t value) { - Atomic::add(&_num_plab_filled, value); + Atomic::add(&_num_plab_filled, value, memory_order_relaxed); } inline void G1EvacStats::add_num_direct_allocated(size_t value) { - Atomic::add(&_num_direct_allocated, value); + Atomic::add(&_num_direct_allocated, value, memory_order_relaxed); } inline void G1EvacStats::add_region_end_waste(size_t value) { - Atomic::add(&_region_end_waste, value); - Atomic::inc(&_regions_filled); + Atomic::add(&_region_end_waste, value, memory_order_relaxed); + Atomic::inc(&_regions_filled, memory_order_relaxed); } inline void G1EvacStats::add_failure_used_and_waste(size_t used, size_t waste) { - Atomic::add(&_failure_used, used); - Atomic::add(&_failure_waste, waste); + Atomic::add(&_failure_used, used, memory_order_relaxed); + Atomic::add(&_failure_waste, waste, memory_order_relaxed); } #endif // SHARE_GC_G1_G1EVACSTATS_INLINE_HPP From 41e31d6b0ae00d70b6fb20c89318fde2bc605edb Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Mon, 12 Aug 2024 17:56:46 +0000 Subject: [PATCH 387/401] 8337622: IllegalArgumentException in java.lang.reflect.Field.get Reviewed-by: dholmes, shade --- src/hotspot/share/classfile/javaClasses.cpp | 7 --- src/hotspot/share/classfile/javaClasses.hpp | 1 + .../reflect/ComponentTypeFieldTest.java | 50 +++++++++++++++++++ 3 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/reflect/ComponentTypeFieldTest.java diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index ab9460e2b9b01..8a6c8a8ce0b36 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1452,19 +1452,12 @@ void java_lang_Class::compute_offsets() { InstanceKlass* k = vmClasses::Class_klass(); CLASS_FIELDS_DO(FIELD_COMPUTE_OFFSET); - - // Init lock is a C union with component_mirror. Only instanceKlass mirrors have - // init_lock and only ArrayKlass mirrors have component_mirror. Since both are oops - // GC treats them the same. - _init_lock_offset = _component_mirror_offset; - CLASS_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); } #if INCLUDE_CDS void java_lang_Class::serialize_offsets(SerializeClosure* f) { f->do_bool(&_offsets_computed); - f->do_u4((u4*)&_init_lock_offset); CLASS_FIELDS_DO(FIELD_SERIALIZE_OFFSET); diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 57914e189b75d..eb3c5e29fdb11 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -209,6 +209,7 @@ class java_lang_String : AllStatic { macro(java_lang_Class, static_oop_field_count, int_signature, false) \ macro(java_lang_Class, protection_domain, object_signature, false) \ macro(java_lang_Class, source_file, object_signature, false) \ + macro(java_lang_Class, init_lock, object_signature, false) class java_lang_Class : AllStatic { friend class VMStructs; diff --git a/test/hotspot/jtreg/runtime/reflect/ComponentTypeFieldTest.java b/test/hotspot/jtreg/runtime/reflect/ComponentTypeFieldTest.java new file mode 100644 index 0000000000000..6296a7f970e74 --- /dev/null +++ b/test/hotspot/jtreg/runtime/reflect/ComponentTypeFieldTest.java @@ -0,0 +1,50 @@ +/* + * 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 8337622 + * @summary (reflect) java.lang.Class componentType field not found. + * @library /test/lib + * @modules java.base/java.lang:open + * @run main ComponentTypeFieldTest + */ + +import java.lang.reflect.Field; +import static jdk.test.lib.Asserts.*; + +public class ComponentTypeFieldTest { + + public static void main(String[] args) throws Exception { + Field f = Class.class.getDeclaredField("componentType"); + f.setAccessible(true); + Object val = f.get(Runnable.class); + assertTrue(val == null); + System.out.println("val is " + val); + + Object arrayVal = f.get(Integer[].class); + System.out.println("val is " + arrayVal); + String arrayValString = arrayVal.toString(); + assertTrue(arrayValString.equals("class java.lang.Integer")); + } +} From b93b74e3ebd220e94fb5e33d2ebc62181db97bb0 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Mon, 12 Aug 2024 19:28:46 +0000 Subject: [PATCH 388/401] 8338060: jdk/internal/util/ReferencedKeyTest should be more robust Reviewed-by: never --- .../jdk/internal/util/ReferencedKeyTest.java | 130 ++++++++++-------- 1 file changed, 76 insertions(+), 54 deletions(-) diff --git a/test/jdk/jdk/internal/util/ReferencedKeyTest.java b/test/jdk/jdk/internal/util/ReferencedKeyTest.java index 75690fa6e258a..c68908a8d5a42 100644 --- a/test/jdk/jdk/internal/util/ReferencedKeyTest.java +++ b/test/jdk/jdk/internal/util/ReferencedKeyTest.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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8285932 8310913 + * @bug 8285932 8310913 8336390 8338060 * @summary Test features provided by the ReferencedKeyMap/ReferencedKeySet classes. * @modules java.base/jdk.internal.util * @compile --patch-module java.base=${test.src} ReferencedKeyTest.java @@ -36,14 +36,27 @@ import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.BooleanSupplier; +import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.IntStream; public class ReferencedKeyTest { - static long BASE_KEY = 10_000_000L; + private static String BASE_KEY = "BASEKEY-"; + + // Return a String (identity object) that can be a key in WeakHashMap. + private static String genKey(int i) { + return BASE_KEY + i; + } + + // Return a String of the letter 'a' plus the integer (0..0xffff) + private static String genValue(int i) { + return String.valueOf((char) ('a' + i)); + } public static void main(String[] args) { mapTest(false, HashMap::new); @@ -63,73 +76,77 @@ static void assertTrue(boolean test, String message) { } } - static void mapTest(boolean isSoft, Supplier, String>> supplier) { - Map map = ReferencedKeyMap.create(isSoft, supplier); - populate(map); + static void mapTest(boolean isSoft, Supplier, String>> supplier) { + Map map = ReferencedKeyMap.create(isSoft, supplier); + var strongKeys = populate(map); // Retain references to the keys + methods(map); + Reference.reachabilityFence(strongKeys); + + strongKeys = null; // drop strong key references if (!isSoft) { if (!collect(() -> map.isEmpty())) { throw new RuntimeException("WeakReference map not collecting!"); } } - populate(map); - methods(map); } - static void setTest(boolean isSoft, Supplier, ReferenceKey>> supplier) { - ReferencedKeySet set = ReferencedKeySet.create(isSoft, supplier); - populate(set); + static void setTest(boolean isSoft, Supplier, ReferenceKey>> supplier) { + ReferencedKeySet set = ReferencedKeySet.create(isSoft, supplier); + var strongKeys = populate(set); // Retain references to the keys + methods(set); + Reference.reachabilityFence(strongKeys); + + strongKeys = null; // drop strong key references if (!isSoft) { if (!collect(() -> set.isEmpty())) { throw new RuntimeException("WeakReference set not collecting!"); } } - populate(set); - methods(set); } - static void methods(Map map) { + static void methods(Map map) { assertTrue(map.size() == 26, "missing key"); - assertTrue(map.containsKey(BASE_KEY + 'a' -'a'), "missing key"); - assertTrue(map.get(BASE_KEY + 'b' -'a').equals("b"), "wrong key"); + assertTrue(map.containsKey(genKey('a' -'a')), "missing key"); + assertTrue(map.get(genKey('b' -'a')).equals("b"), "wrong key"); assertTrue(map.containsValue("c"), "missing value"); - map.remove(BASE_KEY + 'd' -'a'); - assertTrue(map.get(BASE_KEY + 'd' -'a') == null, "not removed"); - map.putAll(Map.of(1L, "A", 2L, "B")); - assertTrue(map.get(2L).equals("B"), "collection not added"); - assertTrue(map.containsKey(1L), "key missing"); + map.remove(genKey('d' -'a')); + assertTrue(map.get(genKey('d' -'a')) == null, "not removed"); + map.putAll(Map.of(genKey(1), "A", genKey(2), "B")); + assertTrue(map.get(genKey(2)).equals("B"), "collection not added"); + assertTrue(map.containsKey(genKey(1)), "key missing"); assertTrue(map.containsValue("A"), "key missing"); - assertTrue(map.entrySet().contains(Map.entry(1L, "A")), "key missing"); - map.putIfAbsent(3L, "C"); - assertTrue(map.get(3L).equals("C"), "key missing"); - map.putIfAbsent(2L, "D"); - assertTrue(map.get(2L).equals("B"), "key replaced"); - map.remove(3L); - assertTrue(map.get(3L) == null, "key not removed"); - map.replace(2L, "D"); - assertTrue(map.get(2L).equals("D"), "key not replaced"); - map.replace(2L, "B", "E"); - assertTrue(map.get(2L).equals("D"), "key replaced"); + assertTrue(map.entrySet().contains(Map.entry(genKey(1), "A")), "key missing"); + map.putIfAbsent(genKey(3), "C"); + assertTrue(map.get(genKey(3)).equals("C"), "key missing"); + map.putIfAbsent(genKey(2), "D"); + assertTrue(map.get(genKey(2)).equals("B"), "key replaced"); + map.remove(genKey(3)); + assertTrue(map.get(genKey(3)) == null, "key not removed"); + map.replace(genKey(2), "D"); + assertTrue(map.get(genKey(2)).equals("D"), "key not replaced"); + map.replace(genKey(2), "B", "E"); + assertTrue(map.get(genKey(2)).equals("D"), "key replaced"); } - static void methods(ReferencedKeySet set) { + static void methods(ReferencedKeySet set) { assertTrue(set.size() == 26, "missing key"); - assertTrue(set.contains(BASE_KEY + 3), "missing key"); - set.remove(BASE_KEY + 3); - assertTrue(!set.contains(BASE_KEY + 3), "not removed"); - Long element1 = set.get(BASE_KEY + 2); - Long element2 = set.get(BASE_KEY + 3); - Long element3 = set.get(BASE_KEY + 4); - Long intern1 = set.intern(BASE_KEY + 2); - Long intern2 = set.intern(BASE_KEY + 3); - Long intern3 = set.intern(BASE_KEY + 4, e -> e); + assertTrue(set.contains(genKey(3)), "missing key"); + set.remove(genKey(3)); + assertTrue(!set.contains(genKey(3)), "not removed"); + String element1 = set.get(genKey(2)); + String element2 = set.get(genKey(3)); + String element3 = set.get(genKey(4)); + String intern1 = set.intern(genKey(2)); + String intern2 = set.intern(genKey(3)); + String intern3 = set.intern(genKey(4), e -> e); assertTrue(element1 != null, "missing key"); assertTrue(element2 == null, "not removed"); assertTrue(element1 == intern1, "intern failed"); // must be same object assertTrue(intern2 != null, "intern failed"); assertTrue(element3 == intern3, "intern failed"); - Long value1 = Long.valueOf(BASE_KEY + 999); - Long value2 = Long.valueOf(BASE_KEY + 999); + String value1 = genKey(999); + String value2 = genKey(999); assertTrue(set.add(value1), "key not added"); assertTrue(!set.add(value1), "key added after second attempt"); assertTrue(!set.add(value2), "key should not have been added"); @@ -164,18 +181,23 @@ static boolean collect(BooleanSupplier booleanSupplier) { return booleanSupplier.getAsBoolean(); } - static void populate(Map map) { - for (int i = 0; i < 26; i++) { - Long key = BASE_KEY + i; - String value = String.valueOf((char) ('a' + i)); - map.put(key, value); + static List populate(Map map) { + var keyRefs = genStrings(0, 26, ReferencedKeyTest::genKey); + var valueRefs = genStrings(0, 26, ReferencedKeyTest::genValue); + for (int i = 0; i < keyRefs.size(); i++) { + map.put(keyRefs.get(i), valueRefs.get(i)); } + return keyRefs; } - static void populate(Set set) { - for (int i = 0; i < 26; i++) { - Long value = BASE_KEY + i; - set.add(value); - } + static List populate(Set set) { + var keyRefs = genStrings(0, 26, ReferencedKeyTest::genKey); + set.addAll(keyRefs); + return keyRefs; + } + + // Generate a List of consecutive strings using a function int -> String + static List genStrings(int min, int maxExclusive, Function genString) { + return IntStream.range(min, maxExclusive).mapToObj(i -> genString.apply(i)).toList(); } } From 4417c276e484c1fe137ed7f4a7c28709d0c99af2 Mon Sep 17 00:00:00 2001 From: Leonid Mesnik Date: Mon, 12 Aug 2024 19:43:36 +0000 Subject: [PATCH 389/401] 8330535: Update nsk/jdb tests to use driver instead of othervm Reviewed-by: cjplummer --- .../caught_exception002/caught_exception002.java | 10 +++------- .../nsk/jdb/classes/classes001/classes001.java | 10 +++------- .../jdb/classpath/classpath001/classpath001.java | 10 +++------- .../vmTestbase/nsk/jdb/clear/clear002/clear002.java | 10 +++------- .../vmTestbase/nsk/jdb/clear/clear003/clear003.java | 10 +++------- .../vmTestbase/nsk/jdb/clear/clear004/clear004.java | 8 ++------ .../vmTestbase/nsk/jdb/down/down002/down002.java | 10 +++------- .../vmTestbase/nsk/jdb/dump/dump002/dump002.java | 10 +++------- .../vmTestbase/nsk/jdb/eval/eval001/eval001.java | 10 +++------- .../nsk/jdb/exclude/exclude001/exclude001.java | 10 +++------- .../nsk/jdb/fields/fields001/fields001.java | 10 +++------- .../nsk/jdb/hidden_class/hc001/hc001.java | 10 +++------- .../nsk/jdb/ignore/ignore001/ignore001.java | 10 +++------- .../jdb/interrupt/interrupt001/interrupt001.java | 10 +++------- .../vmTestbase/nsk/jdb/kill/kill001/kill001.java | 10 +++------- .../vmTestbase/nsk/jdb/kill/kill002/kill002.java | 10 +++------- .../vmTestbase/nsk/jdb/klass/class001/class001.java | 10 +++------- .../vmTestbase/nsk/jdb/list/list002/list002.java | 10 +++------- .../vmTestbase/nsk/jdb/list/list003/list003.java | 11 ++++------- .../nsk/jdb/locals/locals002/locals002.java | 10 +++------- .../nsk/jdb/methods/methods002/methods002.java | 10 +++------- .../nsk/jdb/monitor/monitor001/monitor001.java | 10 +++------- .../nsk/jdb/monitor/monitor002/monitor002.java | 10 +++------- .../vmTestbase/nsk/jdb/next/next001/next001.java | 10 +++------- .../jdb/options/connect/connect001/connect001.java | 10 +++------- .../jdb/options/connect/connect002/connect002.java | 10 +++------- .../jdb/options/connect/connect003/connect003.java | 10 +++------- .../jdb/options/connect/connect004/connect004.java | 10 +++------- .../jdb/options/connect/connect005/connect005.java | 13 ++++--------- .../listconnectors001/listconnectors001.java | 10 +++------- .../jtreg/vmTestbase/nsk/jdb/pop/pop001/pop001.java | 10 +++------- .../pop_exception001/pop_exception001.java | 10 +++------- .../vmTestbase/nsk/jdb/print/print002/print002.java | 10 +++------- .../vmTestbase/nsk/jdb/read/read001/read001.java | 10 +++------- .../nsk/jdb/redefine/redefine001/redefine001.java | 10 +++------- .../nsk/jdb/reenter/reenter001/reenter001.java | 10 +++------- .../nsk/jdb/regression/b4689395/b4689395.java | 10 +++------- .../nsk/jdb/repeat/repeat001/repeat001.java | 10 +++------- .../nsk/jdb/resume/resume002/resume002.java | 10 +++------- .../jtreg/vmTestbase/nsk/jdb/run/run002/run002.java | 10 +++------- .../jtreg/vmTestbase/nsk/jdb/set/set001/set001.java | 10 +++------- .../jtreg/vmTestbase/nsk/jdb/set/set002/set002.java | 10 +++------- .../vmTestbase/nsk/jdb/step/step002/step002.java | 10 +++------- .../nsk/jdb/step_up/step_up001/step_up001.java | 10 +++------- .../nsk/jdb/stop_at/stop_at002/stop_at002.java | 8 ++------ .../nsk/jdb/stop_at/stop_at003/stop_at003.java | 10 +++------- .../nsk/jdb/stop_in/stop_in002/stop_in002.java | 10 +++------- .../nsk/jdb/suspend/suspend001/suspend001.java | 10 +++------- .../nsk/jdb/thread/thread002/thread002.java | 10 +++------- .../threadgroup/threadgroup002/threadgroup002.java | 10 +++------- .../threadgroups002/threadgroups002.java | 10 +++------- .../nsk/jdb/threads/threads002/threads002.java | 10 +++------- .../nsk/jdb/threads/threads003/threads003.java | 10 +++------- .../vmTestbase/nsk/jdb/trace/trace001/trace001.java | 10 +++------- .../uncaught_exception002.java | 10 +++------- .../jdb/unmonitor/unmonitor001/unmonitor001.java | 10 +++------- .../nsk/jdb/untrace/untrace001/untrace001.java | 10 +++------- .../nsk/jdb/unwatch/unwatch001/unwatch001.java | 10 +++------- .../nsk/jdb/unwatch/unwatch002/unwatch002.java | 10 +++------- .../jtreg/vmTestbase/nsk/jdb/up/up002/up002.java | 10 +++------- .../jtreg/vmTestbase/nsk/jdb/use/use001/use001.java | 10 +++------- .../vmTestbase/nsk/jdb/watch/watch001/watch001.java | 10 +++------- .../vmTestbase/nsk/jdb/watch/watch002/watch002.java | 10 +++------- .../vmTestbase/nsk/jdb/where/where004/where004.java | 10 +++------- .../vmTestbase/nsk/jdb/where/where005/where005.java | 10 +++------- .../vmTestbase/nsk/jdb/where/where006/where006.java | 10 +++------- .../nsk/jdb/wherei/wherei001/wherei001.java | 10 +++------- .../jtreg/vmTestbase/nsk/share/jdb/JdbTest.java | 11 +++++------ .../jtreg/vmTestbase/nsk/share/jdb/Launcher.java | 6 ++++-- 69 files changed, 210 insertions(+), 477 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/caught_exception/caught_exception002/caught_exception002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/caught_exception/caught_exception002/caught_exception002.java index 4eef7900d4231..04ace5ba49c5d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/caught_exception/caught_exception002/caught_exception002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/caught_exception/caught_exception002/caught_exception002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.caught_exception.caught_exception002.caught_exception002a - * @run main/othervm + * @run driver * nsk.jdb.caught_exception.caught_exception002.caught_exception002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -69,14 +69,10 @@ public class caught_exception002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new caught_exception002().runTest(argv, out); + new caught_exception002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.caught_exception.caught_exception002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/classes/classes001/classes001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/classes/classes001/classes001.java index 40a5ebaa9393c..8543c7c6f1e1d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/classes/classes001/classes001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/classes/classes001/classes001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -37,7 +37,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.classes.classes001.classes001a - * @run main/othervm + * @run driver * nsk.jdb.classes.classes001.classes001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -60,14 +60,10 @@ public class classes001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new classes001().runTest(argv, out); + new classes001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.classes.classes001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/classpath/classpath001/classpath001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/classpath/classpath001/classpath001.java index 0eea9a92ab26f..25a86fe64cbd9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/classpath/classpath001/classpath001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/classpath/classpath001/classpath001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -36,7 +36,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.classpath.classpath001.classpath001a - * @run main/othervm + * @run driver * nsk.jdb.classpath.classpath001.classpath001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -59,14 +59,10 @@ public class classpath001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new classpath001().runTest(argv, out); + new classpath001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.classpath.classpath001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear002/clear002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear002/clear002.java index 7869a1340a7cd..cca80dad46502 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear002/clear002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear002/clear002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -38,7 +38,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.clear.clear002.clear002a - * @run main/othervm + * @run driver * nsk.jdb.clear.clear002.clear002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -61,14 +61,10 @@ public class clear002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new clear002().runTest(argv, out); + new clear002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.clear.clear002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear003/clear003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear003/clear003.java index cbbc851f29a6f..003b1f36eddb7 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear003/clear003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear003/clear003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -39,7 +39,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.clear.clear003.clear003a - * @run main/othervm + * @run driver * nsk.jdb.clear.clear003.clear003 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -62,14 +62,10 @@ public class clear003 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new clear003().runTest(argv, out); + new clear003().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.clear.clear003"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear004/clear004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear004/clear004.java index c0ec8d2037095..5dfd33430e38c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear004/clear004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/clear/clear004/clear004.java @@ -40,7 +40,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.clear.clear004.clear004a - * @run main/othervm + * @run driver * nsk.jdb.clear.clear004.clear004 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -63,14 +63,10 @@ public class clear004 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new clear004().runTest(argv, out); + new clear004().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.clear.clear004"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/down/down002/down002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/down/down002/down002.java index 29a40d9471d67..99f4254891d1e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/down/down002/down002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/down/down002/down002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -43,7 +43,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.down.down002.down002a - * @run main/othervm + * @run driver * nsk.jdb.down.down002.down002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -66,14 +66,10 @@ public class down002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new down002().runTest(argv, out); + new down002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.down.down002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/dump/dump002/dump002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/dump/dump002/dump002.java index 3e3b5b9b85872..66a26e69f7769 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/dump/dump002/dump002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/dump/dump002/dump002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, 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 @@ -47,7 +47,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.dump.dump002.dump002a - * @run main/othervm + * @run driver * nsk.jdb.dump.dump002.dump002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -70,15 +70,11 @@ public class dump002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; compoundPromptIdent = COMPOUND_PROMPT_IDENT; - return new dump002().runTest(argv, out); + new dump002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.dump.dump002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/eval/eval001/eval001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/eval/eval001/eval001.java index 98848ced90bc7..fc4fb14dd2db6 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/eval/eval001/eval001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/eval/eval001/eval001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -52,7 +52,7 @@ * @clean nsk.jdb.eval.eval001.eval001a * @compile -g:lines,source,vars eval001a.java * - * @run main/othervm + * @run driver * nsk.jdb.eval.eval001.eval001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -75,14 +75,10 @@ public class eval001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new eval001().runTest(argv, out); + new eval001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.eval.eval001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/exclude/exclude001/exclude001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/exclude/exclude001/exclude001.java index cee8ca44d585b..c7805cc6c95de 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/exclude/exclude001/exclude001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/exclude/exclude001/exclude001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -59,7 +59,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.exclude.exclude001.exclude001a - * @run main/othervm/timeout=600 + * @run driver/timeout=600 * nsk.jdb.exclude.exclude001.exclude001 * -arch=${os.family}-${os.simpleArch} * -waittime=10 @@ -82,14 +82,10 @@ public class exclude001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new exclude001().runTest(argv, out); + new exclude001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.exclude.exclude001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/fields/fields001/fields001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/fields/fields001/fields001.java index b5e2ccb58e566..c1cbba3232a84 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/fields/fields001/fields001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/fields/fields001/fields001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -41,7 +41,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.fields.fields001.fields001a - * @run main/othervm + * @run driver * nsk.jdb.fields.fields001.fields001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -64,14 +64,10 @@ public class fields001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new fields001().runTest(argv, out); + new fields001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.fields.fields001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/hidden_class/hc001/hc001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/hidden_class/hc001/hc001.java index 5040eef9cefb2..a7c74e28aaece 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/hidden_class/hc001/hc001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/hidden_class/hc001/hc001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 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 @@ -31,7 +31,7 @@ * jdk.jdwp.agent * @build nsk.jdb.hidden_class.hc001.hc001a * - * @run main/othervm + * @run driver * nsk.jdb.hidden_class.hc001.hc001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -60,13 +60,9 @@ public class hc001 extends JdbTest { static final int MAX_SLEEP_CNT = 3; public static void main(String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; // needed for JdbTest.runTest firstBreak = MAIN_METHOD_NAME; // needed for JdbTest.runTest - return new hc001().runTest(argv, out); + new hc001().runTest(argv); } static boolean checkPattern(String[] arr, String pattern) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/ignore/ignore001/ignore001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/ignore/ignore001/ignore001.java index 6eb8c91e1eb78..48d256d22fc7e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/ignore/ignore001/ignore001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/ignore/ignore001/ignore001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -40,7 +40,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.ignore.ignore001.ignore001a - * @run main/othervm + * @run driver * nsk.jdb.ignore.ignore001.ignore001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -63,14 +63,10 @@ public class ignore001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new ignore001().runTest(argv, out); + new ignore001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.ignore.ignore001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/interrupt/interrupt001/interrupt001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/interrupt/interrupt001/interrupt001.java index 73f251b71e998..51bbdf6757a2d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/interrupt/interrupt001/interrupt001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/interrupt/interrupt001/interrupt001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, 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 @@ -47,7 +47,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.interrupt.interrupt001.interrupt001a - * @run main/othervm + * @run driver * nsk.jdb.interrupt.interrupt001.interrupt001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -73,13 +73,9 @@ public class interrupt001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; - return new interrupt001().runTest(argv, out); + new interrupt001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.interrupt.interrupt001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill001/kill001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill001/kill001.java index b770aafc510db..a96498954b69b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill001/kill001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill001/kill001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, 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 @@ -49,7 +49,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.kill.kill001.kill001a - * @run main/othervm + * @run driver * nsk.jdb.kill.kill001.kill001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -74,13 +74,9 @@ public class kill001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; - return new kill001().runTest(argv, out); + new kill001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.kill.kill001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill002/kill002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill002/kill002.java index 230dcdf12baaf..ed5306346dc3c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill002/kill002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill002/kill002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -43,7 +43,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.kill.kill002.kill002a - * @run main/othervm + * @run driver * nsk.jdb.kill.kill002.kill002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -66,13 +66,9 @@ public class kill002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; - return new kill002().runTest(argv, out); + new kill002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.kill.kill002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/klass/class001/class001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/klass/class001/class001.java index 4c548348dc356..ee37e393f702d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/klass/class001/class001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/klass/class001/class001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -40,7 +40,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.klass.class001.class001a - * @run main/othervm + * @run driver * nsk.jdb.klass.class001.class001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -63,14 +63,10 @@ public class class001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new class001().runTest(argv, out); + new class001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.klass.class001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/list/list002/list002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/list/list002/list002.java index 4180ea3bb453b..38282a425ecd4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/list/list002/list002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/list/list002/list002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -44,7 +44,7 @@ * /test/lib * @build nsk.jdb.list.list002.list002a * @run driver jdk.test.lib.FileInstaller list002a.java src/nsk/jdb/list/list002/list002a.java - * @run main/othervm + * @run driver * nsk.jdb.list.list002.list002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -68,14 +68,10 @@ public class list002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new list002().runTest(argv, out); + new list002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.list.list002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/list/list003/list003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/list/list003/list003.java index d06bf38bd8527..e7d773486eedb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/list/list003/list003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/list/list003/list003.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 @@ -37,7 +37,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.list.list003.list003a - * @run main/othervm + * @run driver * nsk.jdb.list.list003.list003 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -47,6 +47,7 @@ * -jdb.option="-J-Duser.language=en -J-Duser.country=US" * -java.options="${test.vm.opts} ${test.java.opts}" * -workdir=. + * -jdb.option="-sourcepath ${test.src}/../../../.." * -debugee.vmkeys="${test.vm.opts} ${test.java.opts}" */ @@ -98,13 +99,9 @@ protected List parseListOutput(String[] lines) { } public static void main(String[] args) { - System.exit(run(args, System.out) + JCK_STATUS_BASE); - } - - public static int run(String[] args, PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; - return new list003().runTest(args, out); + new list003().runTest(args); } @Override diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/locals/locals002/locals002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/locals/locals002/locals002.java index 793cdc0460876..09a97ff83a528 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/locals/locals002/locals002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/locals/locals002/locals002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -52,7 +52,7 @@ * @clean nsk.jdb.locals.locals002.locals002a * @compile -g:lines,source,vars locals002a.java * - * @run main/othervm + * @run driver * nsk.jdb.locals.locals002.locals002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -75,15 +75,11 @@ public class locals002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; compoundPromptIdent = COMPOUND_PROMPT_IDENT; - return new locals002().runTest(argv, out); + new locals002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.locals.locals002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/methods/methods002/methods002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/methods/methods002/methods002.java index 2bacbab101bd4..ef480d52c037c 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/methods/methods002/methods002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/methods/methods002/methods002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, 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 @@ -50,7 +50,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.methods.methods002.methods002a - * @run main/othervm + * @run driver * nsk.jdb.methods.methods002.methods002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -73,14 +73,10 @@ public class methods002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new methods002().runTest(argv, out); + new methods002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.methods.methods002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor001/monitor001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor001/monitor001.java index 1fd1f8c328b87..94cac5ca787a9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor001/monitor001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor001/monitor001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, 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 @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.monitor.monitor001.monitor001a - * @run main/othervm + * @run driver * nsk.jdb.monitor.monitor001.monitor001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -69,14 +69,10 @@ public class monitor001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new monitor001().runTest(argv, out); + new monitor001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.monitor.monitor001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor002/monitor002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor002/monitor002.java index 53c856128ce7b..790eb7469168d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor002/monitor002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/monitor/monitor002/monitor002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, 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 @@ -42,7 +42,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.monitor.monitor002.monitor002a - * @run main/othervm + * @run driver * nsk.jdb.monitor.monitor002.monitor002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -65,14 +65,10 @@ public class monitor002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new monitor002().runTest(argv, out); + new monitor002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.monitor.monitor002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/next/next001/next001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/next/next001/next001.java index 206199f0bb325..3d0c810b5c4a4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/next/next001/next001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/next/next001/next001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.next.next001.next001a - * @run main/othervm + * @run driver * nsk.jdb.next.next001.next001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -69,14 +69,10 @@ public class next001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new next001().runTest(argv, out); + new next001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.next.next001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect001/connect001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect001/connect001.java index a78f3a96db421..85cdbb279974e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect001/connect001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect001/connect001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.options.connect.connect001.connect001a - * @run main/othervm + * @run driver * nsk.jdb.options.connect.connect001.connect001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,14 +71,10 @@ public class connect001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new connect001().runTest(argv, out); + new connect001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.options.connect.connect001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect002/connect002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect002/connect002.java index 78bcf2fb9737e..a3219de0cc4e3 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect002/connect002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect002/connect002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.options.connect.connect002.connect002a - * @run main/othervm + * @run driver * nsk.jdb.options.connect.connect002.connect002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,14 +71,10 @@ public class connect002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new connect002().runTest(argv, out); + new connect002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.options.connect.connect002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect003/connect003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect003/connect003.java index 701f611d2ff39..465e3c9deb241 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect003/connect003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect003/connect003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.options.connect.connect003.connect003a - * @run main/othervm + * @run driver * nsk.jdb.options.connect.connect003.connect003 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,14 +71,10 @@ public class connect003 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new connect003().runTest(argv, out); + new connect003().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.options.connect.connect003"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect004/connect004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect004/connect004.java index adaa58627dd47..075e9c30268ef 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect004/connect004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect004/connect004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.options.connect.connect004.connect004a - * @run main/othervm + * @run driver * nsk.jdb.options.connect.connect004.connect004 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,14 +71,10 @@ public class connect004 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new connect004().runTest(argv, out); + new connect004().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.options.connect.connect004"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect005/connect005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect005/connect005.java index 8a67039246605..7bd44a5927cc7 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect005/connect005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/connect/connect005/connect005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.options.connect.connect005.connect005a - * @run main/othervm + * @run driver * nsk.jdb.options.connect.connect005.connect005 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -70,15 +70,10 @@ public class connect005 extends JdbTest { - public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { - debuggeeClass = DEBUGGEE_CLASS; + public static void main (String argv[]) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new connect005().runTest(argv, out); + new connect005().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.options.connect.connect005"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/listconnectors/listconnectors001/listconnectors001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/listconnectors/listconnectors001/listconnectors001.java index d814df91cc693..b4961be11eeee 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/listconnectors/listconnectors001/listconnectors001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/options/listconnectors/listconnectors001/listconnectors001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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,7 +51,7 @@ * * @library /vmTestbase * /test/lib - * @run main/othervm + * @run driver * nsk.jdb.options.listconnectors.listconnectors001.listconnectors001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -75,14 +75,10 @@ public class listconnectors001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new listconnectors001().runTest(argv, out); + new listconnectors001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.options.connect"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop/pop001/pop001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop/pop001/pop001.java index e449a5771f27c..c508538fa1e66 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop/pop001/pop001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop/pop001/pop001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -47,7 +47,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.pop.pop001.pop001a - * @run main/othervm + * @run driver * nsk.jdb.pop.pop001.pop001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -70,14 +70,10 @@ public class pop001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new pop001().runTest(argv, out); + new pop001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.pop.pop001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop_exception/pop_exception001/pop_exception001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop_exception/pop_exception001/pop_exception001.java index f70a5ffb96023..49921cd26cc0e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop_exception/pop_exception001/pop_exception001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/pop_exception/pop_exception001/pop_exception001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -34,7 +34,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.pop_exception.pop_exception001.pop_exception001a - * @run main/othervm + * @run driver * nsk.jdb.pop_exception.pop_exception001.pop_exception001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -63,14 +63,10 @@ public class pop_exception001 extends JdbTest { static final String LAST_BREAK = DEBUGGEE_CLASS + ".lastBreak"; public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new pop_exception001().runTest(argv, out); + new pop_exception001().runTest(argv); } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/print/print002/print002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/print/print002/print002.java index e339a0a321b97..1993c1f4d95fc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/print/print002/print002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/print/print002/print002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, 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 @@ -52,7 +52,7 @@ * @clean nsk.jdb.print.print002.print002a * @compile -g:lines,source,vars print002a.java * - * @run main/othervm + * @run driver * nsk.jdb.print.print002.print002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -75,14 +75,10 @@ public class print002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new print002().runTest(argv, out); + new print002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.print.print002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/read/read001/read001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/read/read001/read001.java index b5ca64334d775..60c80139a651f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/read/read001/read001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/read/read001/read001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -52,7 +52,7 @@ * @clean nsk.jdb.read.read001.read001a * @compile -g:lines,source,vars read001a.java * - * @run main/othervm + * @run driver * nsk.jdb.read.read001.read001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -76,14 +76,10 @@ public class read001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new read001().runTest(argv, out); + new read001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.read.read001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/redefine/redefine001/redefine001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/redefine/redefine001/redefine001.java index 80ff33889a410..d3988ac443ca8 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/redefine/redefine001/redefine001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/redefine/redefine001/redefine001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -56,7 +56,7 @@ * -cp ${test.class.path} * ${test.src}/newclass_g/RedefinedClass.java * - * @run main/othervm + * @run driver * nsk.jdb.redefine.redefine001.redefine001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -80,14 +80,10 @@ public class redefine001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new redefine001().runTest(argv, out); + new redefine001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.redefine.redefine001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/reenter/reenter001/reenter001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/reenter/reenter001/reenter001.java index ebc063942c608..4013d85ab7527 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/reenter/reenter001/reenter001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/reenter/reenter001/reenter001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.reenter.reenter001.reenter001a - * @run main/othervm + * @run driver * nsk.jdb.reenter.reenter001.reenter001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -69,14 +69,10 @@ public class reenter001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new reenter001().runTest(argv, out); + new reenter001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.reenter.reenter001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/regression/b4689395/b4689395.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/regression/b4689395/b4689395.java index 82d8235fee724..2cb3cc0eccfc4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/regression/b4689395/b4689395.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/regression/b4689395/b4689395.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -101,7 +101,7 @@ * -cp ${test.class.path} * ${test.src}/newclass/b4689395a.java * - * @run main/othervm + * @run driver * nsk.jdb.regression.b4689395.b4689395 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -131,13 +131,9 @@ public class b4689395 extends JdbTest { private String classFile; public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; - return new b4689395().runTest(argv, out); + new b4689395().runTest(argv); } public b4689395() { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/repeat/repeat001/repeat001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/repeat/repeat001/repeat001.java index e0489db28291e..67ce5ea4e7498 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/repeat/repeat001/repeat001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/repeat/repeat001/repeat001.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 @@ -38,7 +38,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.repeat.repeat001.repeat001a - * @run main/othervm + * @run driver * nsk.jdb.repeat.repeat001.repeat001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -68,13 +68,9 @@ public class repeat001 extends JdbTest { static final String FIRST_BREAK = DEBUGGEE_CLASS + ".main"; public static void main(String[] args) { - System.exit(run(args, System.out) + JCK_STATUS_BASE); - } - - public static int run(String[] args, PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; - return new repeat001().runTest(args, out); + new repeat001().runTest(args); } protected static boolean isPrompt(String line) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/resume/resume002/resume002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/resume/resume002/resume002.java index ab4df2625fe21..9607413036c88 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/resume/resume002/resume002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/resume/resume002/resume002.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 @@ -50,7 +50,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.resume.resume002.resume002a - * @run main/othervm + * @run driver * nsk.jdb.resume.resume002.resume002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -73,14 +73,10 @@ public class resume002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new resume002().runTest(argv, out); + new resume002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.resume.resume002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/run/run002/run002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/run/run002/run002.java index da837ab0f8bce..9b23ac4de25a9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/run/run002/run002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/run/run002/run002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -44,7 +44,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.run.run002.run002a - * @run main/othervm + * @run driver * nsk.jdb.run.run002.run002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -67,14 +67,10 @@ public class run002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new run002().runTest(argv, out); + new run002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.run.run002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set001/set001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set001/set001.java index d00362b228cbf..7b97f47b5294a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set001/set001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set001/set001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -53,7 +53,7 @@ * @clean nsk.jdb.set.set001.set001a * @compile -g:lines,source,vars set001a.java * - * @run main/othervm + * @run driver * nsk.jdb.set.set001.set001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -76,14 +76,10 @@ public class set001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new set001().runTest(argv, out); + new set001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.set.set001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set002/set002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set002/set002.java index dca4e554afaf9..91d8482104045 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set002/set002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/set/set002/set002.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 @@ -53,7 +53,7 @@ * @clean nsk.jdb.set.set002.set002a * @compile -g:lines,source,vars set002a.java * - * @run main/othervm + * @run driver * nsk.jdb.set.set002.set002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -76,15 +76,11 @@ public class set002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new set002().runTest(argv, out); + new set002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.set.set002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/step/step002/step002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/step/step002/step002.java index 4df163ca1a92c..c9cc342783e3f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/step/step002/step002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/step/step002/step002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, 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 @@ -56,7 +56,7 @@ * @clean nsk.jdb.step.step002.step002a * @compile -g:lines,source,vars step002a.java * - * @run main/othervm + * @run driver * nsk.jdb.step.step002.step002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -79,14 +79,10 @@ public class step002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new step002().runTest(argv, out); + new step002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.step.step002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/step_up/step_up001/step_up001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/step_up/step_up001/step_up001.java index 590a476dbbe60..d4c60f937fa2e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/step_up/step_up001/step_up001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/step_up/step_up001/step_up001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -45,7 +45,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.step_up.step_up001.step_up001a - * @run main/othervm + * @run driver * nsk.jdb.step_up.step_up001.step_up001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -68,14 +68,10 @@ public class step_up001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new step_up001().runTest(argv, out); + new step_up001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.step_up.step_up001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java index 9dae8c17cfc36..30cb6ed2c68af 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at002/stop_at002.java @@ -37,7 +37,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.stop_at.stop_at002.stop_at002a - * @run main/othervm + * @run driver * nsk.jdb.stop_at.stop_at002.stop_at002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -67,14 +67,10 @@ public class stop_at002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new stop_at002().runTest(argv, out); + new stop_at002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.stop_at.stop_at002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at003/stop_at003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at003/stop_at003.java index ecd66ca7c9573..06eacea58b913 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at003/stop_at003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_at/stop_at003/stop_at003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -49,7 +49,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.stop_at.stop_at003.stop_at003a - * @run main/othervm + * @run driver * nsk.jdb.stop_at.stop_at003.stop_at003 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -79,14 +79,10 @@ public class stop_at003 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new stop_at003().runTest(argv, out); + new stop_at003().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.stop_at.stop_at003"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_in/stop_in002/stop_in002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_in/stop_in002/stop_in002.java index e4c2058fd97a3..710f05c078c46 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_in/stop_in002/stop_in002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/stop_in/stop_in002/stop_in002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -50,7 +50,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.stop_in.stop_in002.stop_in002a - * @run main/othervm + * @run driver * nsk.jdb.stop_in.stop_in002.stop_in002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -80,14 +80,10 @@ public class stop_in002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new stop_in002().runTest(argv, out); + new stop_in002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.stop_in.stop_in002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/suspend/suspend001/suspend001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/suspend/suspend001/suspend001.java index 18e5c27d31c6c..20c9778f25109 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/suspend/suspend001/suspend001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/suspend/suspend001/suspend001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -46,7 +46,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.suspend.suspend001.suspend001a - * @run main/othervm + * @run driver * nsk.jdb.suspend.suspend001.suspend001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -69,14 +69,10 @@ public class suspend001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new suspend001().runTest(argv, out); + new suspend001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.suspend.suspend001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/thread/thread002/thread002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/thread/thread002/thread002.java index 487ac49e66ec9..c8b55b0beee56 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/thread/thread002/thread002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/thread/thread002/thread002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -43,7 +43,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.thread.thread002.thread002a - * @run main/othervm + * @run driver * nsk.jdb.thread.thread002.thread002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -66,14 +66,10 @@ public class thread002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new thread002().runTest(argv, out); + new thread002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.thread.thread002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroup/threadgroup002/threadgroup002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroup/threadgroup002/threadgroup002.java index 72bbf3584741d..8ff58b11bec19 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroup/threadgroup002/threadgroup002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroup/threadgroup002/threadgroup002.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 @@ -45,7 +45,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.threadgroup.threadgroup002.threadgroup002a - * @run main/othervm + * @run driver * nsk.jdb.threadgroup.threadgroup002.threadgroup002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -69,14 +69,10 @@ public class threadgroup002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new threadgroup002().runTest(argv, out); + new threadgroup002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.threadgroup.threadgroup002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroups/threadgroups002/threadgroups002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroups/threadgroups002/threadgroups002.java index 67ee29006b474..56f4dceda9e2d 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroups/threadgroups002/threadgroups002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threadgroups/threadgroups002/threadgroups002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -41,7 +41,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.threadgroups.threadgroups002.threadgroups002a - * @run main/othervm + * @run driver * nsk.jdb.threadgroups.threadgroups002.threadgroups002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -64,14 +64,10 @@ public class threadgroups002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new threadgroups002().runTest(argv, out); + new threadgroups002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.threadgroups.threadgroups002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads002/threads002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads002/threads002.java index e9afd794d812a..fdc52ad7a2ab5 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads002/threads002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads002/threads002.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 @@ -40,7 +40,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.threads.threads002.threads002a - * @run main/othervm + * @run driver * nsk.jdb.threads.threads002.threads002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -65,14 +65,10 @@ public class threads002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new threads002().runTest(argv, out); + new threads002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.threads.threads002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads003/threads003.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads003/threads003.java index 4332eb69cf94b..f290cc71bb598 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads003/threads003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/threads/threads003/threads003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, 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 @@ -41,7 +41,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.threads.threads003.threads003a - * @run main/othervm + * @run driver * nsk.jdb.threads.threads003.threads003 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -65,14 +65,10 @@ public class threads003 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new threads003().runTest(argv, out); + new threads003().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.threads.threads003"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/trace/trace001/trace001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/trace/trace001/trace001.java index 0e289f93aee20..492d5b438c893 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/trace/trace001/trace001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/trace/trace001/trace001.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 @@ -47,7 +47,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.trace.trace001.trace001a - * @run main/othervm + * @run driver * nsk.jdb.trace.trace001.trace001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,14 +71,10 @@ public class trace001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new trace001().runTest(argv, out); + new trace001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.trace.trace001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/uncaught_exception/uncaught_exception002/uncaught_exception002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/uncaught_exception/uncaught_exception002/uncaught_exception002.java index dd1d0748c0ff2..32f7750cdb5ec 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/uncaught_exception/uncaught_exception002/uncaught_exception002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/uncaught_exception/uncaught_exception002/uncaught_exception002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -52,7 +52,7 @@ * @clean nsk.jdb.uncaught_exception.uncaught_exception002.uncaught_exception002a * @compile -g:lines,source,vars uncaught_exception002a.java * - * @run main/othervm + * @run driver * nsk.jdb.uncaught_exception.uncaught_exception002.uncaught_exception002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -75,14 +75,10 @@ public class uncaught_exception002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new uncaught_exception002(true).runTest(argv, out); + new uncaught_exception002(true).runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.uncaught_exception.uncaught_exception002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java index 7d98824be73c4..195b2427ae58e 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, 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 @@ -56,7 +56,7 @@ * @clean nsk.jdb.unmonitor.unmonitor001.unmonitor001a * @compile -g:lines,source,vars unmonitor001a.java * - * @run main/othervm + * @run driver * nsk.jdb.unmonitor.unmonitor001.unmonitor001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -79,14 +79,10 @@ public class unmonitor001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new unmonitor001().runTest(argv, out); + new unmonitor001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.unmonitor.unmonitor001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/untrace/untrace001/untrace001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/untrace/untrace001/untrace001.java index daad477dbb439..0891e5b931cc4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/untrace/untrace001/untrace001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/untrace/untrace001/untrace001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -54,7 +54,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.untrace.untrace001.untrace001a - * @run main/othervm + * @run driver * nsk.jdb.untrace.untrace001.untrace001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -77,14 +77,10 @@ public class untrace001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new untrace001().runTest(argv, out); + new untrace001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.untrace.untrace001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch001/unwatch001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch001/unwatch001.java index b8c71645edb47..aff9890e58d8b 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch001/unwatch001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch001/unwatch001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -50,7 +50,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.unwatch.unwatch001.unwatch001a - * @run main/othervm + * @run driver * nsk.jdb.unwatch.unwatch001.unwatch001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -73,14 +73,10 @@ public class unwatch001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new unwatch001().runTest(argv, out); + new unwatch001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.unwatch.unwatch001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch002/unwatch002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch002/unwatch002.java index e32cc0b8e5dc6..1078e2b3da358 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch002/unwatch002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/unwatch/unwatch002/unwatch002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -51,7 +51,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.unwatch.unwatch002.unwatch002a - * @run main/othervm + * @run driver * nsk.jdb.unwatch.unwatch002.unwatch002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -74,14 +74,10 @@ public class unwatch002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new unwatch002().runTest(argv, out); + new unwatch002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.unwatch.unwatch002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/up/up002/up002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/up/up002/up002.java index 5b2cb393df4e8..78c01074abb1a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/up/up002/up002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/up/up002/up002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -43,7 +43,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.up.up002.up002a - * @run main/othervm + * @run driver * nsk.jdb.up.up002.up002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -66,14 +66,10 @@ public class up002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new up002().runTest(argv, out); + new up002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.up.up002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/use/use001/use001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/use/use001/use001.java index 1454b39b2bf8e..81ad1dd48accb 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/use/use001/use001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/use/use001/use001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -43,7 +43,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.use.use001.use001a - * @run main/othervm + * @run driver * nsk.jdb.use.use001.use001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -67,14 +67,10 @@ public class use001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new use001().runTest(argv, out); + new use001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.use.use001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch001/watch001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch001/watch001.java index 8d434fcfc7444..dfc154d1b4186 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch001/watch001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch001/watch001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -48,7 +48,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.watch.watch001.watch001a - * @run main/othervm + * @run driver * nsk.jdb.watch.watch001.watch001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,15 +71,11 @@ public class watch001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; compoundPromptIdent = COMPOUND_PROMPT_IDENT; - return new watch001().runTest(argv, out); + new watch001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.watch.watch001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch002/watch002.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch002/watch002.java index cb0535117d9fd..84c80a59ebf73 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch002/watch002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/watch/watch002/watch002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -48,7 +48,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.watch.watch002.watch002a - * @run main/othervm + * @run driver * nsk.jdb.watch.watch002.watch002 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -71,15 +71,11 @@ public class watch002 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; compoundPromptIdent = COMPOUND_PROMPT_IDENT; - return new watch002().runTest(argv, out); + new watch002().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.watch.watch002"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where004/where004.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where004/where004.java index e4cbf50e62f68..9002c35e16e5a 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where004/where004.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where004/where004.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -41,7 +41,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.where.where004.where004a - * @run main/othervm + * @run driver * nsk.jdb.where.where004.where004 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -64,14 +64,10 @@ public class where004 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new where004().runTest(argv, out); + new where004().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.where.where004"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where005/where005.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where005/where005.java index b949916aae74e..2fded98727291 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where005/where005.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where005/where005.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -42,7 +42,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.where.where005.where005a - * @run main/othervm + * @run driver * nsk.jdb.where.where005.where005 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -65,14 +65,10 @@ public class where005 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new where005(true).runTest(argv, out); + new where005(true).runTest(argv); } public where005 (boolean debuggeeShouldFail) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where006/where006.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where006/where006.java index bf7622c48b345..11dc185238f07 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where006/where006.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/where/where006/where006.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -42,7 +42,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.where.where006.where006a - * @run main/othervm + * @run driver * nsk.jdb.where.where006.where006 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -65,14 +65,10 @@ public class where006 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new where006().runTest(argv, out); + new where006().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.where.where006"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdb/wherei/wherei001/wherei001.java b/test/hotspot/jtreg/vmTestbase/nsk/jdb/wherei/wherei001/wherei001.java index 431206b55510e..e4d75620f0b49 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdb/wherei/wherei001/wherei001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdb/wherei/wherei001/wherei001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, 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 @@ -37,7 +37,7 @@ * @library /vmTestbase * /test/lib * @build nsk.jdb.wherei.wherei001.wherei001a - * @run main/othervm + * @run driver * nsk.jdb.wherei.wherei001.wherei001 * -arch=${os.family}-${os.simpleArch} * -waittime=5 @@ -60,14 +60,10 @@ public class wherei001 extends JdbTest { public static void main (String argv[]) { - System.exit(run(argv, System.out) + JCK_STATUS_BASE); - } - - public static int run(String argv[], PrintStream out) { debuggeeClass = DEBUGGEE_CLASS; firstBreak = FIRST_BREAK; lastBreak = LAST_BREAK; - return new wherei001().runTest(argv, out); + new wherei001().runTest(argv); } static final String PACKAGE_NAME = "nsk.jdb.wherei.wherei001"; diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/JdbTest.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/JdbTest.java index 349216f4329c4..aa7ad833b53dc 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/JdbTest.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/JdbTest.java @@ -125,14 +125,15 @@ protected void initJdb() { protected void afterJdbExit() { } - protected int runTest(String argv[], PrintStream out) { + protected void runTest(String argv[]) { + PrintStream out = System.out; try { argumentHandler = new JdbArgumentHandler(argv); log = new Log(out, argumentHandler); if (shouldPass()) { log.println("TEST PASSED"); - return PASSED; + return; } try { @@ -226,16 +227,14 @@ protected int runTest(String argv[], PrintStream out) { if (!success) { log.complain("TEST FAILED"); - return FAILED; + throw new RuntimeException("TEST FAILED"); } } catch (Throwable t) { out.println("Caught unexpected exception while starting the test: " + t); t.printStackTrace(out); - out.println("TEST FAILED"); - return FAILED; + throw new RuntimeException("TEST FAILED", t); } out.println("TEST PASSED"); - return PASSED; } } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java index 35df95b2d6f8a..d443741349560 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Launcher.java @@ -180,10 +180,12 @@ private String[] makeJdbCmdLine (String classToExecute) { } else /* LaunchingConnector or DefaultConnector */ { connect.append("vmexec=" + argumentHandler.getLaunchExecName().trim()); + connect.append(",options="); + connect.append(" \"-cp\""); + connect.append(" \"" + System.getProperty("test.class.path") + "\""); + String debuggeeOpts = argumentHandler.getDebuggeeOptions(); if (debuggeeOpts.trim().length() > 0) { - //connect.append(",options=" + debuggeeOpts.trim()); - connect.append(",options="); for (String arg : debuggeeOpts.split("\\s+")) { connect.append(" \""); connect.append(arg); From 5079c38ddf345b21d8cb1c959bc36c4341e11da6 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Mon, 12 Aug 2024 22:12:01 +0000 Subject: [PATCH 390/401] 8338160: Fix -Wzero-as-null-pointer-constant warnings in management.cpp Reviewed-by: dholmes --- src/hotspot/share/services/management.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp index 2c9f36c098d07..ac7e1daf39706 100644 --- a/src/hotspot/share/services/management.cpp +++ b/src/hotspot/share/services/management.cpp @@ -1820,7 +1820,7 @@ JVM_END // of a given length and return the objArrayOop static objArrayOop get_memory_usage_objArray(jobjectArray array, int length, TRAPS) { if (array == nullptr) { - THROW_(vmSymbols::java_lang_NullPointerException(), 0); + THROW_NULL(vmSymbols::java_lang_NullPointerException()); } objArrayOop oa = objArrayOop(JNIHandles::resolve_non_null(array)); @@ -1828,16 +1828,16 @@ static objArrayOop get_memory_usage_objArray(jobjectArray array, int length, TRA // array must be of the given length if (length != array_h->length()) { - THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), - "The length of the given MemoryUsage array does not match the number of memory pools.", 0); + THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), + "The length of the given MemoryUsage array does not match the number of memory pools."); } // check if the element of array is of type MemoryUsage class Klass* usage_klass = Management::java_lang_management_MemoryUsage_klass(CHECK_NULL); Klass* element_klass = ObjArrayKlass::cast(array_h->klass())->element_klass(); if (element_klass != usage_klass) { - THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), - "The element type is not MemoryUsage class", 0); + THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), + "The element type is not MemoryUsage class"); } return array_h(); From e70c9bccaae375be1ee6812dabc9fbaff01a6ab0 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Mon, 12 Aug 2024 23:00:04 +0000 Subject: [PATCH 391/401] 8338248: PartialArrayStateAllocator::Impl leaks Arena array Reviewed-by: kbarrett, shade --- src/hotspot/share/gc/shared/partialArrayState.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hotspot/share/gc/shared/partialArrayState.cpp b/src/hotspot/share/gc/shared/partialArrayState.cpp index 583c5dede4026..fd23a32022208 100644 --- a/src/hotspot/share/gc/shared/partialArrayState.cpp +++ b/src/hotspot/share/gc/shared/partialArrayState.cpp @@ -100,6 +100,7 @@ PartialArrayStateAllocator::Impl::~Impl() { for (uint i = 0; i < _num_workers; ++i) { _arenas[i].~Arena(); } + FREE_C_HEAP_ARRAY(Arena*, _arenas); } PartialArrayState* PartialArrayStateAllocator::Impl::allocate(uint worker_id, From d77e6fe45c7b834db457a772ce0bea514d2e44f3 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 13 Aug 2024 05:46:38 +0000 Subject: [PATCH 392/401] 8338154: Fix -Wzero-as-null-pointer-constant warnings in gtest framework Reviewed-by: ihse, dholmes, jwaters --- make/hotspot/lib/CompileGtest.gmk | 3 ++- test/hotspot/gtest/gtestMain.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/make/hotspot/lib/CompileGtest.gmk b/make/hotspot/lib/CompileGtest.gmk index 696adb0c95f10..424743ba27976 100644 --- a/make/hotspot/lib/CompileGtest.gmk +++ b/make/hotspot/lib/CompileGtest.gmk @@ -57,7 +57,8 @@ $(eval $(call SetupJdkLibrary, BUILD_GTEST_LIBGTEST, \ $(GTEST_FRAMEWORK_SRC)/googletest/src \ $(GTEST_FRAMEWORK_SRC)/googlemock/src, \ INCLUDE_FILES := gtest-all.cc gmock-all.cc, \ - DISABLED_WARNINGS_gcc := undef unused-result format-nonliteral maybe-uninitialized, \ + DISABLED_WARNINGS_gcc := undef unused-result format-nonliteral \ + maybe-uninitialized zero-as-null-pointer-constant, \ DISABLED_WARNINGS_clang := undef unused-result format-nonliteral, \ DEFAULT_CFLAGS := false, \ CFLAGS := $(JVM_CFLAGS) \ diff --git a/test/hotspot/gtest/gtestMain.cpp b/test/hotspot/gtest/gtestMain.cpp index bc8ca29f72d45..0bd251e8094b3 100644 --- a/test/hotspot/gtest/gtestMain.cpp +++ b/test/hotspot/gtest/gtestMain.cpp @@ -336,7 +336,7 @@ static void run_in_new_thread(const args_t* args) { extern "C" void* thread_wrapper(void* p) { const args_t* const p_args = (const args_t*) p; runUnitTestsInner(p_args->argc, p_args->argv); - return 0; + return nullptr; } static void run_in_new_thread(const args_t* args) { From 73ddb7deab26c526337ec6e7cd5f528f698a552c Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Tue, 13 Aug 2024 05:52:44 +0000 Subject: [PATCH 393/401] 8335628: C2 SuperWord: cleanup: remove SuperWord::longer_type_for_conversion Reviewed-by: chagedorn, kvn --- src/hotspot/share/opto/superword.cpp | 25 +------------------------ src/hotspot/share/opto/superword.hpp | 3 --- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp index 0e1328a448577..2a43d2ec0af4a 100644 --- a/src/hotspot/share/opto/superword.cpp +++ b/src/hotspot/share/opto/superword.cpp @@ -691,9 +691,7 @@ bool SuperWord::can_pack_into_pair(Node* s1, Node* s2) { BasicType bt2 = velt_basic_type(s2); if(!is_java_primitive(bt1) || !is_java_primitive(bt2)) return false; - BasicType longer_bt = longer_type_for_conversion(s1); - if (Matcher::max_vector_size_auto_vectorization(bt1) < 2 || - (longer_bt != T_ILLEGAL && Matcher::max_vector_size_auto_vectorization(longer_bt) < 2)) { + if (Matcher::max_vector_size_auto_vectorization(bt1) < 2) { return false; // No vectors for this type } @@ -2442,27 +2440,6 @@ VStatus VLoopBody::construct() { return VStatus::make_success(); } -BasicType SuperWord::longer_type_for_conversion(Node* n) const { - if (!(VectorNode::is_convert_opcode(n->Opcode()) || - VectorNode::is_scalar_op_that_returns_int_but_vector_op_returns_long(n->Opcode())) || - !in_bb(n->in(1))) { - return T_ILLEGAL; - } - assert(in_bb(n), "must be in the bb"); - BasicType src_t = velt_basic_type(n->in(1)); - BasicType dst_t = velt_basic_type(n); - // Do not use superword for non-primitives. - // Superword does not support casting involving unsigned types. - if (!is_java_primitive(src_t) || is_unsigned_subword_type(src_t) || - !is_java_primitive(dst_t) || is_unsigned_subword_type(dst_t)) { - return T_ILLEGAL; - } - int src_size = type2aelembytes(src_t); - int dst_size = type2aelembytes(dst_t); - return src_size == dst_size ? T_ILLEGAL - : (src_size > dst_size ? src_t : dst_t); -} - void VLoopTypes::compute_vector_element_type() { #ifndef PRODUCT if (_vloop.is_trace_vector_element_type()) { diff --git a/src/hotspot/share/opto/superword.hpp b/src/hotspot/share/opto/superword.hpp index 65f870825251f..8b24e0cf3a11a 100644 --- a/src/hotspot/share/opto/superword.hpp +++ b/src/hotspot/share/opto/superword.hpp @@ -623,9 +623,6 @@ class SuperWord : public ResourceObj { // Is use->in(u_idx) a vector use? bool is_vector_use(Node* use, int u_idx) const; - // Return the longer type for vectorizable type-conversion node or illegal type for other nodes. - BasicType longer_type_for_conversion(Node* n) const; - bool is_velt_basic_type_compatible_use_def(Node* use, Node* def) const; bool schedule_and_apply() const; From c27a8c8c8b867e6812b905f6154762802a498dbd Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Tue, 13 Aug 2024 05:52:58 +0000 Subject: [PATCH 394/401] 8338124: C2 SuperWord: MulAddS2I input permutation still partially broken after JDK-8333840 Reviewed-by: chagedorn, thartmann, kvn --- src/hotspot/share/opto/superword.cpp | 2 +- .../loopopts/superword/TestMulAddS2I.java | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp index 2a43d2ec0af4a..bb5fed78b0274 100644 --- a/src/hotspot/share/opto/superword.cpp +++ b/src/hotspot/share/opto/superword.cpp @@ -2270,7 +2270,7 @@ Node_List* PackSet::strided_pack_input_at_index_or_null(const Node_List* pack, c return nullptr; // size mismatch } - for (uint i = 1; i < pack->size(); i++) { + for (uint i = 0; i < pack->size(); i++) { if (pack->at(i)->in(index) != pack_in->at(i * stride + offset)) { return nullptr; // use-def mismatch } diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestMulAddS2I.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestMulAddS2I.java index e0f073c7f8f7d..fb99fc5983a16 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestMulAddS2I.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestMulAddS2I.java @@ -53,6 +53,7 @@ public class TestMulAddS2I { static final int[] GOLDEN_J; static final int[] GOLDEN_K; static final int[] GOLDEN_L; + static final int[] GOLDEN_M; static { for (int i = 0; i < RANGE; i++) { @@ -71,6 +72,7 @@ public class TestMulAddS2I { GOLDEN_J = testj(new int[ITER]); GOLDEN_K = testk(new int[ITER]); GOLDEN_L = testl(new int[ITER]); + GOLDEN_M = testm(new int[ITER]); } @@ -80,7 +82,7 @@ public static void main(String[] args) { } @Run(test = {"testa", "testb", "testc", "testd", "teste", "testf", "testg", "testh", - "testi", "testj", "testk", "testl"}) + "testi", "testj", "testk", "testl", "testm"}) @Warmup(0) public static void run() { compare(testa(), GOLDEN_A, "testa"); @@ -95,6 +97,7 @@ public static void run() { compare(testj(new int[ITER]), GOLDEN_J, "testj"); compare(testk(new int[ITER]), GOLDEN_K, "testk"); compare(testl(new int[ITER]), GOLDEN_L, "testl"); + compare(testm(new int[ITER]), GOLDEN_M, "testm"); } public static void compare(int[] out, int[] golden, String name) { @@ -299,4 +302,17 @@ public static int[] testl(int[] out) { return out; } + @Test + @IR(counts = {IRNode.MUL_ADD_S2I, "> 0"}, + applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}) + @IR(counts = {IRNode.MUL_ADD_VS2VI, "= 0"}) + public static int[] testm(int[] out) { + for (int i = 0; i < ITER-4; i+=4) { + // Unrolled, with some swaps that prevent vectorization. + out[i+0] += ((sArr1[2*i+0] * sArr2[2*i+1]) + (sArr1[2*i+1] * sArr2[2*i+0])); // bad + out[i+1] += ((sArr1[2*i+2] * sArr2[2*i+2]) + (sArr1[2*i+3] * sArr2[2*i+3])); // ok + // 2-element gap + } + return out; + } } From 73f7a5f15dbba54a98f3916ff1190520ac07874d Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 13 Aug 2024 07:27:49 +0000 Subject: [PATCH 395/401] 8338155: Fix -Wzero-as-null-pointer-constant warnings involving PTHREAD_MUTEX_INITIALIZER Reviewed-by: dholmes, dlong --- src/hotspot/os/linux/os_perf_linux.cpp | 5 ++++- src/hotspot/os/posix/threadCritical_posix.cpp | 8 +++++++- src/hotspot/share/utilities/compilerWarnings.hpp | 6 +++++- src/hotspot/share/utilities/compilerWarnings_gcc.hpp | 5 ++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/hotspot/os/linux/os_perf_linux.cpp b/src/hotspot/os/linux/os_perf_linux.cpp index 87abbebe25faf..a31a58e55af93 100644 --- a/src/hotspot/os/linux/os_perf_linux.cpp +++ b/src/hotspot/os/linux/os_perf_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -430,7 +430,10 @@ static int get_boot_time(uint64_t* time) { } static int perf_context_switch_rate(double* rate) { + PRAGMA_DIAG_PUSH + PRAGMA_ZERO_AS_NULL_POINTER_CONSTANT_IGNORED static pthread_mutex_t contextSwitchLock = PTHREAD_MUTEX_INITIALIZER; + PRAGMA_DIAG_POP static uint64_t bootTime; static uint64_t lastTimeNanos; static uint64_t lastSwitches; diff --git a/src/hotspot/os/posix/threadCritical_posix.cpp b/src/hotspot/os/posix/threadCritical_posix.cpp index 45eba4c15852c..cd3b42e71ba8b 100644 --- a/src/hotspot/os/posix/threadCritical_posix.cpp +++ b/src/hotspot/os/posix/threadCritical_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,6 +26,7 @@ #include "precompiled.hpp" #include "runtime/javaThread.hpp" #include "runtime/threadCritical.hpp" +#include "utilities/compilerWarnings.hpp" // put OS-includes here # include @@ -35,7 +36,12 @@ // static pthread_t tc_owner = 0; + +PRAGMA_DIAG_PUSH +PRAGMA_ZERO_AS_NULL_POINTER_CONSTANT_IGNORED static pthread_mutex_t tc_mutex = PTHREAD_MUTEX_INITIALIZER; +PRAGMA_DIAG_POP + static int tc_count = 0; ThreadCritical::ThreadCritical() { diff --git a/src/hotspot/share/utilities/compilerWarnings.hpp b/src/hotspot/share/utilities/compilerWarnings.hpp index 28954843dc323..ddcaf022fa690 100644 --- a/src/hotspot/share/utilities/compilerWarnings.hpp +++ b/src/hotspot/share/utilities/compilerWarnings.hpp @@ -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 @@ -82,6 +82,10 @@ #define PRAGMA_NONNULL_IGNORED #endif +#ifndef PRAGMA_ZERO_AS_NULL_POINTER_CONSTANT_IGNORED +#define PRAGMA_ZERO_AS_NULL_POINTER_CONSTANT_IGNORED +#endif + // Support warnings for use of certain C functions, except where explicitly // permitted. // diff --git a/src/hotspot/share/utilities/compilerWarnings_gcc.hpp b/src/hotspot/share/utilities/compilerWarnings_gcc.hpp index 53373ec628a46..1dd5892e4c348 100644 --- a/src/hotspot/share/utilities/compilerWarnings_gcc.hpp +++ b/src/hotspot/share/utilities/compilerWarnings_gcc.hpp @@ -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 @@ -67,6 +67,9 @@ #define PRAGMA_NONNULL_IGNORED PRAGMA_DISABLE_GCC_WARNING("-Wnonnull") +#define PRAGMA_ZERO_AS_NULL_POINTER_CONSTANT_IGNORED \ + PRAGMA_DISABLE_GCC_WARNING("-Wzero-as-null-pointer-constant") + #if (__GNUC__ >= 10) // TODO: Re-enable warning attribute for Clang once // https://github.com/llvm/llvm-project/issues/56519 is fixed and released. From 5bf27098e22172ed5d3ec0c43fe0553f8322c4b1 Mon Sep 17 00:00:00 2001 From: Saint Wesonga Date: Tue, 13 Aug 2024 08:10:29 +0000 Subject: [PATCH 396/401] 8334475: UnsafeIntrinsicsTest.java#ZGenerationalDebug assert(!assert_on_failure) failed: Has low-order bits set Reviewed-by: stefank, eosterlund, aboldtch --- .../windows_aarch64/copy_windows_aarch64.hpp | 63 +++++++------------ 1 file changed, 23 insertions(+), 40 deletions(-) diff --git a/src/hotspot/os_cpu/windows_aarch64/copy_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/copy_windows_aarch64.hpp index ce2ad2d046f88..96a34fe967b64 100644 --- a/src/hotspot/os_cpu/windows_aarch64/copy_windows_aarch64.hpp +++ b/src/hotspot/os_cpu/windows_aarch64/copy_windows_aarch64.hpp @@ -26,8 +26,27 @@ #ifndef OS_CPU_WINDOWS_AARCH64_COPY_WINDOWS_AARCH64_HPP #define OS_CPU_WINDOWS_AARCH64_COPY_WINDOWS_AARCH64_HPP +#include "runtime/atomic.hpp" + #include +template +static void pd_conjoint_atomic_helper(const T* from, T* to, size_t count) { + if (from > to) { + while (count-- > 0) { + // Copy forwards + Atomic::store(to++, Atomic::load(from++)); + } + } else { + from += count - 1; + to += count - 1; + while (count-- > 0) { + // Copy backwards + Atomic::store(to--, Atomic::load(from--)); + } + } +} + static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { (void)memmove(to, from, count * HeapWordSize); } @@ -71,55 +90,19 @@ static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) { } static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { - if (from > to) { - while (count-- > 0) { - // Copy forwards - *to++ = *from++; - } - } else { - from += count - 1; - to += count - 1; - while (count-- > 0) { - // Copy backwards - *to-- = *from--; - } - } + pd_conjoint_atomic_helper(from, to, count); } static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { - if (from > to) { - while (count-- > 0) { - // Copy forwards - *to++ = *from++; - } - } else { - from += count - 1; - to += count - 1; - while (count-- > 0) { - // Copy backwards - *to-- = *from--; - } - } + pd_conjoint_atomic_helper(from, to, count); } static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { - pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count); + pd_conjoint_atomic_helper(from, to, count); } static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) { - if (from > to) { - while (count-- > 0) { - // Copy forwards - *to++ = *from++; - } - } else { - from += count - 1; - to += count - 1; - while (count-- > 0) { - // Copy backwards - *to-- = *from--; - } - } + pd_conjoint_atomic_helper(from, to, count); } static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) { From ba69ed7c58fcf99ed18dfd8840125ddcac9460bb Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 13 Aug 2024 08:11:47 +0000 Subject: [PATCH 397/401] 8338202: Shenandoah: Improve handshake closure labels Reviewed-by: rkennke, ysr, wkemper --- src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp | 2 +- .../share/gc/shenandoah/shenandoahConcurrentMark.cpp | 2 +- src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp | 6 +++--- src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp | 2 +- src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp index ac2e732052a28..86d6d91f72c9a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp @@ -823,7 +823,7 @@ void ShenandoahConcurrentGC::op_weak_roots() { // Perform handshake to flush out dead oops { ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_weak_roots_rendezvous); - heap->rendezvous_threads(); + heap->rendezvous_threads("Shenandoah Concurrent Weak Roots"); } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp index 31157616e0ef8..dde446d824b77 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp @@ -179,7 +179,7 @@ class ShenandoahFlushSATBHandshakeClosure : public HandshakeClosure { SATBMarkQueueSet& _qset; public: ShenandoahFlushSATBHandshakeClosure(SATBMarkQueueSet& qset) : - HandshakeClosure("Shenandoah Flush SATB Handshake"), + HandshakeClosure("Shenandoah Flush SATB"), _qset(qset) {} void do_thread(Thread* thread) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index eb6de9719dc62..0a20307abcbbf 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1744,12 +1744,12 @@ void ShenandoahHeap::parallel_heap_region_iterate(ShenandoahHeapRegionClosure* b class ShenandoahRendezvousClosure : public HandshakeClosure { public: - inline ShenandoahRendezvousClosure() : HandshakeClosure("ShenandoahRendezvous") {} + inline ShenandoahRendezvousClosure(const char* name) : HandshakeClosure(name) {} inline void do_thread(Thread* thread) {} }; -void ShenandoahHeap::rendezvous_threads() { - ShenandoahRendezvousClosure cl; +void ShenandoahHeap::rendezvous_threads(const char* name) { + ShenandoahRendezvousClosure cl(name); Handshake::execute(&cl); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index f3625da218cf2..86bd7b83bbe1b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -400,7 +400,7 @@ class ShenandoahHeap : public CollectedHeap, public ShenandoahSpaceInfo { void update_heap_region_states(bool concurrent); void rebuild_free_set(bool concurrent); - void rendezvous_threads(); + void rendezvous_threads(const char* name); void recycle_trash(); public: void notify_gc_progress(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp index 02a7fbeb8b5be..f33b76bcd4e1c 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp @@ -168,7 +168,7 @@ void ShenandoahUnload::unload() { // Make sure stale metadata and nmethods are no longer observable { ShenandoahTimingsTracker t(ShenandoahPhaseTimings::conc_class_unload_rendezvous); - heap->rendezvous_threads(); + heap->rendezvous_threads("Shenandoah Class Unloading"); } // Purge stale metadata and nmethods that were unlinked From fbe4cc96e223882a18c7ff666fe6f68b3fa2cfe4 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Tue, 13 Aug 2024 09:51:08 +0000 Subject: [PATCH 398/401] 8336384: AbstractQueuedSynchronizer.acquire should cancel acquire when failing due to a LinkageError or other errors Reviewed-by: alanb --- .../locks/AbstractQueuedLongSynchronizer.java | 19 ++++++++++++------- .../locks/AbstractQueuedSynchronizer.java | 19 ++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java index f4d7d0c08c0c9..2de1d17e7c18c 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java @@ -369,14 +369,19 @@ final int acquire(Node node, long arg, boolean shared, } else if (node.status == 0) { node.status = WAITING; // enable signal and recheck } else { - long nanos; spins = postSpins = (byte)((postSpins << 1) | 1); - if (!timed) - LockSupport.park(this); - else if ((nanos = time - System.nanoTime()) > 0L) - LockSupport.parkNanos(this, nanos); - else - break; + try { + long nanos; + if (!timed) + LockSupport.park(this); + else if ((nanos = time - System.nanoTime()) > 0L) + LockSupport.parkNanos(this, nanos); + else + break; + } catch (Error | RuntimeException ex) { + cancelAcquire(node, interrupted, interruptible); // cancel & rethrow + throw ex; + } node.clearStatus(); if ((interrupted |= Thread.interrupted()) && interruptible) break; diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java index 1f51419f94c18..2ea0d3ed3b091 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java @@ -748,14 +748,19 @@ final int acquire(Node node, int arg, boolean shared, } else if (node.status == 0) { node.status = WAITING; // enable signal and recheck } else { - long nanos; spins = postSpins = (byte)((postSpins << 1) | 1); - if (!timed) - LockSupport.park(this); - else if ((nanos = time - System.nanoTime()) > 0L) - LockSupport.parkNanos(this, nanos); - else - break; + try { + long nanos; + if (!timed) + LockSupport.park(this); + else if ((nanos = time - System.nanoTime()) > 0L) + LockSupport.parkNanos(this, nanos); + else + break; + } catch (Error | RuntimeException ex) { + cancelAcquire(node, interrupted, interruptible); // cancel & rethrow + throw ex; + } node.clearStatus(); if ((interrupted |= Thread.interrupted()) && interruptible) break; From ff8a9f9267c480fe0be8470cda870fd77763fb31 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Tue, 13 Aug 2024 11:48:50 +0000 Subject: [PATCH 399/401] 8337318: Deoptimization::relock_objects fails assert(monitor->owner() == Thread::current()) failed: must be Co-authored-by: Richard Reingruber Reviewed-by: rrich, dholmes, shade, pchilanomate --- src/hotspot/share/runtime/synchronizer.cpp | 4 +- test/jdk/com/sun/jdi/EATests.java | 83 +++++++++++++++++++++- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp index 2d45163d0f4a2..b4ff263d455b4 100644 --- a/src/hotspot/share/runtime/synchronizer.cpp +++ b/src/hotspot/share/runtime/synchronizer.cpp @@ -596,8 +596,8 @@ bool ObjectSynchronizer::enter_fast_impl(Handle obj, BasicLock* lock, JavaThread log_info(monitorinflation)("LockStack capacity exceeded, inflating."); ObjectMonitor* monitor = inflate_for(locking_thread, lock_stack.bottom(), inflate_cause_vm_internal); - assert(monitor->owner() == Thread::current(), "must be owner=" PTR_FORMAT " current=" PTR_FORMAT " mark=" PTR_FORMAT, - p2i(monitor->owner()), p2i(Thread::current()), monitor->object()->mark_acquire().value()); + assert(monitor->owner() == locking_thread, "must be owner=" PTR_FORMAT " locking_thread=" PTR_FORMAT " mark=" PTR_FORMAT, + p2i(monitor->owner()), p2i(locking_thread), monitor->object()->mark_acquire().value()); assert(!lock_stack.is_full(), "must have made room here"); } diff --git a/test/jdk/com/sun/jdi/EATests.java b/test/jdk/com/sun/jdi/EATests.java index 7285948165989..adeb21741438f 100644 --- a/test/jdk/com/sun/jdi/EATests.java +++ b/test/jdk/com/sun/jdi/EATests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 SAP SE. All rights reserved. + * Copyright (c) 2020, 2024 SAP SE. 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 @@ -288,6 +288,7 @@ public static void main(String[] args) { // Relocking test cases new EARelockingSimpleTarget() .run(); + new EARelockingWithManyLightweightLocksTarget() .run(); new EARelockingSimpleWithAccessInOtherThreadTarget() .run(); new EARelockingSimpleWithAccessInOtherThread_02_DynamicCall_Target() .run(); new EARelockingRecursiveTarget() .run(); @@ -413,6 +414,7 @@ protected void runTests() throws Exception { // Relocking test cases new EARelockingSimple() .run(this); + new EARelockingWithManyLightweightLocks() .run(this); new EARelockingSimpleWithAccessInOtherThread() .run(this); new EARelockingSimpleWithAccessInOtherThread_02_DynamicCall() .run(this); new EARelockingRecursive() .run(this); @@ -1797,6 +1799,85 @@ public void dontinline_testMethod() { ///////////////////////////////////////////////////////////////////////////// +/** + * Like {@link EARelockingSimple}. The difference is that there are many + * lightweight locked objects when the relocking is done. With + * -XX:LockingMode=2 the lock stack of the thread will be full + * because of this. + */ + +class EARelockingWithManyLightweightLocks extends EATestCaseBaseDebugger { + + public void runTestCase() throws Exception { + BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V"); + printStack(bpe.thread()); + @SuppressWarnings("unused") + ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "l1"); + } +} + +class EARelockingWithManyLightweightLocksTarget extends EATestCaseBaseTarget { + + static class Lock { + } + + public static Lock L0, L1, L2, L3, L4, L5, L6, L7, L8, L9; + + void allocateLocks() { + L0 = new Lock(); + L1 = new Lock(); + L2 = new Lock(); + L3 = new Lock(); + L4 = new Lock(); + L5 = new Lock(); + L6 = new Lock(); + L7 = new Lock(); + L8 = new Lock(); + L9 = new Lock(); + } + + @Override + public void setUp() { + super.setUp(); + allocateLocks(); + } + + @Override + public void warmupDone() { + super.warmupDone(); + allocateLocks(); // get rid of already inflated ones + } + + public void dontinline_testMethod() { + XYVal l1 = new XYVal(4, 2); + synchronized(L0) { + synchronized(L1) { + synchronized(L2) { + synchronized(L3) { + synchronized(L4) { + synchronized(L5) { + synchronized(L6) { + synchronized(L7) { + synchronized(L8) { + synchronized(L9) { + synchronized (l1) { + dontinline_brkpt(); + } + } + } + } + } + } + } + } + } + } + } + } +} + +///////////////////////////////////////////////////////////////////////////// + // The debugger reads and publishes an object with eliminated locking to an instance field. // A 2nd thread in the debuggee finds it there and changes its state using a synchronized method. // Without eager relocking the accesses are unsynchronized which can be observed. From 76e33b6c1517599e14ee34371c945aafcd752e4e Mon Sep 17 00:00:00 2001 From: Axel Boldt-Christmas Date: Tue, 13 Aug 2024 13:13:14 +0000 Subject: [PATCH 400/401] 8336148: Test runtime/locking/TestRecursiveMonitorChurn.java failed: Unexpected Inflation Reviewed-by: dholmes, eosterlund --- .../runtime/locking/TestRecursiveMonitorChurn.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/hotspot/jtreg/runtime/locking/TestRecursiveMonitorChurn.java b/test/hotspot/jtreg/runtime/locking/TestRecursiveMonitorChurn.java index 19dd90015bf1c..806f32aad882b 100644 --- a/test/hotspot/jtreg/runtime/locking/TestRecursiveMonitorChurn.java +++ b/test/hotspot/jtreg/runtime/locking/TestRecursiveMonitorChurn.java @@ -70,6 +70,18 @@ public static void main(String[] args) { if (pre_monitor_count != post_monitor_count) { final long monitor_count_change = post_monitor_count - pre_monitor_count; System.out.println("Unexpected change in monitor count: " + monitor_count_change); + + // Intermittent deflation and inflation may occur due to running the test + // with stress flags (like DeoptimizeALot) or with added instrumentation + // which runs in the same VM. + // An arbitrary fuzzy max difference of 10 (= 0.01% of COUNT) is chosen to + // allow for these occurrences to be skipped while still catching regressions. + final long fuzzy_max_difference = 10; + if (Math.abs(monitor_count_change) < fuzzy_max_difference) { + final String type = monitor_count_change < 0 ? "deflation" : "inflation"; + throw new SkippedException("Intermittent " + type + " detected. Invalid test."); + } + if (monitor_count_change < 0) { throw new RuntimeException("Unexpected Deflation"); } From 877fd5a768647790d0a43aaca247043bae70d708 Mon Sep 17 00:00:00 2001 From: Casper Norrbin Date: Tue, 13 Aug 2024 14:43:44 +0000 Subject: [PATCH 401/401] 8337595: Remove empty statements in src/hotspot/share/memory/metaspace Reviewed-by: stefank, dholmes, jwaters --- src/hotspot/share/memory/metaspace/metaspaceCommon.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/memory/metaspace/metaspaceCommon.hpp b/src/hotspot/share/memory/metaspace/metaspaceCommon.hpp index eae75e8194cc4..511f4e6e09244 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceCommon.hpp +++ b/src/hotspot/share/memory/metaspace/metaspaceCommon.hpp @@ -85,7 +85,7 @@ void print_percentage(outputStream* st, size_t total, size_t part); SIZE_FORMAT_X " is not aligned to " \ SIZE_FORMAT_X, (size_t)(uintptr_t)value, (size_t)(alignment)) #define assert_is_aligned_metaspace_pointer(p) \ - assert_is_aligned((p), metaspace::AllocationAlignmentByteSize); + assert_is_aligned((p), metaspace::AllocationAlignmentByteSize) #else #define assert_is_aligned(value, alignment) #define assert_is_aligned_metaspace_pointer(pointer) @@ -141,8 +141,8 @@ void print_number_of_classes(outputStream* out, uintx classes, uintx classes_sha #define HAVE_UL #ifdef HAVE_UL -#define UL(level, message) log_##level(metaspace)(LOGFMT ": " message, LOGFMT_ARGS); -#define UL2(level, message, ...) log_##level(metaspace)(LOGFMT ": " message, LOGFMT_ARGS, __VA_ARGS__); +#define UL(level, message) log_##level(metaspace)(LOGFMT ": " message, LOGFMT_ARGS) +#define UL2(level, message, ...) log_##level(metaspace)(LOGFMT ": " message, LOGFMT_ARGS, __VA_ARGS__) #else #define UL(level, ...) #define UL2(level, ...)