From 7d2ef9d984f96cd260dc233c4acf58669615227f Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 21 Jan 2022 23:18:37 +0000 Subject: [PATCH 001/400] 8279179: Update nroff pages in JDK 18 before RC Reviewed-by: iris, mchung --- src/java.base/share/man/java.1 | 9 +++++++++ src/java.base/share/man/keytool.1 | 12 +++++++++++- src/jdk.jartool/share/man/jarsigner.1 | 15 ++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/man/java.1 b/src/java.base/share/man/java.1 index 3e17a506fa9..246d0080577 100644 --- a/src/java.base/share/man/java.1 +++ b/src/java.base/share/man/java.1 @@ -512,6 +512,15 @@ of the release. .RS .RE .TP +.B \f[CB]\-\-finalization=\f[R]\f[I]value\f[R] +Controls whether the JVM performs finalization of objects. +Valid values are "enabled" and "disabled". +Finalization is enabled by default, so the value "enabled" does nothing. +The value "disabled" disables finalization, so that no finalizers are +invoked. +.RS +.RE +.TP .B \f[CB]\-\-module\-path\f[R] \f[I]modulepath\f[R]... or \f[CB]\-p\f[R] \f[I]modulepath\f[R] A semicolon (\f[CB];\f[R]) separated list of directories in which each directory is a directory of modules. diff --git a/src/java.base/share/man/keytool.1 b/src/java.base/share/man/keytool.1 index 8250cf555b9..5b70729917c 100644 --- a/src/java.base/share/man/keytool.1 +++ b/src/java.base/share/man/keytool.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 1998, 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 @@ -70,6 +70,8 @@ keystore \f[CB]\-storepasswd\f[R]: Changes the store password of a keystore .IP \[bu] 2 \f[CB]\-showinfo\f[R]: Displays security\-related information +.IP \[bu] 2 +\f[CB]\-version\f[R]: Prints the program version .PP See \f[B]Commands and Options\f[R] for a description of these commands with their options. @@ -219,6 +221,10 @@ they perform. \f[B]Commands for Displaying Security\-related Information\f[R]: .IP \[bu] 2 \f[CB]\-showinfo\f[R] +.PP +\f[B]Commands for Displaying Program Version\f[R]: +.IP \[bu] 2 +\f[CB]\-version\f[R] .SH COMMANDS FOR CREATING OR ADDING DATA TO THE KEYSTORE .TP .B \f[CB]\-gencert\f[R] @@ -1314,6 +1320,10 @@ information. The \f[CB]\-tls\f[R] option displays TLS configurations, such as the list of enabled protocols and cipher suites. .RE +.SH COMMANDS FOR DISPLAYING PROGRAM VERSION +.PP +You can use \f[CB]\-version\f[R] to print the program version of +\f[CB]keytool\f[R]. .SH COMMANDS FOR DISPLAYING HELP INFORMATION .PP You can use \f[CB]\-\-help\f[R] to display a list of \f[CB]keytool\f[R] diff --git a/src/jdk.jartool/share/man/jarsigner.1 b/src/jdk.jartool/share/man/jarsigner.1 index a29dc0e714e..290d8de5fcf 100644 --- a/src/jdk.jartool/share/man/jarsigner.1 +++ b/src/jdk.jartool/share/man/jarsigner.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 1998, 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 @@ -33,6 +33,8 @@ jarsigner \- sign and verify Java Archive (JAR) files .PP \f[CB]jarsigner\f[R] \f[CB]\-verify\f[R] [\f[I]options\f[R]] \f[I]jar\-file\f[R] [\f[I]alias\f[R] ...] +.PP +\f[CB]jarsigner\f[R] \f[CB]\-version\f[R] .TP .B \f[I]options\f[R] The command\-line options. @@ -69,6 +71,12 @@ The aliases are defined in the keystore specified by \f[CB]\-keystore\f[R] or the default keystore. .RS .RE +.TP +.B \f[CB]\-version\f[R] +The \f[CB]\-version\f[R] option prints the program version of +\f[CB]jarsigner\f[R]. +.RS +.RE .SH DESCRIPTION .PP The \f[CB]jarsigner\f[R] tool has two purposes: @@ -1079,6 +1087,11 @@ The property keys supported are "jarsigner.all" for all actions, name(s) cannot be set in this file. .RS .RE +.TP +.B \f[CB]\-version\f[R] +Prints the program version. +.RS +.RE .SH DEPRECATED OPTIONS .PP The following \f[CB]jarsigner\f[R] options are deprecated as of JDK 9 and -- GitLab From ead9feccae75ab0491ce86a707f5056d88ac899a Mon Sep 17 00:00:00 2001 From: Julia Boes Date: Mon, 24 Jan 2022 10:03:40 +0000 Subject: [PATCH 002/400] 8280441: Missing "classpath exception" in several files from jdk.httpserver Reviewed-by: alanb, dfuchs --- .../classes/com/sun/net/httpserver/SimpleFileServer.java | 6 ++++-- .../sun/net/httpserver/simpleserver/FileServerHandler.java | 6 ++++-- .../classes/sun/net/httpserver/simpleserver/JWebServer.java | 6 ++++-- .../share/classes/sun/net/httpserver/simpleserver/Main.java | 6 ++++-- .../sun/net/httpserver/simpleserver/OutputFilter.java | 6 ++++-- .../net/httpserver/simpleserver/ResourceBundleHelper.java | 6 ++++-- .../net/httpserver/simpleserver/SimpleFileServerImpl.java | 6 ++++-- 7 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/SimpleFileServer.java b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/SimpleFileServer.java index a08f48567c9..2952a40b142 100644 --- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/SimpleFileServer.java +++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/SimpleFileServer.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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. + * 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 diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/FileServerHandler.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/FileServerHandler.java index b1b28446b4d..e0e9736cad4 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/FileServerHandler.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/FileServerHandler.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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. + * 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 diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java index 59f77abbae8..015d1b95244 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/JWebServer.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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. + * 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 diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/Main.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/Main.java index 83441cdbc7f..30535c9296d 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/Main.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/Main.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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. + * 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 diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/OutputFilter.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/OutputFilter.java index bdbcf2361ee..0a4d901303e 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/OutputFilter.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/OutputFilter.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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. + * 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 diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/ResourceBundleHelper.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/ResourceBundleHelper.java index 99349fe3474..690722bddb9 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/ResourceBundleHelper.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/ResourceBundleHelper.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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. + * 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 diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/SimpleFileServerImpl.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/SimpleFileServerImpl.java index 852aae5a838..7e97d203b6c 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/SimpleFileServerImpl.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/SimpleFileServerImpl.java @@ -1,10 +1,12 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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. + * 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 -- GitLab From 2b13341500cb9474f5fd6375b97d102ffb635b13 Mon Sep 17 00:00:00 2001 From: Angelos Bimpoudis Date: Mon, 24 Jan 2022 15:09:17 +0000 Subject: [PATCH 003/400] 8036019: Insufficient alternatives listed in some errors produced by the parser Reviewed-by: vromero --- .../sun/tools/javac/parser/JavacParser.java | 6 +-- .../tools/javac/resources/compiler.properties | 3 ++ test/langtools/tools/javac/T8036019.java | 46 +++++++++++++++++++ test/langtools/tools/javac/T8036019.out | 10 ++++ .../typeAnnotations/6967002/T6967002.out | 2 +- .../AnnotationMissingElementValue.java | 28 +++++++++++ .../tools/javac/enum/EnumMembersOrder.out | 2 +- .../tools/javac/parser/7157165/T7157165.out | 2 +- .../parser/SingleCommaAnnotationValueFail.out | 2 +- 9 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 test/langtools/tools/javac/T8036019.java create mode 100644 test/langtools/tools/javac/T8036019.out create mode 100644 test/langtools/tools/javac/diags/examples/AnnotationMissingElementValue.java 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 4b508c4bdf0..b14673532bf 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 @@ -2035,7 +2035,7 @@ public class JavacParser implements Parser { args.append(parseExpression()); } } - accept(RPAREN); + accept(RPAREN, tk -> Errors.Expected2(RPAREN, COMMA)); } else { syntaxError(token.pos, Errors.Expected(LPAREN)); } @@ -2123,7 +2123,7 @@ public class JavacParser implements Parser { nextToken(); break; default: - args.append(syntaxError(token.pos, Errors.Expected(GT))); + args.append(syntaxError(token.pos, Errors.Expected2(GT, COMMA))); break; } return args.toList(); @@ -3379,7 +3379,7 @@ public class JavacParser implements Parser { buf.append(annotationValue()); } } - accept(RBRACE); + accept(RBRACE, tk -> Errors.AnnotationMissingElementValue); return toP(F.at(pos).NewArray(null, List.nil(), buf.toList())); default: selectExprMode(); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index ae2f1f8c6fc..fddd3e935e1 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -118,6 +118,9 @@ compiler.err.already.defined.static.single.import=\ compiler.err.already.defined.this.unit=\ {0} is already defined in this compilation unit +compiler.err.annotation.missing.element.value=\ + annotation is missing element value + # 0: type, 1: list of name compiler.err.annotation.missing.default.value=\ annotation @{0} is missing a default value for the element ''{1}'' diff --git a/test/langtools/tools/javac/T8036019.java b/test/langtools/tools/javac/T8036019.java new file mode 100644 index 00000000000..709b8abba46 --- /dev/null +++ b/test/langtools/tools/javac/T8036019.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8036019 + * @summary Insufficient alternatives listed in some errors produced by the parser + * @compile/fail/ref=T8036019.out -XDrawDiagnostics T8036019.java + */ + + +public class T8036019 { + enum E { + E(String value) { } + } + + interface A {} + interface B {} + public class Foo { + Foo foo1 = null; + } + + @SuppressWarnings({,0}) + public class AV { + } +} diff --git a/test/langtools/tools/javac/T8036019.out b/test/langtools/tools/javac/T8036019.out new file mode 100644 index 00000000000..2c874175793 --- /dev/null +++ b/test/langtools/tools/javac/T8036019.out @@ -0,0 +1,10 @@ +T8036019.java:34:17: compiler.err.expected2: ')', ',' +T8036019.java:34:23: compiler.err.expected3: ',', '}', ';' +T8036019.java:34:25: compiler.err.enum.constant.expected +T8036019.java:40:24: compiler.err.expected2: >, ',' +T8036019.java:40:26: compiler.err.expected: token.identifier +T8036019.java:40:32: compiler.err.expected: token.identifier +T8036019.java:43:25: compiler.err.annotation.missing.element.value +T8036019.java:43:27: compiler.err.expected4: class, interface, enum, record +T8036019.java:46:1: compiler.err.expected4: class, interface, enum, record +9 errors \ No newline at end of file diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/6967002/T6967002.out b/test/langtools/tools/javac/annotations/typeAnnotations/6967002/T6967002.out index 86480c2bfa8..d9a3545d31d 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/6967002/T6967002.out +++ b/test/langtools/tools/javac/annotations/typeAnnotations/6967002/T6967002.out @@ -1,2 +1,2 @@ -T6967002.java:10:22: compiler.err.expected: ')' +T6967002.java:10:22: compiler.err.expected2: ')', ',' 1 error diff --git a/test/langtools/tools/javac/diags/examples/AnnotationMissingElementValue.java b/test/langtools/tools/javac/diags/examples/AnnotationMissingElementValue.java new file mode 100644 index 00000000000..65f24aad316 --- /dev/null +++ b/test/langtools/tools/javac/diags/examples/AnnotationMissingElementValue.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * 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. + */ + +// key: compiler.err.annotation.missing.element.value + +@SuppressWarnings({,0}) +public class AV { +} diff --git a/test/langtools/tools/javac/enum/EnumMembersOrder.out b/test/langtools/tools/javac/enum/EnumMembersOrder.out index b1e01860f34..94aff47aca8 100644 --- a/test/langtools/tools/javac/enum/EnumMembersOrder.out +++ b/test/langtools/tools/javac/enum/EnumMembersOrder.out @@ -1,4 +1,4 @@ -EnumMembersOrder.java:11:16: compiler.err.expected: ')' +EnumMembersOrder.java:11:16: compiler.err.expected2: ')', ',' EnumMembersOrder.java:11:18: compiler.err.expected3: ',', '}', ';' EnumMembersOrder.java:11:20: compiler.err.enum.constant.expected 3 errors diff --git a/test/langtools/tools/javac/parser/7157165/T7157165.out b/test/langtools/tools/javac/parser/7157165/T7157165.out index deb580df96c..7552381ba15 100644 --- a/test/langtools/tools/javac/parser/7157165/T7157165.out +++ b/test/langtools/tools/javac/parser/7157165/T7157165.out @@ -1,4 +1,4 @@ -T7157165.java:11:20: compiler.err.expected: > +T7157165.java:11:20: compiler.err.expected2: >, ',' T7157165.java:11:22: compiler.err.expected: token.identifier T7157165.java:11:28: compiler.err.expected: token.identifier 3 errors diff --git a/test/langtools/tools/javac/parser/SingleCommaAnnotationValueFail.out b/test/langtools/tools/javac/parser/SingleCommaAnnotationValueFail.out index 23d1082361b..05d27bc67df 100644 --- a/test/langtools/tools/javac/parser/SingleCommaAnnotationValueFail.out +++ b/test/langtools/tools/javac/parser/SingleCommaAnnotationValueFail.out @@ -1,3 +1,3 @@ -SingleCommaAnnotationValueFail.java:11:12: compiler.err.expected: '}' +SingleCommaAnnotationValueFail.java:11:12: compiler.err.annotation.missing.element.value SingleCommaAnnotationValueFail.java:11:14: compiler.err.expected4: class, interface, enum, record 2 errors -- GitLab From 4b329addf1aca4b5f67057b5c6852d283d0c8f49 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Mon, 24 Jan 2022 17:08:50 +0000 Subject: [PATCH 004/400] 8280496: Remove unused G1PageBasedVirtualSpace::pretouch_internal Reviewed-by: tschatzl, sjohanss, mli --- src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp | 9 +-------- src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp | 5 +---- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp index 7a164e6461f..94f51c8fdd1 100644 --- a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp +++ b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -178,13 +178,6 @@ char* G1PageBasedVirtualSpace::bounded_end_addr(size_t end_page) const { return MIN2(_high_boundary, page_start(end_page)); } -void G1PageBasedVirtualSpace::pretouch_internal(size_t start_page, size_t end_page) { - guarantee(start_page < end_page, - "Given start page " SIZE_FORMAT " is larger or equal to end page " SIZE_FORMAT, start_page, end_page); - - os::pretouch_memory(page_start(start_page), bounded_end_addr(end_page), _page_size); -} - bool G1PageBasedVirtualSpace::commit(size_t start_page, size_t size_in_pages) { // We need to make sure to commit all pages covered by the given area. guarantee(is_area_uncommitted(start_page, size_in_pages), diff --git a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp index 8b68ad60e56..0b97656c883 100644 --- a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp +++ b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -87,9 +87,6 @@ class G1PageBasedVirtualSpace { // Uncommit the given memory range. void uncommit_internal(size_t start_page, size_t end_page); - // Pretouch the given memory range. - void pretouch_internal(size_t start_page, size_t end_page); - // Returns the index of the page which contains the given address. size_t addr_to_page_index(char* addr) const; -- GitLab From 1c7769d35b3a2aa4afe3125239dbfa1da5cfdeee Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Mon, 24 Jan 2022 17:23:14 +0000 Subject: [PATCH 005/400] 8280437: Move G1BufferNodeList to gc/shared Reviewed-by: sjohanss, iwalulya, mli --- src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp | 10 +++++----- src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp | 8 ++++---- src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp | 10 +++++----- src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp | 10 +++++----- src/hotspot/share/gc/g1/g1RemSet.cpp | 5 +++-- .../bufferNodeList.cpp} | 12 ++++++------ .../bufferNodeList.hpp} | 15 +++++++-------- 7 files changed, 35 insertions(+), 35 deletions(-) rename src/hotspot/share/gc/{g1/g1BufferNodeList.cpp => shared/bufferNodeList.cpp} (80%) rename src/hotspot/share/gc/{g1/g1BufferNodeList.hpp => shared/bufferNodeList.hpp} (79%) diff --git a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp index 8f704fce350..4ef40d29f16 100644 --- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp +++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp @@ -24,7 +24,6 @@ #include "precompiled.hpp" #include "gc/g1/g1BarrierSet.inline.hpp" -#include "gc/g1/g1BufferNodeList.hpp" #include "gc/g1/g1CardTableEntryClosure.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentRefineStats.hpp" @@ -35,6 +34,7 @@ #include "gc/g1/g1RemSet.hpp" #include "gc/g1/g1ThreadLocalData.hpp" #include "gc/g1/heapRegionRemSet.inline.hpp" +#include "gc/shared/bufferNodeList.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "memory/iterator.hpp" #include "runtime/atomic.hpp" @@ -313,7 +313,7 @@ void G1DirtyCardQueueSet::enqueue_all_paused_buffers() { } void G1DirtyCardQueueSet::abandon_completed_buffers() { - G1BufferNodeList list = take_all_completed_buffers(); + BufferNodeList list = take_all_completed_buffers(); BufferNode* buffers_to_delete = list._head; while (buffers_to_delete != NULL) { BufferNode* bn = buffers_to_delete; @@ -334,20 +334,20 @@ void G1DirtyCardQueueSet::notify_if_necessary() { // result. The queue sets must share the same allocator. void G1DirtyCardQueueSet::merge_bufferlists(G1RedirtyCardsQueueSet* src) { assert(allocator() == src->allocator(), "precondition"); - const G1BufferNodeList from = src->take_all_completed_buffers(); + const BufferNodeList from = src->take_all_completed_buffers(); if (from._head != NULL) { Atomic::add(&_num_cards, from._entry_count); _completed.append(*from._head, *from._tail); } } -G1BufferNodeList G1DirtyCardQueueSet::take_all_completed_buffers() { +BufferNodeList G1DirtyCardQueueSet::take_all_completed_buffers() { enqueue_all_paused_buffers(); verify_num_cards(); Pair pair = _completed.take_all(); size_t num_cards = Atomic::load(&_num_cards); Atomic::store(&_num_cards, size_t(0)); - return G1BufferNodeList(pair.first, pair.second, num_cards); + return BufferNodeList(pair.first, pair.second, num_cards); } class G1RefineBufferedCards : public StackObj { diff --git a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp index 9e9ad0ee80c..051e29058eb 100644 --- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp +++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -25,10 +25,10 @@ #ifndef SHARE_GC_G1_G1DIRTYCARDQUEUE_HPP #define SHARE_GC_G1_G1DIRTYCARDQUEUE_HPP -#include "gc/g1/g1BufferNodeList.hpp" #include "gc/g1/g1FreeIdSet.hpp" #include "gc/g1/g1CardTable.hpp" #include "gc/g1/g1ConcurrentRefineStats.hpp" +#include "gc/shared/bufferNodeList.hpp" #include "gc/shared/ptrQueue.hpp" #include "memory/allocation.hpp" #include "memory/padded.hpp" @@ -69,7 +69,7 @@ public: class G1DirtyCardQueueSet: public PtrQueueSet { // Head and tail of a list of BufferNodes, linked through their next() - // fields. Similar to G1BufferNodeList, but without the _entry_count. + // fields. Similar to BufferNodeList, but without the _entry_count. struct HeadTail { BufferNode* _head; BufferNode* _tail; @@ -275,7 +275,7 @@ public: void merge_bufferlists(G1RedirtyCardsQueueSet* src); - G1BufferNodeList take_all_completed_buffers(); + BufferNodeList take_all_completed_buffers(); void flush_queue(G1DirtyCardQueue& queue); diff --git a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp index a1802e01821..d6c2ae148be 100644 --- a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp +++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -67,7 +67,7 @@ void G1RedirtyCardsLocalQueueSet::enqueue(void* value) { void G1RedirtyCardsLocalQueueSet::flush() { flush_queue(_queue); _shared_qset->add_bufferlist(_buffers); - _buffers = G1BufferNodeList(); + _buffers = BufferNodeList(); } // G1RedirtyCardsLocalQueueSet::Queue @@ -109,9 +109,9 @@ BufferNode* G1RedirtyCardsQueueSet::all_completed_buffers() const { return _list.top(); } -G1BufferNodeList G1RedirtyCardsQueueSet::take_all_completed_buffers() { +BufferNodeList G1RedirtyCardsQueueSet::take_all_completed_buffers() { DEBUG_ONLY(_collecting = false;) - G1BufferNodeList result(_list.pop_all(), _tail, _entry_count); + BufferNodeList result(_list.pop_all(), _tail, _entry_count); _tail = NULL; _entry_count = 0; DEBUG_ONLY(_collecting = true;) @@ -135,7 +135,7 @@ void G1RedirtyCardsQueueSet::enqueue_completed_buffer(BufferNode* node) { update_tail(node); } -void G1RedirtyCardsQueueSet::add_bufferlist(const G1BufferNodeList& buffers) { +void G1RedirtyCardsQueueSet::add_bufferlist(const BufferNodeList& buffers) { assert(_collecting, "precondition"); if (buffers._head != NULL) { assert(buffers._tail != NULL, "invariant"); diff --git a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp index 26bb78c4096..b464d377298 100644 --- a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp +++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP #define SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP -#include "gc/g1/g1BufferNodeList.hpp" +#include "gc/shared/bufferNodeList.hpp" #include "gc/shared/ptrQueue.hpp" #include "memory/padded.hpp" #include "utilities/macros.hpp" @@ -42,7 +42,7 @@ class G1RedirtyCardsLocalQueueSet : private PtrQueueSet { }; G1RedirtyCardsQueueSet* _shared_qset; - G1BufferNodeList _buffers; + BufferNodeList _buffers; Queue _queue; // Add the buffer to the local list. @@ -84,12 +84,12 @@ public: // Collect buffers. These functions are thread-safe. // precondition: Must not be concurrent with buffer processing. virtual void enqueue_completed_buffer(BufferNode* node); - void add_bufferlist(const G1BufferNodeList& buffers); + void add_bufferlist(const BufferNodeList& buffers); // Processing phase operations. // precondition: Must not be concurrent with buffer collection. BufferNode* all_completed_buffers() const; - G1BufferNodeList take_all_completed_buffers(); + BufferNodeList take_all_completed_buffers(); }; #endif // SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index c8f3b0d49b2..603ddbc1e26 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -45,6 +45,7 @@ #include "gc/g1/heapRegion.inline.hpp" #include "gc/g1/heapRegionManager.inline.hpp" #include "gc/g1/heapRegionRemSet.inline.hpp" +#include "gc/shared/bufferNodeList.hpp" #include "gc/shared/gcTraceTime.inline.hpp" #include "gc/shared/ptrQueue.hpp" #include "gc/shared/suspendibleThreadSet.hpp" @@ -1429,7 +1430,7 @@ public: { if (initial_evacuation) { G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); - G1BufferNodeList buffers = dcqs.take_all_completed_buffers(); + BufferNodeList buffers = dcqs.take_all_completed_buffers(); if (buffers._entry_count != 0) { _dirty_card_buffers.prepend(*buffers._head, *buffers._tail); } diff --git a/src/hotspot/share/gc/g1/g1BufferNodeList.cpp b/src/hotspot/share/gc/shared/bufferNodeList.cpp similarity index 80% rename from src/hotspot/share/gc/g1/g1BufferNodeList.cpp rename to src/hotspot/share/gc/shared/bufferNodeList.cpp index 3b89b0c7cd7..bcf4b42ec96 100644 --- a/src/hotspot/share/gc/g1/g1BufferNodeList.cpp +++ b/src/hotspot/share/gc/shared/bufferNodeList.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -23,15 +23,15 @@ */ #include "precompiled.hpp" -#include "gc/g1/g1BufferNodeList.hpp" +#include "gc/shared/bufferNodeList.hpp" #include "utilities/debug.hpp" -G1BufferNodeList::G1BufferNodeList() : +BufferNodeList::BufferNodeList() : _head(NULL), _tail(NULL), _entry_count(0) {} -G1BufferNodeList::G1BufferNodeList(BufferNode* head, - BufferNode* tail, - size_t entry_count) : +BufferNodeList::BufferNodeList(BufferNode* head, + BufferNode* tail, + size_t entry_count) : _head(head), _tail(tail), _entry_count(entry_count) { assert((_head == NULL) == (_tail == NULL), "invariant"); diff --git a/src/hotspot/share/gc/g1/g1BufferNodeList.hpp b/src/hotspot/share/gc/shared/bufferNodeList.hpp similarity index 79% rename from src/hotspot/share/gc/g1/g1BufferNodeList.hpp rename to src/hotspot/share/gc/shared/bufferNodeList.hpp index 785c3118f9b..ae66a1fcc71 100644 --- a/src/hotspot/share/gc/g1/g1BufferNodeList.hpp +++ b/src/hotspot/share/gc/shared/bufferNodeList.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -22,21 +22,20 @@ * */ -#ifndef SHARE_GC_G1_G1BUFFERNODELIST_HPP -#define SHARE_GC_G1_G1BUFFERNODELIST_HPP +#ifndef SHARE_GC_SHARED_BUFFERNODELIST_HPP +#define SHARE_GC_SHARED_BUFFERNODELIST_HPP #include "utilities/globalDefinitions.hpp" class BufferNode; -struct G1BufferNodeList { +struct BufferNodeList { BufferNode* _head; // First node in list or NULL if empty. BufferNode* _tail; // Last node in list or NULL if empty. size_t _entry_count; // Sum of entries in nodes in list. - G1BufferNodeList(); - G1BufferNodeList(BufferNode* head, BufferNode* tail, size_t entry_count); + BufferNodeList(); + BufferNodeList(BufferNode* head, BufferNode* tail, size_t entry_count); }; -#endif // SHARE_GC_G1_G1BUFFERNODELIST_HPP - +#endif // SHARE_GC_SHARED_BUFFERNODELIST_HPP -- GitLab From dae2226a538f7156056d1f101fb5b4d1c6f72520 Mon Sep 17 00:00:00 2001 From: Alexey Ivanov Date: Mon, 24 Jan 2022 18:30:31 +0000 Subject: [PATCH 006/400] 8279795: Fix typo in BasicFileChooserUI: Constucts -> Constructs Reviewed-by: prr, serb --- .../swing/plaf/basic/BasicFileChooserUI.java | 72 ++++++++++++++----- 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java index 33f42da00f8..439101c0ef2 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -25,21 +25,58 @@ package javax.swing.plaf.basic; -import javax.swing.*; -import javax.swing.filechooser.*; -import javax.swing.filechooser.FileFilter; -import javax.swing.event.*; -import javax.swing.plaf.*; -import java.awt.*; -import java.awt.event.*; -import java.awt.datatransfer.*; -import java.beans.*; -import java.io.*; -import java.util.*; +import java.awt.BorderLayout; +import java.awt.Toolkit; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.beans.PropertyChangeListener; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Hashtable; import java.util.List; -import java.util.regex.*; +import java.util.Locale; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ActionMap; +import javax.swing.Icon; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JFileChooser; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.LookAndFeel; +import javax.swing.SwingUtilities; +import javax.swing.TransferHandler; +import javax.swing.UIDefaults; +import javax.swing.UIManager; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.filechooser.FileFilter; +import javax.swing.filechooser.FileSystemView; +import javax.swing.filechooser.FileView; +import javax.swing.plaf.ActionMapUIResource; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.FileChooserUI; +import javax.swing.plaf.UIResource; + import sun.awt.shell.ShellFolder; -import sun.swing.*; +import sun.swing.DefaultLookup; +import sun.swing.FilePane; +import sun.swing.SwingUtilities2; +import sun.swing.UIAction; /** * Basic L&F implementation of a FileChooser. @@ -723,11 +760,12 @@ public class BasicFileChooserUI extends FileChooserUI { // new functionality add it to the Handler, but make sure this // class calls into the Handler. Handler handler; + /** - * Constucts a {@code DoubleClickListener}. - * @param list the lsit + * Constructs a {@code DoubleClickListener}. + * @param list the list */ - public DoubleClickListener(JList list) { + public DoubleClickListener(JList list) { handler = new Handler(list); } -- GitLab From acd98294c628e8e03a036a8e3e08d775147b2fda Mon Sep 17 00:00:00 2001 From: Alexey Ivanov Date: Mon, 24 Jan 2022 18:31:43 +0000 Subject: [PATCH 007/400] 8279794: Fix typos in BasicScrollBarUI: Laysouts a vertical scroll bar Reviewed-by: prr, psadhukhan --- .../swing/plaf/basic/BasicScrollBarUI.java | 53 ++++++++++++++----- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java index afb2d58b885..8c7f348097e 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,18 +25,47 @@ package javax.swing.plaf.basic; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import javax.swing.BoundedRangeModel; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JScrollBar; +import javax.swing.JScrollPane; +import javax.swing.JViewport; +import javax.swing.LookAndFeel; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.Timer; +import javax.swing.UIManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.ScrollBarUI; +import javax.swing.plaf.UIResource; + import sun.swing.DefaultLookup; import sun.swing.UIAction; -import java.awt.*; -import java.awt.event.*; - -import java.beans.*; - -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.plaf.*; - import static sun.swing.SwingUtilities2.drawHLine; import static sun.swing.SwingUtilities2.drawRect; import static sun.swing.SwingUtilities2.drawVLine; @@ -754,7 +783,7 @@ public class BasicScrollBarUI } /** - * Laysouts a vertical scroll bar. + * Lays out a vertical scroll bar. * @param sb the scroll bar */ protected void layoutVScrollbar(JScrollBar sb) @@ -856,7 +885,7 @@ public class BasicScrollBarUI } /** - * Laysouts a vertical scroll bar. + * Lays out a horizontal scroll bar. * @param sb the scroll bar */ protected void layoutHScrollbar(JScrollBar sb) -- GitLab From 0b5c54be675c63ecac17cd37f6d388fd42f09aa8 Mon Sep 17 00:00:00 2001 From: Alexey Ivanov Date: Mon, 24 Jan 2022 18:32:35 +0000 Subject: [PATCH 008/400] 8279798: Javadoc for BasicTabbedPaneUI is inconsistent Reviewed-by: prr, psadhukhan --- .../swing/plaf/basic/BasicTabbedPaneUI.java | 89 +++++++++++++------ 1 file changed, 64 insertions(+), 25 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java index c9e5fd51f7f..3fc99dd2bc7 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,21 +25,60 @@ package javax.swing.plaf.basic; -import sun.swing.SwingUtilities2; - -import javax.swing.*; -import javax.swing.event.*; -import javax.swing.plaf.*; -import javax.swing.text.View; - -import java.awt.*; -import java.awt.event.*; -import java.beans.PropertyChangeListener; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Point; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ContainerEvent; +import java.awt.event.ContainerListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; import java.beans.PropertyChangeEvent; -import java.util.Vector; +import java.beans.PropertyChangeListener; import java.util.Hashtable; +import java.util.Vector; + +import javax.swing.Action; +import javax.swing.ActionMap; +import javax.swing.Icon; +import javax.swing.InputMap; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.JViewport; +import javax.swing.KeyStroke; +import javax.swing.LookAndFeel; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.ComponentInputMapUIResource; +import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.TabbedPaneUI; +import javax.swing.plaf.UIResource; +import javax.swing.text.View; import sun.swing.DefaultLookup; +import sun.swing.SwingUtilities2; import sun.swing.UIAction; /** @@ -216,7 +255,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { public BasicTabbedPaneUI() {} /** - * Create a UI. + * Creates a UI. * @param c a component * @return a UI */ @@ -386,7 +425,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Install the defaults. + * Installs the defaults. */ protected void installDefaults() { LookAndFeel.installColorsAndFont(tabPane, "TabbedPane.background", @@ -423,7 +462,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Uninstall the defaults. + * Uninstalls the defaults. */ protected void uninstallDefaults() { highlight = null; @@ -438,7 +477,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Install the listeners. + * Installs the listeners. */ protected void installListeners() { if ((propertyChangeListener = createPropertyChangeListener()) != null) { @@ -461,7 +500,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Uninstall the listeners. + * Uninstalls the listeners. */ protected void uninstallListeners() { if (mouseListener != null) { @@ -1090,9 +1129,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Laysout a label. + * Lays out a label. * @param tabPlacement the tab placement - * @param metrics the font metric + * @param metrics the font metrics * @param tabIndex the tab index * @param title the title * @param icon the icon @@ -2144,7 +2183,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { // Tab Navigation methods /** - * Navigate the selected tab. + * Navigates the selected tab. * @param direction the direction */ protected void navigateSelectedTab(int direction) { @@ -2226,7 +2265,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Select the next tab in the run. + * Selects the next tab in the run. * @param current the current tab */ protected void selectNextTabInRun(int current) { @@ -2240,7 +2279,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Select the previous tab in the run. + * Selects the previous tab in the run. * @param current the current tab */ protected void selectPreviousTabInRun(int current) { @@ -2254,7 +2293,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Select the next tab. + * Selects the next tab. * @param current the current tab */ protected void selectNextTab(int current) { @@ -2267,7 +2306,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Select the previous tab. + * Selects the previous tab. * @param current the current tab */ protected void selectPreviousTab(int current) { @@ -2772,7 +2811,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { * Returns the preferred tab area width. * @param tabPlacement the tab placement * @param height the height - * @return the preferred tab area widty + * @return the preferred tab area width */ protected int preferredTabAreaWidth(int tabPlacement, int height) { FontMetrics metrics = getFontMetrics(); -- GitLab From a825a4a1dba14317547b57bc0188b1e912baa251 Mon Sep 17 00:00:00 2001 From: Alexey Ivanov Date: Mon, 24 Jan 2022 18:35:53 +0000 Subject: [PATCH 009/400] 8279861: Clarify 'rect' parameters and description of paintTabBorder method in BasicTabbedPaneUI Reviewed-by: prr, psadhukhan --- .../javax/swing/plaf/basic/BasicTabbedPaneUI.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java index 3fc99dd2bc7..360e98eee7a 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java @@ -955,7 +955,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { * Paints a tab. * @param g the graphics * @param tabPlacement the tab placement - * @param rects rectangles + * @param rects the tab rectangles * @param tabIndex the tab index * @param iconRect the icon rectangle * @param textRect the text rectangle @@ -1301,7 +1301,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { * Paints the focus indicator. * @param g the graphics * @param tabPlacement the tab placement - * @param rects rectangles + * @param rects the tab rectangles * @param tabIndex the tab index * @param iconRect the icon rectangle * @param textRect the text rectangle @@ -1346,9 +1346,9 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * this function draws the border around each tab - * note that this function does now draw the background of the tab. - * that is done elsewhere + * Paints the border around a tab. + * Note that this function does not paint the background of the tab, + * that is done elsewhere. * * @param g the graphics context in which to paint * @param tabPlacement the placement (left, right, bottom, top) of the tab @@ -1878,7 +1878,7 @@ public class BasicTabbedPaneUI extends TabbedPaneUI implements SwingConstants { } /** - * Assure the rectangles are created. + * Assures the tab rectangles are created. * @param tabCount the tab count */ protected void assureRectsCreated(int tabCount) { -- GitLab From a5416669a57a7739af13efc32ec084560527862b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jeli=C5=84ski?= Date: Mon, 24 Jan 2022 19:31:11 +0000 Subject: [PATCH 010/400] 8280474: Garbage value passed to getLocaleInfoWrapper in HostLocaleProviderAdapter_md Reviewed-by: naoto, alanb --- .../windows/native/libjava/HostLocaleProviderAdapter_md.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/windows/native/libjava/HostLocaleProviderAdapter_md.c b/src/java.base/windows/native/libjava/HostLocaleProviderAdapter_md.c index 879422f096f..b7c2bcc28db 100644 --- a/src/java.base/windows/native/libjava/HostLocaleProviderAdapter_md.c +++ b/src/java.base/windows/native/libjava/HostLocaleProviderAdapter_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -835,7 +835,7 @@ void replaceCalendarArrayElems(JNIEnv *env, jstring jlangtag, jint calid, jobjec WCHAR name[BUFLEN]; const jchar *langtag = (*env)->GetStringChars(env, jlangtag, JNI_FALSE); jstring tmp_string; - CALTYPE isGenitive; + CALTYPE isGenitive = 0; CHECK_NULL(langtag); -- GitLab From 8e82d0021c119b7793870811fad37d7659c1174d Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Mon, 24 Jan 2022 20:16:38 +0000 Subject: [PATCH 011/400] 8280492: Use cross-module syntax for cross-module links Reviewed-by: iris, serb, lancea, dfuchs, aivanov --- .../share/classes/java/io/FilenameFilter.java | 4 +-- .../share/classes/java/lang/Character.java | 8 +++--- .../share/classes/java/lang/System.java | 24 ++++++++--------- .../java/lang/invoke/MethodHandleProxies.java | 4 +-- .../java/lang/invoke/MethodHandles.java | 4 +-- .../share/classes/java/net/package-info.java | 4 +-- .../text/AttributedCharacterIterator.java | 6 ++--- .../share/classes/java/text/Bidi.java | 8 +++--- .../share/classes/java/util/Observable.java | 4 +-- .../classes/java/util/ServiceLoader.java | 4 +-- .../java/awt/datatransfer/Clipboard.java | 14 +++++----- .../classes/java/util/logging/LogManager.java | 8 +++--- .../java/util/logging/LoggingMXBean.java | 14 +++++----- .../lang/management/ManagementFactory.java | 4 +-- .../management/PlatformLoggingMXBean.java | 26 +++++++++---------- .../management/remote/JMXAddressable.java | 4 +-- .../remote/JMXServerErrorException.java | 4 +-- 17 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/java.base/share/classes/java/io/FilenameFilter.java b/src/java.base/share/classes/java/io/FilenameFilter.java index fcd81479ee1..019ffb11771 100644 --- a/src/java.base/share/classes/java/io/FilenameFilter.java +++ b/src/java.base/share/classes/java/io/FilenameFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -34,7 +34,7 @@ package java.io; * * @author Arthur van Hoff * @author Jonathan Payne - * @see java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter) + * @see java.desktop/java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter) * @see java.io.File * @see java.io.File#list(java.io.FilenameFilter) * @since 1.0 diff --git a/src/java.base/share/classes/java/lang/Character.java b/src/java.base/share/classes/java/lang/Character.java index 1cc12940ef1..0fdd23997cc 100644 --- a/src/java.base/share/classes/java/lang/Character.java +++ b/src/java.base/share/classes/java/lang/Character.java @@ -10302,7 +10302,7 @@ class Character implements java.io.Serializable, Comparable, Constabl * @see Character#isJavaIdentifierPart(char) * @see Character#isLetter(char) * @see Character#isUnicodeIdentifierStart(char) - * @see javax.lang.model.SourceVersion#isIdentifier(CharSequence) + * @see java.compiler/javax.lang.model.SourceVersion#isIdentifier(CharSequence) * @since 1.1 */ public static boolean isJavaIdentifierStart(char ch) { @@ -10331,7 +10331,7 @@ class Character implements java.io.Serializable, Comparable, Constabl * @see Character#isJavaIdentifierPart(int) * @see Character#isLetter(int) * @see Character#isUnicodeIdentifierStart(int) - * @see javax.lang.model.SourceVersion#isIdentifier(CharSequence) + * @see java.compiler/javax.lang.model.SourceVersion#isIdentifier(CharSequence) * @since 1.5 */ public static boolean isJavaIdentifierStart(int codePoint) { @@ -10368,7 +10368,7 @@ class Character implements java.io.Serializable, Comparable, Constabl * @see Character#isJavaIdentifierStart(char) * @see Character#isLetterOrDigit(char) * @see Character#isUnicodeIdentifierPart(char) - * @see javax.lang.model.SourceVersion#isIdentifier(CharSequence) + * @see java.compiler/javax.lang.model.SourceVersion#isIdentifier(CharSequence) * @since 1.1 */ public static boolean isJavaIdentifierPart(char ch) { @@ -10401,7 +10401,7 @@ class Character implements java.io.Serializable, Comparable, Constabl * @see Character#isJavaIdentifierStart(int) * @see Character#isLetterOrDigit(int) * @see Character#isUnicodeIdentifierPart(int) - * @see javax.lang.model.SourceVersion#isIdentifier(CharSequence) + * @see java.compiler/javax.lang.model.SourceVersion#isIdentifier(CharSequence) * @since 1.5 */ public static boolean isJavaIdentifierPart(int codePoint) { diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 47b436847cb..2f9c205a327 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -1207,7 +1207,7 @@ public final class System { * Severity values and Mapping to {@code java.util.logging.Level}. *

* {@linkplain System.Logger.Level System logger levels} are mapped to - * {@linkplain java.util.logging.Level java.util.logging levels} + * {@linkplain java.logging/java.util.logging.Level java.util.logging levels} * of corresponding severity. *
The mapping is as follows: *

@@ -1219,19 +1219,19 @@ public final class System { * * * {@link Logger.Level#ALL ALL} - * {@link java.util.logging.Level#ALL ALL} + * {@link java.logging/java.util.logging.Level#ALL ALL} * {@link Logger.Level#TRACE TRACE} - * {@link java.util.logging.Level#FINER FINER} + * {@link java.logging/java.util.logging.Level#FINER FINER} * {@link Logger.Level#DEBUG DEBUG} - * {@link java.util.logging.Level#FINE FINE} + * {@link java.logging/java.util.logging.Level#FINE FINE} * {@link Logger.Level#INFO INFO} - * {@link java.util.logging.Level#INFO INFO} + * {@link java.logging/java.util.logging.Level#INFO INFO} * {@link Logger.Level#WARNING WARNING} - * {@link java.util.logging.Level#WARNING WARNING} + * {@link java.logging/java.util.logging.Level#WARNING WARNING} * {@link Logger.Level#ERROR ERROR} - * {@link java.util.logging.Level#SEVERE SEVERE} + * {@link java.logging/java.util.logging.Level#SEVERE SEVERE} * {@link Logger.Level#OFF OFF} - * {@link java.util.logging.Level#OFF OFF} + * {@link java.logging/java.util.logging.Level#OFF OFF} * * * @@ -1542,7 +1542,7 @@ public final class System { * {@code java.util.logging} as the backend framework when the * {@code java.logging} module is present. * It returns a {@linkplain System.Logger logger} instance - * that will route log messages to a {@link java.util.logging.Logger + * that will route log messages to a {@link java.logging/java.util.logging.Logger * java.util.logging.Logger}. Otherwise, if {@code java.logging} is not * present, the default implementation will return a simple logger * instance that will route log messages of {@code INFO} level and above to @@ -1556,7 +1556,7 @@ public final class System { * logging backend, and usually requires using APIs specific to that backend. *

For the default {@code LoggerFinder} implementation * using {@code java.util.logging} as its backend, refer to - * {@link java.util.logging java.util.logging} for logging configuration. + * {@link java.logging/java.util.logging java.util.logging} for logging configuration. * For the default {@code LoggerFinder} implementation returning simple loggers * when the {@code java.logging} module is absent, the configuration * is implementation dependent. @@ -1591,7 +1591,7 @@ public final class System { * System.Logger.Level} to a level supported by the logging backend it uses. *
The default LoggerFinder using {@code java.util.logging} as the backend * maps {@code System.Logger} levels to - * {@linkplain java.util.logging.Level java.util.logging} levels + * {@linkplain java.logging/java.util.logging.Level java.util.logging} levels * of corresponding severity - as described in {@link Logger.Level * Logger.Level}. * diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java index 4dd2b1fce7e..784d672ff8f 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -88,7 +88,7 @@ public class MethodHandleProxies { * Therefore, each instance must implement a unique single-method interface. * Implementations may not bundle together * multiple single-method interfaces onto single implementation classes - * in the style of {@link java.awt.AWTEventMulticaster}. + * in the style of {@link java.desktop/java.awt.AWTEventMulticaster}. *

* The method handle may throw an undeclared exception, * which means any checked exception (or other checked throwable) diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index 743ebb66759..908c277fa86 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -2002,7 +2002,7 @@ public class MethodHandles { * there is no internal form available to record in any class's constant pool. * A hidden class or interface is not discoverable by {@link Class#forName(String, boolean, ClassLoader)}, * {@link ClassLoader#loadClass(String, boolean)}, or {@link #findClass(String)}, and - * is not {@linkplain java.lang.instrument.Instrumentation#isModifiableClass(Class) + * is not {@linkplain java.instrument/java.lang.instrument.Instrumentation#isModifiableClass(Class) * modifiable} by Java agents or tool agents using the * JVM Tool Interface. * diff --git a/src/java.base/share/classes/java/net/package-info.java b/src/java.base/share/classes/java/net/package-info.java index b221c6bf2f7..e0325f6a0f1 100644 --- a/src/java.base/share/classes/java/net/package-info.java +++ b/src/java.base/share/classes/java/net/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -122,7 +122,7 @@ *

  • {@link java.net.HttpURLConnection} is a subclass of URLConnection * and provides some additional functionalities specific to the * HTTP protocol. This API has been superseded by the newer - * {@linkplain java.net.http HTTP Client API}.
  • + * {@linkplain java.net.http/java.net.http HTTP Client API}. * *

    The recommended usage is to use {@link java.net.URI} to identify * resources, then convert it into a {@link java.net.URL} when it is time to diff --git a/src/java.base/share/classes/java/text/AttributedCharacterIterator.java b/src/java.base/share/classes/java/text/AttributedCharacterIterator.java index 31b5b7d8d3c..a77417462a7 100644 --- a/src/java.base/share/classes/java/text/AttributedCharacterIterator.java +++ b/src/java.base/share/classes/java/text/AttributedCharacterIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -67,10 +67,10 @@ import java.util.Set; * *

    * Attribute keys are instances of {@link AttributedCharacterIterator.Attribute} and its - * subclasses, such as {@link java.awt.font.TextAttribute}. + * subclasses, such as {@link java.desktop/java.awt.font.TextAttribute}. * * @see AttributedCharacterIterator.Attribute - * @see java.awt.font.TextAttribute + * @see java.desktop/java.awt.font.TextAttribute * @see AttributedString * @see Annotation * @since 1.2 diff --git a/src/java.base/share/classes/java/text/Bidi.java b/src/java.base/share/classes/java/text/Bidi.java index 00a878e1c64..41269afac9b 100644 --- a/src/java.base/share/classes/java/text/Bidi.java +++ b/src/java.base/share/classes/java/text/Bidi.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -121,9 +121,9 @@ public final class Bidi { * * @param paragraph a paragraph of text with optional character and paragraph attribute information * - * @see java.awt.font.TextAttribute#BIDI_EMBEDDING - * @see java.awt.font.TextAttribute#NUMERIC_SHAPING - * @see java.awt.font.TextAttribute#RUN_DIRECTION + * @see java.desktop/java.awt.font.TextAttribute#BIDI_EMBEDDING + * @see java.desktop/java.awt.font.TextAttribute#NUMERIC_SHAPING + * @see java.desktop/java.awt.font.TextAttribute#RUN_DIRECTION */ public Bidi(AttributedCharacterIterator paragraph) { if (paragraph == null) { diff --git a/src/java.base/share/classes/java/util/Observable.java b/src/java.base/share/classes/java/util/Observable.java index d71bf5d5d4c..37a90f631ad 100644 --- a/src/java.base/share/classes/java/util/Observable.java +++ b/src/java.base/share/classes/java/util/Observable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -66,7 +66,7 @@ package java.util; * {@code Observable} is unspecified, and state changes are not in * one-for-one correspondence with notifications. * For a richer event model, consider using the - * {@link java.beans} package. For reliable and ordered + * {@link java.desktop/java.beans} package. For reliable and ordered * messaging among threads, consider using one of the concurrent data * structures in the {@link java.util.concurrent} package. * For reactive streams style programming, see the diff --git a/src/java.base/share/classes/java/util/ServiceLoader.java b/src/java.base/share/classes/java/util/ServiceLoader.java index 64b01c3157e..c5d921896a0 100644 --- a/src/java.base/share/classes/java/util/ServiceLoader.java +++ b/src/java.base/share/classes/java/util/ServiceLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -1585,7 +1585,7 @@ public final class ServiceLoader * are located in the order that its module descriptor {@linkplain * java.lang.module.ModuleDescriptor.Provides#providers() lists the * providers}. Providers added dynamically by instrumentation agents (see - * {@link java.lang.instrument.Instrumentation#redefineModule redefineModule}) + * {@link java.instrument/java.lang.instrument.Instrumentation#redefineModule redefineModule}) * are always located after providers declared by the module.

    * *
  • Step 2: Locate providers in unnamed modules.

    diff --git a/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java b/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java index ad3a56a701f..8aac4495547 100644 --- a/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java +++ b/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -43,8 +43,8 @@ import sun.datatransfer.DataFlavorUtil; * * @author Amy Fowler * @author Alexander Gerasimov - * @see java.awt.Toolkit#getSystemClipboard - * @see java.awt.Toolkit#getSystemSelection + * @see java.desktop/java.awt.Toolkit#getSystemClipboard + * @see java.desktop/java.awt.Toolkit#getSystemSelection * @since 1.1 */ public class Clipboard { @@ -81,7 +81,7 @@ public class Clipboard { * Creates a clipboard object. * * @param name for the clipboard - * @see java.awt.Toolkit#getSystemClipboard + * @see java.desktop/java.awt.Toolkit#getSystemClipboard */ public Clipboard(String name) { this.name = name; @@ -91,7 +91,7 @@ public class Clipboard { * Returns the name of this clipboard object. * * @return the name of this clipboard object - * @see java.awt.Toolkit#getSystemClipboard + * @see java.desktop/java.awt.Toolkit#getSystemClipboard */ public String getName() { return name; @@ -118,7 +118,7 @@ public class Clipboard { * content * @param owner the object which owns the clipboard content * @throws IllegalStateException if the clipboard is currently unavailable - * @see java.awt.Toolkit#getSystemClipboard + * @see java.desktop/java.awt.Toolkit#getSystemClipboard */ public synchronized void setContents(Transferable contents, ClipboardOwner owner) { final ClipboardOwner oldOwner = this.owner; @@ -145,7 +145,7 @@ public class Clipboard { * @param requestor the object requesting the clip data (not used) * @return the current transferable object on the clipboard * @throws IllegalStateException if the clipboard is currently unavailable - * @see java.awt.Toolkit#getSystemClipboard + * @see java.desktop/java.awt.Toolkit#getSystemClipboard */ public synchronized Transferable getContents(Object requestor) { return contents; diff --git a/src/java.logging/share/classes/java/util/logging/LogManager.java b/src/java.logging/share/classes/java/util/logging/LogManager.java index 59950865283..38e9ebafeb6 100644 --- a/src/java.logging/share/classes/java/util/logging/LogManager.java +++ b/src/java.logging/share/classes/java/util/logging/LogManager.java @@ -2556,10 +2556,10 @@ public class LogManager { /** * String representation of the - * {@link javax.management.ObjectName} for the management interface + * {@link java.management/javax.management.ObjectName} for the management interface * for the logging facility. * - * @see java.lang.management.PlatformLoggingMXBean + * @see java.management/java.lang.management.PlatformLoggingMXBean * * @since 1.5 */ @@ -2573,11 +2573,11 @@ public class LogManager { * * @deprecated {@code java.util.logging.LoggingMXBean} is deprecated and * replaced with {@code java.lang.management.PlatformLoggingMXBean}. Use - * {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class) + * {@link java.management/java.lang.management.ManagementFactory#getPlatformMXBean(Class) * ManagementFactory.getPlatformMXBean}(PlatformLoggingMXBean.class) * instead. * - * @see java.lang.management.PlatformLoggingMXBean + * @see java.management/java.lang.management.PlatformLoggingMXBean * @since 1.5 */ @Deprecated(since="9") diff --git a/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java b/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java index 812eb36622d..b966421f9b0 100644 --- a/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java +++ b/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -29,18 +29,18 @@ package java.util.logging; /** * The management interface for the logging facility. * - * {@link java.lang.management.PlatformLoggingMXBean + * {@link java.management/java.lang.management.PlatformLoggingMXBean * java.lang.management.PlatformLoggingMXBean} is the management interface * for logging facility registered in the {@link - * java.lang.management.ManagementFactory#getPlatformMBeanServer() + * java.management/java.lang.management.ManagementFactory#getPlatformMBeanServer() * platform MBeanServer}. * It is recommended to use the {@code PlatformLoggingMXBean} obtained via - * the {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class) + * the {@link java.management/java.lang.management.ManagementFactory#getPlatformMXBean(Class) * ManagementFactory.getPlatformMXBean(PlatformLoggingMXBean.class)} method. * * @deprecated {@code LoggingMXBean} is no longer a {@link - * java.lang.management.PlatformManagedObject platform MXBean} and is replaced - * with {@link java.lang.management.PlatformLoggingMXBean}. + * java.management/java.lang.management.PlatformManagedObject platform MXBean} and is replaced + * with {@link java.management/java.lang.management.PlatformLoggingMXBean}. * It will not register in the platform {@code MBeanServer}. * Use {@code ManagementFactory.getPlatformMXBean(PlatformLoggingMXBean.class)} * instead. @@ -49,7 +49,7 @@ package java.util.logging; * @author Mandy Chung * @since 1.5 * - * @see java.lang.management.PlatformLoggingMXBean + * @see java.management/java.lang.management.PlatformLoggingMXBean */ @Deprecated(since="9") public interface LoggingMXBean { diff --git a/src/java.management/share/classes/java/lang/management/ManagementFactory.java b/src/java.management/share/classes/java/lang/management/ManagementFactory.java index cba413ccf63..76bc7417e68 100644 --- a/src/java.management/share/classes/java/lang/management/ManagementFactory.java +++ b/src/java.management/share/classes/java/lang/management/ManagementFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -176,7 +176,7 @@ import sun.management.spi.PlatformMBeanProvider.PlatformComponent; * * * {@link PlatformLoggingMXBean} - * {@link java.util.logging.LogManager#LOGGING_MXBEAN_NAME + * {@link java.logging/java.util.logging.LogManager#LOGGING_MXBEAN_NAME * java.util.logging:type=Logging} * * diff --git a/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java b/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java index 80595dd75d6..280d145be37 100644 --- a/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java +++ b/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -26,7 +26,7 @@ package java.lang.management; /** - * The management interface for the {@linkplain java.util.logging logging} facility. + * The management interface for the {@linkplain java.logging/java.util.logging logging} facility. * *

    There is a single global instance of the {@code PlatformLoggingMXBean}. * The {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class) @@ -41,7 +41,7 @@ package java.lang.management; * The {@link javax.management.ObjectName ObjectName} for uniquely * identifying the {@code PlatformLoggingMXBean} within an MBeanServer is: *

    - *      {@link java.util.logging.LogManager#LOGGING_MXBEAN_NAME java.util.logging:type=Logging}
    + *      {@link java.logging/java.util.logging.LogManager#LOGGING_MXBEAN_NAME java.util.logging:type=Logging}
      * 
    * * @since 1.7 @@ -50,8 +50,8 @@ public interface PlatformLoggingMXBean extends PlatformManagedObject { /** * Returns the list of the currently registered - * {@linkplain java.util.logging.Logger logger} names. This method - * calls {@link java.util.logging.LogManager#getLoggerNames} and + * {@linkplain java.logging/java.util.logging.Logger logger} names. This method + * calls {@link java.logging/java.util.logging.LogManager#getLoggerNames} and * returns a list of the logger names. * * @return A list of {@code String} each of which is a @@ -60,15 +60,15 @@ public interface PlatformLoggingMXBean extends PlatformManagedObject { java.util.List getLoggerNames(); /** - * Gets the name of the log {@linkplain java.util.logging.Logger#getLevel + * Gets the name of the log {@linkplain java.logging/java.util.logging.Logger#getLevel * level} associated with the specified logger. * If the specified logger does not exist, {@code null} * is returned. * This method first finds the logger of the given name and * then returns the name of the log level by calling: *
    - * {@link java.util.logging.Logger#getLevel - * Logger.getLevel()}.{@link java.util.logging.Level#getName getName()}; + * {@link java.logging/java.util.logging.Logger#getLevel + * Logger.getLevel()}.{@link java.logging/java.util.logging.Level#getName getName()}; *
    * *

    @@ -83,16 +83,16 @@ public interface PlatformLoggingMXBean extends PlatformManagedObject { * is {@code null}. If the specified logger does not * exist, {@code null} is returned. * - * @see java.util.logging.Logger#getLevel + * @see java.logging/java.util.logging.Logger#getLevel */ String getLoggerLevel(String loggerName); /** * Sets the specified logger to the specified new - * {@linkplain java.util.logging.Logger#setLevel level}. + * {@linkplain java.logging/java.util.logging.Logger#setLevel level}. * If the {@code levelName} is not {@code null}, the level * of the specified logger is set to the parsed - * {@link java.util.logging.Level Level} + * {@link java.logging/java.util.logging.Level Level} * matching the {@code levelName}. * If the {@code levelName} is {@code null}, the level * of the specified logger is set to {@code null} and @@ -111,13 +111,13 @@ public interface PlatformLoggingMXBean extends PlatformManagedObject { * @throws SecurityException if a security manager exists and if * the caller does not have LoggingPermission("control"). * - * @see java.util.logging.Logger#setLevel + * @see java.logging/java.util.logging.Logger#setLevel */ void setLoggerLevel(String loggerName, String levelName); /** * Returns the name of the - * {@linkplain java.util.logging.Logger#getParent parent} + * {@linkplain java.logging/java.util.logging.Logger#getParent parent} * for the specified logger. * If the specified logger does not exist, {@code null} is returned. * If the specified logger is the root {@code Logger} in the namespace, diff --git a/src/java.management/share/classes/javax/management/remote/JMXAddressable.java b/src/java.management/share/classes/javax/management/remote/JMXAddressable.java index cc770b75194..973626b99a1 100644 --- a/src/java.management/share/classes/javax/management/remote/JMXAddressable.java +++ b/src/java.management/share/classes/javax/management/remote/JMXAddressable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -32,7 +32,7 @@ package javax.management.remote; * Depending on the connector implementation, a {@link JMXConnector} * object may implement this interface too. {@code JMXConnector} * objects for the RMI Connector are instances of - * {@link javax.management.remote.rmi.RMIConnector RMIConnector} which + * {@link java.management.rmi/javax.management.remote.rmi.RMIConnector RMIConnector} which * implements this interface.

    * *

    An object implementing this interface might not have an address diff --git a/src/java.management/share/classes/javax/management/remote/JMXServerErrorException.java b/src/java.management/share/classes/javax/management/remote/JMXServerErrorException.java index a8bf827fd3e..856234ad5dc 100644 --- a/src/java.management/share/classes/javax/management/remote/JMXServerErrorException.java +++ b/src/java.management/share/classes/javax/management/remote/JMXServerErrorException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -38,7 +38,7 @@ import javax.management.MBeanServer; * JMXServerErrorException instance contains the original * Error that occurred as its cause. * - * @see java.rmi.ServerError + * @see java.rmi/java.rmi.ServerError * @since 1.5 */ public class JMXServerErrorException extends IOException { -- GitLab From e3076552ec528864e61a6e0ec91e228006fddefc Mon Sep 17 00:00:00 2001 From: Ian Graves Date: Mon, 24 Jan 2022 22:21:22 +0000 Subject: [PATCH 012/400] 8280403: RegEx: String.split can fail with NPE in Pattern.CharPredicate::match Reviewed-by: lancea, iris, naoto, rriggs --- .../share/classes/java/util/regex/Pattern.java | 4 +++- test/jdk/java/util/regex/RegExTest.java | 11 ++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/util/regex/Pattern.java b/src/java.base/share/classes/java/util/regex/Pattern.java index 84e1063621d..b1e3977d0b2 100644 --- a/src/java.base/share/classes/java/util/regex/Pattern.java +++ b/src/java.base/share/classes/java/util/regex/Pattern.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -2689,6 +2689,8 @@ loop: for(int x=0, offset=0; x + Pattern.compile(pattern)); + assertTrue(e.getMessage().contains("Bad intersection syntax")); + } } -- GitLab From f35df5bfb5d23f439fb64e8511fd5ca34c773f30 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Tue, 25 Jan 2022 01:22:48 +0000 Subject: [PATCH 013/400] 8280422: thread_from_jni_environment can never return NULL Reviewed-by: shade, kbarrett --- src/hotspot/share/runtime/globals.hpp | 4 ---- .../share/runtime/interfaceSupport.inline.hpp | 9 ++++++-- src/hotspot/share/runtime/thread.hpp | 23 +++++++++++-------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index c963a69fa60..bc80a2eb45f 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -1191,10 +1191,6 @@ const intx ObjectAlignmentInBytes = 8; develop(bool, VerifyJNIFields, trueInDebug, \ "Verify jfieldIDs for instance fields") \ \ - notproduct(bool, VerifyJNIEnvThread, false, \ - "Verify JNIEnv.thread == Thread::current() when entering VM " \ - "from JNI") \ - \ develop(bool, VerifyFPU, false, \ "Verify FPU state (check for NaN's, etc.)") \ \ diff --git a/src/hotspot/share/runtime/interfaceSupport.inline.hpp b/src/hotspot/share/runtime/interfaceSupport.inline.hpp index 26a0cfe608e..13ecf2d80ce 100644 --- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp +++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp @@ -340,6 +340,11 @@ class VMNativeEntryWrapper { #define JRT_END } // Definitions for JNI +// +// As the JNIEnv can be passed from external native code we validate +// it in debug builds, primarily for our own testing. In general JNI +// does not attempt to detect programming errors and a bad JNIEnv may +// not even be readable. #define JNI_ENTRY(result_type, header) \ JNI_ENTRY_NO_PRESERVE(result_type, header) \ @@ -349,7 +354,7 @@ class VMNativeEntryWrapper { extern "C" { \ result_type JNICALL header { \ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ - assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \ + assert(thread == Thread::current(), "JNIEnv is only valid in same thread"); \ MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ ThreadInVMfromNative __tiv(thread); \ debug_only(VMNativeEntryWrapper __vew;) \ @@ -360,7 +365,7 @@ extern "C" { \ extern "C" { \ result_type JNICALL header { \ JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ - assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \ + assert(thread == Thread::current(), "JNIEnv is only valid in same thread"); \ VM_LEAF_BASE(result_type, header) diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index 74916b98275..71100dbe637 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -1312,16 +1312,21 @@ class JavaThread: public Thread { // Returns the jni environment for this thread JNIEnv* jni_environment() { return &_jni_environment; } + // Returns the current thread as indicated by the given JNIEnv. + // We don't assert it is Thread::current here as that is done at the + // external JNI entry points where the JNIEnv is passed into the VM. static JavaThread* thread_from_jni_environment(JNIEnv* env) { - JavaThread *thread_from_jni_env = (JavaThread*)((intptr_t)env - in_bytes(jni_environment_offset())); - // Only return NULL if thread is off the thread list; starting to - // exit should not return NULL. - if (thread_from_jni_env->is_terminated()) { - thread_from_jni_env->block_if_vm_exited(); - return NULL; - } else { - return thread_from_jni_env; + JavaThread* current = (JavaThread*)((intptr_t)env - in_bytes(jni_environment_offset())); + // We can't get here in a thread that has completed its execution and so + // "is_terminated", but a thread is also considered terminated if the VM + // has exited, so we have to check this and block in case this is a daemon + // thread returning to the VM (the JNI DirectBuffer entry points rely on + // this). + if (current->is_terminated()) { + current->block_if_vm_exited(); + ShouldNotReachHere(); } + return current; } // JNI critical regions. These can nest. -- GitLab From a59d717fd65d523bb6f4fc57949054e904a149f1 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Tue, 25 Jan 2022 01:31:24 +0000 Subject: [PATCH 014/400] 8280289: Enhance debug pp() command with NMT info Reviewed-by: stuefe, iklam --- src/hotspot/share/services/mallocTracker.cpp | 55 ++++++++++++------- src/hotspot/share/services/mallocTracker.hpp | 14 +++-- .../share/services/virtualMemoryTracker.cpp | 28 +++++++++- .../share/services/virtualMemoryTracker.hpp | 6 +- src/hotspot/share/utilities/debug.cpp | 40 +++++++++++++- 5 files changed, 113 insertions(+), 30 deletions(-) diff --git a/src/hotspot/share/services/mallocTracker.cpp b/src/hotspot/share/services/mallocTracker.cpp index 285a60d853f..e27d312ad81 100644 --- a/src/hotspot/share/services/mallocTracker.cpp +++ b/src/hotspot/share/services/mallocTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -31,6 +31,8 @@ #include "utilities/debug.hpp" #include "utilities/ostream.hpp" +#include "jvm_io.h" + size_t MallocMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(MallocMemorySnapshot, size_t)]; #ifdef ASSERT @@ -115,7 +117,7 @@ void MallocHeader::mark_block_as_dead() { void MallocHeader::release() { assert(MemTracker::enabled(), "Sanity"); - check_block_integrity(); + assert_block_integrity(); MallocMemorySummary::record_free(size(), flags()); MallocMemorySummary::record_free_malloc_header(sizeof(MallocHeader)); @@ -153,13 +155,18 @@ void MallocHeader::print_block_on_error(outputStream* st, address bad_address) c os::print_hex_dump(st, from1, to2, 1); } } +void MallocHeader::assert_block_integrity() const { + char msg[256]; + address corruption = NULL; + if (!check_block_integrity(msg, sizeof(msg), &corruption)) { + if (corruption != NULL) { + print_block_on_error(tty, (address)this); + } + fatal("NMT corruption: Block at " PTR_FORMAT ": %s", p2i(this), msg); + } +} -// Check block integrity. If block is broken, print out a report -// to tty (optionally with hex dump surrounding the broken block), -// then trigger a fatal error. -void MallocHeader::check_block_integrity() const { - -#define PREFIX "NMT corruption: " +bool MallocHeader::check_block_integrity(char* msg, size_t msglen, address* p_corruption) const { // Note: if you modify the error messages here, make sure you // adapt the associated gtests too. @@ -167,7 +174,8 @@ void MallocHeader::check_block_integrity() const { // values. Note that we should not call this for ::free(NULL), // which should be handled by os::free() above us. if (((size_t)p2i(this)) < K) { - fatal(PREFIX "Block at " PTR_FORMAT ": invalid block address", p2i(this)); + jio_snprintf(msg, msglen, "invalid block address"); + return false; } // From here on we assume the block pointer to be valid. We could @@ -186,37 +194,42 @@ void MallocHeader::check_block_integrity() const { // Should we ever start using std::max_align_t, this would be one place to // fix up. if (!is_aligned(this, sizeof(uint64_t))) { - print_block_on_error(tty, (address)this); - fatal(PREFIX "Block at " PTR_FORMAT ": block address is unaligned", p2i(this)); + *p_corruption = (address)this; + jio_snprintf(msg, msglen, "block address is unaligned"); + return false; } // Check header canary if (_canary != _header_canary_life_mark) { - print_block_on_error(tty, (address)this); - fatal(PREFIX "Block at " PTR_FORMAT ": header canary broken.", p2i(this)); + *p_corruption = (address)this; + jio_snprintf(msg, msglen, "header canary broken"); + return false; } #ifndef _LP64 // On 32-bit we have a second canary, check that one too. if (_alt_canary != _header_alt_canary_life_mark) { - print_block_on_error(tty, (address)this); - fatal(PREFIX "Block at " PTR_FORMAT ": header alternate canary broken.", p2i(this)); + *p_corruption = (address)this; + jio_snprintf(msg, msglen, "header canary broken"); + return false; } #endif // Does block size seems reasonable? if (_size >= max_reasonable_malloc_size) { - print_block_on_error(tty, (address)this); - fatal(PREFIX "Block at " PTR_FORMAT ": header looks invalid (weirdly large block size)", p2i(this)); + *p_corruption = (address)this; + jio_snprintf(msg, msglen, "header looks invalid (weirdly large block size)"); + return false; } // Check footer canary if (get_footer() != _footer_canary_life_mark) { - print_block_on_error(tty, footer_address()); - fatal(PREFIX "Block at " PTR_FORMAT ": footer canary broken at " PTR_FORMAT " (buffer overflow?)", - p2i(this), p2i(footer_address())); + *p_corruption = footer_address(); + jio_snprintf(msg, msglen, "footer canary broken at " PTR_FORMAT " (buffer overflow?)", + p2i(footer_address())); + return false; } -#undef PREFIX + return true; } bool MallocHeader::record_malloc_site(const NativeCallStack& stack, size_t size, diff --git a/src/hotspot/share/services/mallocTracker.hpp b/src/hotspot/share/services/mallocTracker.hpp index 6490b3d53ff..a0953c2b186 100644 --- a/src/hotspot/share/services/mallocTracker.hpp +++ b/src/hotspot/share/services/mallocTracker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -314,10 +314,9 @@ class MallocHeader { // We discount sizes larger than these static const size_t max_reasonable_malloc_size = LP64_ONLY(256 * G) NOT_LP64(3500 * M); - // Check block integrity. If block is broken, print out a report - // to tty (optionally with hex dump surrounding the broken block), - // then trigger a fatal error. - void check_block_integrity() const; + // If block is broken, print out a report to tty (optionally with + // hex dump surrounding the broken block), then trigger a fatal error + void assert_block_integrity() const; void print_block_on_error(outputStream* st, address bad_address) const; void mark_block_as_dead(); @@ -363,6 +362,11 @@ class MallocHeader { // Cleanup tracking information and mark block as dead before the memory is released. void release(); + // If block is broken, fill in a short descriptive text in out, + // an option pointer to the corruption in p_corruption, and return false. + // Return true if block is fine. + bool check_block_integrity(char* msg, size_t msglen, address* p_corruption) const; + private: inline void set_size(size_t size) { _size = size; diff --git a/src/hotspot/share/services/virtualMemoryTracker.cpp b/src/hotspot/share/services/virtualMemoryTracker.cpp index 77fb24927f5..53a2cf10642 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.cpp +++ b/src/hotspot/share/services/virtualMemoryTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -671,3 +671,29 @@ bool VirtualMemoryTracker::walk_virtual_memory(VirtualMemoryWalker* walker) { } return true; } + +class FindAndSnapshotRegionWalker : public VirtualMemoryWalker { +private: + ReservedMemoryRegion& _region; + const address _p; + bool _found_region; +public: + FindAndSnapshotRegionWalker(void* p, ReservedMemoryRegion& region) : + _region(region), _p((address)p), _found_region(false) { } + + bool do_allocation_site(const ReservedMemoryRegion* rgn) { + if (rgn->contain_address(_p)) { + _region = *rgn; + _found_region = true; + return false; + } + return true; + } + bool found_region() const { return _found_region; } +}; + +const bool VirtualMemoryTracker::snapshot_region_contains(void* p, ReservedMemoryRegion& region) { + FindAndSnapshotRegionWalker walker(p, region); + walk_virtual_memory(&walker); + return walker.found_region(); +} diff --git a/src/hotspot/share/services/virtualMemoryTracker.hpp b/src/hotspot/share/services/virtualMemoryTracker.hpp index c96af6b8387..2f04503cf6e 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.hpp +++ b/src/hotspot/share/services/virtualMemoryTracker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -341,7 +341,7 @@ class ReservedMemoryRegion : public VirtualMemoryRegion { return *this; } - const char* flag_name() { return NMTUtil::flag_to_name(_flag); } + const char* flag_name() const { return NMTUtil::flag_to_name(_flag); } private: // The committed region contains the uncommitted region, subtract the uncommitted @@ -387,6 +387,8 @@ class VirtualMemoryTracker : AllStatic { // Walk virtual memory data structure for creating baseline, etc. static bool walk_virtual_memory(VirtualMemoryWalker* walker); + static const bool snapshot_region_contains(void* p, ReservedMemoryRegion& region); + // Snapshot current thread stacks static void snapshot_thread_stacks(); diff --git a/src/hotspot/share/utilities/debug.cpp b/src/hotspot/share/utilities/debug.cpp index 1a0c3a84647..c3c98d3067f 100644 --- a/src/hotspot/share/utilities/debug.cpp +++ b/src/hotspot/share/utilities/debug.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -44,6 +44,7 @@ #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" +#include "runtime/safefetch.inline.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubCodeGenerator.hpp" #include "runtime/stubRoutines.hpp" @@ -51,7 +52,9 @@ #include "runtime/vframe.hpp" #include "runtime/vm_version.hpp" #include "services/heapDumper.hpp" +#include "services/mallocTracker.hpp" #include "services/memTracker.hpp" +#include "services/virtualMemoryTracker.hpp" #include "utilities/defaultStream.hpp" #include "utilities/events.hpp" #include "utilities/formatBuffer.hpp" @@ -480,6 +483,41 @@ extern "C" JNIEXPORT void pp(void* p) { oop obj = cast_to_oop(p); obj->print(); } else { +#if INCLUDE_NMT + // With NMT + if (MemTracker::enabled()) { + const NMT_TrackingLevel tracking_level = MemTracker::tracking_level(); + ReservedMemoryRegion region(0, 0); + // Check and snapshot a mmap'd region that contains the pointer + if (VirtualMemoryTracker::snapshot_region_contains(p, region)) { + tty->print_cr(PTR_FORMAT " in mmap'd memory region [" PTR_FORMAT " - " PTR_FORMAT "] by %s", + p2i(p), p2i(region.base()), p2i(region.base() + region.size()), region.flag_name()); + if (tracking_level == NMT_detail) { + region.call_stack()->print_on(tty); + tty->cr(); + } + return; + } + // Check if it is a malloc'd memory block + if (CanUseSafeFetchN() && SafeFetchN((intptr_t*)p, 0) != 0) { + const MallocHeader* mhdr = (const MallocHeader*)MallocTracker::get_base(p, tracking_level); + char msg[256]; + address p_corrupted; + if (SafeFetchN((intptr_t*)mhdr, 0) != 0 && mhdr->check_block_integrity(msg, sizeof(msg), &p_corrupted)) { + tty->print_cr(PTR_FORMAT " malloc'd " SIZE_FORMAT " bytes by %s", + p2i(p), mhdr->size(), NMTUtil::flag_to_name(mhdr->flags())); + if (tracking_level == NMT_detail) { + NativeCallStack ncs; + if (mhdr->get_stack(ncs)) { + ncs.print_on(tty); + tty->cr(); + } + } + return; + } + } + } +#endif // INCLUDE_NMT tty->print(PTR_FORMAT, p2i(p)); } } -- GitLab From 53804720a04b5b314701de82eddf1a55798eba00 Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Tue, 25 Jan 2022 08:08:17 +0000 Subject: [PATCH 015/400] 8280470: Confusing instanceof check in HijrahChronology.range Reviewed-by: rriggs, naoto, dfuchs, iris --- .../java/time/chrono/HijrahChronology.java | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/java.base/share/classes/java/time/chrono/HijrahChronology.java b/src/java.base/share/classes/java/time/chrono/HijrahChronology.java index 87f307e15d3..1ce99906708 100644 --- a/src/java.base/share/classes/java/time/chrono/HijrahChronology.java +++ b/src/java.base/share/classes/java/time/chrono/HijrahChronology.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -533,18 +533,14 @@ public final class HijrahChronology extends AbstractChronology implements Serial @Override public ValueRange range(ChronoField field) { checkCalendarInit(); - if (field instanceof ChronoField) { - ChronoField f = field; - return switch (f) { - case DAY_OF_MONTH -> ValueRange.of(1, 1, getMinimumMonthLength(), getMaximumMonthLength()); - case DAY_OF_YEAR -> ValueRange.of(1, getMaximumDayOfYear()); - case ALIGNED_WEEK_OF_MONTH -> ValueRange.of(1, 5); - case YEAR, YEAR_OF_ERA -> ValueRange.of(getMinimumYear(), getMaximumYear()); - case ERA -> ValueRange.of(1, 1); - default -> field.range(); - }; - } - return field.range(); + return switch (field) { + case DAY_OF_MONTH -> ValueRange.of(1, 1, getMinimumMonthLength(), getMaximumMonthLength()); + case DAY_OF_YEAR -> ValueRange.of(1, getMaximumDayOfYear()); + case ALIGNED_WEEK_OF_MONTH -> ValueRange.of(1, 5); + case YEAR, YEAR_OF_ERA -> ValueRange.of(getMinimumYear(), getMaximumYear()); + case ERA -> ValueRange.of(1, 1); + default -> field.range(); + }; } //----------------------------------------------------------------------- -- GitLab From b32774653f72f379655192874cb7076079d238e6 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Tue, 25 Jan 2022 09:12:18 +0000 Subject: [PATCH 016/400] 8280384: Parallel: Remove VMThread specific ParCompactionManager Reviewed-by: ayang, sjohanss --- .../share/gc/parallel/psCompactionManager.cpp | 13 ++++---- .../share/gc/parallel/psCompactionManager.hpp | 4 ++- .../share/gc/parallel/psParallelCompact.cpp | 30 ++++--------------- .../share/gc/parallel/psParallelCompact.hpp | 5 ++-- .../gc/parallel/psParallelCompact.inline.hpp | 6 +--- .../share/gc/parallel/psPromotionManager.cpp | 12 ++++---- .../gc/parallel/psPromotionManager.inline.hpp | 2 +- 7 files changed, 23 insertions(+), 49 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.cpp b/src/hotspot/share/gc/parallel/psCompactionManager.cpp index 0a71ec80e3b..3a7fc8ae758 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.cpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.cpp @@ -70,7 +70,7 @@ void ParCompactionManager::initialize(ParMarkBitMap* mbm) { uint parallel_gc_threads = ParallelScavengeHeap::heap()->workers().max_workers(); assert(_manager_array == NULL, "Attempt to initialize twice"); - _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1, mtGC); + _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads, mtGC); _oop_task_queues = new OopTaskQueueSet(parallel_gc_threads); _objarray_task_queues = new ObjArrayTaskQueueSet(parallel_gc_threads); @@ -84,9 +84,6 @@ void ParCompactionManager::initialize(ParMarkBitMap* mbm) { region_task_queues()->register_queue(i, _manager_array[i]->region_stack()); } - // The VMThread gets its own ParCompactionManager, which is not available - // for work stealing. - _manager_array[parallel_gc_threads] = new ParCompactionManager(); assert(ParallelScavengeHeap::heap()->workers().max_workers() != 0, "Not initialized?"); @@ -97,14 +94,14 @@ void ParCompactionManager::initialize(ParMarkBitMap* mbm) { void ParCompactionManager::reset_all_bitmap_query_caches() { uint parallel_gc_threads = ParallelScavengeHeap::heap()->workers().max_workers(); - for (uint i=0; i<=parallel_gc_threads; i++) { + for (uint i=0; ireset_bitmap_query_cache(); } } void ParCompactionManager::flush_all_string_dedup_requests() { uint parallel_gc_threads = ParallelScavengeHeap::heap()->workers().max_workers(); - for (uint i=0; i<=parallel_gc_threads; i++) { + for (uint i=0; iflush_string_dedup_requests(); } } @@ -184,14 +181,14 @@ void ParCompactionManager::remove_all_shadow_regions() { #ifdef ASSERT void ParCompactionManager::verify_all_marking_stack_empty() { uint parallel_gc_threads = ParallelGCThreads; - for (uint i = 0; i <= parallel_gc_threads; i++) { + for (uint i = 0; i < parallel_gc_threads; i++) { assert(_manager_array[i]->marking_stacks_empty(), "Marking stack should be empty"); } } void ParCompactionManager::verify_all_region_stack_empty() { uint parallel_gc_threads = ParallelGCThreads; - for (uint i = 0; i <= parallel_gc_threads; i++) { + for (uint i = 0; i < parallel_gc_threads; i++) { assert(_manager_array[i]->region_stack()->is_empty(), "Region stack should be empty"); } } diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.hpp index 2e73da920b5..4299f7e4c02 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.hpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.hpp @@ -147,7 +147,9 @@ class ParCompactionManager : public CHeapObj { RegionTaskQueue* region_stack() { return &_region_stack; } - static ParCompactionManager* get_vmthread_cm() { return _manager_array[ParallelGCThreads]; } + // Get the compaction manager when doing evacuation work from the VM thread. + // Simply use the first compaction manager here. + static ParCompactionManager* get_vmthread_cm() { return _manager_array[0]; } ParCompactionManager(); diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index 9d30f4bf2e2..4657975b1bc 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -1595,8 +1595,7 @@ void PSParallelCompact::summary_phase_msg(SpaceId dst_space_id, } #endif // #ifndef PRODUCT -void PSParallelCompact::summary_phase(ParCompactionManager* cm, - bool maximum_compaction) +void PSParallelCompact::summary_phase(bool maximum_compaction) { GCTraceTime(Info, gc, phases) tm("Summary Phase", &_gc_timer); @@ -1756,9 +1755,6 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { const PreGenGCValues pre_gc_values = heap->get_pre_gc_values(); - // Get the compaction manager reserved for the VM thread. - ParCompactionManager* const vmthread_cm = ParCompactionManager::get_vmthread_cm(); - { const uint active_workers = WorkerPolicy::calc_active_workers(ParallelScavengeHeap::heap()->workers().max_workers(), @@ -1787,11 +1783,11 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { ref_processor()->start_discovery(maximum_heap_compaction); - marking_phase(vmthread_cm, &_gc_tracer); + marking_phase(&_gc_tracer); bool max_on_system_gc = UseMaximumCompactionOnSystemGC && GCCause::is_user_requested_gc(gc_cause); - summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc); + summary_phase(maximum_heap_compaction || max_on_system_gc); #if COMPILER2_OR_JVMCI assert(DerivedPointerTable::is_active(), "Sanity"); @@ -2063,8 +2059,7 @@ public: } }; -void PSParallelCompact::marking_phase(ParCompactionManager* cm, - ParallelOldTracer *gc_tracer) { +void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) { // Recursively traverse all live objects and mark them GCTraceTime(Info, gc, phases) tm("Marking Phase", &_gc_timer); @@ -2125,19 +2120,6 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm, _gc_tracer.report_object_count_after_gc(is_alive_closure()); } -#ifdef ASSERT -void PCAdjustPointerClosure::verify_cm(ParCompactionManager* cm) { - assert(cm != NULL, "associate ParCompactionManage should not be NULL"); - auto vmthread_cm = ParCompactionManager::get_vmthread_cm(); - if (Thread::current()->is_VM_thread()) { - assert(cm == vmthread_cm, "VM threads should use ParCompactionManager from get_vmthread_cm()"); - } else { - assert(Thread::current()->is_Worker_thread(), "Must be a GC thread"); - assert(cm != vmthread_cm, "GC threads should use ParCompactionManager from gc_thread_compaction_manager()"); - } -} -#endif - class PSAdjustTask final : public WorkerTask { SubTasksDone _sub_tasks; WeakProcessor::Task _weak_proc_task; @@ -2528,9 +2510,7 @@ void PSParallelCompact::compact() { { GCTraceTime(Trace, gc, phases) tm("Deferred Updates", &_gc_timer); - // Update the deferred objects, if any. In principle, any compaction - // manager can be used. However, since the current thread is VM thread, we - // use the rightful one to keep the verification logic happy. + // Update the deferred objects, if any. ParCompactionManager* cm = ParCompactionManager::get_vmthread_cm(); for (unsigned int id = old_space_id; id < last_space_id; ++id) { update_deferred_objects(cm, SpaceId(id)); diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.hpp b/src/hotspot/share/gc/parallel/psParallelCompact.hpp index 0b8eb6b0116..77a9d44f9b6 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.hpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.hpp @@ -1062,8 +1062,7 @@ class PSParallelCompact : AllStatic { static void post_compact(); // Mark live objects - static void marking_phase(ParCompactionManager* cm, - ParallelOldTracer *gc_tracer); + static void marking_phase(ParallelOldTracer *gc_tracer); // Compute the dense prefix for the designated space. This is an experimental // implementation currently not used in production. @@ -1123,7 +1122,7 @@ class PSParallelCompact : AllStatic { static void summarize_spaces_quick(); static void summarize_space(SpaceId id, bool maximum_compaction); - static void summary_phase(ParCompactionManager* cm, bool maximum_compaction); + static void summary_phase(bool maximum_compaction); // Adjust addresses in roots. Does not adjust addresses in heap. static void adjust_roots(); diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp b/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp index 001f55c076a..48c5a98fd1a 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.inline.hpp @@ -126,9 +126,7 @@ inline void PSParallelCompact::adjust_pointer(T* p, ParCompactionManager* cm) { class PCAdjustPointerClosure: public BasicOopIterateClosure { public: - PCAdjustPointerClosure(ParCompactionManager* cm) { - verify_cm(cm); - _cm = cm; + PCAdjustPointerClosure(ParCompactionManager* cm) : _cm(cm) { } template void do_oop_nv(T* p) { PSParallelCompact::adjust_pointer(p, _cm); } virtual void do_oop(oop* p) { do_oop_nv(p); } @@ -137,8 +135,6 @@ public: virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; } private: ParCompactionManager* _cm; - - static void verify_cm(ParCompactionManager* cm) NOT_DEBUG_RETURN; }; #endif // SHARE_GC_PARALLEL_PSPARALLELCOMPACT_INLINE_HPP diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.cpp b/src/hotspot/share/gc/parallel/psPromotionManager.cpp index 7ef706aba93..f7308366400 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp @@ -54,7 +54,7 @@ void PSPromotionManager::initialize() { _old_gen = heap->old_gen(); _young_space = heap->young_gen()->to_space(); - const uint promotion_manager_num = ParallelGCThreads + 1; + const uint promotion_manager_num = ParallelGCThreads; // To prevent false sharing, we pad the PSPromotionManagers // and make sure that the first instance starts at a cache line. @@ -95,7 +95,7 @@ PSPromotionManager* PSPromotionManager::gc_thread_promotion_manager(uint index) PSPromotionManager* PSPromotionManager::vm_thread_promotion_manager() { assert(_manager_array != NULL, "Sanity"); - return &_manager_array[ParallelGCThreads]; + return &_manager_array[0]; } void PSPromotionManager::pre_scavenge() { @@ -104,7 +104,7 @@ void PSPromotionManager::pre_scavenge() { _preserved_marks_set->assert_empty(); _young_space = heap->young_gen()->to_space(); - for(uint i=0; ireset(); } } @@ -113,7 +113,7 @@ bool PSPromotionManager::post_scavenge(YoungGCTracer& gc_tracer) { bool promotion_failure_occurred = false; TASKQUEUE_STATS_ONLY(print_taskqueue_stats()); - for (uint i = 0; i < ParallelGCThreads + 1; i++) { + for (uint i = 0; i < ParallelGCThreads; i++) { PSPromotionManager* manager = manager_array(i); assert(manager->claimed_stack_depth()->is_empty(), "should be empty"); if (manager->_promotion_failed_info.has_failed()) { @@ -162,7 +162,7 @@ PSPromotionManager::print_taskqueue_stats() { TaskQueueStats totals; out->print("thr "); TaskQueueStats::print_header(1, out); out->cr(); out->print("--- "); TaskQueueStats::print_header(2, out); out->cr(); - for (uint i = 0; i < ParallelGCThreads + 1; ++i) { + for (uint i = 0; i < ParallelGCThreads; ++i) { TaskQueueStats& next = manager_array(i)->_claimed_stack_depth.stats; out->print("%3d ", i); next.print(out); out->cr(); totals += next; @@ -171,7 +171,7 @@ PSPromotionManager::print_taskqueue_stats() { const uint hlines = sizeof(pm_stats_hdr) / sizeof(pm_stats_hdr[0]); for (uint i = 0; i < hlines; ++i) out->print_cr("%s", pm_stats_hdr[i]); - for (uint i = 0; i < ParallelGCThreads + 1; ++i) { + for (uint i = 0; i < ParallelGCThreads; ++i) { manager_array(i)->print_local_stats(out, i); } } diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp index 733af9bee7f..b3f1c7297f4 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.inline.hpp @@ -44,7 +44,7 @@ inline PSPromotionManager* PSPromotionManager::manager_array(uint index) { assert(_manager_array != NULL, "access of NULL manager_array"); - assert(index <= ParallelGCThreads, "out of range manager_array access"); + assert(index < ParallelGCThreads, "out of range manager_array access"); return &_manager_array[index]; } -- GitLab From 295b263fa951b9d51bfa92c04e49b2a17a62bd6f Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Tue, 25 Jan 2022 09:13:50 +0000 Subject: [PATCH 017/400] 8279241: G1 Full GC does not always slide memory to bottom addresses Reviewed-by: iwalulya, ayang, sjohanss --- src/hotspot/share/gc/g1/g1FullCollector.cpp | 65 ++++- src/hotspot/share/gc/g1/g1FullCollector.hpp | 12 +- .../share/gc/g1/g1FullCollector.inline.hpp | 6 +- .../share/gc/g1/g1FullGCHeapRegionAttr.hpp | 6 +- .../share/gc/g1/g1FullGCPrepareTask.cpp | 239 ++++++------------ .../share/gc/g1/g1FullGCPrepareTask.hpp | 93 ++++--- .../gc/g1/g1FullGCPrepareTask.inline.hpp | 126 +++++++++ src/hotspot/share/gc/g1/g1FullGCScope.cpp | 4 +- src/hotspot/share/gc/g1/g1FullGCScope.hpp | 4 +- 9 files changed, 346 insertions(+), 209 deletions(-) create mode 100644 src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index 603b3818029..dd20a099919 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -32,7 +32,7 @@ #include "gc/g1/g1FullGCCompactTask.hpp" #include "gc/g1/g1FullGCMarker.inline.hpp" #include "gc/g1/g1FullGCMarkTask.hpp" -#include "gc/g1/g1FullGCPrepareTask.hpp" +#include "gc/g1/g1FullGCPrepareTask.inline.hpp" #include "gc/g1/g1FullGCScope.hpp" #include "gc/g1/g1OopClosures.hpp" #include "gc/g1/g1Policy.hpp" @@ -297,14 +297,67 @@ void G1FullCollector::phase1_mark_live_objects() { } void G1FullCollector::phase2_prepare_compaction() { - GCTraceTime(Info, gc, phases) info("Phase 2: Prepare for compaction", scope()->timer()); + GCTraceTime(Info, gc, phases) info("Phase 2: Prepare compaction", scope()->timer()); + + phase2a_determine_worklists(); + + bool has_free_compaction_targets = phase2b_forward_oops(); + + // Try to avoid OOM immediately after Full GC in case there are no free regions + // left after determining the result locations (i.e. this phase). Prepare to + // maximally compact the tail regions of the compaction queues serially. + if (!has_free_compaction_targets) { + phase2c_prepare_serial_compaction(); + } +} + +void G1FullCollector::phase2a_determine_worklists() { + GCTraceTime(Debug, gc, phases) debug("Phase 2: Determine work lists", scope()->timer()); + + G1DetermineCompactionQueueClosure cl(this); + _heap->heap_region_iterate(&cl); +} + +bool G1FullCollector::phase2b_forward_oops() { + GCTraceTime(Debug, gc, phases) debug("Phase 2: Prepare parallel compaction", scope()->timer()); + G1FullGCPrepareTask task(this); run_task(&task); - // To avoid OOM when there is memory left. - if (!task.has_freed_regions()) { - task.prepare_serial_compaction(); + return task.has_free_compaction_targets(); +} + +void G1FullCollector::phase2c_prepare_serial_compaction() { + GCTraceTime(Debug, gc, phases) debug("Phase 2: Prepare serial compaction", scope()->timer()); + // At this point we know that after parallel compaction there will be no + // completely free regions. That means that the last region of + // all compaction queues still have data in them. We try to compact + // these regions in serial to avoid a premature OOM when the mutator wants + // to allocate the first eden region after gc. + for (uint i = 0; i < workers(); i++) { + G1FullGCCompactionPoint* cp = compaction_point(i); + if (cp->has_regions()) { + serial_compaction_point()->add(cp->remove_last()); + } + } + + // Update the forwarding information for the regions in the serial + // compaction point. + G1FullGCCompactionPoint* cp = serial_compaction_point(); + for (GrowableArrayIterator it = cp->regions()->begin(); it != cp->regions()->end(); ++it) { + HeapRegion* current = *it; + if (!cp->is_initialized()) { + // Initialize the compaction point. Nothing more is needed for the first heap region + // since it is already prepared for compaction. + cp->initialize(current, false); + } else { + assert(!current->is_humongous(), "Should be no humongous regions in compaction queue"); + G1SerialRePrepareClosure re_prepare(cp, current); + current->set_compaction_top(current->bottom()); + current->apply_to_marked_objects(mark_bitmap(), &re_prepare); + } } + cp->update(); } void G1FullCollector::phase3_adjust_pointers() { diff --git a/src/hotspot/share/gc/g1/g1FullCollector.hpp b/src/hotspot/share/gc/g1/g1FullCollector.hpp index c4d019629dd..f9087298b86 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.hpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -110,7 +110,7 @@ public: G1FullGCCompactionPoint* serial_compaction_point() { return &_serial_compaction_point; } G1CMBitMap* mark_bitmap(); ReferenceProcessor* reference_processor(); - size_t live_words(uint region_index) { + size_t live_words(uint region_index) const { assert(region_index < _heap->max_regions(), "sanity"); return _live_stats[region_index]._live_words; } @@ -121,6 +121,9 @@ public: inline bool is_skip_compacting(uint region_index) const; inline bool is_skip_marking(oop obj) const; + // Are we (potentially) going to compact into this region? + inline bool is_compaction_target(uint region_index) const; + inline void set_free(uint region_idx); inline bool is_free(uint region_idx) const; inline void update_from_compacting_to_skip_compacting(uint region_idx); @@ -128,6 +131,11 @@ public: private: void phase1_mark_live_objects(); void phase2_prepare_compaction(); + + void phase2a_determine_worklists(); + bool phase2b_forward_oops(); + void phase2c_prepare_serial_compaction(); + void phase3_adjust_pointers(); void phase4_do_compaction(); diff --git a/src/hotspot/share/gc/g1/g1FullCollector.inline.hpp b/src/hotspot/share/gc/g1/g1FullCollector.inline.hpp index 5a0863b202a..37e16fc6f78 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -43,6 +43,10 @@ bool G1FullCollector::is_skip_marking(oop obj) const { return _region_attr_table.is_skip_marking(cast_from_oop(obj)); } +bool G1FullCollector::is_compaction_target(uint region_index) const { + return _region_attr_table.is_compacting(region_index) || is_free(region_index); +} + void G1FullCollector::set_free(uint region_idx) { _region_attr_table.set_free(region_idx); } diff --git a/src/hotspot/share/gc/g1/g1FullGCHeapRegionAttr.hpp b/src/hotspot/share/gc/g1/g1FullGCHeapRegionAttr.hpp index ca2f970edde..017877785f4 100644 --- a/src/hotspot/share/gc/g1/g1FullGCHeapRegionAttr.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCHeapRegionAttr.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -70,6 +70,10 @@ public: return get_by_address(obj) == Compacting; } + bool is_compacting(uint idx) const { + return get_by_index(idx) == Compacting; + } + bool is_skip_compacting(uint idx) const { return get_by_index(idx) == SkipCompacting; } diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp index 883e0a51f86..4ffe9329dc7 100644 --- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -23,13 +23,13 @@ */ #include "precompiled.hpp" -#include "gc/g1/g1CollectedHeap.hpp" +#include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ConcurrentMarkBitMap.inline.hpp" #include "gc/g1/g1FullCollector.inline.hpp" #include "gc/g1/g1FullGCCompactionPoint.hpp" #include "gc/g1/g1FullGCMarker.hpp" #include "gc/g1/g1FullGCOopClosures.inline.hpp" -#include "gc/g1/g1FullGCPrepareTask.hpp" +#include "gc/g1/g1FullGCPrepareTask.inline.hpp" #include "gc/g1/g1HotCardCache.hpp" #include "gc/g1/heapRegion.inline.hpp" #include "gc/shared/gcTraceTime.inline.hpp" @@ -39,113 +39,84 @@ #include "oops/oop.inline.hpp" #include "utilities/ticks.hpp" -template -void G1FullGCPrepareTask::G1CalculatePointersClosure::free_pinned_region(HeapRegion* hr) { - _regions_freed = true; - if (is_humongous) { - _g1h->free_humongous_region(hr, nullptr); - } else { - _g1h->free_region(hr, nullptr); - } - _collector->set_free(hr->hrm_index()); - prepare_for_compaction(hr); -} +G1DetermineCompactionQueueClosure::G1DetermineCompactionQueueClosure(G1FullCollector* collector) : + _g1h(G1CollectedHeap::heap()), + _collector(collector), + _cur_worker(0) { } bool G1FullGCPrepareTask::G1CalculatePointersClosure::do_heap_region(HeapRegion* hr) { - if (should_compact(hr)) { - assert(!hr->is_humongous(), "moving humongous objects not supported."); - prepare_for_compaction(hr); - } else { - // There is no need to iterate and forward objects in pinned regions ie. - // prepare them for compaction. The adjust pointers phase will skip - // work for them. - assert(hr->containing_set() == nullptr, "already cleared by PrepareRegionsClosure"); - if (hr->is_humongous()) { - oop obj = cast_to_oop(hr->humongous_start_region()->bottom()); - if (!_bitmap->is_marked(obj)) { - free_pinned_region(hr); - } - } else if (hr->is_open_archive()) { - bool is_empty = _collector->live_words(hr->hrm_index()) == 0; - if (is_empty) { - free_pinned_region(hr); - } - } else if (hr->is_closed_archive()) { - // nothing to do with closed archive region - } else { - assert(MarkSweepDeadRatio > 0, - "only skip compaction for other regions when MarkSweepDeadRatio > 0"); - - // Too many live objects; skip compacting it. - _collector->update_from_compacting_to_skip_compacting(hr->hrm_index()); - if (hr->is_young()) { - // G1 updates the BOT for old region contents incrementally, but young regions - // lack BOT information for performance reasons. - // Recreate BOT information of high live ratio young regions here to keep expected - // performance during scanning their card tables in the collection pauses later. - hr->update_bot(); - } - log_trace(gc, phases)("Phase 2: skip compaction region index: %u, live words: " SIZE_FORMAT, - hr->hrm_index(), _collector->live_words(hr->hrm_index())); - } - } + uint region_idx = hr->hrm_index(); + assert(_collector->is_compaction_target(region_idx), "must be"); - // Reset data structures not valid after Full GC. - reset_region_metadata(hr); + assert(!hr->is_pinned(), "must be"); + assert(!hr->is_closed_archive(), "must be"); + assert(!hr->is_open_archive(), "must be"); + + prepare_for_compaction(hr); return false; } G1FullGCPrepareTask::G1FullGCPrepareTask(G1FullCollector* collector) : G1FullGCTask("G1 Prepare Compact Task", collector), - _freed_regions(false), + _has_free_compaction_targets(false), _hrclaimer(collector->workers()) { } -void G1FullGCPrepareTask::set_freed_regions() { - if (!_freed_regions) { - _freed_regions = true; +void G1FullGCPrepareTask::set_has_free_compaction_targets() { + if (!_has_free_compaction_targets) { + _has_free_compaction_targets = true; } } -bool G1FullGCPrepareTask::has_freed_regions() { - return _freed_regions; +bool G1FullGCPrepareTask::has_free_compaction_targets() { + return _has_free_compaction_targets; } void G1FullGCPrepareTask::work(uint worker_id) { Ticks start = Ticks::now(); - G1FullGCCompactionPoint* compaction_point = collector()->compaction_point(worker_id); - G1CalculatePointersClosure closure(collector(), compaction_point); - G1CollectedHeap::heap()->heap_region_par_iterate_from_start(&closure, &_hrclaimer); - - compaction_point->update(); + // Calculate the target locations for the objects in the non-free regions of + // the compaction queues provided by the associate compaction point. + { + G1FullGCCompactionPoint* compaction_point = collector()->compaction_point(worker_id); + G1CalculatePointersClosure closure(collector(), compaction_point); + + for (GrowableArrayIterator it = compaction_point->regions()->begin(); + it != compaction_point->regions()->end(); + ++it) { + closure.do_heap_region(*it); + } + compaction_point->update(); + // Determine if there are any unused compaction targets. This is only the case if + // there are + // - any regions in queue, so no free ones either. + // - and the current region is not the last one in the list. + if (compaction_point->has_regions() && + compaction_point->current_region() != compaction_point->regions()->last()) { + set_has_free_compaction_targets(); + } + } - // Check if any regions was freed by this worker and store in task. - if (closure.freed_regions()) { - set_freed_regions(); + // Clear region metadata that is invalid after GC for all regions. + { + G1ResetMetadataClosure closure(collector()); + G1CollectedHeap::heap()->heap_region_par_iterate_from_start(&closure, &_hrclaimer); } log_task("Prepare compaction task", worker_id, start); } G1FullGCPrepareTask::G1CalculatePointersClosure::G1CalculatePointersClosure(G1FullCollector* collector, G1FullGCCompactionPoint* cp) : - _g1h(G1CollectedHeap::heap()), - _collector(collector), - _bitmap(collector->mark_bitmap()), - _cp(cp), - _regions_freed(false) { } - -bool G1FullGCPrepareTask::G1CalculatePointersClosure::should_compact(HeapRegion* hr) { - if (hr->is_pinned()) { - return false; - } - size_t live_words = _collector->live_words(hr->hrm_index()); - size_t live_words_threshold = _collector->scope()->region_compaction_threshold(); - // High live ratio region will not be compacted. - return live_words <= live_words_threshold; -} + _g1h(G1CollectedHeap::heap()), + _collector(collector), + _bitmap(collector->mark_bitmap()), + _cp(cp) { } -void G1FullGCPrepareTask::G1CalculatePointersClosure::reset_region_metadata(HeapRegion* hr) { +G1FullGCPrepareTask::G1ResetMetadataClosure::G1ResetMetadataClosure(G1FullCollector* collector) : + _g1h(G1CollectedHeap::heap()), + _collector(collector) { } + +void G1FullGCPrepareTask::G1ResetMetadataClosure::reset_region_metadata(HeapRegion* hr) { hr->rem_set()->clear(); hr->clear_cardtable(); @@ -155,6 +126,26 @@ void G1FullGCPrepareTask::G1CalculatePointersClosure::reset_region_metadata(Heap } } +bool G1FullGCPrepareTask::G1ResetMetadataClosure::do_heap_region(HeapRegion* hr) { + uint const region_idx = hr->hrm_index(); + if (!_collector->is_compaction_target(region_idx)) { + assert(!hr->is_free(), "all free regions should be compaction targets"); + assert(_collector->is_skip_compacting(region_idx) || hr->is_closed_archive(), "must be"); + if (hr->is_young()) { + // G1 updates the BOT for old region contents incrementally, but young regions + // lack BOT information for performance reasons. + // Recreate BOT information of high live ratio young regions here to keep expected + // performance during scanning their card tables in the collection pauses later. + hr->update_bot(); + } + } + + // Reset data structures not valid after Full GC. + reset_region_metadata(hr); + + return false; +} + G1FullGCPrepareTask::G1PrepareCompactLiveClosure::G1PrepareCompactLiveClosure(G1FullGCCompactionPoint* cp) : _cp(cp) { } @@ -164,87 +155,9 @@ size_t G1FullGCPrepareTask::G1PrepareCompactLiveClosure::apply(oop object) { return size; } -size_t G1FullGCPrepareTask::G1RePrepareClosure::apply(oop obj) { - // We only re-prepare objects forwarded within the current region, so - // skip objects that are already forwarded to another region. - if (obj->is_forwarded() && !_current->is_in(obj->forwardee())) { - return obj->size(); - } - - // Get size and forward. - size_t size = obj->size(); - _cp->forward(obj, size); - - return size; -} - -void G1FullGCPrepareTask::G1CalculatePointersClosure::prepare_for_compaction_work(G1FullGCCompactionPoint* cp, - HeapRegion* hr) { - hr->set_compaction_top(hr->bottom()); +void G1FullGCPrepareTask::G1CalculatePointersClosure::prepare_for_compaction(HeapRegion* hr) { if (!_collector->is_free(hr->hrm_index())) { - G1PrepareCompactLiveClosure prepare_compact(cp); + G1PrepareCompactLiveClosure prepare_compact(_cp); hr->apply_to_marked_objects(_bitmap, &prepare_compact); } } - -void G1FullGCPrepareTask::G1CalculatePointersClosure::prepare_for_compaction(HeapRegion* hr) { - if (!_cp->is_initialized()) { - hr->set_compaction_top(hr->bottom()); - _cp->initialize(hr, true); - } - // Add region to the compaction queue and prepare it. - _cp->add(hr); - prepare_for_compaction_work(_cp, hr); -} - -void G1FullGCPrepareTask::prepare_serial_compaction() { - GCTraceTime(Debug, gc, phases) debug("Phase 2: Prepare Serial Compaction", collector()->scope()->timer()); - // At this point we know that no regions were completely freed by - // the parallel compaction. That means that the last region of - // all compaction queues still have data in them. We try to compact - // these regions in serial to avoid a premature OOM. - for (uint i = 0; i < collector()->workers(); i++) { - G1FullGCCompactionPoint* cp = collector()->compaction_point(i); - if (cp->has_regions()) { - collector()->serial_compaction_point()->add(cp->remove_last()); - } - } - - // Update the forwarding information for the regions in the serial - // compaction point. - G1FullGCCompactionPoint* cp = collector()->serial_compaction_point(); - for (GrowableArrayIterator it = cp->regions()->begin(); it != cp->regions()->end(); ++it) { - HeapRegion* current = *it; - if (!cp->is_initialized()) { - // Initialize the compaction point. Nothing more is needed for the first heap region - // since it is already prepared for compaction. - cp->initialize(current, false); - } else { - assert(!current->is_humongous(), "Should be no humongous regions in compaction queue"); - G1RePrepareClosure re_prepare(cp, current); - current->set_compaction_top(current->bottom()); - current->apply_to_marked_objects(collector()->mark_bitmap(), &re_prepare); - } - } - cp->update(); -} - -bool G1FullGCPrepareTask::G1CalculatePointersClosure::freed_regions() { - if (_regions_freed) { - return true; - } - - if (!_cp->has_regions()) { - // No regions in queue, so no free ones either. - return false; - } - - if (_cp->current_region() != _cp->regions()->last()) { - // The current region used for compaction is not the last in the - // queue. That means there is at least one free region in the queue. - return true; - } - - // No free regions in the queue. - return false; -} diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp index d694fc6ffca..41c0c67d87c 100644 --- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -25,53 +25,81 @@ #ifndef SHARE_GC_G1_G1FULLGCPREPARETASK_HPP #define SHARE_GC_G1_G1FULLGCPREPARETASK_HPP -#include "gc/g1/g1FullGCCompactionPoint.hpp" -#include "gc/g1/g1FullGCScope.hpp" #include "gc/g1/g1FullGCTask.hpp" -#include "gc/g1/g1RootProcessor.hpp" -#include "gc/g1/heapRegionManager.hpp" -#include "gc/shared/referenceProcessor.hpp" +#include "gc/g1/heapRegion.hpp" +#include "memory/allocation.hpp" +class G1CollectedHeap; class G1CMBitMap; class G1FullCollector; +class G1FullGCCompactionPoint; +class HeapRegion; + +// Determines the regions in the heap that should be part of the compaction and +// distributes them among the compaction queues in round-robin fashion. +class G1DetermineCompactionQueueClosure : public HeapRegionClosure { + G1CollectedHeap* _g1h; + G1FullCollector* _collector; + uint _cur_worker; + + template + inline void free_pinned_region(HeapRegion* hr); + + inline bool should_compact(HeapRegion* hr) const; + + // Returns the current worker id to assign a compaction point to, and selects + // the next one round-robin style. + inline uint next_worker(); + + inline G1FullGCCompactionPoint* next_compaction_point(); + + inline void add_to_compaction_queue(HeapRegion* hr); + +public: + G1DetermineCompactionQueueClosure(G1FullCollector* collector); + + inline bool do_heap_region(HeapRegion* hr) override; +}; class G1FullGCPrepareTask : public G1FullGCTask { -protected: - volatile bool _freed_regions; + volatile bool _has_free_compaction_targets; HeapRegionClaimer _hrclaimer; - void set_freed_regions(); + void set_has_free_compaction_targets(); public: G1FullGCPrepareTask(G1FullCollector* collector); void work(uint worker_id); - void prepare_serial_compaction(); - bool has_freed_regions(); + // After the Prepare phase, are there any unused (empty) regions (compaction + // targets) at the end of any compaction queues? + bool has_free_compaction_targets(); -protected: +private: class G1CalculatePointersClosure : public HeapRegionClosure { - private: - template - void free_pinned_region(HeapRegion* hr); - protected: G1CollectedHeap* _g1h; G1FullCollector* _collector; G1CMBitMap* _bitmap; G1FullGCCompactionPoint* _cp; - bool _regions_freed; - bool should_compact(HeapRegion* hr); void prepare_for_compaction(HeapRegion* hr); - void prepare_for_compaction_work(G1FullGCCompactionPoint* cp, HeapRegion* hr); - - void reset_region_metadata(HeapRegion* hr); public: G1CalculatePointersClosure(G1FullCollector* collector, G1FullGCCompactionPoint* cp); bool do_heap_region(HeapRegion* hr); - bool freed_regions(); + }; + + class G1ResetMetadataClosure : public HeapRegionClosure { + G1CollectedHeap* _g1h; + G1FullCollector* _collector; + + void reset_region_metadata(HeapRegion* hr); + + public: + G1ResetMetadataClosure(G1FullCollector* collector); + + bool do_heap_region(HeapRegion* hr); }; class G1PrepareCompactLiveClosure : public StackObj { @@ -81,19 +109,20 @@ protected: G1PrepareCompactLiveClosure(G1FullGCCompactionPoint* cp); size_t apply(oop object); }; +}; - class G1RePrepareClosure : public StackObj { - G1FullGCCompactionPoint* _cp; - HeapRegion* _current; +// Closure to re-prepare objects in the serial compaction point queue regions for +// serial compaction. +class G1SerialRePrepareClosure : public StackObj { + G1FullGCCompactionPoint* _cp; + HeapRegion* _current; - public: - G1RePrepareClosure(G1FullGCCompactionPoint* hrcp, - HeapRegion* hr) : - _cp(hrcp), - _current(hr) { } +public: + G1SerialRePrepareClosure(G1FullGCCompactionPoint* hrcp, HeapRegion* hr) : + _cp(hrcp), + _current(hr) { } - size_t apply(oop object); - }; + inline size_t apply(oop obj); }; #endif // SHARE_GC_G1_G1FULLGCPREPARETASK_HPP diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp new file mode 100644 index 00000000000..75493b7de4f --- /dev/null +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp @@ -0,0 +1,126 @@ +/* + * 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. + * + * 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_G1_G1FULLGCPREPARETASK_INLINE_HPP +#define SHARE_GC_G1_G1FULLGCPREPARETASK_INLINE_HPP + +#include "gc/g1/g1FullGCPrepareTask.hpp" + +#include "gc/g1/g1CollectedHeap.inline.hpp" +#include "gc/g1/g1FullCollector.hpp" +#include "gc/g1/g1FullGCCompactionPoint.hpp" +#include "gc/g1/g1FullGCScope.hpp" +#include "gc/g1/heapRegion.inline.hpp" + +template +void G1DetermineCompactionQueueClosure::free_pinned_region(HeapRegion* hr) { + if (is_humongous) { + _g1h->free_humongous_region(hr, nullptr); + } else { + _g1h->free_region(hr, nullptr); + } + _collector->set_free(hr->hrm_index()); + add_to_compaction_queue(hr); +} + +inline bool G1DetermineCompactionQueueClosure::should_compact(HeapRegion* hr) const { + // There is no need to iterate and forward objects in pinned regions ie. + // prepare them for compaction. + if (hr->is_pinned()) { + return false; + } + size_t live_words = _collector->live_words(hr->hrm_index()); + size_t live_words_threshold = _collector->scope()->region_compaction_threshold(); + // High live ratio region will not be compacted. + return live_words <= live_words_threshold; +} + +inline uint G1DetermineCompactionQueueClosure::next_worker() { + uint result = _cur_worker; + _cur_worker = (_cur_worker + 1) % _collector->workers(); + return result; +} + +inline G1FullGCCompactionPoint* G1DetermineCompactionQueueClosure::next_compaction_point() { + return _collector->compaction_point(next_worker()); +} + +inline void G1DetermineCompactionQueueClosure::add_to_compaction_queue(HeapRegion* hr) { + hr->set_compaction_top(hr->bottom()); + G1FullGCCompactionPoint* cp = next_compaction_point(); + if (!cp->is_initialized()) { + cp->initialize(hr, true); + } + // Add region to the compaction queue. + cp->add(hr); +} + +inline bool G1DetermineCompactionQueueClosure::do_heap_region(HeapRegion* hr) { + if (should_compact(hr)) { + assert(!hr->is_humongous(), "moving humongous objects not supported."); + add_to_compaction_queue(hr); + } else { + assert(hr->containing_set() == nullptr, "already cleared by PrepareRegionsClosure"); + if (hr->is_humongous()) { + oop obj = cast_to_oop(hr->humongous_start_region()->bottom()); + bool is_empty = !_collector->mark_bitmap()->is_marked(obj); + if (is_empty) { + free_pinned_region(hr); + } + } else if (hr->is_open_archive()) { + bool is_empty = _collector->live_words(hr->hrm_index()) == 0; + if (is_empty) { + free_pinned_region(hr); + } + } else if (hr->is_closed_archive()) { + // nothing to do with closed archive region + } else { + assert(MarkSweepDeadRatio > 0, + "only skip compaction for other regions when MarkSweepDeadRatio > 0"); + + // Too many live objects in the region; skip compacting it. + _collector->update_from_compacting_to_skip_compacting(hr->hrm_index()); + log_trace(gc, phases)("Phase 2: skip compaction region index: %u, live words: " SIZE_FORMAT, + hr->hrm_index(), _collector->live_words(hr->hrm_index())); + } + } + + return false; +} + +inline size_t G1SerialRePrepareClosure::apply(oop obj) { + // We only re-prepare objects forwarded within the current region, so + // skip objects that are already forwarded to another region. + if (obj->is_forwarded() && !_current->is_in(obj->forwardee())) { + return obj->size(); + } + + // Get size and forward. + size_t size = obj->size(); + _cp->forward(obj, size); + + return size; +} + +#endif // SHARE_GC_G1_G1FULLGCPREPARETASK_INLINE_HPP diff --git a/src/hotspot/share/gc/g1/g1FullGCScope.cpp b/src/hotspot/share/gc/g1/g1FullGCScope.cpp index b4d3b365603..0437d157eb0 100644 --- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -70,6 +70,6 @@ G1FullGCTracer* G1FullGCScope::tracer() { return &_tracer; } -size_t G1FullGCScope::region_compaction_threshold() { +size_t G1FullGCScope::region_compaction_threshold() const { return _region_compaction_threshold; } diff --git a/src/hotspot/share/gc/g1/g1FullGCScope.hpp b/src/hotspot/share/gc/g1/g1FullGCScope.hpp index c0035b9052a..a6e079f4d63 100644 --- a/src/hotspot/share/gc/g1/g1FullGCScope.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCScope.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -71,7 +71,7 @@ public: STWGCTimer* timer(); G1FullGCTracer* tracer(); G1HeapTransition* heap_transition(); - size_t region_compaction_threshold(); + size_t region_compaction_threshold() const; }; #endif // SHARE_GC_G1_G1FULLGCSCOPE_HPP -- GitLab From 2155afe2a87d718757b009d712361d7a63946a7f Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Tue, 25 Jan 2022 09:15:11 +0000 Subject: [PATCH 018/400] 8280503: Use allStatic.hpp instead of allocation.hpp where possible Reviewed-by: dholmes, iklam --- src/hotspot/cpu/aarch64/bytes_aarch64.hpp | 4 ++-- src/hotspot/cpu/aarch64/jniTypes_aarch64.hpp | 4 ++-- src/hotspot/cpu/arm/bytes_arm.hpp | 4 ++-- src/hotspot/cpu/arm/jniTypes_arm.hpp | 4 ++-- src/hotspot/cpu/ppc/bytes_ppc.hpp | 6 +++--- src/hotspot/cpu/ppc/jniTypes_ppc.hpp | 6 +++--- src/hotspot/cpu/s390/bytes_s390.hpp | 6 +++--- src/hotspot/cpu/s390/jniTypes_s390.hpp | 4 ++-- src/hotspot/cpu/x86/bytes_x86.hpp | 4 ++-- src/hotspot/cpu/x86/c2_intelJccErratum_x86.hpp | 4 ++-- src/hotspot/cpu/x86/jniTypes_x86.hpp | 4 ++-- src/hotspot/cpu/x86/rdtsc_x86.hpp | 5 +++-- src/hotspot/cpu/zero/bytes_zero.hpp | 4 ++-- src/hotspot/cpu/zero/jniTypes_zero.hpp | 4 ++-- src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp | 1 + src/hotspot/os/linux/gc/z/zSyscall_linux.hpp | 5 +++-- src/hotspot/os/linux/osContainer_linux.hpp | 4 ++-- src/hotspot/os/posix/signals_posix.hpp | 4 ++-- src/hotspot/os/posix/threadLocalStorage_posix.cpp | 3 ++- src/hotspot/os/windows/gc/z/zMapper_windows.hpp | 2 +- src/hotspot/os/windows/iphlp_interface.hpp | 4 ++-- src/hotspot/os/windows/pdh_interface.hpp | 4 ++-- src/hotspot/os/windows/threadLocalStorage_windows.cpp | 1 + src/hotspot/share/c1/c1_Runtime1.hpp | 4 ++-- src/hotspot/share/cds/archiveUtils.cpp | 4 +++- src/hotspot/share/cds/dynamicArchive.hpp | 4 ++-- src/hotspot/share/classfile/altHashing.hpp | 5 +++-- src/hotspot/share/classfile/klassFactory.hpp | 4 ++-- src/hotspot/share/classfile/modules.hpp | 4 ++-- src/hotspot/share/code/vtableStubs.hpp | 4 ++-- src/hotspot/share/compiler/compilerDefinitions.hpp | 4 ++-- src/hotspot/share/compiler/compilerEvent.hpp | 4 ++-- src/hotspot/share/compiler/compilerOracle.hpp | 4 ++-- src/hotspot/share/gc/g1/g1CollectionSetChooser.hpp | 4 ++-- src/hotspot/share/gc/g1/g1FromCardCache.hpp | 4 ++-- src/hotspot/share/gc/g1/g1HeapRegionEventSender.hpp | 4 ++-- src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp | 4 ++-- src/hotspot/share/gc/g1/heapRegionBounds.hpp | 5 +++-- src/hotspot/share/gc/g1/heapRegionTracer.hpp | 5 +++-- src/hotspot/share/gc/g1/heapRegionType.hpp | 3 ++- src/hotspot/share/gc/parallel/psRootType.hpp | 4 ++-- src/hotspot/share/gc/parallel/psScavenge.hpp | 4 ++-- src/hotspot/share/gc/shared/accessBarrierSupport.hpp | 4 ++-- src/hotspot/share/gc/shared/ageTableTracer.hpp | 5 +++-- src/hotspot/share/gc/shared/allocTracer.hpp | 4 ++-- src/hotspot/share/gc/shared/blockOffsetTable.hpp | 4 ++-- src/hotspot/share/gc/shared/concurrentGCBreakpoints.hpp | 4 ++-- src/hotspot/share/gc/shared/gcCause.hpp | 5 +++-- src/hotspot/share/gc/shared/gcConfig.hpp | 2 +- src/hotspot/share/gc/shared/gcLocker.hpp | 4 ++-- src/hotspot/share/gc/shared/gcLogPrecious.hpp | 2 +- src/hotspot/share/gc/shared/gcWhen.hpp | 4 ++-- src/hotspot/share/gc/shared/locationPrinter.hpp | 2 +- src/hotspot/share/gc/shared/objectCountEventSender.hpp | 4 ++-- src/hotspot/share/gc/shared/scavengableNMethods.hpp | 4 ++-- src/hotspot/share/gc/shared/spaceDecorator.hpp | 4 ++-- src/hotspot/share/gc/shared/weakProcessor.hpp | 4 ++-- src/hotspot/share/gc/shared/workerPolicy.hpp | 4 ++-- src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.hpp | 6 +++--- src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp | 4 ++-- src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp | 4 ++-- src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp | 4 ++-- src/hotspot/share/gc/z/zAbort.hpp | 4 ++-- src/hotspot/share/gc/z/zAddress.hpp | 5 +++-- src/hotspot/share/gc/z/zAddressSpaceLimit.hpp | 5 +++-- src/hotspot/share/gc/z/zBarrier.hpp | 4 ++-- src/hotspot/share/gc/z/zBarrierSetRuntime.hpp | 2 +- src/hotspot/share/gc/z/zBitField.hpp | 5 +++-- src/hotspot/share/gc/z/zBreakpoint.hpp | 4 ++-- src/hotspot/share/gc/z/zCPU.hpp | 4 ++-- src/hotspot/share/gc/z/zHash.hpp | 4 ++-- src/hotspot/share/gc/z/zHeuristics.hpp | 4 ++-- src/hotspot/share/gc/z/zLargePages.hpp | 4 ++-- src/hotspot/share/gc/z/zNMethod.hpp | 4 ++-- src/hotspot/share/gc/z/zNMethodTable.hpp | 4 ++-- src/hotspot/share/gc/z/zNUMA.hpp | 5 +++-- src/hotspot/share/gc/z/zOop.hpp | 4 ++-- src/hotspot/share/gc/z/zResurrection.hpp | 4 ++-- src/hotspot/share/gc/z/zThread.hpp | 4 ++-- src/hotspot/share/gc/z/zThreadLocalAllocBuffer.hpp | 4 ++-- src/hotspot/share/gc/z/zUtils.hpp | 5 +++-- src/hotspot/share/gc/z/zValue.hpp | 4 ++-- src/hotspot/share/gc/z/zVerify.hpp | 4 ++-- src/hotspot/share/interpreter/bytecodeHistogram.hpp | 4 ++-- src/hotspot/share/interpreter/bytecodeTracer.hpp | 4 ++-- src/hotspot/share/interpreter/bytecodeUtils.hpp | 6 +++--- src/hotspot/share/interpreter/bytecodes.hpp | 5 +++-- src/hotspot/share/interpreter/templateTable.hpp | 4 ++-- .../share/jfr/instrumentation/jfrEventClassTransformer.hpp | 4 ++-- src/hotspot/share/jfr/jfr.hpp | 6 ++++-- src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.hpp | 4 ++-- .../jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp | 4 ++-- .../share/jfr/leakprofiler/checkpoint/rootResolver.hpp | 4 ++-- src/hotspot/share/jfr/leakprofiler/leakProfiler.hpp | 5 +++-- .../share/jfr/leakprofiler/utilities/granularTimer.hpp | 4 ++-- src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp | 4 ++-- .../share/jfr/periodic/jfrFinalizerStatisticsEvent.hpp | 4 ++-- src/hotspot/share/jfr/periodic/jfrModuleEvent.hpp | 4 ++-- src/hotspot/share/jfr/periodic/jfrNetworkUtilization.hpp | 4 ++-- src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.hpp | 4 ++-- src/hotspot/share/jfr/periodic/jfrThreadDumpEvent.hpp | 4 ++-- .../share/jfr/recorder/checkpoint/jfrMetadataEvent.hpp | 4 ++-- .../share/jfr/recorder/checkpoint/types/jfrThreadState.hpp | 4 ++-- .../jfr/recorder/checkpoint/types/traceid/jfrTraceId.hpp | 4 ++-- .../recorder/checkpoint/types/traceid/jfrTraceIdBits.hpp | 2 +- .../recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp | 4 ++-- .../checkpoint/types/traceid/jfrTraceIdLoadBarrier.hpp | 4 ++-- .../share/jfr/recorder/repository/jfrChunkRotation.hpp | 4 ++-- .../share/jfr/recorder/repository/jfrEmergencyDump.hpp | 4 ++-- src/hotspot/share/jfr/recorder/service/jfrMemorySizer.hpp | 4 ++-- src/hotspot/share/jfr/recorder/service/jfrOptionSet.hpp | 4 ++-- .../share/jfr/recorder/service/jfrRecorderThread.hpp | 4 ++-- src/hotspot/share/jfr/support/jfrJdkJfrEvent.hpp | 4 ++-- src/hotspot/share/jfr/support/jfrKlassUnloading.hpp | 4 ++-- src/hotspot/share/jfr/support/jfrMethodLookup.hpp | 2 +- src/hotspot/share/jfr/support/jfrObjectAllocationSample.hpp | 4 ++-- src/hotspot/share/jfr/utilities/jfrBigEndian.hpp | 4 ++-- src/hotspot/share/jfr/utilities/jfrJavaLog.hpp | 4 ++-- src/hotspot/share/jfr/utilities/jfrPredicate.hpp | 4 ++-- src/hotspot/share/jfr/utilities/jfrTimeConverter.hpp | 4 ++-- src/hotspot/share/jfr/writers/jfrEncoding.hpp | 4 ++-- src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp | 4 ++-- src/hotspot/share/logging/logConfiguration.hpp | 5 +++-- src/hotspot/share/logging/logLevel.hpp | 5 +++-- src/hotspot/share/logging/logTag.hpp | 6 ++++-- src/hotspot/share/memory/metaspace/internalStats.hpp | 6 +++--- src/hotspot/share/memory/metaspace/metaspaceReporter.hpp | 6 +++--- src/hotspot/share/memory/metaspace/metaspaceSettings.hpp | 6 +++--- src/hotspot/share/memory/metaspace/runningCounters.hpp | 6 +++--- src/hotspot/share/memory/metaspaceCounters.hpp | 4 ++-- src/hotspot/share/memory/metaspaceCriticalAllocation.hpp | 2 +- src/hotspot/share/metaprogramming/conditional.hpp | 4 ++-- src/hotspot/share/metaprogramming/decay.hpp | 4 ++-- src/hotspot/share/metaprogramming/removeCV.hpp | 4 ++-- src/hotspot/share/metaprogramming/removeExtent.hpp | 4 ++-- src/hotspot/share/metaprogramming/removePointer.hpp | 4 ++-- src/hotspot/share/metaprogramming/removeReference.hpp | 4 ++-- src/hotspot/share/oops/access.hpp | 4 ++-- src/hotspot/share/oops/accessDecorators.hpp | 4 ++-- src/hotspot/share/oops/compressedOops.hpp | 4 ++-- src/hotspot/share/prims/jniFastGetField.hpp | 4 ++-- src/hotspot/share/prims/jvmtiEventController.hpp | 4 ++-- src/hotspot/share/prims/jvmtiExtensions.hpp | 4 ++-- src/hotspot/share/prims/jvmtiManageCapabilities.hpp | 4 ++-- src/hotspot/share/prims/nativeLookup.hpp | 4 ++-- src/hotspot/share/prims/resolvedMethodTable.hpp | 4 ++-- src/hotspot/share/prims/vectorSupport.hpp | 4 ++-- src/hotspot/share/runtime/abstract_vm_version.hpp | 4 ++-- src/hotspot/share/runtime/arguments.hpp | 4 ++-- src/hotspot/share/runtime/handshake.hpp | 4 ++-- src/hotspot/share/runtime/icache.hpp | 4 ++-- src/hotspot/share/runtime/jniHandles.hpp | 4 ++-- src/hotspot/share/runtime/orderAccess.hpp | 4 ++-- src/hotspot/share/runtime/prefetch.hpp | 4 ++-- src/hotspot/share/runtime/reflectionUtils.hpp | 4 ++-- src/hotspot/share/runtime/safepoint.hpp | 2 +- src/hotspot/share/runtime/sharedRuntime.hpp | 4 ++-- src/hotspot/share/runtime/stackWatermark.hpp | 4 ++-- src/hotspot/share/runtime/threadLocalStorage.hpp | 4 ++-- src/hotspot/share/services/attachListener.hpp | 4 ++-- src/hotspot/share/services/gcNotifier.hpp | 4 ++-- src/hotspot/share/services/lowMemoryDetector.hpp | 4 ++-- src/hotspot/share/services/nmtCommon.hpp | 4 ++-- src/hotspot/share/services/threadIdTable.hpp | 2 +- src/hotspot/share/utilities/decoder.hpp | 4 ++-- src/hotspot/share/utilities/globalCounter.hpp | 4 ++-- src/hotspot/share/utilities/quickSort.hpp | 4 ++-- src/hotspot/share/utilities/stringUtils.cpp | 4 +++- src/hotspot/share/utilities/stringUtils.hpp | 4 ++-- src/hotspot/share/utilities/utf8.cpp | 6 +++++- src/hotspot/share/utilities/utf8.hpp | 6 ++++-- test/hotspot/gtest/classfile/test_AltHashing.cpp | 3 ++- 172 files changed, 368 insertions(+), 333 deletions(-) diff --git a/src/hotspot/cpu/aarch64/bytes_aarch64.hpp b/src/hotspot/cpu/aarch64/bytes_aarch64.hpp index acb2e493a9a..672f03b93a9 100644 --- a/src/hotspot/cpu/aarch64/bytes_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/bytes_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,7 +26,7 @@ #ifndef CPU_AARCH64_BYTES_AARCH64_HPP #define CPU_AARCH64_BYTES_AARCH64_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class Bytes: AllStatic { public: diff --git a/src/hotspot/cpu/aarch64/jniTypes_aarch64.hpp b/src/hotspot/cpu/aarch64/jniTypes_aarch64.hpp index 4254cdf4cfd..8d20a6a1701 100644 --- a/src/hotspot/cpu/aarch64/jniTypes_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/jniTypes_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -27,7 +27,7 @@ #define CPU_AARCH64_JNITYPES_AARCH64_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" // This file holds platform-dependent routines used to write primitive jni diff --git a/src/hotspot/cpu/arm/bytes_arm.hpp b/src/hotspot/cpu/arm/bytes_arm.hpp index b0d481f314d..34af43edcac 100644 --- a/src/hotspot/cpu/arm/bytes_arm.hpp +++ b/src/hotspot/cpu/arm/bytes_arm.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -25,7 +25,7 @@ #ifndef CPU_ARM_BYTES_ARM_HPP #define CPU_ARM_BYTES_ARM_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/macros.hpp" #ifndef VM_LITTLE_ENDIAN diff --git a/src/hotspot/cpu/arm/jniTypes_arm.hpp b/src/hotspot/cpu/arm/jniTypes_arm.hpp index 66596eac1a0..660e58110f8 100644 --- a/src/hotspot/cpu/arm/jniTypes_arm.hpp +++ b/src/hotspot/cpu/arm/jniTypes_arm.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -26,7 +26,7 @@ #define CPU_ARM_JNITYPES_ARM_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" // This file holds platform-dependent routines used to write primitive jni diff --git a/src/hotspot/cpu/ppc/bytes_ppc.hpp b/src/hotspot/cpu/ppc/bytes_ppc.hpp index 8249068ecd6..a4d061e9b73 100644 --- a/src/hotspot/cpu/ppc/bytes_ppc.hpp +++ b/src/hotspot/cpu/ppc/bytes_ppc.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2016 SAP SE. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022 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 @@ -26,7 +26,7 @@ #ifndef CPU_PPC_BYTES_PPC_HPP #define CPU_PPC_BYTES_PPC_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class Bytes: AllStatic { public: diff --git a/src/hotspot/cpu/ppc/jniTypes_ppc.hpp b/src/hotspot/cpu/ppc/jniTypes_ppc.hpp index ef1fe4acfdf..13ccaf408e9 100644 --- a/src/hotspot/cpu/ppc/jniTypes_ppc.hpp +++ b/src/hotspot/cpu/ppc/jniTypes_ppc.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2013 SAP SE. All rights reserved. + * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022 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 @@ -27,7 +27,7 @@ #define CPU_PPC_JNITYPES_PPC_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" // This file holds platform-dependent routines used to write primitive diff --git a/src/hotspot/cpu/s390/bytes_s390.hpp b/src/hotspot/cpu/s390/bytes_s390.hpp index f6882f980ab..9b4d7b04221 100644 --- a/src/hotspot/cpu/s390/bytes_s390.hpp +++ b/src/hotspot/cpu/s390/bytes_s390.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2018 SAP SE. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022 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 @@ -26,7 +26,7 @@ #ifndef CPU_S390_BYTES_S390_HPP #define CPU_S390_BYTES_S390_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class Bytes: AllStatic { public: diff --git a/src/hotspot/cpu/s390/jniTypes_s390.hpp b/src/hotspot/cpu/s390/jniTypes_s390.hpp index 56f4a05c6d4..951e7f5f6d2 100644 --- a/src/hotspot/cpu/s390/jniTypes_s390.hpp +++ b/src/hotspot/cpu/s390/jniTypes_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -30,7 +30,7 @@ // jni types to the array of arguments passed into JavaCalls::call. #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" class JNITypes : AllStatic { diff --git a/src/hotspot/cpu/x86/bytes_x86.hpp b/src/hotspot/cpu/x86/bytes_x86.hpp index 4ce19a473b4..cb5987d2c82 100644 --- a/src/hotspot/cpu/x86/bytes_x86.hpp +++ b/src/hotspot/cpu/x86/bytes_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,7 +25,7 @@ #ifndef CPU_X86_BYTES_X86_HPP #define CPU_X86_BYTES_X86_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/align.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/cpu/x86/c2_intelJccErratum_x86.hpp b/src/hotspot/cpu/x86/c2_intelJccErratum_x86.hpp index f3f66f3d7bc..415d8a99933 100644 --- a/src/hotspot/cpu/x86/c2_intelJccErratum_x86.hpp +++ b/src/hotspot/cpu/x86/c2_intelJccErratum_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -25,7 +25,7 @@ #ifndef CPU_X86_INTELJCCERRATUM_X86_HPP #define CPU_X86_INTELJCCERRATUM_X86_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class Block; diff --git a/src/hotspot/cpu/x86/jniTypes_x86.hpp b/src/hotspot/cpu/x86/jniTypes_x86.hpp index 403a0b63e2b..5c925474796 100644 --- a/src/hotspot/cpu/x86/jniTypes_x86.hpp +++ b/src/hotspot/cpu/x86/jniTypes_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -26,7 +26,7 @@ #define CPU_X86_JNITYPES_X86_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" // This file holds platform-dependent routines used to write primitive jni diff --git a/src/hotspot/cpu/x86/rdtsc_x86.hpp b/src/hotspot/cpu/x86/rdtsc_x86.hpp index f66997c9cfe..d9e77a0ae6b 100644 --- a/src/hotspot/cpu/x86/rdtsc_x86.hpp +++ b/src/hotspot/cpu/x86/rdtsc_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,7 +25,8 @@ #ifndef CPU_X86_RDTSC_X86_HPP #define CPU_X86_RDTSC_X86_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" // Interface to the x86 rdtsc() time counter, if available. diff --git a/src/hotspot/cpu/zero/bytes_zero.hpp b/src/hotspot/cpu/zero/bytes_zero.hpp index 9acd9dd2430..93d49b8a28d 100644 --- a/src/hotspot/cpu/zero/bytes_zero.hpp +++ b/src/hotspot/cpu/zero/bytes_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2009 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,7 +26,7 @@ #ifndef CPU_ZERO_BYTES_ZERO_HPP #define CPU_ZERO_BYTES_ZERO_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" typedef union unaligned { u4 u; diff --git a/src/hotspot/cpu/zero/jniTypes_zero.hpp b/src/hotspot/cpu/zero/jniTypes_zero.hpp index 8d5a6bee7fa..9f6fe78005b 100644 --- a/src/hotspot/cpu/zero/jniTypes_zero.hpp +++ b/src/hotspot/cpu/zero/jniTypes_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -26,7 +26,7 @@ #define CPU_ZERO_JNITYPES_ZERO_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" // This file holds platform-dependent routines used to write primitive jni diff --git a/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp b/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp index a0fe34c6504..e5b3895c44e 100644 --- a/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp +++ b/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp @@ -23,6 +23,7 @@ #include "precompiled.hpp" #include "gc/z/zNUMA.hpp" +#include "utilities/globalDefinitions.hpp" void ZNUMA::pd_initialize() { _enabled = false; diff --git a/src/hotspot/os/linux/gc/z/zSyscall_linux.hpp b/src/hotspot/os/linux/gc/z/zSyscall_linux.hpp index 95b13841b2a..1e1becf5a14 100644 --- a/src/hotspot/os/linux/gc/z/zSyscall_linux.hpp +++ b/src/hotspot/os/linux/gc/z/zSyscall_linux.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -24,7 +24,8 @@ #ifndef OS_LINUX_GC_Z_ZSYSCALL_LINUX_HPP #define OS_LINUX_GC_Z_ZSYSCALL_LINUX_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" // Flags for get_mempolicy() #ifndef MPOL_F_NODE diff --git a/src/hotspot/os/linux/osContainer_linux.hpp b/src/hotspot/os/linux/osContainer_linux.hpp index 940bc0e3874..1ba4a9dabdc 100644 --- a/src/hotspot/os/linux/osContainer_linux.hpp +++ b/src/hotspot/os/linux/osContainer_linux.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -27,7 +27,7 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #define OSCONTAINER_ERROR (-2) diff --git a/src/hotspot/os/posix/signals_posix.hpp b/src/hotspot/os/posix/signals_posix.hpp index 373a02ff3a3..2efdb374c4e 100644 --- a/src/hotspot/os/posix/signals_posix.hpp +++ b/src/hotspot/os/posix/signals_posix.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -25,7 +25,7 @@ #ifndef OS_POSIX_SIGNALS_POSIX_HPP #define OS_POSIX_SIGNALS_POSIX_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class outputStream; diff --git a/src/hotspot/os/posix/threadLocalStorage_posix.cpp b/src/hotspot/os/posix/threadLocalStorage_posix.cpp index cc703ef811f..25bbbe2244f 100644 --- a/src/hotspot/os/posix/threadLocalStorage_posix.cpp +++ b/src/hotspot/os/posix/threadLocalStorage_posix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -23,6 +23,7 @@ */ #include "runtime/threadLocalStorage.hpp" +#include "utilities/debug.hpp" #include static pthread_key_t _thread_key; diff --git a/src/hotspot/os/windows/gc/z/zMapper_windows.hpp b/src/hotspot/os/windows/gc/z/zMapper_windows.hpp index 4db80c89956..3e47b470f5f 100644 --- a/src/hotspot/os/windows/gc/z/zMapper_windows.hpp +++ b/src/hotspot/os/windows/gc/z/zMapper_windows.hpp @@ -24,7 +24,7 @@ #ifndef OS_WINDOWS_GC_Z_ZMAPPER_WINDOWS_HPP #define OS_WINDOWS_GC_Z_ZMAPPER_WINDOWS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" #include diff --git a/src/hotspot/os/windows/iphlp_interface.hpp b/src/hotspot/os/windows/iphlp_interface.hpp index 0ebe971a5f1..3e7e0adef65 100644 --- a/src/hotspot/os/windows/iphlp_interface.hpp +++ b/src/hotspot/os/windows/iphlp_interface.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -25,7 +25,7 @@ #ifndef OS_WINDOWS_IPHLP_INTERFACE_HPP #define OS_WINDOWS_IPHLP_INTERFACE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/macros.hpp" #include #include diff --git a/src/hotspot/os/windows/pdh_interface.hpp b/src/hotspot/os/windows/pdh_interface.hpp index 743c737d998..151f9edd0e9 100644 --- a/src/hotspot/os/windows/pdh_interface.hpp +++ b/src/hotspot/os/windows/pdh_interface.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,7 +25,7 @@ #ifndef OS_WINDOWS_PDH_INTERFACE_HPP #define OS_WINDOWS_PDH_INTERFACE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include #include diff --git a/src/hotspot/os/windows/threadLocalStorage_windows.cpp b/src/hotspot/os/windows/threadLocalStorage_windows.cpp index 5648a672d71..7d809518aab 100644 --- a/src/hotspot/os/windows/threadLocalStorage_windows.cpp +++ b/src/hotspot/os/windows/threadLocalStorage_windows.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "runtime/threadLocalStorage.hpp" +#include "utilities/debug.hpp" #include static DWORD _thread_key; diff --git a/src/hotspot/share/c1/c1_Runtime1.hpp b/src/hotspot/share/c1/c1_Runtime1.hpp index 9212a4fb249..3dcb27476a6 100644 --- a/src/hotspot/share/c1/c1_Runtime1.hpp +++ b/src/hotspot/share/c1/c1_Runtime1.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -28,7 +28,7 @@ #include "c1/c1_FrameMap.hpp" #include "code/stubs.hpp" #include "interpreter/interpreter.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/deoptimization.hpp" class StubAssembler; diff --git a/src/hotspot/share/cds/archiveUtils.cpp b/src/hotspot/share/cds/archiveUtils.cpp index 8c273c06a8d..27c94290c23 100644 --- a/src/hotspot/share/cds/archiveUtils.cpp +++ b/src/hotspot/share/cds/archiveUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -39,7 +39,9 @@ #include "oops/compressedOops.inline.hpp" #include "runtime/arguments.hpp" #include "utilities/bitMap.inline.hpp" +#include "utilities/debug.hpp" #include "utilities/formatBuffer.hpp" +#include "utilities/globalDefinitions.hpp" CHeapBitMap* ArchivePtrMarker::_ptrmap = NULL; VirtualSpace* ArchivePtrMarker::_vs; diff --git a/src/hotspot/share/cds/dynamicArchive.hpp b/src/hotspot/share/cds/dynamicArchive.hpp index fbb831ae195..ec8a505978b 100644 --- a/src/hotspot/share/cds/dynamicArchive.hpp +++ b/src/hotspot/share/cds/dynamicArchive.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -27,7 +27,7 @@ #include "cds/filemap.hpp" #include "classfile/compactHashtable.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/memRegion.hpp" #include "memory/virtualspace.hpp" #include "oops/oop.hpp" diff --git a/src/hotspot/share/classfile/altHashing.hpp b/src/hotspot/share/classfile/altHashing.hpp index f2fc52410d1..555720c0666 100644 --- a/src/hotspot/share/classfile/altHashing.hpp +++ b/src/hotspot/share/classfile/altHashing.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -26,7 +26,8 @@ #define SHARE_CLASSFILE_ALTHASHING_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" /** * Implementation of alternate more secure hashing. diff --git a/src/hotspot/share/classfile/klassFactory.hpp b/src/hotspot/share/classfile/klassFactory.hpp index 2b2ee36dfa3..b1584b3e2ca 100644 --- a/src/hotspot/share/classfile/klassFactory.hpp +++ b/src/hotspot/share/classfile/klassFactory.hpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2015, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_CLASSFILE_KLASSFACTORY_HPP #define SHARE_CLASSFILE_KLASSFACTORY_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/handles.hpp" class ClassFileStream; diff --git a/src/hotspot/share/classfile/modules.hpp b/src/hotspot/share/classfile/modules.hpp index 31cab8209fa..5c52a323b0c 100644 --- a/src/hotspot/share/classfile/modules.hpp +++ b/src/hotspot/share/classfile/modules.hpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2016, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_CLASSFILE_MODULES_HPP #define SHARE_CLASSFILE_MODULES_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/handles.hpp" class ModuleEntryTable; diff --git a/src/hotspot/share/code/vtableStubs.hpp b/src/hotspot/share/code/vtableStubs.hpp index 8fc2bdae94c..9498ad7d329 100644 --- a/src/hotspot/share/code/vtableStubs.hpp +++ b/src/hotspot/share/code/vtableStubs.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -27,7 +27,7 @@ #include "asm/macroAssembler.hpp" #include "code/vmreg.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // A VtableStub holds an individual code stub for a pair (vtable index, #args) for either itables or vtables // There's a one-to-one relationship between a VtableStub and such a pair. diff --git a/src/hotspot/share/compiler/compilerDefinitions.hpp b/src/hotspot/share/compiler/compilerDefinitions.hpp index 1c8096918a6..153dfaad364 100644 --- a/src/hotspot/share/compiler/compilerDefinitions.hpp +++ b/src/hotspot/share/compiler/compilerDefinitions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -27,7 +27,7 @@ #include "compiler/compiler_globals.hpp" #include "jvmci/jvmci_globals.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/globals.hpp" // The (closed set) of concrete compiler classes. diff --git a/src/hotspot/share/compiler/compilerEvent.hpp b/src/hotspot/share/compiler/compilerEvent.hpp index 65fc296b66b..cf04ce9a436 100644 --- a/src/hotspot/share/compiler/compilerEvent.hpp +++ b/src/hotspot/share/compiler/compilerEvent.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -26,7 +26,7 @@ #include "jni.h" #include "compiler/compilerDefinitions.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/macros.hpp" #include "utilities/ticks.hpp" diff --git a/src/hotspot/share/compiler/compilerOracle.hpp b/src/hotspot/share/compiler/compilerOracle.hpp index e5be64cbdd4..f2fc0e8251d 100644 --- a/src/hotspot/share/compiler/compilerOracle.hpp +++ b/src/hotspot/share/compiler/compilerOracle.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_COMPILER_COMPILERORACLE_HPP #define SHARE_COMPILER_COMPILERORACLE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oopsHierarchy.hpp" class methodHandle; diff --git a/src/hotspot/share/gc/g1/g1CollectionSetChooser.hpp b/src/hotspot/share/gc/g1/g1CollectionSetChooser.hpp index 5692a0c407e..e8894323d65 100644 --- a/src/hotspot/share/gc/g1/g1CollectionSetChooser.hpp +++ b/src/hotspot/share/gc/g1/g1CollectionSetChooser.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -26,7 +26,7 @@ #define SHARE_GC_G1_G1COLLECTIONSETCHOOSER_HPP #include "gc/g1/heapRegion.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/globals.hpp" class G1CollectionSetCandidates; diff --git a/src/hotspot/share/gc/g1/g1FromCardCache.hpp b/src/hotspot/share/gc/g1/g1FromCardCache.hpp index b76d7b1b863..0a01e0102ae 100644 --- a/src/hotspot/share/gc/g1/g1FromCardCache.hpp +++ b/src/hotspot/share/gc/g1/g1FromCardCache.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_GC_G1_G1FROMCARDCACHE_HPP #define SHARE_GC_G1_G1FROMCARDCACHE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/ostream.hpp" // G1FromCardCache remembers the most recently processed card on the heap on diff --git a/src/hotspot/share/gc/g1/g1HeapRegionEventSender.hpp b/src/hotspot/share/gc/g1/g1HeapRegionEventSender.hpp index c8518a5172e..eb3d60656d4 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionEventSender.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionEventSender.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_GC_G1_G1HEAPREGIONEVENTSENDER_HPP #define SHARE_GC_G1_G1HEAPREGIONEVENTSENDER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class G1HeapRegionEventSender : public AllStatic { public: diff --git a/src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp b/src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp index ab3ee03137c..1c5690e566d 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionTraceType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_GC_G1_G1HEAPREGIONTRACETYPE_HPP #define SHARE_GC_G1_G1HEAPREGIONTRACETYPE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/debug.hpp" class G1HeapRegionTraceType : AllStatic { diff --git a/src/hotspot/share/gc/g1/heapRegionBounds.hpp b/src/hotspot/share/gc/g1/heapRegionBounds.hpp index 5e748de5928..5a6db9fac3b 100644 --- a/src/hotspot/share/gc/g1/heapRegionBounds.hpp +++ b/src/hotspot/share/gc/g1/heapRegionBounds.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -25,7 +25,8 @@ #ifndef SHARE_GC_G1_HEAPREGIONBOUNDS_HPP #define SHARE_GC_G1_HEAPREGIONBOUNDS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class HeapRegionBounds : public AllStatic { private: diff --git a/src/hotspot/share/gc/g1/heapRegionTracer.hpp b/src/hotspot/share/gc/g1/heapRegionTracer.hpp index bdfcd1cfd8e..647744d0d5e 100644 --- a/src/hotspot/share/gc/g1/heapRegionTracer.hpp +++ b/src/hotspot/share/gc/g1/heapRegionTracer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -26,7 +26,8 @@ #define SHARE_GC_G1_HEAPREGIONTRACER_HPP #include "gc/g1/g1HeapRegionTraceType.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class HeapRegionTracer : AllStatic { public: diff --git a/src/hotspot/share/gc/g1/heapRegionType.hpp b/src/hotspot/share/gc/g1/heapRegionType.hpp index 74807c37746..9e1c79ea0d0 100644 --- a/src/hotspot/share/gc/g1/heapRegionType.hpp +++ b/src/hotspot/share/gc/g1/heapRegionType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -26,6 +26,7 @@ #define SHARE_GC_G1_HEAPREGIONTYPE_HPP #include "gc/g1/g1HeapRegionTraceType.hpp" +#include "utilities/globalDefinitions.hpp" #define hrt_assert_is_valid(tag) \ assert(is_valid((tag)), "invalid HR type: %u", (uint) (tag)) diff --git a/src/hotspot/share/gc/parallel/psRootType.hpp b/src/hotspot/share/gc/parallel/psRootType.hpp index 921bbfdd2b0..cbdc94dc9ab 100644 --- a/src/hotspot/share/gc/parallel/psRootType.hpp +++ b/src/hotspot/share/gc/parallel/psRootType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_GC_PARALLEL_PSROOTTYPE_HPP #define SHARE_GC_PARALLEL_PSROOTTYPE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/macros.hpp" class ParallelRootType : public AllStatic { diff --git a/src/hotspot/share/gc/parallel/psScavenge.hpp b/src/hotspot/share/gc/parallel/psScavenge.hpp index 80f41a99934..c575e8a3f2c 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.hpp +++ b/src/hotspot/share/gc/parallel/psScavenge.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -29,7 +29,7 @@ #include "gc/parallel/psVirtualspace.hpp" #include "gc/shared/collectorCounters.hpp" #include "gc/shared/gcTrace.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oop.hpp" #include "utilities/stack.hpp" diff --git a/src/hotspot/share/gc/shared/accessBarrierSupport.hpp b/src/hotspot/share/gc/shared/accessBarrierSupport.hpp index 58bc562d988..ca3b4589224 100644 --- a/src/hotspot/share/gc/shared/accessBarrierSupport.hpp +++ b/src/hotspot/share/gc/shared/accessBarrierSupport.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_ACCESSBARRIERSUPPORT_HPP #define SHARE_GC_SHARED_ACCESSBARRIERSUPPORT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/access.hpp" class AccessBarrierSupport: AllStatic { diff --git a/src/hotspot/share/gc/shared/ageTableTracer.hpp b/src/hotspot/share/gc/shared/ageTableTracer.hpp index cca3f125bfd..02e1fe3338d 100644 --- a/src/hotspot/share/gc/shared/ageTableTracer.hpp +++ b/src/hotspot/share/gc/shared/ageTableTracer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -25,7 +25,8 @@ #ifndef SHARE_GC_SHARED_AGETABLETRACER_HPP #define SHARE_GC_SHARED_AGETABLETRACER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class AgeTableTracer : AllStatic { public: diff --git a/src/hotspot/share/gc/shared/allocTracer.hpp b/src/hotspot/share/gc/shared/allocTracer.hpp index c30628b2889..273f20d70ea 100644 --- a/src/hotspot/share/gc/shared/allocTracer.hpp +++ b/src/hotspot/share/gc/shared/allocTracer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_ALLOCTRACER_HPP #define SHARE_GC_SHARED_ALLOCTRACER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/handles.hpp" class AllocTracer : AllStatic { diff --git a/src/hotspot/share/gc/shared/blockOffsetTable.hpp b/src/hotspot/share/gc/shared/blockOffsetTable.hpp index 7d6ddfdf799..9a32594c123 100644 --- a/src/hotspot/share/gc/shared/blockOffsetTable.hpp +++ b/src/hotspot/share/gc/shared/blockOffsetTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -28,7 +28,7 @@ #include "gc/shared/gc_globals.hpp" #include "gc/shared/memset_with_concurrent_readers.hpp" #include "gc/shared/cardTable.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/memRegion.hpp" #include "memory/virtualspace.hpp" #include "runtime/globals.hpp" diff --git a/src/hotspot/share/gc/shared/concurrentGCBreakpoints.hpp b/src/hotspot/share/gc/shared/concurrentGCBreakpoints.hpp index c11c0e116c5..7af1b5746c3 100644 --- a/src/hotspot/share/gc/shared/concurrentGCBreakpoints.hpp +++ b/src/hotspot/share/gc/shared/concurrentGCBreakpoints.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -26,7 +26,7 @@ #define SHARE_GC_SHARED_CONCURRENTGCBREAKPOINTS_HPP #include "gc/shared/gcCause.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class Monitor; diff --git a/src/hotspot/share/gc/shared/gcCause.hpp b/src/hotspot/share/gc/shared/gcCause.hpp index 75f7dc73a8c..a3746fa8745 100644 --- a/src/hotspot/share/gc/shared/gcCause.hpp +++ b/src/hotspot/share/gc/shared/gcCause.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -25,7 +25,8 @@ #ifndef SHARE_GC_SHARED_GCCAUSE_HPP #define SHARE_GC_SHARED_GCCAUSE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/debug.hpp" // // This class exposes implementation details of the various diff --git a/src/hotspot/share/gc/shared/gcConfig.hpp b/src/hotspot/share/gc/shared/gcConfig.hpp index 2dfbf186b7f..9b0da3ad528 100644 --- a/src/hotspot/share/gc/shared/gcConfig.hpp +++ b/src/hotspot/share/gc/shared/gcConfig.hpp @@ -26,7 +26,7 @@ #define SHARE_GC_SHARED_GCCONFIG_HPP #include "gc/shared/collectedHeap.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class GCArguments; diff --git a/src/hotspot/share/gc/shared/gcLocker.hpp b/src/hotspot/share/gc/shared/gcLocker.hpp index 91ed84c41a9..e567d0c1f16 100644 --- a/src/hotspot/share/gc/shared/gcLocker.hpp +++ b/src/hotspot/share/gc/shared/gcLocker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,7 @@ #define SHARE_GC_SHARED_GCLOCKER_HPP #include "gc/shared/gcCause.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/share/gc/shared/gcLogPrecious.hpp b/src/hotspot/share/gc/shared/gcLogPrecious.hpp index 5f1158caca7..ec8b1c670f3 100644 --- a/src/hotspot/share/gc/shared/gcLogPrecious.hpp +++ b/src/hotspot/share/gc/shared/gcLogPrecious.hpp @@ -26,7 +26,7 @@ #include "utilities/globalDefinitions.hpp" #include "logging/logHandle.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/debug.hpp" class Mutex; diff --git a/src/hotspot/share/gc/shared/gcWhen.hpp b/src/hotspot/share/gc/shared/gcWhen.hpp index ff489226f65..23e2ef6b229 100644 --- a/src/hotspot/share/gc/shared/gcWhen.hpp +++ b/src/hotspot/share/gc/shared/gcWhen.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_GCWHEN_HPP #define SHARE_GC_SHARED_GCWHEN_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/debug.hpp" class GCWhen : AllStatic { diff --git a/src/hotspot/share/gc/shared/locationPrinter.hpp b/src/hotspot/share/gc/shared/locationPrinter.hpp index 2c99e452845..2d5d997376d 100644 --- a/src/hotspot/share/gc/shared/locationPrinter.hpp +++ b/src/hotspot/share/gc/shared/locationPrinter.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_LOCATIONPRINTER_HPP #define SHARE_GC_SHARED_LOCATIONPRINTER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oopsHierarchy.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/shared/objectCountEventSender.hpp b/src/hotspot/share/gc/shared/objectCountEventSender.hpp index 58e6da016da..115fbfdaf7d 100644 --- a/src/hotspot/share/gc/shared/objectCountEventSender.hpp +++ b/src/hotspot/share/gc/shared/objectCountEventSender.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -26,7 +26,7 @@ #define SHARE_GC_SHARED_OBJECTCOUNTEVENTSENDER_HPP #include "gc/shared/gcTrace.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" #include "utilities/ticks.hpp" diff --git a/src/hotspot/share/gc/shared/scavengableNMethods.hpp b/src/hotspot/share/gc/shared/scavengableNMethods.hpp index 276ea9843c0..4852e6d32fb 100644 --- a/src/hotspot/share/gc/shared/scavengableNMethods.hpp +++ b/src/hotspot/share/gc/shared/scavengableNMethods.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_SCAVENGABLENMETHODS_HPP #define SHARE_GC_SHARED_SCAVENGABLENMETHODS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/macros.hpp" class BoolObjectClosure; diff --git a/src/hotspot/share/gc/shared/spaceDecorator.hpp b/src/hotspot/share/gc/shared/spaceDecorator.hpp index d421a2a40f5..778881f75a1 100644 --- a/src/hotspot/share/gc/shared/spaceDecorator.hpp +++ b/src/hotspot/share/gc/shared/spaceDecorator.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_SPACEDECORATOR_HPP #define SHARE_GC_SHARED_SPACEDECORATOR_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/memRegion.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/shared/weakProcessor.hpp b/src/hotspot/share/gc/shared/weakProcessor.hpp index 5eb2c59f3f2..b86129c9b93 100644 --- a/src/hotspot/share/gc/shared/weakProcessor.hpp +++ b/src/hotspot/share/gc/shared/weakProcessor.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -28,7 +28,7 @@ #include "gc/shared/oopStorageParState.hpp" #include "gc/shared/oopStorageSetParState.hpp" #include "gc/shared/workerThread.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class WeakProcessorTimes; class WorkerThreads; diff --git a/src/hotspot/share/gc/shared/workerPolicy.hpp b/src/hotspot/share/gc/shared/workerPolicy.hpp index 377c9135d29..769b0e0ed8b 100644 --- a/src/hotspot/share/gc/shared/workerPolicy.hpp +++ b/src/hotspot/share/gc/shared/workerPolicy.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHARED_WORKERPOLICY_HPP #define SHARE_GC_SHARED_WORKERPOLICY_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class WorkerPolicy : public AllStatic { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.hpp index f8b7489a3bb..acc497618c9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBreakpoint.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021, Red Hat, Inc. All rights reserved. - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Red Hat, Inc. All rights reserved. + * Copyright (c) 2020, 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 @@ -26,7 +26,7 @@ #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHBREAKPOINT_HPP #define SHARE_GC_SHENANDOAH_SHENANDOAHBREAKPOINT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ShenandoahBreakpoint : public AllStatic { private: diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp index 17bc5b78934..377d7688333 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Red Hat, Inc. All rights reserved. + * Copyright (c) 2017, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ #include "gc/shenandoah/shenandoahSharedVariables.hpp" #include "gc/shenandoah/shenandoahLock.hpp" #include "gc/shenandoah/shenandoahPadding.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/iterator.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp index 788fe3fbeca..e187e4360b1 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahRuntime.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2018, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHRUNTIME_HPP #define SHARE_GC_SHENANDOAH_SHENANDOAHRUNTIME_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oopsHierarchy.hpp" class JavaThread; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp index 10a6fec6535..3f47822f220 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahWorkerPolicy.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved. + * Copyright (c) 2017, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHWORKERPOLICY_HPP #define SHARE_GC_SHENANDOAH_SHENANDOAHWORKERPOLICY_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ShenandoahWorkerPolicy : AllStatic { private: diff --git a/src/hotspot/share/gc/z/zAbort.hpp b/src/hotspot/share/gc/z/zAbort.hpp index 1a5bcc15f19..f87bca8c0a3 100644 --- a/src/hotspot/share/gc/z/zAbort.hpp +++ b/src/hotspot/share/gc/z/zAbort.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZABORT_HPP #define SHARE_GC_Z_ZABORT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ZAbort : public AllStatic { private: diff --git a/src/hotspot/share/gc/z/zAddress.hpp b/src/hotspot/share/gc/z/zAddress.hpp index eddd104189e..2908c37bbe6 100644 --- a/src/hotspot/share/gc/z/zAddress.hpp +++ b/src/hotspot/share/gc/z/zAddress.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,7 +24,8 @@ #ifndef SHARE_GC_Z_ZADDRESS_HPP #define SHARE_GC_Z_ZADDRESS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class ZAddress : public AllStatic { friend class ZAddressTest; diff --git a/src/hotspot/share/gc/z/zAddressSpaceLimit.hpp b/src/hotspot/share/gc/z/zAddressSpaceLimit.hpp index b6a03776f5c..ec0faf2c087 100644 --- a/src/hotspot/share/gc/z/zAddressSpaceLimit.hpp +++ b/src/hotspot/share/gc/z/zAddressSpaceLimit.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -24,7 +24,8 @@ #ifndef SHARE_GC_Z_ZADDRESSSPACELIMIT_HPP #define SHARE_GC_Z_ZADDRESSSPACELIMIT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class ZAddressSpaceLimit : public AllStatic { public: diff --git a/src/hotspot/share/gc/z/zBarrier.hpp b/src/hotspot/share/gc/z/zBarrier.hpp index d57bef74f91..2dfc1591888 100644 --- a/src/hotspot/share/gc/z/zBarrier.hpp +++ b/src/hotspot/share/gc/z/zBarrier.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZBARRIER_HPP #define SHARE_GC_Z_ZBARRIER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/iterator.hpp" #include "oops/oop.hpp" diff --git a/src/hotspot/share/gc/z/zBarrierSetRuntime.hpp b/src/hotspot/share/gc/z/zBarrierSetRuntime.hpp index f3d4fb9c6bd..b3a143de3e9 100644 --- a/src/hotspot/share/gc/z/zBarrierSetRuntime.hpp +++ b/src/hotspot/share/gc/z/zBarrierSetRuntime.hpp @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZBARRIERSETRUNTIME_HPP #define SHARE_GC_Z_ZBARRIERSETRUNTIME_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/accessDecorators.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/z/zBitField.hpp b/src/hotspot/share/gc/z/zBitField.hpp index 4d7171c41ac..9bec4e05594 100644 --- a/src/hotspot/share/gc/z/zBitField.hpp +++ b/src/hotspot/share/gc/z/zBitField.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -24,8 +24,9 @@ #ifndef SHARE_GC_Z_ZBITFIELD_HPP #define SHARE_GC_Z_ZBITFIELD_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" // // Example diff --git a/src/hotspot/share/gc/z/zBreakpoint.hpp b/src/hotspot/share/gc/z/zBreakpoint.hpp index 14ba227e189..920169fb6a6 100644 --- a/src/hotspot/share/gc/z/zBreakpoint.hpp +++ b/src/hotspot/share/gc/z/zBreakpoint.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZBREAKPOINT_HPP #define SHARE_GC_Z_ZBREAKPOINT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ZBreakpoint : public AllStatic { private: diff --git a/src/hotspot/share/gc/z/zCPU.hpp b/src/hotspot/share/gc/z/zCPU.hpp index 65e04cc75e3..0acc949e508 100644 --- a/src/hotspot/share/gc/z/zCPU.hpp +++ b/src/hotspot/share/gc/z/zCPU.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZCPU_HPP #define SHARE_GC_Z_ZCPU_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/padded.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/gc/z/zHash.hpp b/src/hotspot/share/gc/z/zHash.hpp index 5752d2abee3..e6469698488 100644 --- a/src/hotspot/share/gc/z/zHash.hpp +++ b/src/hotspot/share/gc/z/zHash.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZHASH_HPP #define SHARE_GC_Z_ZHASH_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class ZHash : public AllStatic { diff --git a/src/hotspot/share/gc/z/zHeuristics.hpp b/src/hotspot/share/gc/z/zHeuristics.hpp index 5b810a84851..362fd775f0f 100644 --- a/src/hotspot/share/gc/z/zHeuristics.hpp +++ b/src/hotspot/share/gc/z/zHeuristics.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZHEURISTICS_HPP #define SHARE_GC_Z_ZHEURISTICS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ZHeuristics : public AllStatic { public: diff --git a/src/hotspot/share/gc/z/zLargePages.hpp b/src/hotspot/share/gc/z/zLargePages.hpp index 1201b496266..9f7c8310e50 100644 --- a/src/hotspot/share/gc/z/zLargePages.hpp +++ b/src/hotspot/share/gc/z/zLargePages.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZLARGEPAGES_HPP #define SHARE_GC_Z_ZLARGEPAGES_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ZLargePages : public AllStatic { private: diff --git a/src/hotspot/share/gc/z/zNMethod.hpp b/src/hotspot/share/gc/z/zNMethod.hpp index 40ac93adb8e..117c5e34f4e 100644 --- a/src/hotspot/share/gc/z/zNMethod.hpp +++ b/src/hotspot/share/gc/z/zNMethod.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZNMETHOD_HPP #define SHARE_GC_Z_ZNMETHOD_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class nmethod; class NMethodClosure; diff --git a/src/hotspot/share/gc/z/zNMethodTable.hpp b/src/hotspot/share/gc/z/zNMethodTable.hpp index 26ae2d27933..a1af8512f69 100644 --- a/src/hotspot/share/gc/z/zNMethodTable.hpp +++ b/src/hotspot/share/gc/z/zNMethodTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -26,7 +26,7 @@ #include "gc/z/zNMethodTableIteration.hpp" #include "gc/z/zSafeDelete.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class nmethod; class NMethodClosure; diff --git a/src/hotspot/share/gc/z/zNUMA.hpp b/src/hotspot/share/gc/z/zNUMA.hpp index 0dc4390e8b4..fb29e1faaa7 100644 --- a/src/hotspot/share/gc/z/zNUMA.hpp +++ b/src/hotspot/share/gc/z/zNUMA.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -24,7 +24,8 @@ #ifndef SHARE_GC_Z_ZNUMA_HPP #define SHARE_GC_Z_ZNUMA_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class ZNUMA : public AllStatic { private: diff --git a/src/hotspot/share/gc/z/zOop.hpp b/src/hotspot/share/gc/z/zOop.hpp index cf752ba61c3..4fb0e6499e1 100644 --- a/src/hotspot/share/gc/z/zOop.hpp +++ b/src/hotspot/share/gc/z/zOop.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZOOP_HPP #define SHARE_GC_Z_ZOOP_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oopsHierarchy.hpp" class ZOop : public AllStatic { diff --git a/src/hotspot/share/gc/z/zResurrection.hpp b/src/hotspot/share/gc/z/zResurrection.hpp index a88b9354469..3d6a8f95a1c 100644 --- a/src/hotspot/share/gc/z/zResurrection.hpp +++ b/src/hotspot/share/gc/z/zResurrection.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZRESURRECTION_HPP #define SHARE_GC_Z_ZRESURRECTION_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ZResurrection : public AllStatic { private: diff --git a/src/hotspot/share/gc/z/zThread.hpp b/src/hotspot/share/gc/z/zThread.hpp index f98b7a05fb6..c67807ff96e 100644 --- a/src/hotspot/share/gc/z/zThread.hpp +++ b/src/hotspot/share/gc/z/zThread.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZTHREAD_HPP #define SHARE_GC_Z_ZTHREAD_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class ZThread : public AllStatic { diff --git a/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.hpp b/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.hpp index d6693fceb00..086c8a5c351 100644 --- a/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.hpp +++ b/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -26,7 +26,7 @@ #include "gc/shared/threadLocalAllocBuffer.hpp" #include "gc/z/zValue.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class JavaThread; diff --git a/src/hotspot/share/gc/z/zUtils.hpp b/src/hotspot/share/gc/z/zUtils.hpp index f4abea9c6fe..470329daf0d 100644 --- a/src/hotspot/share/gc/z/zUtils.hpp +++ b/src/hotspot/share/gc/z/zUtils.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,7 +24,8 @@ #ifndef SHARE_GC_Z_ZUTILS_HPP #define SHARE_GC_Z_ZUTILS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class ZUtils : public AllStatic { public: diff --git a/src/hotspot/share/gc/z/zValue.hpp b/src/hotspot/share/gc/z/zValue.hpp index 281a2e48b8c..e2c67e8c48d 100644 --- a/src/hotspot/share/gc/z/zValue.hpp +++ b/src/hotspot/share/gc/z/zValue.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZVALUE_HPP #define SHARE_GC_Z_ZVALUE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" // diff --git a/src/hotspot/share/gc/z/zVerify.hpp b/src/hotspot/share/gc/z/zVerify.hpp index db2d56d0095..8d7abd4a8d5 100644 --- a/src/hotspot/share/gc/z/zVerify.hpp +++ b/src/hotspot/share/gc/z/zVerify.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -24,7 +24,7 @@ #ifndef SHARE_GC_Z_ZVERIFY_HPP #define SHARE_GC_Z_ZVERIFY_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class frame; class ZPageAllocator; diff --git a/src/hotspot/share/interpreter/bytecodeHistogram.hpp b/src/hotspot/share/interpreter/bytecodeHistogram.hpp index b919227702f..44ddca074d0 100644 --- a/src/hotspot/share/interpreter/bytecodeHistogram.hpp +++ b/src/hotspot/share/interpreter/bytecodeHistogram.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,7 @@ #define SHARE_INTERPRETER_BYTECODEHISTOGRAM_HPP #include "interpreter/bytecodes.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // BytecodeCounter counts the number of bytecodes executed diff --git a/src/hotspot/share/interpreter/bytecodeTracer.hpp b/src/hotspot/share/interpreter/bytecodeTracer.hpp index 52e91a0e712..38c2b092ce3 100644 --- a/src/hotspot/share/interpreter/bytecodeTracer.hpp +++ b/src/hotspot/share/interpreter/bytecodeTracer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_INTERPRETER_BYTECODETRACER_HPP #define SHARE_INTERPRETER_BYTECODETRACER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/ostream.hpp" // The BytecodeTracer is a helper class used by the interpreter for run-time diff --git a/src/hotspot/share/interpreter/bytecodeUtils.hpp b/src/hotspot/share/interpreter/bytecodeUtils.hpp index ede99a995b7..ff23b9c000f 100644 --- a/src/hotspot/share/interpreter/bytecodeUtils.hpp +++ b/src/hotspot/share/interpreter/bytecodeUtils.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2019 SAP SE. All rights reserved. + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2022 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 @@ -26,7 +26,7 @@ #ifndef SHARE_INTERPRETER_BYTECODEUTILS_HPP #define SHARE_INTERPRETER_BYTECODEUTILS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class Method; diff --git a/src/hotspot/share/interpreter/bytecodes.hpp b/src/hotspot/share/interpreter/bytecodes.hpp index 9a34a227c04..7c70518d2b1 100644 --- a/src/hotspot/share/interpreter/bytecodes.hpp +++ b/src/hotspot/share/interpreter/bytecodes.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,7 +25,8 @@ #ifndef SHARE_INTERPRETER_BYTECODES_HPP #define SHARE_INTERPRETER_BYTECODES_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" // Bytecodes specifies all bytecodes used in the VM and // provides utility functions to get bytecode attributes. diff --git a/src/hotspot/share/interpreter/templateTable.hpp b/src/hotspot/share/interpreter/templateTable.hpp index ff5d2c33880..e7575eeb40a 100644 --- a/src/hotspot/share/interpreter/templateTable.hpp +++ b/src/hotspot/share/interpreter/templateTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,7 @@ #define SHARE_INTERPRETER_TEMPLATETABLE_HPP #include "interpreter/bytecodes.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/frame.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.hpp b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.hpp index d34a4e57a78..939c02bfdf4 100644 --- a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.hpp +++ b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_INSTRUMENTATION_JFREVENTCLASSTRANSFORMER_HPP #define SHARE_JFR_INSTRUMENTATION_JFREVENTCLASSTRANSFORMER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/exceptions.hpp" class ClassFileParser; diff --git a/src/hotspot/share/jfr/jfr.hpp b/src/hotspot/share/jfr/jfr.hpp index c97cc807c3b..b4b1ae78adc 100644 --- a/src/hotspot/share/jfr/jfr.hpp +++ b/src/hotspot/share/jfr/jfr.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -26,11 +26,13 @@ #define SHARE_JFR_JFR_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class JavaThread; class Thread; class Klass; +class outputStream; extern "C" void JNICALL jfr_register_natives(JNIEnv*, jclass); diff --git a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.hpp b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.hpp index c9a169e6edb..0f107e7c32e 100644 --- a/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.hpp +++ b/src/hotspot/share/jfr/leakprofiler/chains/edgeUtils.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_LEAKPROFILER_CHAINS_EDGEUTILS_HPP #define SHARE_JFR_LEAKPROFILER_CHAINS_EDGEUTILS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class Edge; class Symbol; diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp index 0ed82fd55c8..f9f928699e2 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_LEAKPROFILER_CHECKPOINT_OBJECTSAMPLECHECKPOINT_HPP #define SHARE_JFR_LEAKPROFILER_CHECKPOINT_OBJECTSAMPLECHECKPOINT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "jfr/utilities/jfrTypes.hpp" class EdgeStore; diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.hpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.hpp index 63dca4afc72..279cb5032ff 100644 --- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.hpp +++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -27,7 +27,7 @@ #include "jfr/leakprofiler/utilities/rootType.hpp" #include "jfr/leakprofiler/utilities/unifiedOopRef.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oopsHierarchy.hpp" struct RootCallbackInfo { diff --git a/src/hotspot/share/jfr/leakprofiler/leakProfiler.hpp b/src/hotspot/share/jfr/leakprofiler/leakProfiler.hpp index c541ff1086d..6290a10ff74 100644 --- a/src/hotspot/share/jfr/leakprofiler/leakProfiler.hpp +++ b/src/hotspot/share/jfr/leakprofiler/leakProfiler.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -25,7 +25,8 @@ #ifndef SHARE_JFR_LEAKPROFILER_LEAKPROFILER_HPP #define SHARE_JFR_LEAKPROFILER_LEAKPROFILER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/globalDefinitions.hpp" class JavaThread; diff --git a/src/hotspot/share/jfr/leakprofiler/utilities/granularTimer.hpp b/src/hotspot/share/jfr/leakprofiler/utilities/granularTimer.hpp index 231c1b26df4..e42a815c10d 100644 --- a/src/hotspot/share/jfr/leakprofiler/utilities/granularTimer.hpp +++ b/src/hotspot/share/jfr/leakprofiler/utilities/granularTimer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -26,7 +26,7 @@ #define SHARE_JFR_LEAKPROFILER_UTILITIES_GRANULARTIMER_HPP #include "jfr/utilities/jfrTime.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class GranularTimer : public AllStatic { private: diff --git a/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp b/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp index ffc47c7b833..ce975e9b802 100644 --- a/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp +++ b/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -26,7 +26,7 @@ #define SHARE_JFR_LEAKPROFILER_UTILITIES_ROOTTYPE_HPP #include "gc/shared/oopStorageSet.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/enumIterator.hpp" class OldObjectRoot : public AllStatic { diff --git a/src/hotspot/share/jfr/periodic/jfrFinalizerStatisticsEvent.hpp b/src/hotspot/share/jfr/periodic/jfrFinalizerStatisticsEvent.hpp index fe739495718..756b5318298 100644 --- a/src/hotspot/share/jfr/periodic/jfrFinalizerStatisticsEvent.hpp +++ b/src/hotspot/share/jfr/periodic/jfrFinalizerStatisticsEvent.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_PERIODIC_JFRFINALIZERSTATISTICSEVENT_HPP #define SHARE_JFR_PERIODIC_JFRFINALIZERSTATISTICSEVENT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class InstanceKlass; diff --git a/src/hotspot/share/jfr/periodic/jfrModuleEvent.hpp b/src/hotspot/share/jfr/periodic/jfrModuleEvent.hpp index aec662be231..a417ab1bb48 100644 --- a/src/hotspot/share/jfr/periodic/jfrModuleEvent.hpp +++ b/src/hotspot/share/jfr/periodic/jfrModuleEvent.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_PERIODIC_JFRMODULEEVENT_HPP #define SHARE_JFR_PERIODIC_JFRMODULEEVENT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class JfrModuleEvent : AllStatic { public: diff --git a/src/hotspot/share/jfr/periodic/jfrNetworkUtilization.hpp b/src/hotspot/share/jfr/periodic/jfrNetworkUtilization.hpp index b7a78498a9f..0ec3de18dee 100644 --- a/src/hotspot/share/jfr/periodic/jfrNetworkUtilization.hpp +++ b/src/hotspot/share/jfr/periodic/jfrNetworkUtilization.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_PERIODIC_JFRNETWORKUTILIZATION_HPP #define SHARE_JFR_PERIODIC_JFRNETWORKUTILIZATION_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class NetworkInterface; diff --git a/src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.hpp b/src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.hpp index 84d3099e825..d5bed0fd821 100644 --- a/src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.hpp +++ b/src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -26,7 +26,7 @@ #define SHARE_JFR_PERIODIC_JFRTHREADCPULOADEVENT_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class JavaThread; class EventThreadCPULoad; diff --git a/src/hotspot/share/jfr/periodic/jfrThreadDumpEvent.hpp b/src/hotspot/share/jfr/periodic/jfrThreadDumpEvent.hpp index 23af6a3060b..c00925903b1 100644 --- a/src/hotspot/share/jfr/periodic/jfrThreadDumpEvent.hpp +++ b/src/hotspot/share/jfr/periodic/jfrThreadDumpEvent.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_PERIODIC_JFRTHREADDUMPEVENT_HPP #define SHARE_JFR_PERIODIC_JFRTHREADDUMPEVENT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" /* * Helper for generating jfr events using output data from Dcmd's. diff --git a/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.hpp b/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.hpp index 0111d3becbe..abadbfb0b13 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.hpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -26,7 +26,7 @@ #define SHARE_JFR_RECORDER_CHECKPOINT_JFRMETADATAEVENT_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class JfrChunkWriter; diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.hpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.hpp index 9421273dca7..4fd519b5064 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.hpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.hpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2016, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_RECORDER_CHECKPOINT_TYPES_JFRTHREADSTATE_HPP #define SHARE_JFR_RECORDER_CHECKPOINT_TYPES_JFRTHREADSTATE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class JfrCheckpointWriter; class Thread; diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.hpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.hpp index 8136d125804..456599b45f3 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.hpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -27,7 +27,7 @@ #include "jni.h" #include "jfr/utilities/jfrTypes.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ClassLoaderData; class Klass; diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdBits.hpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdBits.hpp index 7fba5d8d1e8..d7f7effdc3e 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdBits.hpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdBits.hpp @@ -27,7 +27,7 @@ #include "jni.h" #include "jfr/utilities/jfrTypes.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class JfrTraceIdBits : AllStatic { public: diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp index ba14919c935..1216f6956ef 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdEpoch.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -27,7 +27,7 @@ #include "jfr/utilities/jfrSignal.hpp" #include "jfr/utilities/jfrTypes.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/atomic.hpp" #define BIT 1 diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.hpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.hpp index 7113a65bd42..e7b7e1a8780 100644 --- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.hpp +++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -26,7 +26,7 @@ #define SHARE_JFR_RECORDER_CHECKPOINT_TYPES_TRACEID_JFRTRACEIDLOADBARRIER_HPP #include "jfr/utilities/jfrTypes.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class ClassLoaderData; class JfrBuffer; diff --git a/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.hpp b/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.hpp index 973fa611718..76603b1cd5e 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.hpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_RECORDER_REPOSITORY_JFRCHUNKROTATION_HPP #define SHARE_JFR_RECORDER_REPOSITORY_JFRCHUNKROTATION_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class JfrChunkWriter; diff --git a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.hpp b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.hpp index c96a7d802dc..7912daf35c9 100644 --- a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.hpp +++ b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_RECORDER_REPOSITORY_JFREMERGENCYDUMP_HPP #define SHARE_JFR_RECORDER_REPOSITORY_JFREMERGENCYDUMP_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/ostream.hpp" // diff --git a/src/hotspot/share/jfr/recorder/service/jfrMemorySizer.hpp b/src/hotspot/share/jfr/recorder/service/jfrMemorySizer.hpp index 8f056e95398..5e226437987 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrMemorySizer.hpp +++ b/src/hotspot/share/jfr/recorder/service/jfrMemorySizer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_RECORDER_SERVICE_JFRMEMORYSIZER_HPP #define SHARE_JFR_RECORDER_SERVICE_JFRMEMORYSIZER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" extern const julong MIN_BUFFER_COUNT; diff --git a/src/hotspot/share/jfr/recorder/service/jfrOptionSet.hpp b/src/hotspot/share/jfr/recorder/service/jfrOptionSet.hpp index 9e1dd6cef11..9ad810bc3cd 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrOptionSet.hpp +++ b/src/hotspot/share/jfr/recorder/service/jfrOptionSet.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -26,7 +26,7 @@ #define SHARE_JFR_RECORDER_SERVICE_JFROPTIONSET_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/exceptions.hpp" template diff --git a/src/hotspot/share/jfr/recorder/service/jfrRecorderThread.hpp b/src/hotspot/share/jfr/recorder/service/jfrRecorderThread.hpp index 736cc350833..ca8d3e87841 100644 --- a/src/hotspot/share/jfr/recorder/service/jfrRecorderThread.hpp +++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderThread.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_RECORDER_SERVICE_JFRRECORDERTHREAD_HPP #define SHARE_JFR_RECORDER_SERVICE_JFRRECORDERTHREAD_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/debug.hpp" class JavaThread; diff --git a/src/hotspot/share/jfr/support/jfrJdkJfrEvent.hpp b/src/hotspot/share/jfr/support/jfrJdkJfrEvent.hpp index 06dddd6d39e..3c3a6d69377 100644 --- a/src/hotspot/share/jfr/support/jfrJdkJfrEvent.hpp +++ b/src/hotspot/share/jfr/support/jfrJdkJfrEvent.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -26,7 +26,7 @@ #define SHARE_JFR_SUPPORT_JFRJDKJFREVENT_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/exceptions.hpp" class Klass; diff --git a/src/hotspot/share/jfr/support/jfrKlassUnloading.hpp b/src/hotspot/share/jfr/support/jfrKlassUnloading.hpp index dcbe11ab8f6..5d380df436c 100644 --- a/src/hotspot/share/jfr/support/jfrKlassUnloading.hpp +++ b/src/hotspot/share/jfr/support/jfrKlassUnloading.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -26,7 +26,7 @@ #define SHARE_JFR_SUPPORT_JFRKLASSUNLOADING_HPP #include "jfr/utilities/jfrTypes.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class Klass; diff --git a/src/hotspot/share/jfr/support/jfrMethodLookup.hpp b/src/hotspot/share/jfr/support/jfrMethodLookup.hpp index 2f998a9def3..106648b25d7 100644 --- a/src/hotspot/share/jfr/support/jfrMethodLookup.hpp +++ b/src/hotspot/share/jfr/support/jfrMethodLookup.hpp @@ -26,7 +26,7 @@ #define SHARE_JFR_SUPPORT_JFRMETHODLOOKUP_HPP #include "jfr/utilities/jfrTypes.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class InstanceKlass; class Method; diff --git a/src/hotspot/share/jfr/support/jfrObjectAllocationSample.hpp b/src/hotspot/share/jfr/support/jfrObjectAllocationSample.hpp index 0902db68f5b..f58caf3c2a6 100644 --- a/src/hotspot/share/jfr/support/jfrObjectAllocationSample.hpp +++ b/src/hotspot/share/jfr/support/jfrObjectAllocationSample.hpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. +* Copyright (c) 2020, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_SUPPORT_JFROBJECTALLOCATIONSAMPLE_HPP #define SHARE_JFR_SUPPORT_JFROBJECTALLOCATIONSAMPLE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class Klass; class Thread; diff --git a/src/hotspot/share/jfr/utilities/jfrBigEndian.hpp b/src/hotspot/share/jfr/utilities/jfrBigEndian.hpp index db2e7ebaad2..b2e641269e0 100644 --- a/src/hotspot/share/jfr/utilities/jfrBigEndian.hpp +++ b/src/hotspot/share/jfr/utilities/jfrBigEndian.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_UTILITIES_JFRBIGENDIAN_HPP #define SHARE_JFR_UTILITIES_JFRBIGENDIAN_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/bytes.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/share/jfr/utilities/jfrJavaLog.hpp b/src/hotspot/share/jfr/utilities/jfrJavaLog.hpp index daef51ac81e..3b5ccc661fe 100644 --- a/src/hotspot/share/jfr/utilities/jfrJavaLog.hpp +++ b/src/hotspot/share/jfr/utilities/jfrJavaLog.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_UTILITIES_JFRJAVALOG_HPP #define SHARE_JFR_UTILITIES_JFRJAVALOG_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/exceptions.hpp" /* diff --git a/src/hotspot/share/jfr/utilities/jfrPredicate.hpp b/src/hotspot/share/jfr/utilities/jfrPredicate.hpp index b5f87b4c1e0..51ad1fec0c9 100644 --- a/src/hotspot/share/jfr/utilities/jfrPredicate.hpp +++ b/src/hotspot/share/jfr/utilities/jfrPredicate.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_UTILITIES_JFRPREDICATE_HPP #define SHARE_JFR_UTILITIES_JFRPREDICATE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/growableArray.hpp" /* diff --git a/src/hotspot/share/jfr/utilities/jfrTimeConverter.hpp b/src/hotspot/share/jfr/utilities/jfrTimeConverter.hpp index 9ce2308a551..6871fbb5461 100644 --- a/src/hotspot/share/jfr/utilities/jfrTimeConverter.hpp +++ b/src/hotspot/share/jfr/utilities/jfrTimeConverter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_JFR_UTILITIES_JFRTIMECONVERTER_HPP #define SHARE_JFR_UTILITIES_JFRTIMECONVERTER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class JfrTimeConverter : AllStatic { diff --git a/src/hotspot/share/jfr/writers/jfrEncoding.hpp b/src/hotspot/share/jfr/writers/jfrEncoding.hpp index 4684cc4bc9d..3d4c7c55e0e 100644 --- a/src/hotspot/share/jfr/writers/jfrEncoding.hpp +++ b/src/hotspot/share/jfr/writers/jfrEncoding.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -26,7 +26,7 @@ #define SHARE_JFR_WRITERS_JFRENCODING_HPP #include "jfr/writers/jfrEncoders.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" enum JfrStringEncoding { diff --git a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp index 844ce51a3d9..1159766428e 100644 --- a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp +++ b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -26,7 +26,7 @@ #define SHARE_JFR_WRITERS_JFRJAVAEVENTWRITER_HPP #include "jni.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class JavaThread; class Thread; diff --git a/src/hotspot/share/logging/logConfiguration.hpp b/src/hotspot/share/logging/logConfiguration.hpp index 542aaa2433b..35491d7459b 100644 --- a/src/hotspot/share/logging/logConfiguration.hpp +++ b/src/hotspot/share/logging/logConfiguration.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -25,12 +25,13 @@ #define SHARE_LOGGING_LOGCONFIGURATION_HPP #include "logging/logLevel.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" class LogOutput; class LogDecorators; class LogSelectionList; +class outputStream; // Global configuration of logging. Handles parsing and configuration of the logging framework, // and manages the list of configured log outputs. The actual tag and level configuration is diff --git a/src/hotspot/share/logging/logLevel.hpp b/src/hotspot/share/logging/logLevel.hpp index 7fe2d31f999..56ea7f5958a 100644 --- a/src/hotspot/share/logging/logLevel.hpp +++ b/src/hotspot/share/logging/logLevel.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,7 +24,8 @@ #ifndef SHARE_LOGGING_LOGLEVEL_HPP #define SHARE_LOGGING_LOGLEVEL_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "utilities/debug.hpp" #include "utilities/macros.hpp" // The list of log levels: diff --git a/src/hotspot/share/logging/logTag.hpp b/src/hotspot/share/logging/logTag.hpp index 78e0a88d112..9b216a9d35f 100644 --- a/src/hotspot/share/logging/logTag.hpp +++ b/src/hotspot/share/logging/logTag.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,9 +24,11 @@ #ifndef SHARE_LOGGING_LOGTAG_HPP #define SHARE_LOGGING_LOGTAG_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" +class outputStream; + // List of available logging tags. New tags should be added here, in // alphabetical order. // (The tags 'all', 'disable' and 'help' are special tags that can diff --git a/src/hotspot/share/memory/metaspace/internalStats.hpp b/src/hotspot/share/memory/metaspace/internalStats.hpp index dff2534e303..9c127568e57 100644 --- a/src/hotspot/share/memory/metaspace/internalStats.hpp +++ b/src/hotspot/share/memory/metaspace/internalStats.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020 SAP SE. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022 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 @@ -26,7 +26,7 @@ #ifndef SHARE_MEMORY_METASPACE_INTERNALSTATS_HPP #define SHARE_MEMORY_METASPACE_INTERNALSTATS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/atomic.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/memory/metaspace/metaspaceReporter.hpp b/src/hotspot/share/memory/metaspace/metaspaceReporter.hpp index 2aab2063379..acc5ca211e8 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceReporter.hpp +++ b/src/hotspot/share/memory/metaspace/metaspaceReporter.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, 2020 SAP SE. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022 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 @@ -26,7 +26,7 @@ #ifndef SHARE_MEMORY_METASPACE_METASPACEREPORTER_HPP #define SHARE_MEMORY_METASPACE_METASPACEREPORTER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" namespace metaspace { diff --git a/src/hotspot/share/memory/metaspace/metaspaceSettings.hpp b/src/hotspot/share/memory/metaspace/metaspaceSettings.hpp index e6d47fec3f4..d2dc3f97441 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceSettings.hpp +++ b/src/hotspot/share/memory/metaspace/metaspaceSettings.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020 SAP SE. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022 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 @@ -26,7 +26,7 @@ #ifndef SHARE_MEMORY_METASPACE_METASPACESETTINGS_HPP #define SHARE_MEMORY_METASPACE_METASPACESETTINGS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/metaspace/chunklevel.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/memory/metaspace/runningCounters.hpp b/src/hotspot/share/memory/metaspace/runningCounters.hpp index 8ef751896d3..ff24ead7ebd 100644 --- a/src/hotspot/share/memory/metaspace/runningCounters.hpp +++ b/src/hotspot/share/memory/metaspace/runningCounters.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2020 SAP SE. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022 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 @@ -26,7 +26,7 @@ #ifndef SHARE_MEMORY_METASPACE_RUNNINGCOUNTERS_HPP #define SHARE_MEMORY_METASPACE_RUNNINGCOUNTERS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/metaspace/counters.hpp" namespace metaspace { diff --git a/src/hotspot/share/memory/metaspaceCounters.hpp b/src/hotspot/share/memory/metaspaceCounters.hpp index 38d9c94ddb6..b83e1fdb1ba 100644 --- a/src/hotspot/share/memory/metaspaceCounters.hpp +++ b/src/hotspot/share/memory/metaspaceCounters.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,7 +26,7 @@ #ifndef SHARE_MEMORY_METASPACECOUNTERS_HPP #define SHARE_MEMORY_METASPACECOUNTERS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // Perf Counters for Metaspace diff --git a/src/hotspot/share/memory/metaspaceCriticalAllocation.hpp b/src/hotspot/share/memory/metaspaceCriticalAllocation.hpp index 71e8819aef3..bdc9ad8cf2c 100644 --- a/src/hotspot/share/memory/metaspaceCriticalAllocation.hpp +++ b/src/hotspot/share/memory/metaspaceCriticalAllocation.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_MEMORY_METASPACECRITICALALLOCATION_HPP #define SHARE_MEMORY_METASPACECRITICALALLOCATION_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/metaspace.hpp" class MetadataAllocationRequest; diff --git a/src/hotspot/share/metaprogramming/conditional.hpp b/src/hotspot/share/metaprogramming/conditional.hpp index 2d4fe1a86e8..3ba2fb7594e 100644 --- a/src/hotspot/share/metaprogramming/conditional.hpp +++ b/src/hotspot/share/metaprogramming/conditional.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_METAPROGRAMMING_CONDITIONAL_HPP #define SHARE_METAPROGRAMMING_CONDITIONAL_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // This trait evaluates its typedef called "type" to TrueType iff the condition // is true. Otherwise it evaluates to FalseType. diff --git a/src/hotspot/share/metaprogramming/decay.hpp b/src/hotspot/share/metaprogramming/decay.hpp index 4dff0500f13..f504c099e4d 100644 --- a/src/hotspot/share/metaprogramming/decay.hpp +++ b/src/hotspot/share/metaprogramming/decay.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_METAPROGRAMMING_DECAY_HPP #define SHARE_METAPROGRAMMING_DECAY_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "metaprogramming/removeCV.hpp" #include "metaprogramming/removeReference.hpp" diff --git a/src/hotspot/share/metaprogramming/removeCV.hpp b/src/hotspot/share/metaprogramming/removeCV.hpp index 0c0b2f47fa7..5ddafc54746 100644 --- a/src/hotspot/share/metaprogramming/removeCV.hpp +++ b/src/hotspot/share/metaprogramming/removeCV.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_METAPROGRAMMING_REMOVECV_HPP #define SHARE_METAPROGRAMMING_REMOVECV_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" template struct RemoveCV: AllStatic { diff --git a/src/hotspot/share/metaprogramming/removeExtent.hpp b/src/hotspot/share/metaprogramming/removeExtent.hpp index f188e0db264..3f93dd3eeb6 100644 --- a/src/hotspot/share/metaprogramming/removeExtent.hpp +++ b/src/hotspot/share/metaprogramming/removeExtent.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_METAPROGRAMMING_REMOVEEXTENT_HPP #define SHARE_METAPROGRAMMING_REMOVEEXTENT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" template struct RemoveExtent: AllStatic { typedef T type; }; diff --git a/src/hotspot/share/metaprogramming/removePointer.hpp b/src/hotspot/share/metaprogramming/removePointer.hpp index be0f5b6e6fb..eb267c0702d 100644 --- a/src/hotspot/share/metaprogramming/removePointer.hpp +++ b/src/hotspot/share/metaprogramming/removePointer.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_METAPROGRAMMING_REMOVEPOINTER_HPP #define SHARE_METAPROGRAMMING_REMOVEPOINTER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // This metafunction returns for a type T either the underlying type behind // the pointer iff T is a pointer type (irrespective of CV qualifiers), diff --git a/src/hotspot/share/metaprogramming/removeReference.hpp b/src/hotspot/share/metaprogramming/removeReference.hpp index 274c327a0ad..bd263d911a5 100644 --- a/src/hotspot/share/metaprogramming/removeReference.hpp +++ b/src/hotspot/share/metaprogramming/removeReference.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_METAPROGRAMMING_REMOVEREFERENCE_HPP #define SHARE_METAPROGRAMMING_REMOVEREFERENCE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // This metafunction returns for a type T either the underlying type behind // the reference iff T is a reference type, or the same type T if T is not diff --git a/src/hotspot/share/oops/access.hpp b/src/hotspot/share/oops/access.hpp index c3f3d0ba45c..47e6bd27ea0 100644 --- a/src/hotspot/share/oops/access.hpp +++ b/src/hotspot/share/oops/access.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_OOPS_ACCESS_HPP #define SHARE_OOPS_ACCESS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/accessBackend.hpp" #include "oops/accessDecorators.hpp" #include "oops/oopsHierarchy.hpp" diff --git a/src/hotspot/share/oops/accessDecorators.hpp b/src/hotspot/share/oops/accessDecorators.hpp index 21bcff9113d..976f2e355e1 100644 --- a/src/hotspot/share/oops/accessDecorators.hpp +++ b/src/hotspot/share/oops/accessDecorators.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -26,7 +26,7 @@ #define SHARE_OOPS_ACCESSDECORATORS_HPP #include "gc/shared/barrierSetConfig.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "metaprogramming/integralConstant.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/oops/compressedOops.hpp b/src/hotspot/share/oops/compressedOops.hpp index 83f18138b5a..2755b1eef92 100644 --- a/src/hotspot/share/oops/compressedOops.hpp +++ b/src/hotspot/share/oops/compressedOops.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_OOPS_COMPRESSEDOOPS_HPP #define SHARE_OOPS_COMPRESSEDOOPS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/memRegion.hpp" #include "oops/oopsHierarchy.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/prims/jniFastGetField.hpp b/src/hotspot/share/prims/jniFastGetField.hpp index 4673d2cb5c9..525ff0aba87 100644 --- a/src/hotspot/share/prims/jniFastGetField.hpp +++ b/src/hotspot/share/prims/jniFastGetField.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_PRIMS_JNIFASTGETFIELD_HPP #define SHARE_PRIMS_JNIFASTGETFIELD_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "prims/jvm_misc.hpp" // Basic logic of a fast version of jni_GetField: diff --git a/src/hotspot/share/prims/jvmtiEventController.hpp b/src/hotspot/share/prims/jvmtiEventController.hpp index 69156d27108..06a3e801876 100644 --- a/src/hotspot/share/prims/jvmtiEventController.hpp +++ b/src/hotspot/share/prims/jvmtiEventController.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -26,7 +26,7 @@ #define SHARE_PRIMS_JVMTIEVENTCONTROLLER_HPP #include "jvmtifiles/jvmti.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "utilities/globalDefinitions.hpp" // forward declaration diff --git a/src/hotspot/share/prims/jvmtiExtensions.hpp b/src/hotspot/share/prims/jvmtiExtensions.hpp index b1156b8be49..d44c6dd4f51 100644 --- a/src/hotspot/share/prims/jvmtiExtensions.hpp +++ b/src/hotspot/share/prims/jvmtiExtensions.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -27,7 +27,7 @@ #include "jvmtifiles/jvmti.h" #include "jvmtifiles/jvmtiEnv.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // JvmtiExtensions // diff --git a/src/hotspot/share/prims/jvmtiManageCapabilities.hpp b/src/hotspot/share/prims/jvmtiManageCapabilities.hpp index fc6ef884f07..e588be4fa15 100644 --- a/src/hotspot/share/prims/jvmtiManageCapabilities.hpp +++ b/src/hotspot/share/prims/jvmtiManageCapabilities.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -26,7 +26,7 @@ #define SHARE_PRIMS_JVMTIMANAGECAPABILITIES_HPP #include "jvmtifiles/jvmti.h" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class JvmtiManageCapabilities : public AllStatic { diff --git a/src/hotspot/share/prims/nativeLookup.hpp b/src/hotspot/share/prims/nativeLookup.hpp index a00b16c2fa4..9aafed6f272 100644 --- a/src/hotspot/share/prims/nativeLookup.hpp +++ b/src/hotspot/share/prims/nativeLookup.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_PRIMS_NATIVELOOKUP_HPP #define SHARE_PRIMS_NATIVELOOKUP_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/handles.hpp" // NativeLookup provides an interface for finding DLL entry points for diff --git a/src/hotspot/share/prims/resolvedMethodTable.hpp b/src/hotspot/share/prims/resolvedMethodTable.hpp index b89de0e419a..b437f012946 100644 --- a/src/hotspot/share/prims/resolvedMethodTable.hpp +++ b/src/hotspot/share/prims/resolvedMethodTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_PRIMS_RESOLVEDMETHODTABLE_HPP #define SHARE_PRIMS_RESOLVEDMETHODTABLE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/symbol.hpp" #include "oops/weakHandle.hpp" diff --git a/src/hotspot/share/prims/vectorSupport.hpp b/src/hotspot/share/prims/vectorSupport.hpp index 324400c198d..ccae8bbcfc0 100644 --- a/src/hotspot/share/prims/vectorSupport.hpp +++ b/src/hotspot/share/prims/vectorSupport.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -27,7 +27,7 @@ #include "jni.h" #include "code/debugInfo.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/typeArrayOop.hpp" #include "runtime/registerMap.hpp" #include "utilities/exceptions.hpp" diff --git a/src/hotspot/share/runtime/abstract_vm_version.hpp b/src/hotspot/share/runtime/abstract_vm_version.hpp index d2f210ca04d..a1dd51dad2c 100644 --- a/src/hotspot/share/runtime/abstract_vm_version.hpp +++ b/src/hotspot/share/runtime/abstract_vm_version.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_ABSTRACT_VM_VERSION_HPP #define SHARE_RUNTIME_ABSTRACT_VM_VERSION_HPP -#include "memory/allocation.hpp" // For declaration of class AllStatic +#include "memory/allStatic.hpp" // For declaration of class AllStatic #include "utilities/globalDefinitions.hpp" typedef enum { diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index 7b03205cb08..19bb12196e3 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -27,7 +27,7 @@ #include "logging/logLevel.hpp" #include "logging/logTag.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/globals.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" diff --git a/src/hotspot/share/runtime/handshake.hpp b/src/hotspot/share/runtime/handshake.hpp index f66c731cc2d..f6a8e28a037 100644 --- a/src/hotspot/share/runtime/handshake.hpp +++ b/src/hotspot/share/runtime/handshake.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_HANDSHAKE_HPP #define SHARE_RUNTIME_HANDSHAKE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/iterator.hpp" #include "runtime/flags/flagSetting.hpp" #include "runtime/mutex.hpp" diff --git a/src/hotspot/share/runtime/icache.hpp b/src/hotspot/share/runtime/icache.hpp index 522fc5ed1fe..d273372a877 100644 --- a/src/hotspot/share/runtime/icache.hpp +++ b/src/hotspot/share/runtime/icache.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_ICACHE_HPP #define SHARE_RUNTIME_ICACHE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/stubCodeGenerator.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/share/runtime/jniHandles.hpp b/src/hotspot/share/runtime/jniHandles.hpp index 0ec73966f20..f1d9ee43529 100644 --- a/src/hotspot/share/runtime/jniHandles.hpp +++ b/src/hotspot/share/runtime/jniHandles.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_JNIHANDLES_HPP #define SHARE_RUNTIME_JNIHANDLES_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/handles.hpp" class JavaThread; diff --git a/src/hotspot/share/runtime/orderAccess.hpp b/src/hotspot/share/runtime/orderAccess.hpp index 8e5944916f9..159fbd9038d 100644 --- a/src/hotspot/share/runtime/orderAccess.hpp +++ b/src/hotspot/share/runtime/orderAccess.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_ORDERACCESS_HPP #define SHARE_RUNTIME_ORDERACCESS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/vm_version.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/share/runtime/prefetch.hpp b/src/hotspot/share/runtime/prefetch.hpp index dac34f6cd26..d949899813c 100644 --- a/src/hotspot/share/runtime/prefetch.hpp +++ b/src/hotspot/share/runtime/prefetch.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_PREFETCH_HPP #define SHARE_RUNTIME_PREFETCH_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // If calls to prefetch methods are in a loop, the loop should be cloned // such that if Prefetch{Scan,Copy}Interval and/or PrefetchFieldInterval diff --git a/src/hotspot/share/runtime/reflectionUtils.hpp b/src/hotspot/share/runtime/reflectionUtils.hpp index a928c50596e..ef9f8bbd62e 100644 --- a/src/hotspot/share/runtime/reflectionUtils.hpp +++ b/src/hotspot/share/runtime/reflectionUtils.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_REFLECTIONUTILS_HPP #define SHARE_RUNTIME_REFLECTIONUTILS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/instanceKlass.hpp" #include "oops/objArrayOop.hpp" #include "oops/oopsHierarchy.hpp" diff --git a/src/hotspot/share/runtime/safepoint.hpp b/src/hotspot/share/runtime/safepoint.hpp index 8024ade2520..e67c960626b 100644 --- a/src/hotspot/share/runtime/safepoint.hpp +++ b/src/hotspot/share/runtime/safepoint.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_SAFEPOINT_HPP #define SHARE_RUNTIME_SAFEPOINT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/os.hpp" #include "runtime/thread.hpp" #include "runtime/vmOperation.hpp" diff --git a/src/hotspot/share/runtime/sharedRuntime.hpp b/src/hotspot/share/runtime/sharedRuntime.hpp index 1adc9661985..10e4b0ec0af 100644 --- a/src/hotspot/share/runtime/sharedRuntime.hpp +++ b/src/hotspot/share/runtime/sharedRuntime.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -29,7 +29,7 @@ #include "code/vmreg.hpp" #include "interpreter/bytecodeTracer.hpp" #include "interpreter/linkResolver.hpp" -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/resourceArea.hpp" #include "utilities/hashtable.hpp" #include "utilities/macros.hpp" diff --git a/src/hotspot/share/runtime/stackWatermark.hpp b/src/hotspot/share/runtime/stackWatermark.hpp index 3cf7ce59cd9..6210a0bc2bf 100644 --- a/src/hotspot/share/runtime/stackWatermark.hpp +++ b/src/hotspot/share/runtime/stackWatermark.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_STACKWATERMARK_HPP #define SHARE_RUNTIME_STACKWATERMARK_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/mutex.hpp" #include "runtime/stackWatermarkKind.hpp" diff --git a/src/hotspot/share/runtime/threadLocalStorage.hpp b/src/hotspot/share/runtime/threadLocalStorage.hpp index 93607612a4d..604b624757e 100644 --- a/src/hotspot/share/runtime/threadLocalStorage.hpp +++ b/src/hotspot/share/runtime/threadLocalStorage.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_RUNTIME_THREADLOCALSTORAGE_HPP #define SHARE_RUNTIME_THREADLOCALSTORAGE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" // forward-decl as we can't have an include cycle class Thread; diff --git a/src/hotspot/share/services/attachListener.hpp b/src/hotspot/share/services/attachListener.hpp index 25fad127d0f..5765240c16c 100644 --- a/src/hotspot/share/services/attachListener.hpp +++ b/src/hotspot/share/services/attachListener.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_SERVICES_ATTACHLISTENER_HPP #define SHARE_SERVICES_ATTACHLISTENER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/atomic.hpp" #include "runtime/globals.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/services/gcNotifier.hpp b/src/hotspot/share/services/gcNotifier.hpp index a13b85e0e69..1a4582025c4 100644 --- a/src/hotspot/share/services/gcNotifier.hpp +++ b/src/hotspot/share/services/gcNotifier.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_SERVICES_GCNOTIFIER_HPP #define SHARE_SERVICES_GCNOTIFIER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "services/memoryPool.hpp" #include "services/memoryService.hpp" #include "services/memoryManager.hpp" diff --git a/src/hotspot/share/services/lowMemoryDetector.hpp b/src/hotspot/share/services/lowMemoryDetector.hpp index 09bb1ce6406..3070eb00ab7 100644 --- a/src/hotspot/share/services/lowMemoryDetector.hpp +++ b/src/hotspot/share/services/lowMemoryDetector.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_SERVICES_LOWMEMORYDETECTOR_HPP #define SHARE_SERVICES_LOWMEMORYDETECTOR_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "oops/oopHandle.hpp" #include "runtime/atomic.hpp" #include "services/memoryPool.hpp" diff --git a/src/hotspot/share/services/nmtCommon.hpp b/src/hotspot/share/services/nmtCommon.hpp index b573fb6b7df..dc85338c025 100644 --- a/src/hotspot/share/services/nmtCommon.hpp +++ b/src/hotspot/share/services/nmtCommon.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_SERVICES_NMTCOMMON_HPP #define SHARE_SERVICES_NMTCOMMON_HPP -#include "memory/allocation.hpp" +#include "memory/allocation.hpp" // for MEMFLAGS only #include "utilities/align.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/services/threadIdTable.hpp b/src/hotspot/share/services/threadIdTable.hpp index 223b57fcecb..12772aed88c 100644 --- a/src/hotspot/share/services/threadIdTable.hpp +++ b/src/hotspot/share/services/threadIdTable.hpp @@ -26,7 +26,7 @@ #ifndef SHARE_SERVICES_THREADIDTABLE_HPP #define SHARE_SERVICES_THREADIDTABLE_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class JavaThread; class ThreadsList; diff --git a/src/hotspot/share/utilities/decoder.hpp b/src/hotspot/share/utilities/decoder.hpp index ccf3ac4ba3c..b0a368fd058 100644 --- a/src/hotspot/share/utilities/decoder.hpp +++ b/src/hotspot/share/utilities/decoder.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -26,7 +26,7 @@ #ifndef SHARE_UTILITIES_DECODER_HPP #define SHARE_UTILITIES_DECODER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/mutex.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/ostream.hpp" diff --git a/src/hotspot/share/utilities/globalCounter.hpp b/src/hotspot/share/utilities/globalCounter.hpp index beba72a954a..5f5eba263b9 100644 --- a/src/hotspot/share/utilities/globalCounter.hpp +++ b/src/hotspot/share/utilities/globalCounter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_UTILITIES_GLOBALCOUNTER_HPP #define SHARE_UTILITIES_GLOBALCOUNTER_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "memory/padded.hpp" class Thread; diff --git a/src/hotspot/share/utilities/quickSort.hpp b/src/hotspot/share/utilities/quickSort.hpp index 000f1bf4f42..a94a7cd8b6c 100644 --- a/src/hotspot/share/utilities/quickSort.hpp +++ b/src/hotspot/share/utilities/quickSort.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_UTILITIES_QUICKSORT_HPP #define SHARE_UTILITIES_QUICKSORT_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" #include "runtime/globals.hpp" #include "utilities/debug.hpp" diff --git a/src/hotspot/share/utilities/stringUtils.cpp b/src/hotspot/share/utilities/stringUtils.cpp index 21fb7a6e8d3..0ee73de809a 100644 --- a/src/hotspot/share/utilities/stringUtils.cpp +++ b/src/hotspot/share/utilities/stringUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -26,6 +26,8 @@ #include "utilities/debug.hpp" #include "utilities/stringUtils.hpp" +#include + int StringUtils::replace_no_expand(char* string, const char* from, const char* to) { int replace_count = 0; size_t from_len = strlen(from); diff --git a/src/hotspot/share/utilities/stringUtils.hpp b/src/hotspot/share/utilities/stringUtils.hpp index 372222d7c70..54d6847a4c4 100644 --- a/src/hotspot/share/utilities/stringUtils.hpp +++ b/src/hotspot/share/utilities/stringUtils.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -25,7 +25,7 @@ #ifndef SHARE_UTILITIES_STRINGUTILS_HPP #define SHARE_UTILITIES_STRINGUTILS_HPP -#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" class StringUtils : AllStatic { public: diff --git a/src/hotspot/share/utilities/utf8.cpp b/src/hotspot/share/utilities/utf8.cpp index 6ebeb9a6c9b..81ad02a9ba6 100644 --- a/src/hotspot/share/utilities/utf8.cpp +++ b/src/hotspot/share/utilities/utf8.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -23,8 +23,12 @@ */ #include "precompiled.hpp" +#include "memory/allocation.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/utf8.hpp" + // Assume the utf8 string is in legal form and has been // checked in the class file parser/format checker. template char* UTF8::next(const char* str, T* value) { diff --git a/src/hotspot/share/utilities/utf8.hpp b/src/hotspot/share/utilities/utf8.hpp index 0ebd65b0658..e7b2905e046 100644 --- a/src/hotspot/share/utilities/utf8.hpp +++ b/src/hotspot/share/utilities/utf8.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -25,7 +25,9 @@ #ifndef SHARE_UTILITIES_UTF8_HPP #define SHARE_UTILITIES_UTF8_HPP -#include "memory/allocation.hpp" +#include "jni.h" +#include "memory/allStatic.hpp" +#include "utilities/debug.hpp" // Low-level interface for UTF8 strings diff --git a/test/hotspot/gtest/classfile/test_AltHashing.cpp b/test/hotspot/gtest/classfile/test_AltHashing.cpp index d11dc0fb4a2..0070c4fd2c1 100644 --- a/test/hotspot/gtest/classfile/test_AltHashing.cpp +++ b/test/hotspot/gtest/classfile/test_AltHashing.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -24,6 +24,7 @@ #include "classfile/altHashing.hpp" #include "utilities/debug.hpp" #include "utilities/formatBuffer.hpp" +#include "utilities/globalDefinitions.hpp" #include "unittest.hpp" class AltHashingTest : public ::testing::Test { -- GitLab From 1b14157677b34891385f643a76a7aa19d7003acf Mon Sep 17 00:00:00 2001 From: Tobias Holenstein <71546117+tobiasholenstein@users.noreply.github.com> Date: Tue, 25 Jan 2022 09:59:55 +0000 Subject: [PATCH 019/400] 8280274: Guard printing code of Compile::print_method in PRODUCT Reviewed-by: thartmann, neliasso --- src/hotspot/share/opto/compile.cpp | 10 ++++++---- src/hotspot/share/opto/compile.hpp | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index b0a2b3241e7..c730d1d9c98 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -2357,7 +2357,7 @@ void Compile::inline_vector_reboxing_calls() { CallGenerator* cg = _vector_reboxing_late_inlines.pop(); cg->do_late_inline(); if (failing()) return; - print_method(PHASE_INLINE_VECTOR_REBOX, cg->call_node()); + print_method(PHASE_INLINE_VECTOR_REBOX, cg->call_node(), 3); } _vector_reboxing_late_inlines.trunc_to(0); } @@ -4815,10 +4815,11 @@ void Compile::sort_macro_nodes() { } void Compile::print_method(CompilerPhaseType cpt, int level) { - print_method_impl(cpt, CompilerPhaseTypeHelper::to_string(cpt), level); + print_method_impl(cpt, NOT_PRODUCT(CompilerPhaseTypeHelper::to_string(cpt) COMMA) level); } void Compile::print_method(CompilerPhaseType cpt, Node* n, int level) { +#ifndef PRODUCT ResourceMark rm; stringStream ss; ss.print_raw(CompilerPhaseTypeHelper::to_string(cpt)); @@ -4827,10 +4828,11 @@ void Compile::print_method(CompilerPhaseType cpt, Node* n, int level) { } else { ss.print_raw(": NULL"); } - C->print_method_impl(cpt, ss.as_string(), level); +#endif + C->print_method_impl(cpt, NOT_PRODUCT(ss.as_string() COMMA) level); } -void Compile::print_method_impl(CompilerPhaseType cpt, const char *name, int level) { +void Compile::print_method_impl(CompilerPhaseType cpt, NOT_PRODUCT(const char* name COMMA) int level) { EventCompilerPhase event; if (event.should_commit()) { CompilerEvent::PhaseEvent::post(event, C->_latest_stage_start_counter, cpt, C->_compile_id, level); diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp index 9b2fd80b589..0bf6b88eb17 100644 --- a/src/hotspot/share/opto/compile.hpp +++ b/src/hotspot/share/opto/compile.hpp @@ -656,8 +656,8 @@ class Compile : public Phase { bool should_print_igv(int level); void print_method(CompilerPhaseType cpt, int level); - void print_method(CompilerPhaseType cpt, Node* n, int level = 3); - void print_method_impl(CompilerPhaseType cpt, const char *name, int level); + void print_method(CompilerPhaseType cpt, Node* n, int level); + void print_method_impl(CompilerPhaseType cpt, NOT_PRODUCT(const char* name COMMA) int level); #ifndef PRODUCT void igv_print_method_to_file(const char* phase_name = "Debug", bool append = false); -- GitLab From c43ce85f01c96a4b80b971865306254c9417e549 Mon Sep 17 00:00:00 2001 From: Lutz Schmidt Date: Tue, 25 Jan 2022 10:07:07 +0000 Subject: [PATCH 020/400] 8278302: [s390] Implement fast-path for ASCII-compatible CharsetEncoders Reviewed-by: mdoerr --- .../cpu/s390/c2_MacroAssembler_s390.cpp | 83 +++++++++++++------ .../cpu/s390/c2_MacroAssembler_s390.hpp | 5 +- src/hotspot/cpu/s390/matcher_s390.hpp | 5 +- src/hotspot/cpu/s390/s390.ad | 24 ++++-- 4 files changed, 82 insertions(+), 35 deletions(-) diff --git a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp index 83040fb6b7f..04a6b88052c 100644 --- a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022 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 @@ -46,22 +47,44 @@ // Note: // cnt is signed int. Do not rely on high word! // counts # characters, not bytes. -// The result is the number of characters copied before the first incompatible character was found. -// If precise is true, the processing stops exactly at this point. Otherwise, the result may be off -// by a few bytes. The result always indicates the number of copied characters. -// When used as a character index, the returned value points to the first incompatible character. // -// Note: Does not behave exactly like package private StringUTF16 compress java implementation in case of failure: -// - Different number of characters may have been written to dead array (if precise is false). -// - Returns a number --- - // Strings with 4 and 8 characters were fond to occur very frequently. + // Strings with 4 and 8 characters were found to occur very frequently. // Therefore, we handle them right away with minimal overhead. Label skipShortcut, skip4Shortcut, skip8Shortcut; Register Rout = Z_R0; @@ -133,7 +156,8 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R if (VM_Version::has_VectorFacility()) { const int min_vcnt = 32; // Minimum #characters required to use vector instructions. // Otherwise just do nothing in vector mode. - // Must be multiple of 2*(vector register length in chars (8 HW = 128 bits)). + // Must correspond to # vector registers used by implementation, + // and must be a power of 2. const int log_min_vcnt = exact_log2(min_vcnt); Label VectorLoop, VectorDone, VectorBreak; @@ -150,7 +174,7 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R z_brz(VectorDone); // not enough data for vector loop z_vzero(Vzero); // all zeroes - z_vgmh(Vmask, 0, 7); // generate 0xff00 mask for all 2-byte elements + z_vgmh(Vmask, mask_ix_l, mask_ix_r); // generate 0xff00/0xff80 mask for all 2-byte elements z_sllg(Z_R0, Rix, log_min_vcnt); // remember #chars that will be processed by vector loop bind(VectorLoop); @@ -162,7 +186,7 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R z_vo(Vtmp2, Z_V22, Z_V23); z_vo(Vtmp1, Vtmp1, Vtmp2); z_vn(Vtmp1, Vtmp1, Vmask); - z_vceqhs(Vtmp1, Vtmp1, Vzero); // high half of all chars must be zero for successful compress. + z_vceqhs(Vtmp1, Vtmp1, Vzero); // all bits selected by mask must be zero for successful compress. z_bvnt(VectorBreak); // break vector loop if not all vector elements compare eq -> incompatible character found. // re-process data from current iteration in break handler. @@ -187,7 +211,8 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R { const int min_cnt = 8; // Minimum #characters required to use unrolled loop. // Otherwise just do nothing in unrolled loop. - // Must be multiple of 8. + // Must correspond to # registers used by implementation, + // and must be a power of 2. const int log_min_cnt = exact_log2(min_cnt); Label UnrolledLoop, UnrolledDone, UnrolledBreak; @@ -197,7 +222,7 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R z_lr(Rix, Rcnt); z_sr(Rix, Z_R0); } - z_sra(Rix, log_min_cnt); // unrolled loop count + z_sra(Rix, log_min_cnt); // unrolled loop count z_brz(UnrolledDone); bind(UnrolledLoop); @@ -244,6 +269,8 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R z_sll(Rix, log_min_cnt); // # chars not yet processed in UnrolledLoop (due to break), broken iteration not included. z_sr(Z_R0, Rix); // fix # chars processed OK so far. if (!precise) { + // Because we don't need to be precise, we just return the # of characters which have been written. + // The first illegal character is in the index range [result-min_cnt/2, result+min_cnt/2). z_lgfr(result, Z_R0); z_sllg(Z_R1, Z_R0, 1); // # src bytes already processed. Only lower 32 bits are valid! // Z_R1 contents must be treated as unsigned operand! For huge strings, @@ -274,7 +301,7 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R z_brh(ScalarDoit); z_llh(Z_R1, 0, Z_R0, Rsrc); z_bre(Scalar2Char); - z_tmll(Z_R1, 0xff00); + z_tmll(Z_R1, char_mask); z_lghi(result, 0); // cnt == 1, first char invalid, no chars successfully processed z_brnaz(AllDone); z_stc(Z_R1, 0, Z_R0, Rdst); @@ -283,11 +310,11 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R bind(Scalar2Char); z_llh(Z_R0, 2, Z_R0, Rsrc); - z_tmll(Z_R1, 0xff00); + z_tmll(Z_R1, char_mask); z_lghi(result, 0); // cnt == 2, first char invalid, no chars successfully processed z_brnaz(AllDone); z_stc(Z_R1, 0, Z_R0, Rdst); - z_tmll(Z_R0, 0xff00); + z_tmll(Z_R0, char_mask); z_lghi(result, 1); // cnt == 2, second char invalid, one char successfully processed z_brnaz(AllDone); z_stc(Z_R0, 1, Z_R0, Rdst); @@ -299,17 +326,17 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R #endif if (VM_Version::has_DistinctOpnds()) { - z_srk(Rix, Rcnt, Z_R0); // remaining # chars to compress in unrolled loop + z_srk(Rix, Rcnt, Z_R0); // remaining # chars to compress in scalar loop } else { z_lr(Rix, Rcnt); z_sr(Rix, Z_R0); } - z_lgfr(result, Rcnt); // # processed characters (if all runs ok). - z_brz(ScalarDone); // uses CC from Rix calculation + z_lgfr(result, Rcnt); // # processed characters (if all encodes ok). + z_brz(ScalarDone); // anything left to do? (uses CC from Rix calculation) bind(ScalarLoop); z_llh(Z_R1, 0, Z_R0, Rsrc); - z_tmll(Z_R1, 0xff00); + z_tmll(Z_R1, char_mask); z_brnaz(ScalarBreak); z_stc(Z_R1, 0, Z_R0, Rdst); add2reg(Rsrc, 2); @@ -329,7 +356,11 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R bind(AllDone); if (precise) { - BLOCK_COMMENT("} encode_iso_array"); + if (toASCII) { + BLOCK_COMMENT("} encode_ascii_array"); + } else { + BLOCK_COMMENT("} encode_iso_array"); + } } else { BLOCK_COMMENT("} string_compress"); } diff --git a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.hpp b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.hpp index 08112a482d0..a6c98656495 100644 --- a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.hpp +++ b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.hpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022 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 @@ -38,7 +39,7 @@ // Early clobber: result. // Boolean precise controls accuracy of result value. unsigned int string_compress(Register result, Register src, Register dst, Register cnt, - Register tmp, bool precise); + Register tmp, bool precise, bool toASCII); // Inflate byte[] to char[]. unsigned int string_inflate_trot(Register src, Register dst, Register cnt, Register tmp); diff --git a/src/hotspot/cpu/s390/matcher_s390.hpp b/src/hotspot/cpu/s390/matcher_s390.hpp index d95e3c17f43..ac55bd84dff 100644 --- a/src/hotspot/cpu/s390/matcher_s390.hpp +++ b/src/hotspot/cpu/s390/matcher_s390.hpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022 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 @@ -150,6 +151,6 @@ } // Implements a variant of EncodeISOArrayNode that encode ASCII only - static const bool supports_encode_ascii_array = false; + static const bool supports_encode_ascii_array = true; #endif // CPU_S390_MATCHER_S390_HPP diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad index 8a6e62a809b..74ad8ef40d3 100644 --- a/src/hotspot/cpu/s390/s390.ad +++ b/src/hotspot/cpu/s390/s390.ad @@ -1,6 +1,6 @@ // -// Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2017, 2020 SAP SE. All rights reserved. +// Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2017, 2022 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 @@ -10230,7 +10230,7 @@ instruct string_compress(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI tm format %{ "String Compress $src->$dst($len) -> $result" %} ins_encode %{ __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register, - $tmp$$Register, false); + $tmp$$Register, false, false); %} ins_pipe(pipe_class_dummy); %} @@ -10291,10 +10291,24 @@ instruct encode_iso_array(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI t match(Set result (EncodeISOArray src (Binary dst len))); effect(TEMP_DEF result, TEMP tmp, KILL cr); // R0, R1 are killed, too. ins_cost(300); - format %{ "Encode array $src->$dst($len) -> $result" %} + format %{ "Encode iso array $src->$dst($len) -> $result" %} ins_encode %{ __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register, - $tmp$$Register, true); + $tmp$$Register, true, false); + %} + ins_pipe(pipe_class_dummy); +%} + +// encode char[] to byte[] in ASCII +instruct encode_ascii_array(iRegP src, iRegP dst, iRegI result, iRegI len, iRegI tmp, flagsReg cr) %{ + predicate(((EncodeISOArrayNode*)n)->is_ascii()); + match(Set result (EncodeISOArray src (Binary dst len))); + effect(TEMP_DEF result, TEMP tmp, KILL cr); // R0, R1 are killed, too. + ins_cost(300); + format %{ "Encode ascii array $src->$dst($len) -> $result" %} + ins_encode %{ + __ string_compress($result$$Register, $src$$Register, $dst$$Register, $len$$Register, + $tmp$$Register, true, true); %} ins_pipe(pipe_class_dummy); %} -- GitLab From 28796cbd1d15de678b80295418f5d1f9f59176a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jeli=C5=84ski?= Date: Tue, 25 Jan 2022 11:10:51 +0000 Subject: [PATCH 021/400] 8163921: HttpURLConnection default Accept header is malformed according to HTTP/1.1 RFC Reviewed-by: dfuchs, michaelm --- .../net/www/protocol/http/HttpURLConnection.java | 5 ++--- test/jdk/sun/net/www/B8185898.java | 16 ++++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index cba385f04fa..c3d33014409 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -288,8 +288,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } static final String httpVersion = "HTTP/1.1"; - static final String acceptString = - "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"; + static final String acceptString = "*/*"; // the following http request headers should NOT have their values // returned for security reasons. diff --git a/test/jdk/sun/net/www/B8185898.java b/test/jdk/sun/net/www/B8185898.java index a50c6f93c7e..cfa54e15a52 100644 --- a/test/jdk/sun/net/www/B8185898.java +++ b/test/jdk/sun/net/www/B8185898.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -23,7 +23,7 @@ /** * @test - * @bug 8185898 + * @bug 8185898 8163921 * @modules java.base/sun.net.www * @library /test/lib * @run main/othervm B8185898 @@ -143,32 +143,32 @@ public class B8185898 { // {{inputString1, expectedToString1, expectedPrint1}, {...}} String[][] strings = { {"HTTP/1.1 200 OK\r\n" - + "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n" + + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Host: 127.0.0.1:12345\r\n" + "User-agent: Java/12\r\n\r\nfoooo", "pairs: {null: HTTP/1.1 200 OK}" - + "{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}" + + "{Accept: */*}" + "{Connection: keep-alive}" + "{Host: 127.0.0.1:12345}" + "{User-agent: Java/12}", - "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n" + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Host: 127.0.0.1:12345\r\n" + "User-agent: Java/12\r\n\r\n"}, {"HTTP/1.1 200 OK\r\n" - + "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n" + + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Host: 127.0.0.1:12345\r\n" + "User-agent: Java/12\r\n" + "X-Header:\r\n\r\n", "pairs: {null: HTTP/1.1 200 OK}" - + "{Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2}" + + "{Accept: */*}" + "{Connection: keep-alive}" + "{Host: 127.0.0.1:12345}" + "{User-agent: Java/12}" + "{X-Header: }", - "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\n" + "Accept: */*\r\n" + "Connection: keep-alive\r\n" + "Host: 127.0.0.1:12345\r\n" + "User-agent: Java/12\r\n" -- GitLab From 36fbec78be837fe1defb72f39c6e3f2b5135fddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jeli=C5=84ski?= Date: Tue, 25 Jan 2022 11:15:47 +0000 Subject: [PATCH 022/400] 8280241: (aio) AsynchronousSocketChannel init fails in IPv6 only Windows env Reviewed-by: dfuchs, alanb --- .../libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c | 6 +++++- .../native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c index a08f3a3564f..340bbb9c8de 100644 --- a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c +++ b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -69,6 +69,10 @@ Java_sun_nio_ch_WindowsAsynchronousServerSocketChannelImpl_initIDs(JNIEnv* env, DWORD dwBytes; s = socket(AF_INET, SOCK_STREAM, 0); + if (s == INVALID_SOCKET && WSAGetLastError() == WSAEAFNOSUPPORT) { + /* IPv4 unavailable... try IPv6 instead */ + s = socket(AF_INET6, SOCK_STREAM, 0); + } if (s == INVALID_SOCKET) { JNU_ThrowIOExceptionWithLastError(env, "socket failed"); return; diff --git a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c index 40b8d8ba8dc..6b1fa64e708 100644 --- a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c +++ b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -66,6 +66,10 @@ Java_sun_nio_ch_WindowsAsynchronousSocketChannelImpl_initIDs(JNIEnv* env, jclass DWORD dwBytes; s = socket(AF_INET, SOCK_STREAM, 0); + if (s == INVALID_SOCKET && WSAGetLastError() == WSAEAFNOSUPPORT) { + /* IPv4 unavailable... try IPv6 instead */ + s = socket(AF_INET6, SOCK_STREAM, 0); + } if (s == INVALID_SOCKET) { JNU_ThrowIOExceptionWithLastError(env, "socket failed"); return; -- GitLab From 4503d0431c0dd4d177cf5eb4df592f26b9d372bb Mon Sep 17 00:00:00 2001 From: Hamlin Li Date: Tue, 25 Jan 2022 12:11:21 +0000 Subject: [PATCH 023/400] 8280375: G1: Tighten mem region limit in G1RebuildRemSetHeapRegionClosure Reviewed-by: tschatzl, ayang --- src/hotspot/share/gc/g1/g1RemSet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index 603ddbc1e26..13977348825 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -1958,7 +1958,7 @@ public: HeapWord* const top_at_mark_start = hr->prev_top_at_mark_start(); HeapWord* cur = hr->bottom(); - while (cur < hr->end()) { + while (true) { // After every iteration (yield point) we need to check whether the region's // TARS changed due to e.g. eager reclaim. HeapWord* const top_at_rebuild_start = _cm->top_at_rebuild_start(region_idx); -- GitLab From 496baada1021eecae03e737afe838ad6d383cba9 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Tue, 25 Jan 2022 14:09:53 +0000 Subject: [PATCH 024/400] 8280030: [REDO] Parallel: More precise boundary in ObjectStartArray::object_starts_in_range Reviewed-by: sjohanss, tschatzl --- src/hotspot/share/gc/parallel/objectStartArray.cpp | 9 ++++++++- src/hotspot/share/gc/parallel/objectStartArray.hpp | 8 +++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/gc/parallel/objectStartArray.cpp b/src/hotspot/share/gc/parallel/objectStartArray.cpp index 827ff73fb58..3e4820aa941 100644 --- a/src/hotspot/share/gc/parallel/objectStartArray.cpp +++ b/src/hotspot/share/gc/parallel/objectStartArray.cpp @@ -132,8 +132,15 @@ bool ObjectStartArray::object_starts_in_range(HeapWord* start_addr, "Range is wrong. start_addr (" PTR_FORMAT ") is after end_addr (" PTR_FORMAT ")", p2i(start_addr), p2i(end_addr)); + assert(is_aligned(start_addr, _card_size), "precondition"); + + if (start_addr == end_addr) { + // No objects in empty range. + return false; + } + jbyte* start_block = block_for_addr(start_addr); - jbyte* end_block = block_for_addr(end_addr); + jbyte* end_block = block_for_addr(end_addr - 1); for (jbyte* block = start_block; block <= end_block; block++) { if (*block != clean_block) { diff --git a/src/hotspot/share/gc/parallel/objectStartArray.hpp b/src/hotspot/share/gc/parallel/objectStartArray.hpp index be91b51cd94..06005fc0075 100644 --- a/src/hotspot/share/gc/parallel/objectStartArray.hpp +++ b/src/hotspot/share/gc/parallel/objectStartArray.hpp @@ -165,9 +165,11 @@ class ObjectStartArray : public CHeapObj { return *block != clean_block; } - // Return true if an object starts in the range of heap addresses. - // If an object starts at an address corresponding to - // "start", the method will return true. + // Return true iff an object starts in + // [start_addr, end_addr_aligned_up) + // where + // end_addr_aligned_up = align_up(end_addr, _card_size) + // Precondition: start_addr is card-size aligned bool object_starts_in_range(HeapWord* start_addr, HeapWord* end_addr) const; }; -- GitLab From fe77250fa450ec803d2818dc90c5bf156521d537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jeli=C5=84ski?= Date: Tue, 25 Jan 2022 14:41:41 +0000 Subject: [PATCH 025/400] 8280414: Memory leak in DefaultProxySelector Reviewed-by: dfuchs --- .../native/libnet/DefaultProxySelector.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/java.base/windows/native/libnet/DefaultProxySelector.c b/src/java.base/windows/native/libnet/DefaultProxySelector.c index d9107e738b3..6b91874eda1 100644 --- a/src/java.base/windows/native/libnet/DefaultProxySelector.c +++ b/src/java.base/windows/native/libnet/DefaultProxySelector.c @@ -104,7 +104,6 @@ static int createProxyList(LPWSTR win_proxy, const WCHAR *pproto, list_item **he int nr_elems = 0; wchar_t *context = NULL; wchar_t *current_proxy = NULL; - BOOL error = FALSE; /* * The proxy server list contains one or more of the following strings @@ -116,7 +115,6 @@ static int createProxyList(LPWSTR win_proxy, const WCHAR *pproto, list_item **he LPWSTR pport; LPWSTR phost; int portVal = 0; - wchar_t *next_proxy = NULL; list_item *proxy = NULL; wchar_t* pos = NULL; @@ -292,7 +290,6 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env, } if (win_proxy != NULL) { - wchar_t *context = NULL; int defport = 0; int nr_elems = 0; @@ -315,27 +312,28 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env, nr_elems = createProxyList(win_proxy, lpProto, &head); if (nr_elems != 0 && head != NULL) { int index = 0; + list_item *current = head; proxy_array = (*env)->NewObjectArray(env, nr_elems, proxy_class, NULL); if (proxy_array == NULL || (*env)->ExceptionCheck(env)) { goto noproxy; } - while (head != NULL && index < nr_elems) { + while (current != NULL && index < nr_elems) { jstring jhost; jobject isa; jobject proxy; - if (head->host != NULL && proxy_array != NULL) { + if (current->host != NULL && proxy_array != NULL) { /* Let's create the appropriate Proxy object then. */ - if (head->port == 0) { - head->port = defport; + if (current->port == 0) { + current->port = defport; } - jhost = (*env)->NewString(env, head->host, (jsize)wcslen(head->host)); + jhost = (*env)->NewString(env, current->host, (jsize)wcslen(current->host)); if (jhost == NULL || (*env)->ExceptionCheck(env)) { proxy_array = NULL; } isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, - head->port); + current->port); if (isa == NULL || (*env)->ExceptionCheck(env)) { proxy_array = NULL; } @@ -349,7 +347,7 @@ Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env, } index++; } - head = head->next; + current = current->next; } } } -- GitLab From 674a97b27ef621e7b54c13c121c625f91df5ee60 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Tue, 25 Jan 2022 16:27:30 +0000 Subject: [PATCH 026/400] 8280396: G1: Full gc mark stack draining should prefer to make work available to other threads Reviewed-by: sjohanss, ayang --- src/hotspot/share/gc/g1/g1FullGCMarker.hpp | 12 +++-- .../share/gc/g1/g1FullGCMarker.inline.hpp | 46 +++++++++++++------ 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1FullGCMarker.hpp b/src/hotspot/share/gc/g1/g1FullGCMarker.hpp index ec7f029b7ce..2d935d863c5 100644 --- a/src/hotspot/share/gc/g1/g1FullGCMarker.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCMarker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -71,8 +71,6 @@ class G1FullGCMarker : public CHeapObj { G1RegionMarkStatsCache _mark_stats_cache; inline bool is_empty(); - inline bool pop_object(oop& obj); - inline bool pop_objarray(ObjArrayTask& array); inline void push_objarray(oop obj, size_t index); inline bool mark_object(oop obj); @@ -80,6 +78,14 @@ class G1FullGCMarker : public CHeapObj { inline void follow_object(oop obj); inline void follow_array(objArrayOop array); inline void follow_array_chunk(objArrayOop array, int index); + + inline void drain_oop_stack(); + // Transfer contents from the objArray task queue overflow stack to the shared + // objArray stack. + // Returns true and a valid task if there has not been enough space in the shared + // objArray stack, otherwise the task is invalid. + inline bool transfer_objArray_overflow_stack(ObjArrayTask& task); + public: G1FullGCMarker(G1FullCollector* collector, uint worker_id, diff --git a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp index c261c150e46..a68bae5ced6 100644 --- a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -91,20 +91,12 @@ inline bool G1FullGCMarker::is_empty() { return _oop_stack.is_empty() && _objarray_stack.is_empty(); } -inline bool G1FullGCMarker::pop_object(oop& oop) { - return _oop_stack.pop_overflow(oop) || _oop_stack.pop_local(oop); -} - inline void G1FullGCMarker::push_objarray(oop obj, size_t index) { ObjArrayTask task(obj, index); assert(task.is_valid(), "bad ObjArrayTask"); _objarray_stack.push(task); } -inline bool G1FullGCMarker::pop_objarray(ObjArrayTask& arr) { - return _objarray_stack.pop_overflow(arr) || _objarray_stack.pop_local(arr); -} - inline void G1FullGCMarker::follow_array(objArrayOop array) { follow_klass(array->klass()); // Don't push empty arrays to avoid unnecessary work. @@ -159,16 +151,40 @@ inline void G1FullGCMarker::follow_object(oop obj) { } } -void G1FullGCMarker::drain_stack() { - do { - oop obj; - while (pop_object(obj)) { +inline void G1FullGCMarker::drain_oop_stack() { + oop obj; + while (_oop_stack.pop_overflow(obj)) { + if (!_oop_stack.try_push_to_taskqueue(obj)) { assert(_bitmap->is_marked(obj), "must be marked"); follow_object(obj); } - // Process ObjArrays one at a time to avoid marking stack bloat. + } + while (_oop_stack.pop_local(obj)) { + assert(_bitmap->is_marked(obj), "must be marked"); + follow_object(obj); + } +} + +inline bool G1FullGCMarker::transfer_objArray_overflow_stack(ObjArrayTask& task) { + // It is desirable to move as much as possible work from the overflow queue to + // the shared queue as quickly as possible. + while (_objarray_stack.pop_overflow(task)) { + if (!_objarray_stack.try_push_to_taskqueue(task)) { + return true; + } + } + return false; +} + +void G1FullGCMarker::drain_stack() { + do { + // First, drain regular oop stack. + drain_oop_stack(); + + // Then process ObjArrays one at a time to avoid marking stack bloat. ObjArrayTask task; - if (pop_objarray(task)) { + if (transfer_objArray_overflow_stack(task) || + _objarray_stack.pop_local(task)) { follow_array_chunk(objArrayOop(task.obj()), task.index()); } } while (!is_empty()); -- GitLab From f4575e4052bf66f1259c626e01a74d3ac593e645 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Tue, 25 Jan 2022 18:02:18 +0000 Subject: [PATCH 027/400] 8279946: (ch) java.nio.channels.FileChannel tryLock and write methods are missing @throws NonWritableChannelException Reviewed-by: alanb --- .../java/nio/channels/FileChannel.java | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/java/nio/channels/FileChannel.java b/src/java.base/share/classes/java/nio/channels/FileChannel.java index 2ea213b3509..d8fee6ca995 100644 --- a/src/java.base/share/classes/java/nio/channels/FileChannel.java +++ b/src/java.base/share/classes/java/nio/channels/FileChannel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -25,13 +25,16 @@ package java.nio.channels; -import java.io.*; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.spi.AbstractInterruptibleChannel; -import java.nio.file.*; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; import java.nio.file.attribute.FileAttribute; -import java.nio.file.spi.*; +import java.nio.file.spi.FileSystemProvider; import java.util.Set; import java.util.HashSet; import java.util.Collections; @@ -403,6 +406,9 @@ public abstract class FileChannel * with the number of bytes actually written. Otherwise this method * behaves exactly as specified by the {@link WritableByteChannel} * interface.

    + * + * @throws NonWritableChannelException + * If this channel was not opened for writing */ public abstract int write(ByteBuffer src) throws IOException; @@ -417,6 +423,9 @@ public abstract class FileChannel * with the number of bytes actually written. Otherwise this method * behaves exactly as specified in the {@link GatheringByteChannel} * interface.

    + * + * @throws NonWritableChannelException + * If this channel was not opened for writing */ public abstract long write(ByteBuffer[] srcs, int offset, int length) throws IOException; @@ -431,6 +440,9 @@ public abstract class FileChannel * with the number of bytes actually written. Otherwise this method * behaves exactly as specified in the {@link GatheringByteChannel} * interface.

    + * + * @throws NonWritableChannelException + * If this channel was not opened for writing */ public final long write(ByteBuffer[] srcs) throws IOException { return write(srcs, 0, srcs.length); @@ -1030,7 +1042,7 @@ public abstract class FileChannel * region * * @throws NonReadableChannelException - * If {@code shared} is {@code true} this channel was not + * If {@code shared} is {@code true} but this channel was not * opened for reading * * @throws NonWritableChannelException @@ -1148,6 +1160,14 @@ public abstract class FileChannel * blocked in this method and is attempting to lock an overlapping * region of the same file * + * @throws NonReadableChannelException + * If {@code shared} is {@code true} but this channel was not + * opened for reading + * + * @throws NonWritableChannelException + * If {@code shared} is {@code false} but this channel was not + * opened for writing + * * @throws IOException * If some other I/O error occurs * @@ -1180,6 +1200,9 @@ public abstract class FileChannel * blocked in this method and is attempting to lock an overlapping * region * + * @throws NonWritableChannelException + * If this channel was not opened for writing + * * @throws IOException * If some other I/O error occurs * -- GitLab From cbe8395ace3230dc599c7f082e3524a861b2da8e Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 25 Jan 2022 18:15:37 +0000 Subject: [PATCH 028/400] 8280168: Add Objects.toIdentityString Reviewed-by: alanb, mchung, rriggs, smarks --- .../java/lang/invoke/MethodHandleProxies.java | 2 +- .../share/classes/java/util/Objects.java | 26 ++++++++++++- .../java/util/Objects/BasicObjectsTest.java | 37 +++++++++++++++++-- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java index 784d672ff8f..c1c34185ffb 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java @@ -292,7 +292,7 @@ public class MethodHandleProxies { private static Object callObjectMethod(Object self, Method m, Object[] args) { assert(isObjectMethod(m)) : m; return switch (m.getName()) { - case "toString" -> self.getClass().getName() + "@" + Integer.toHexString(self.hashCode()); + case "toString" -> java.util.Objects.toIdentityString(self); case "hashCode" -> System.identityHashCode(self); case "equals" -> (self == args[0]); default -> null; diff --git a/src/java.base/share/classes/java/util/Objects.java b/src/java.base/share/classes/java/util/Objects.java index c32a67441da..0b727d6310b 100644 --- a/src/java.base/share/classes/java/util/Objects.java +++ b/src/java.base/share/classes/java/util/Objects.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -164,6 +164,30 @@ public final class Objects { return (o != null) ? o.toString() : nullDefault; } + /** + * {@return a string equivalent to the string returned by {@code + * Object.toString} if that method and {@code hashCode} are not + * overridden} + * + * @implNote + * This method constructs a string for an object without calling + * any overridable methods of the object. + * + * @implSpec + * The method returns a string equivalent to:
    + * {@code o.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(o))} + * + * @param o an object + * @throws NullPointerException if the argument is null + * @see Object#toString + * @see System#identityHashCode(Object) + * @since 19 + */ + public static String toIdentityString(Object o) { + requireNonNull(o); + return o.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(o)); + } + /** * Returns 0 if the arguments are identical and {@code * c.compare(a, b)} otherwise. diff --git a/test/jdk/java/util/Objects/BasicObjectsTest.java b/test/jdk/java/util/Objects/BasicObjectsTest.java index a7636ef11d5..51268d4cbaf 100644 --- a/test/jdk/java/util/Objects/BasicObjectsTest.java +++ b/test/jdk/java/util/Objects/BasicObjectsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -23,9 +23,8 @@ /* * @test - * @bug 6797535 6889858 6891113 8013712 8011800 8014365 + * @bug 6797535 6889858 6891113 8013712 8011800 8014365 8280168 * @summary Basic tests for methods in java.util.Objects - * @author Joseph D. Darcy */ import java.util.*; @@ -40,6 +39,7 @@ public class BasicObjectsTest { errors += testHash(); errors += testToString(); errors += testToString2(); + errors += testToIdentityString(); errors += testCompare(); errors += testRequireNonNull(); errors += testIsNull(); @@ -134,6 +134,37 @@ public class BasicObjectsTest { return errors; } + private static int testToIdentityString() { + int errors = 0; + // Test null behavior + try { + Objects.toIdentityString(null); + errors++; + } catch (NullPointerException npe) { + ; // Expected + } + // Behavior on typical objects + Object o = new Object(){}; + errors += (Objects.toIdentityString(o).equals(o.toString()))? 0 : 1; + // Verify object's toString *not* called + Object badToString = new Object() { + @Override + public String toString() { + throw new RuntimeException(); + } + }; + Objects.toIdentityString(badToString); + // Verify object's hashCode *not* called + Object badHashCode = new Object() { + @Override + public int hashCode() { + throw new RuntimeException("0xDEADBEFF"); + } + }; + Objects.toIdentityString(badHashCode); + return errors; + } + private static int testCompare() { int errors = 0; String[] values = {"e. e. cummings", "zzz"}; -- GitLab From cebaad1c94c301304fd146526cac95bfeaac66bf Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 25 Jan 2022 19:22:07 +0000 Subject: [PATCH 029/400] 8280041: Retry loop issues in java.io.ClassCache Co-authored-by: Peter Levart Reviewed-by: rkennke, rriggs, plevart --- .../share/classes/java/io/ClassCache.java | 53 ++++++++++++++----- .../java/io/ClassCache/ContinuousGCTest.java | 50 +++++++++++++++++ .../jdk/java/io/ClassCache/NullValueTest.java | 42 +++++++++++++++ .../java.base/java/io/NameClassCache.java | 35 ++++++++++++ .../java.base/java/io/NullClassCache.java | 34 ++++++++++++ 5 files changed, 202 insertions(+), 12 deletions(-) create mode 100644 test/jdk/java/io/ClassCache/ContinuousGCTest.java create mode 100644 test/jdk/java/io/ClassCache/NullValueTest.java create mode 100644 test/jdk/java/io/ClassCache/java.base/java/io/NameClassCache.java create mode 100644 test/jdk/java/io/ClassCache/java.base/java/io/NullClassCache.java diff --git a/src/java.base/share/classes/java/io/ClassCache.java b/src/java.base/share/classes/java/io/ClassCache.java index a3901d479ef..48e7a36c05a 100644 --- a/src/java.base/share/classes/java/io/ClassCache.java +++ b/src/java.base/share/classes/java/io/ClassCache.java @@ -28,6 +28,7 @@ package java.io; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; +import java.util.Objects; // Maps Class instances to values of type T. Under memory pressure, the // mapping is released (under soft references GC policy) and would be @@ -38,19 +39,29 @@ abstract class ClassCache { private static class CacheRef extends SoftReference { private final Class type; + private T strongReferent; CacheRef(T referent, ReferenceQueue queue, Class type) { super(referent, queue); this.type = type; + this.strongReferent = referent; } Class getType() { return type; } + + T getStrong() { + return strongReferent; + } + + void clearStrong() { + strongReferent = null; + } } private final ReferenceQueue queue; - private final ClassValue> map; + private final ClassValue> map; protected abstract T computeValue(Class cl); @@ -58,23 +69,41 @@ abstract class ClassCache { queue = new ReferenceQueue<>(); map = new ClassValue<>() { @Override - protected SoftReference computeValue(Class type) { - return new CacheRef<>(ClassCache.this.computeValue(type), queue, type); + protected CacheRef computeValue(Class type) { + T v = ClassCache.this.computeValue(type); + Objects.requireNonNull(v); + return new CacheRef<>(v, queue, type); } }; } T get(Class cl) { - processQueue(); - T val; - do { - SoftReference ref = map.get(cl); - val = ref.get(); - if (val == null) { - map.remove(cl); + while (true) { + processQueue(); + + CacheRef ref = map.get(cl); + + // Case 1: A recently created CacheRef. + // We might still have strong referent, and can return it. + // This guarantees progress for at least one thread on every CacheRef. + // Clear the strong referent before returning to make the cache soft. + T strongVal = ref.getStrong(); + if (strongVal != null) { + ref.clearStrong(); + return strongVal; + } + + // Case 2: Older or recently cleared CacheRef. + // Check if its soft referent is still available, and return it. + T val = ref.get(); + if (val != null) { + return val; } - } while (val == null); - return val; + + // Case 3: The reference was cleared. + // Clear the mapping and retry. + map.remove(cl); + } } private void processQueue() { diff --git a/test/jdk/java/io/ClassCache/ContinuousGCTest.java b/test/jdk/java/io/ClassCache/ContinuousGCTest.java new file mode 100644 index 00000000000..681663029e4 --- /dev/null +++ b/test/jdk/java/io/ClassCache/ContinuousGCTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.NameClassCache; + +/** + * @test + * @bug 8280041 + * @summary Sanity test for ClassCache under continuous GC + * @compile/module=java.base java/io/NameClassCache.java + * @run main ContinuousGCTest + */ +public class ContinuousGCTest { + static final NameClassCache CACHE = new NameClassCache(); + static final String VALUE = "ClassCache-ContinuousGCTest"; + + public static void main(String... args) throws Throwable { + for (int c = 0; c < 1000; c++) { + test(); + System.gc(); + } + } + + public static void test() { + String cached = CACHE.get(ContinuousGCTest.class); + if (!cached.equals(VALUE)) { + throw new IllegalStateException("Cache failure, got: " + cached); + } + } +} diff --git a/test/jdk/java/io/ClassCache/NullValueTest.java b/test/jdk/java/io/ClassCache/NullValueTest.java new file mode 100644 index 00000000000..22b41fa071d --- /dev/null +++ b/test/jdk/java/io/ClassCache/NullValueTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.NullClassCache; + +/** + * @test + * @bug 8280041 + * @summary Test that ClassCache throws on trying to pass null value + * @compile/module=java.base java/io/NullClassCache.java + * @run main NullValueTest + */ +public class NullValueTest { + public static void main(String... args) throws Throwable { + try { + new NullClassCache().get(Object.class); + throw new IllegalStateException("Should have failed"); + } catch (NullPointerException npe) { + // Expected + } + } +} diff --git a/test/jdk/java/io/ClassCache/java.base/java/io/NameClassCache.java b/test/jdk/java/io/ClassCache/java.base/java/io/NameClassCache.java new file mode 100644 index 00000000000..ff2149fc6a2 --- /dev/null +++ b/test/jdk/java/io/ClassCache/java.base/java/io/NameClassCache.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.io; + +public class NameClassCache extends ClassCache { + protected String computeValue(Class cl) { + // Return string that is not interned and specific to class + return "ClassCache-" + cl.getName(); + } + + public String get(Class cl) { + return super.get(cl); + } +} diff --git a/test/jdk/java/io/ClassCache/java.base/java/io/NullClassCache.java b/test/jdk/java/io/ClassCache/java.base/java/io/NullClassCache.java new file mode 100644 index 00000000000..58c92ef1399 --- /dev/null +++ b/test/jdk/java/io/ClassCache/java.base/java/io/NullClassCache.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.io; + +public class NullClassCache extends ClassCache { + protected Object computeValue(Class cl) { + return null; + } + + public Object get(Class cl) { + return super.get(cl); + } +} -- GitLab From 76fe03fe01a7c824e2e9263de95b8bcbb4b9d752 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 25 Jan 2022 19:23:02 +0000 Subject: [PATCH 030/400] 8280166: Extend java/lang/instrument/GetObjectSizeIntrinsicsTest.java test cases Reviewed-by: sspitsyn, lmesnik --- .../GetObjectSizeIntrinsicsTest.java | 116 ++++++++++++++---- 1 file changed, 89 insertions(+), 27 deletions(-) diff --git a/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java b/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java index 1417eb427a0..975adb23cf5 100644 --- a/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java +++ b/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Red Hat, Inc. All rights reserved. + * Copyright (c) 2020, 2022, Red Hat, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -264,6 +264,39 @@ * -javaagent:basicAgent.jar GetObjectSizeIntrinsicsTest GetObjectSizeIntrinsicsTest */ +/* + * @test + * @summary Test for fInst.getObjectSize with large arrays + * @library /test/lib + * @requires vm.bits == 64 + * @requires vm.debug + * @requires os.maxMemory >= 10G + * + * @build sun.hotspot.WhiteBox + * @run build GetObjectSizeIntrinsicsTest + * @run shell MakeJAR.sh basicAgent + * + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * + * @run main/othervm -Xmx8g + * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * -XX:ObjectAlignmentInBytes=32 + * -Xint + * -javaagent:basicAgent.jar GetObjectSizeIntrinsicsTest GetObjectSizeIntrinsicsTest large + * + * @run main/othervm -Xmx8g + * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * -XX:ObjectAlignmentInBytes=32 + * -Xbatch -XX:TieredStopAtLevel=1 + * -javaagent:basicAgent.jar GetObjectSizeIntrinsicsTest GetObjectSizeIntrinsicsTest large + * + * @run main/othervm -Xmx8g + * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * -XX:ObjectAlignmentInBytes=32 + * -Xbatch -XX:-TieredCompilation + * -javaagent:basicAgent.jar GetObjectSizeIntrinsicsTest GetObjectSizeIntrinsicsTest large + */ + import java.util.*; import jdk.test.lib.Platform; @@ -271,18 +304,26 @@ import sun.hotspot.WhiteBox; public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase { - static final Boolean compressedOops = WhiteBox.getWhiteBox().getBooleanVMFlag("UseCompressedOops"); - static final int REF_SIZE = (compressedOops == null || compressedOops == true) ? 4 : 8; + static final Boolean COMPRESSED_OOPS = WhiteBox.getWhiteBox().getBooleanVMFlag("UseCompressedOops"); + static final long REF_SIZE = (COMPRESSED_OOPS == null || COMPRESSED_OOPS == true) ? 4 : 8; static final Long align = WhiteBox.getWhiteBox().getIntxVMFlag("ObjectAlignmentInBytes"); static final int OBJ_ALIGN = (align == null ? 8 : align.intValue()); - public GetObjectSizeIntrinsicsTest(String name) { + static final int SMALL_ARRAY_SIZE = 1024; + + // With int[] arrays, this overflows 4G boundary + static final int LARGE_ARRAY_SIZE = 1024*1024*1024 + 1024; + + final String mode; + + public GetObjectSizeIntrinsicsTest(String name, String mode) { super(name); + this.mode = mode; } public static void main(String[] args)throws Throwable { - new GetObjectSizeIntrinsicsTest(args[0]).runTest(); + new GetObjectSizeIntrinsicsTest(args[0], (args.length >= 2 ? args[1] : "")).runTest(); } public static final int ITERS = 200_000; @@ -312,30 +353,35 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase testSize_localObject(); testSize_fieldObject(); - testSize_newSmallByteArray(); - testSize_localSmallByteArray(); - testSize_fieldSmallByteArray(); + testSize_newSmallIntArray(); + testSize_localSmallIntArray(); + testSize_fieldSmallIntArray(); testSize_newSmallObjArray(); testSize_localSmallObjArray(); testSize_fieldSmallObjArray(); + if (mode.equals("large")) { + testSize_localLargeIntArray(); + testSize_localLargeObjArray(); + } + testNulls(); } - private static int roundUp(int v, int a) { + private static long roundUp(long v, long a) { return (v + a - 1) / a * a; } private void testSize_newObject() { - int expected = roundUp(Platform.is64bit() ? 16 : 8, OBJ_ALIGN); + long expected = roundUp(Platform.is64bit() ? 16 : 8, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(new Object())); } } private void testSize_localObject() { - int expected = roundUp(Platform.is64bit() ? 16 : 8, OBJ_ALIGN); + long expected = roundUp(Platform.is64bit() ? 16 : 8, OBJ_ALIGN); Object o = new Object(); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(o)); @@ -345,60 +391,76 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase static Object staticO = new Object(); private void testSize_fieldObject() { - int expected = roundUp(Platform.is64bit() ? 16 : 8, OBJ_ALIGN); + long expected = roundUp(Platform.is64bit() ? 16 : 8, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(staticO)); } } - private void testSize_newSmallByteArray() { - int expected = roundUp(1024 + 16, OBJ_ALIGN); + private void testSize_newSmallIntArray() { + long expected = roundUp(4L*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { - assertEquals(expected, fInst.getObjectSize(new byte[1024])); + assertEquals(expected, fInst.getObjectSize(new int[SMALL_ARRAY_SIZE])); } } - private void testSize_localSmallByteArray() { - byte[] arr = new byte[1024]; - int expected = roundUp(arr.length + 16, OBJ_ALIGN); + private void testSize_localSmallIntArray() { + int[] arr = new int[SMALL_ARRAY_SIZE]; + long expected = roundUp(4L*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(arr)); } } - static byte[] smallArr = new byte[1024]; + static int[] smallArr = new int[SMALL_ARRAY_SIZE]; - private void testSize_fieldSmallByteArray() { - int expected = roundUp(smallArr.length + 16, OBJ_ALIGN); + private void testSize_fieldSmallIntArray() { + long expected = roundUp(4L*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(smallArr)); } } private void testSize_newSmallObjArray() { - int expected = roundUp(1024*REF_SIZE + 16, OBJ_ALIGN); + long expected = roundUp(REF_SIZE*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { - assertEquals(expected, fInst.getObjectSize(new Object[1024])); + assertEquals(expected, fInst.getObjectSize(new Object[SMALL_ARRAY_SIZE])); } } private void testSize_localSmallObjArray() { - Object[] arr = new Object[1024]; - int expected = roundUp(arr.length*REF_SIZE + 16, OBJ_ALIGN); + Object[] arr = new Object[SMALL_ARRAY_SIZE]; + long expected = roundUp(REF_SIZE*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(arr)); } } - static Object[] smallObjArr = new Object[1024]; + static Object[] smallObjArr = new Object[SMALL_ARRAY_SIZE]; private void testSize_fieldSmallObjArray() { - int expected = roundUp(smallArr.length*REF_SIZE + 16, OBJ_ALIGN); + long expected = roundUp(REF_SIZE*SMALL_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(smallObjArr)); } } + private void testSize_localLargeIntArray() { + int[] arr = new int[LARGE_ARRAY_SIZE]; + long expected = roundUp(4L*LARGE_ARRAY_SIZE + 16, OBJ_ALIGN); + for (int c = 0; c < ITERS; c++) { + assertEquals(expected, fInst.getObjectSize(arr)); + } + } + + private void testSize_localLargeObjArray() { + Object[] arr = new Object[LARGE_ARRAY_SIZE]; + long expected = roundUp(REF_SIZE*LARGE_ARRAY_SIZE + 16, OBJ_ALIGN); + for (int c = 0; c < ITERS; c++) { + assertEquals(expected, fInst.getObjectSize(arr)); + } + } + private void testNulls() { for (int c = 0; c < ITERS; c++) { try { -- GitLab From 841eae6f527c00115e0455c4e04f042c28a014bb Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Tue, 25 Jan 2022 19:26:11 +0000 Subject: [PATCH 031/400] 8269542: JDWP: EnableCollection support is no longer spec compliant after JDK-8255987 8258071: Fix for JDK-8255987 can be subverted with ObjectReference.EnableCollection Reviewed-by: dholmes, pliden --- .../share/native/libjdwp/commonRef.c | 73 ++++++++++++------- .../share/native/libjdwp/util.h | 5 +- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/commonRef.c b/src/jdk.jdwp.agent/share/native/libjdwp/commonRef.c index bc7ddb660bf..d55c517332b 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/commonRef.c +++ b/src/jdk.jdwp.agent/share/native/libjdwp/commonRef.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -82,6 +82,14 @@ newSeqNum(void) return gdata->nextSeqNum++; } +/* Returns true if this is a strong reference, meaning that either or both of + isPinAll and isCommonPin are true. */ +static jboolean +isStrong(RefNode* node) +{ + return node->isPinAll || node->isCommonPin; +} + /* Create a fresh RefNode structure, create a weak ref and tag the object */ static RefNode * createNode(JNIEnv *env, jobject ref) @@ -89,7 +97,7 @@ createNode(JNIEnv *env, jobject ref) RefNode *node; jobject strongOrWeakRef; jvmtiError error; - jboolean pin = gdata->pinAllCount != 0; + jboolean pinAll = gdata->pinAllCount != 0; /* Could allocate RefNode's in blocks, not sure it would help much */ node = (RefNode*)jvmtiAllocate((int)sizeof(RefNode)); @@ -97,7 +105,7 @@ createNode(JNIEnv *env, jobject ref) return NULL; } - if (pin) { + if (pinAll) { /* Create strong reference to make sure we have a reference */ strongOrWeakRef = JNI_FUNC_PTR(env,NewGlobalRef)(env, ref); } else { @@ -116,7 +124,7 @@ createNode(JNIEnv *env, jobject ref) error = JVMTI_FUNC_PTR(gdata->jvmti, SetTag) (gdata->jvmti, strongOrWeakRef, ptr_to_jlong(node)); if ( error != JVMTI_ERROR_NONE ) { - if (pin) { + if (pinAll) { JNI_FUNC_PTR(env,DeleteGlobalRef)(env, strongOrWeakRef); } else { JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, strongOrWeakRef); @@ -128,7 +136,8 @@ createNode(JNIEnv *env, jobject ref) /* Fill in RefNode */ node->ref = strongOrWeakRef; node->count = 1; - node->strongCount = pin ? 1 : 0; + node->isPinAll = pinAll; + node->isCommonPin = JNI_FALSE; node->seqNum = newSeqNum(); /* Count RefNode's created */ @@ -146,7 +155,7 @@ deleteNode(JNIEnv *env, RefNode *node) /* Clear tag */ (void)JVMTI_FUNC_PTR(gdata->jvmti,SetTag) (gdata->jvmti, node->ref, NULL_OBJECT_ID); - if (node->strongCount != 0) { + if (isStrong(node)) { JNI_FUNC_PTR(env,DeleteGlobalRef)(env, node->ref); } else { JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, node->ref); @@ -158,9 +167,9 @@ deleteNode(JNIEnv *env, RefNode *node) /* Change a RefNode to have a strong reference */ static jobject -strengthenNode(JNIEnv *env, RefNode *node) +strengthenNode(JNIEnv *env, RefNode *node, jboolean isPinAll) { - if (node->strongCount == 0) { + if (!isStrong(node)) { jobject strongRef; strongRef = JNI_FUNC_PTR(env,NewGlobalRef)(env, node->ref); @@ -176,20 +185,27 @@ strengthenNode(JNIEnv *env, RefNode *node) if (strongRef != NULL) { JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, node->ref); node->ref = strongRef; - node->strongCount = 1; + } else { + return NULL; } - return strongRef; + } + if (isPinAll) { + node->isPinAll = JNI_TRUE; } else { - node->strongCount++; - return node->ref; + node->isCommonPin = JNI_TRUE; } + return node->ref; } /* Change a RefNode to have a weak reference */ static jweak -weakenNode(JNIEnv *env, RefNode *node) +weakenNode(JNIEnv *env, RefNode *node, jboolean isUnpinAll) { - if (node->strongCount == 1) { + jboolean willStillBeStrong = (node->isPinAll && !isUnpinAll) || (node->isCommonPin && isUnpinAll); + + // If the node is strong, but the reason(s) for it being strong + // will no longer exist, then weaken it. + if (isStrong(node) && !willStillBeStrong) { jweak weakRef; weakRef = JNI_FUNC_PTR(env,NewWeakGlobalRef)(env, node->ref); @@ -200,16 +216,18 @@ weakenNode(JNIEnv *env, RefNode *node) if (weakRef != NULL) { JNI_FUNC_PTR(env,DeleteGlobalRef)(env, node->ref); - node->ref = weakRef; - node->strongCount = 0; + node->ref = weakRef; + } else { + return NULL; } - return weakRef; + } + + if (isUnpinAll) { + node->isPinAll = JNI_FALSE; } else { - if (node->strongCount > 0) { - node->strongCount--; - } - return node->ref; + node->isCommonPin = JNI_FALSE; } + return node->ref; } /* @@ -470,7 +488,7 @@ commonRef_idToRef(JNIEnv *env, jlong id) node = findNodeByID(env, id); if (node != NULL) { - if (node->strongCount != 0) { + if (isStrong(node)) { saveGlobalRef(env, node->ref, &ref); } else { jobject lref; @@ -522,7 +540,7 @@ commonRef_pin(jlong id) } else { jobject strongRef; - strongRef = strengthenNode(env, node); + strongRef = strengthenNode(env, node, JNI_FALSE /* isPinAll */); if (strongRef == NULL) { /* * Referent has been collected, clean up now. @@ -551,7 +569,7 @@ commonRef_unpin(jlong id) if (node != NULL) { jweak weakRef; - weakRef = weakenNode(env, node); + weakRef = weakenNode(env, node, JNI_FALSE /* isUnpinAll */); if (weakRef == NULL) { error = AGENT_ERROR_OUT_OF_MEMORY; } @@ -585,7 +603,7 @@ commonRef_pinAll() while (node != NULL) { jobject strongRef; - strongRef = strengthenNode(env, node); + strongRef = strengthenNode(env, node, JNI_TRUE /* isPinAll */); /* Has the object been collected? */ if (strongRef == NULL) { @@ -628,7 +646,7 @@ commonRef_unpinAll() for (node = gdata->objectsByID[i]; node != NULL; node = node->next) { jweak weakRef; - weakRef = weakenNode(env, node); + weakRef = weakenNode(env, node, JNI_TRUE /* isUnpinAll */); if (weakRef == NULL) { EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"NewWeakGlobalRef"); } @@ -676,8 +694,7 @@ commonRef_compact(void) prev = NULL; while (node != NULL) { /* Has the object been collected? */ - if ( (node->strongCount == 0) && - isSameObject(env, node->ref, NULL)) { + if (!isStrong(node) && isSameObject(env, node->ref, NULL)) { RefNode *freed; /* Detach from the ID list */ diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/util.h b/src/jdk.jdwp.agent/share/native/libjdwp/util.h index 134bf03db7a..0619648d957 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/util.h +++ b/src/jdk.jdwp.agent/share/native/libjdwp/util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -65,7 +65,8 @@ typedef struct RefNode { jobject ref; /* could be strong or weak */ struct RefNode *next; /* next RefNode* in bucket chain */ jint count; /* count of references */ - unsigned strongCount; /* count of strong reference */ + jboolean isPinAll; /* true if this is a strong reference due to a commonRef_pinAll() */ + jboolean isCommonPin; /* true if this is a strong reference due to a commonRef_pin() */ } RefNode; /* Value of a NULL ID */ -- GitLab From 295c0474c43484e793b67a70af316aaae49fe361 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 25 Jan 2022 20:05:49 +0000 Subject: [PATCH 032/400] 8279242: Reflection newInstance() error message when constructor has no access modifiers could use improvement Reviewed-by: iris, dholmes, mchung --- .../jdk/internal/reflect/Reflection.java | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java index 76a4bf8fa4a..23b686041e6 100644 --- a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java +++ b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -379,11 +379,8 @@ public class Reflection { String msg = currentClass + currentSuffix + " cannot access "; if (m2.isExported(memberPackageName, m1)) { - // module access okay so include the modifiers in the message - msg += "a member of " + memberClass + memberSuffix + - " with modifiers \"" + Modifier.toString(modifiers) + "\""; - + msg += "a member of " + memberClass + memberSuffix + msgSuffix(modifiers); } else { // module access failed msg += memberClass + memberSuffix+ " because " @@ -410,11 +407,8 @@ public class Reflection { String msg = "JNI attached native thread (null caller frame) cannot access "; if (m2.isExported(memberPackageName)) { - // module access okay so include the modifiers in the message - msg += "a member of " + memberClass + memberSuffix + - " with modifiers \"" + Modifier.toString(modifiers) + "\""; - + msg += "a member of " + memberClass + memberSuffix + msgSuffix(modifiers); } else { // module access failed msg += memberClass + memberSuffix+ " because " @@ -424,6 +418,16 @@ public class Reflection { return new IllegalAccessException(msg); } + private static String msgSuffix(int modifiers) { + boolean packageAccess = + ((Modifier.PRIVATE | + Modifier.PROTECTED | + Modifier.PUBLIC) & modifiers) == 0; + return packageAccess ? + " with package access" : + " with modifiers \"" + Modifier.toString(modifiers) + "\""; + } + /** * Returns true if {@code currentClass} and {@code memberClass} * are nestmates - that is, if they have the same nesthost as -- GitLab From 2eab86b513a9e4566b3f5989f899ae44280d3834 Mon Sep 17 00:00:00 2001 From: Vicente Romero Date: Wed, 26 Jan 2022 00:33:10 +0000 Subject: [PATCH 033/400] 8213905: reflection not working for type annotations applied to exception types in the inner class constructor Reviewed-by: jlahoda --- .../annotation/TypeAnnotationParser.java | 3 ++- .../annotation/TypeAnnotationReflection.java | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java b/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java index 5c7356fca81..fc51faad6fc 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java +++ b/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java @@ -132,7 +132,8 @@ public final class TypeAnnotationParser { Class declaringClass = ctor.getDeclaringClass(); if (!declaringClass.isEnum() && (declaringClass.isMemberClass() && - (declaringClass.getModifiers() & Modifier.STATIC) == 0) ) { + (declaringClass.getModifiers() & Modifier.STATIC) == 0) && + filter == TypeAnnotation.TypeAnnotationTarget.METHOD_FORMAL_PARAMETER) { offset = true; } } diff --git a/test/jdk/java/lang/annotation/TypeAnnotationReflection.java b/test/jdk/java/lang/annotation/TypeAnnotationReflection.java index 64234ccc215..9c0a101c2b6 100644 --- a/test/jdk/java/lang/annotation/TypeAnnotationReflection.java +++ b/test/jdk/java/lang/annotation/TypeAnnotationReflection.java @@ -39,7 +39,8 @@ public class TypeAnnotationReflection { testReturnType(); testNested(); testArray(); - testRunException(); + testRunException(TestClassException.class.getDeclaredMethod("foo", (Class[])null)); + testRunException(Outer2.TestClassException2.class.getDeclaredConstructor(Outer2.class)); testClassTypeVarBounds(); testMethodTypeVarBounds(); testFields(); @@ -142,9 +143,8 @@ public class TypeAnnotationReflection { check(((TypeAnno)annos[0]).value().equals("return4")); } - private static void testRunException() throws Exception { - Method m = TestClassException.class.getDeclaredMethod("foo", (Class[])null); - AnnotatedType[] ts = m.getAnnotatedExceptionTypes(); + private static void testRunException(Executable e) throws Exception { + AnnotatedType[] ts = e.getAnnotatedExceptionTypes(); check(ts.length == 3); AnnotatedType t; @@ -624,6 +624,15 @@ abstract class TestClassException { } } +class Outer2 { + abstract class TestClassException2 { + public TestClassException2() throws + @TypeAnno("RE") @TypeAnno2("RE2") RuntimeException, + NullPointerException, + @TypeAnno("AIOOBE") ArrayIndexOutOfBoundsException {} + } +} + abstract class TestClassTypeVarAndField { -- GitLab From ef08e2c63b040cef6ca5f71dbce49f3d7647fdd8 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Wed, 26 Jan 2022 01:12:37 +0000 Subject: [PATCH 034/400] 8280592: Small javadoc tweaks to foreign API Reviewed-by: psandoz --- .../jdk/incubator/foreign/Addressable.java | 3 +- .../incubator/foreign/FunctionDescriptor.java | 12 +++---- .../jdk/incubator/foreign/GroupLayout.java | 8 ++--- .../jdk/incubator/foreign/MemoryAddress.java | 6 ++-- .../jdk/incubator/foreign/MemoryLayout.java | 32 +++++------------- .../jdk/incubator/foreign/MemorySegment.java | 18 ++++------ .../jdk/incubator/foreign/NativeSymbol.java | 9 ++--- .../jdk/incubator/foreign/ResourceScope.java | 3 +- .../jdk/incubator/foreign/SequenceLayout.java | 8 ++--- .../classes/jdk/incubator/foreign/VaList.java | 6 ++-- .../jdk/incubator/foreign/ValueLayout.java | 33 +++++++++---------- .../jdk/incubator/foreign/package-info.java | 2 +- 12 files changed, 49 insertions(+), 91 deletions(-) diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/Addressable.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/Addressable.java index 39f61e76122..17d417bee51 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/Addressable.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/Addressable.java @@ -40,8 +40,7 @@ package jdk.incubator.foreign; public sealed interface Addressable permits MemorySegment, MemoryAddress, NativeSymbol, VaList { /** - * Returns the memory address associated with this addressable. - * @return The memory address associated with this addressable. + * {@return the {@linkplain MemoryAddress memory address} associated with this addressable} */ MemoryAddress address(); } diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/FunctionDescriptor.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/FunctionDescriptor.java index 9c557ec9e9e..6bedfc4c16a 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/FunctionDescriptor.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/FunctionDescriptor.java @@ -54,16 +54,14 @@ public sealed class FunctionDescriptor implements Constable permits FunctionDesc } /** - * Returns the return layout associated with this function. - * @return the return layout. + * {@return the return layout (if any) associated with this function descriptor} */ public Optional returnLayout() { return Optional.ofNullable(resLayout); } /** - * Returns the argument layouts associated with this function. - * @return the argument layouts. + * {@return the argument layouts associated with this function descriptor}. */ public List argumentLayouts() { return argLayouts; @@ -166,8 +164,7 @@ public sealed class FunctionDescriptor implements Constable permits FunctionDesc } /** - * Returns a string representation of this function descriptor. - * @return a string representation of this function descriptor. + * {@return the string representation of this function descriptor} */ @Override public String toString() { @@ -201,8 +198,7 @@ public sealed class FunctionDescriptor implements Constable permits FunctionDesc } /** - * Returns the hash code value for this function descriptor. - * @return the hash code value for this function descriptor. + * {@return the hash code value for this function descriptor} */ @Override public int hashCode() { diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/GroupLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/GroupLayout.java index d08bb716ae8..6fc9baad7ff 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/GroupLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/GroupLayout.java @@ -133,18 +133,14 @@ public final class GroupLayout extends AbstractLayout implements MemoryLayout { } /** - * Is this group layout a struct? - * - * @return true, if this group layout is a struct. + * {@return {@code true}, if this group layout is a struct} */ public boolean isStruct() { return kind == Kind.STRUCT; } /** - * Is this group layout a union? - * - * @return true, if this group layout is a union. + * {@return {@code true}, if this group layout is a union} */ public boolean isUnion() { return kind == Kind.UNION; diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java index 47a17799700..007464d1691 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java @@ -78,8 +78,7 @@ import java.nio.ByteOrder; public sealed interface MemoryAddress extends Addressable permits MemoryAddressImpl { /** - * Returns the raw long value associated with this memory address. - * @return The raw long value associated with this memory address. + * {@return the raw long value associated with this memory address} */ long toRawLongValue(); @@ -141,8 +140,7 @@ public sealed interface MemoryAddress extends Addressable permits MemoryAddressI boolean equals(Object that); /** - * Returns the hash code value for this address. - * @return the hash code value for this address. + * {@return the hash code value for this address} */ @Override int hashCode(); diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java index fe0fb4e93f9..991897c367d 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java @@ -195,18 +195,15 @@ import java.util.stream.Stream; public sealed interface MemoryLayout extends Constable permits AbstractLayout, SequenceLayout, GroupLayout, PaddingLayout, ValueLayout { /** - * Returns an {@link Optional} containing the nominal descriptor for this + * {@return an {@link Optional} containing the nominal descriptor for this * layout, if one can be constructed, or an empty {@link Optional} - * if one cannot be constructed. - * - * @return An {@link Optional} containing the resulting nominal descriptor, - * or an empty {@link Optional} if one cannot be constructed. + * if one cannot be constructed} */ @Override Optional> describeConstable(); /** - * Does this layout have a specified size? A layout does not have a specified size if it is (or contains) a sequence layout whose + * Returns {@code true} if this layout has a specified size. A layout does not have a specified size if it is (or contains) a sequence layout whose * size is unspecified (see {@link SequenceLayout#elementCount()}). * * Value layouts (see {@link ValueLayout}) and padding layouts (see {@link MemoryLayout#paddingLayout(long)}) @@ -217,26 +214,20 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S boolean hasSize(); /** - * Computes the layout size, in bits. - * - * @return the layout size, in bits. + * {@return the layout size, in bits} * @throws UnsupportedOperationException if the layout is, or contains, a sequence layout with unspecified size (see {@link SequenceLayout}). */ long bitSize(); /** - * Computes the layout size, in bytes. - * - * @return the layout size, in bytes. + * {@return the layout size, in bytes} * @throws UnsupportedOperationException if the layout is, or contains, a sequence layout with unspecified size (see {@link SequenceLayout}), * or if {@code bitSize()} is not a multiple of 8. */ long byteSize(); /** - * Return the name (if any) associated with this layout. - * - * @return the layout name (if any). + * {@return the name (if any) associated with this layout} * @see MemoryLayout#withName(String) */ Optional name(); @@ -534,8 +525,7 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S } /** - * Is this a {@linkplain #paddingLayout(long) padding layout} ? - * @return true, if this layout is a padding layout. + * {@return true, if this layout is a padding layout} */ boolean isPadding(); @@ -651,16 +641,12 @@ public sealed interface MemoryLayout extends Constable permits AbstractLayout, S boolean equals(Object that); /** - * Returns the hash code value for this layout. - * - * @return the hash code value for this layout. + * {@return the hash code value for this layout} */ int hashCode(); /** - * Returns a string representation of this layout. - * - * @return a string representation of this layout. + * {@return the string representation of this layout} */ @Override String toString(); diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java index 3d3401ef05b..a4508530734 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java @@ -250,11 +250,10 @@ boolean isAligned(MemorySegment segment, long offset, MemoryLayout layout) { public sealed interface MemorySegment extends Addressable permits AbstractMemorySegmentImpl { /** - * The base memory address associated with this native memory segment. + * {@return the base memory address associated with this native memory segment} * @throws UnsupportedOperationException if this segment is not a {@linkplain #isNative() native} segment. * @throws IllegalStateException if the scope associated with this segment has been closed, or if access occurs from * a thread other than the thread owning that scope. - * @return The base memory address. */ @Override MemoryAddress address(); @@ -299,14 +298,12 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory Stream elements(MemoryLayout elementLayout); /** - * Returns the resource scope associated with this memory segment. - * @return the resource scope associated with this memory segment. + * {@return the resource scope associated with this memory segment} */ ResourceScope scope(); /** - * The size (in bytes) of this memory segment. - * @return The size (in bytes) of this memory segment. + * {@return the size (in bytes) of this memory segment} */ long byteSize(); @@ -343,8 +340,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory } /** - * Is this segment read-only? - * @return {@code true}, if this segment is read-only. + * {@return {@code true}, if this segment is read-only} * @see #asReadOnly() */ boolean isReadOnly(); @@ -358,7 +354,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory MemorySegment asReadOnly(); /** - * Is this a native segment? Returns true if this segment is a native memory segment, + * Returns {@code true} if this segment is a native segment. A native memory segment is * created using the {@link #allocateNative(long, ResourceScope)} (and related) factory, or a buffer segment * derived from a direct {@link java.nio.ByteBuffer} using the {@link #ofByteBuffer(ByteBuffer)} factory, * or if this is a {@linkplain #isMapped() mapped} segment. @@ -367,7 +363,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory boolean isNative(); /** - * Is this a mapped segment? Returns true if this segment is a mapped memory segment, + * Returns {@code true} if this segment is a mapped segment. A mapped memory segment is * created using the {@link #mapFile(Path, long, long, FileChannel.MapMode, ResourceScope)} factory, or a buffer segment * derived from a {@link java.nio.MappedByteBuffer} using the {@link #ofByteBuffer(ByteBuffer)} factory. * @return {@code true} if this segment is a mapped segment. @@ -484,7 +480,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory long mismatch(MemorySegment other); /** - * Tells whether the contents of this mapped segment is resident in physical + * Determines whether the contents of this mapped segment is resident in physical * memory. * *

    A return value of {@code true} implies that it is highly likely diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/NativeSymbol.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/NativeSymbol.java index bf137e965d7..3dc583f98fc 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/NativeSymbol.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/NativeSymbol.java @@ -43,22 +43,19 @@ import java.util.Objects; sealed public interface NativeSymbol extends Addressable permits NativeSymbolImpl { /** - * Returns the name of this symbol. - * @return the name of this symbol. + * {@return the name of this symbol} */ String name(); /** - * Returns the resource scope associated with this symbol. - * @return the resource scope associated with this symbol. + * {@return the resource scope associated with this symbol} */ ResourceScope scope(); /** - * Returns the memory address associated with this symbol. + * {@return the memory address associated with this symbol} * @throws IllegalStateException if the scope associated with this symbol has been closed, or if access occurs from * a thread other than the thread owning that scope. - * @return The memory address associated with this symbol. */ @Override MemoryAddress address(); diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ResourceScope.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ResourceScope.java index 24665c7dfe9..6c5d6b2b66f 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ResourceScope.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ResourceScope.java @@ -147,8 +147,7 @@ import java.util.Spliterator; */ public sealed interface ResourceScope extends AutoCloseable permits ResourceScopeImpl { /** - * Is this resource scope alive? - * @return true, if this resource scope is alive. + * {@return {@code true}, if this resource scope is alive} * @see ResourceScope#close() */ boolean isAlive(); diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java index 13ac7192728..8143d2929ce 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java @@ -82,18 +82,14 @@ public final class SequenceLayout extends AbstractLayout implements MemoryLayout } /** - * Returns the element layout associated with this sequence layout. - * - * @return The element layout associated with this sequence layout. + * {@return the element layout associated with this sequence layout} */ public MemoryLayout elementLayout() { return elementLayout; } /** - * Returns the element count of this sequence layout (if any). - * - * @return the element count of this sequence layout (if any). + * {@return the element count of this sequence layout (if any)} */ public OptionalLong elementCount() { return elemCount; diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/VaList.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/VaList.java index 1bc449fa907..73ede4e4e9a 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/VaList.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/VaList.java @@ -132,8 +132,7 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList void skip(MemoryLayout... layouts); /** - * Returns the resource scope associated with this variable argument list. - * @return the resource scope associated with this variable argument list. + * {@return the resource scope associated with this variable argument list} */ ResourceScope scope(); @@ -153,10 +152,9 @@ sealed public interface VaList extends Addressable permits WinVaList, SysVVaList VaList copy(); /** - * Returns the memory address associated with this variable argument list. + * {@return the {@linkplain MemoryAddress memory address} associated with this variable argument list} * @throws IllegalStateException if the scope associated with this variable argument list has been closed, or if access occurs from * a thread other than the thread owning that scope. - * @return The memory address associated with this variable argument list. */ @Override MemoryAddress address(); diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java index 3ce22d8743f..c2df9e1b25f 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java @@ -41,9 +41,9 @@ import java.util.OptionalLong; /** * A value layout. A value layout is used to model the memory layout associated with values of basic data types, such as integral types - * (either signed or unsigned) and floating-point types. Each value layout has a size, an alignment, a {@linkplain ByteOrder byte order}) - * and a carrier, that is, the Java type that should be used when {@linkplain MemorySegment#get(OfInt, long) accessing} - * a memory region using the value layout. + * (either signed or unsigned) and floating-point types. Each value layout has a size, an alignment (in bits), + * a {@linkplain ByteOrder byte order}, and a carrier, that is, the Java type that should be used when + * {@linkplain MemorySegment#get(OfInt, long) accessing} a memory region using the value layout. *

    * This class defines useful value layout constants for Java primitive types and addresses. * The layout constants in this class make implicit alignment and byte-ordering assumption: all layout @@ -82,9 +82,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { } /** - * Returns the value's byte order. - * - * @return the value's byte order. + * {@return the value's byte order} */ public ByteOrder order() { return order; @@ -125,8 +123,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { } /** - * Returns the carrier associated with this value layout. - * @return the carrier associated with this value layout. + * {@return the carrier associated with this value layout} */ public Class carrier() { return carrier; @@ -513,8 +510,8 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { } /** - * A value layout constant whose size is the same as that of a machine address (e.g. {@code size_t}), - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * A value layout constant whose size is the same as that of a machine address ({@code size_t}), + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: * {@snippet lang=java : * MemoryLayout.valueLayout(MemoryAddress.class, ByteOrder.nativeOrder()).withBitAlignment(8); @@ -524,7 +521,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { /** * A value layout constant whose size is the same as that of a Java {@code byte}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: * {@snippet lang=java : * MemoryLayout.valueLayout(byte.class, ByteOrder.nativeOrder()).withBitAlignment(8); @@ -534,7 +531,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { /** * A value layout constant whose size is the same as that of a Java {@code boolean}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: * {@snippet lang=java : * MemoryLayout.valueLayout(boolean.class, ByteOrder.nativeOrder()).withBitAlignment(8); @@ -544,7 +541,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { /** * A value layout constant whose size is the same as that of a Java {@code char}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: * {@snippet lang=java : * MemoryLayout.valueLayout(char.class, ByteOrder.nativeOrder()).withBitAlignment(8); @@ -554,7 +551,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { /** * A value layout constant whose size is the same as that of a Java {@code short}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: * {@snippet lang=java : * MemoryLayout.valueLayout(short.class, ByteOrder.nativeOrder()).withBitAlignment(8); @@ -564,7 +561,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { /** * A value layout constant whose size is the same as that of a Java {@code int}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: * {@snippet lang=java : * MemoryLayout.valueLayout(int.class, ByteOrder.nativeOrder()).withBitAlignment(8); @@ -574,7 +571,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { /** * A value layout constant whose size is the same as that of a Java {@code long}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: * {@snippet lang=java : * MemoryLayout.valueLayout(long.class, ByteOrder.nativeOrder()).withBitAlignment(8); @@ -585,7 +582,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { /** * A value layout constant whose size is the same as that of a Java {@code float}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: * {@snippet lang=java : * MemoryLayout.valueLayout(float.class, ByteOrder.nativeOrder()).withBitAlignment(8); @@ -595,7 +592,7 @@ public sealed class ValueLayout extends AbstractLayout implements MemoryLayout { /** * A value layout constant whose size is the same as that of a Java {@code double}, - * bit-alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. + * bit alignment set to 8, and byte order set to {@link ByteOrder#nativeOrder()}. * Equivalent to the following code: * {@snippet lang=java : * MemoryLayout.valueLayout(double.class, ByteOrder.nativeOrder()).withBitAlignment(8); diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java index 3621495d064..a74c6d3a55d 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/package-info.java @@ -30,7 +30,7 @@ *

    Foreign memory access

    * *

    - * The main abstractions introduced to support foreign memory access is {@link jdk.incubator.foreign.MemorySegment}, which + * The main abstraction introduced to support foreign memory access is {@link jdk.incubator.foreign.MemorySegment}, which * models a contiguous memory region, which can reside either inside or outside the Java heap. * A memory segment represents the main access coordinate of a memory access var handle, which can be obtained * using the combinator methods defined in the {@link jdk.incubator.foreign.MemoryHandles} class; a set of -- GitLab From a183bfb436a7dd998e602c2d16486e88c390fca1 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Wed, 26 Jan 2022 01:24:15 +0000 Subject: [PATCH 035/400] 8280377: MethodHandleProxies does not correctly invoke default methods with varags Reviewed-by: alanb --- .../java/lang/invoke/MethodHandleProxies.java | 43 ++-------- .../java/lang/reflect/InvocationHandler.java | 30 +------ .../classes/java/lang/reflect/Proxy.java | 40 ++++++++++ .../java/lang/reflect/ReflectAccess.java | 5 ++ .../access/JavaLangReflectAccess.java | 7 ++ .../invoke/MethodHandleProxies/Driver.java | 32 ++++++++ .../MethodHandlesProxiesTest.java | 0 .../invoke/MethodHandleProxies/Unnamed.java | 45 +++++++++++ .../MethodHandleProxies/m1/module-info.java | 27 +++++++ .../MethodHandleProxies/m1/p1/Main.java | 80 +++++++++++++++++++ .../MethodHandleProxies/m2/module-info.java | 25 ++++++ .../MethodHandleProxies/m2/p2/TestIntf.java | 27 +++++++ 12 files changed, 295 insertions(+), 66 deletions(-) create mode 100644 test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java rename test/jdk/java/lang/invoke/{ => MethodHandleProxies}/MethodHandlesProxiesTest.java (100%) create mode 100644 test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java create mode 100644 test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java create mode 100644 test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java create mode 100644 test/jdk/java/lang/invoke/MethodHandleProxies/m2/module-info.java create mode 100644 test/jdk/java/lang/invoke/MethodHandleProxies/m2/p2/TestIntf.java diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java index c1c34185ffb..b2e93afea12 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java @@ -28,9 +28,11 @@ package java.lang.invoke; import java.lang.reflect.*; import java.security.AccessController; import java.security.PrivilegedAction; + +import jdk.internal.access.JavaLangReflectAccess; +import jdk.internal.access.SharedSecrets; import sun.invoke.WrapperInstance; import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; @@ -184,8 +186,6 @@ public class MethodHandleProxies { checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class)); vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount()); } - final ConcurrentHashMap defaultMethodMap = - hasDefaultMethods(intfc) ? new ConcurrentHashMap<>() : null; final InvocationHandler ih = new InvocationHandler() { private Object getArg(String name) { if ((Object)name == "getWrapperInstanceTarget") return target; @@ -202,7 +202,8 @@ public class MethodHandleProxies { if (isObjectMethod(method)) return callObjectMethod(proxy, method, args); if (isDefaultMethod(method)) { - return callDefaultMethod(defaultMethodMap, proxy, intfc, method, args); + // no additional access check is performed + return JLRA.invokeDefault(proxy, method, args, null); } throw newInternalError("bad proxy method: "+method); } @@ -320,37 +321,5 @@ public class MethodHandleProxies { return !Modifier.isAbstract(m.getModifiers()); } - private static boolean hasDefaultMethods(Class intfc) { - for (Method m : intfc.getMethods()) { - if (!isObjectMethod(m) && - !Modifier.isAbstract(m.getModifiers())) { - return true; - } - } - return false; - } - - private static Object callDefaultMethod(ConcurrentHashMap defaultMethodMap, - Object self, Class intfc, Method m, Object[] args) throws Throwable { - assert(isDefaultMethod(m) && !isObjectMethod(m)) : m; - - // Lazily compute the associated method handle from the method - MethodHandle dmh = defaultMethodMap.computeIfAbsent(m, mk -> { - try { - // Look up the default method for special invocation thereby - // avoiding recursive invocation back to the proxy - MethodHandle mh = MethodHandles.Lookup.IMPL_LOOKUP.findSpecial( - intfc, mk.getName(), - MethodType.methodType(mk.getReturnType(), mk.getParameterTypes()), - self.getClass()); - return mh.asSpreader(Object[].class, mk.getParameterCount()); - } catch (NoSuchMethodException | IllegalAccessException e) { - // The method is known to exist and should be accessible, this - // method would not be called unless the invokeinterface to the - // default (public) method passed access control checks - throw new InternalError(e); - } - }); - return dmh.invoke(self, args); - } + private static final JavaLangReflectAccess JLRA = SharedSecrets.getJavaLangReflectAccess(); } diff --git a/src/java.base/share/classes/java/lang/reflect/InvocationHandler.java b/src/java.base/share/classes/java/lang/reflect/InvocationHandler.java index 4ca59906367..d5d00f34c86 100644 --- a/src/java.base/share/classes/java/lang/reflect/InvocationHandler.java +++ b/src/java.base/share/classes/java/lang/reflect/InvocationHandler.java @@ -28,7 +28,6 @@ package java.lang.reflect; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; -import java.lang.invoke.MethodHandle; import java.util.Objects; /** @@ -262,33 +261,6 @@ public interface InvocationHandler { throws Throwable { Objects.requireNonNull(proxy); Objects.requireNonNull(method); - - // verify that the object is actually a proxy instance - if (!Proxy.isProxyClass(proxy.getClass())) { - throw new IllegalArgumentException("'proxy' is not a proxy instance"); - } - if (!method.isDefault()) { - throw new IllegalArgumentException("\"" + method + "\" is not a default method"); - } - @SuppressWarnings("unchecked") - Class proxyClass = (Class)proxy.getClass(); - - Class intf = method.getDeclaringClass(); - // access check on the default method - method.checkAccess(Reflection.getCallerClass(), intf, proxyClass, method.getModifiers()); - - MethodHandle mh = Proxy.defaultMethodHandle(proxyClass, method); - // invoke the super method - try { - // the args array can be null if the number of formal parameters required by - // the method is zero (consistent with Method::invoke) - Object[] params = args != null ? args : Proxy.EMPTY_ARGS; - return mh.invokeExact(proxy, params); - } catch (ClassCastException | NullPointerException e) { - throw new IllegalArgumentException(e.getMessage(), e); - } catch (Proxy.InvocationException e) { - // unwrap and throw the exception thrown by the default method - throw e.getCause(); - } + return Proxy.invokeDefault(proxy, method, args, Reflection.getCallerClass()); } } diff --git a/src/java.base/share/classes/java/lang/reflect/Proxy.java b/src/java.base/share/classes/java/lang/reflect/Proxy.java index c9e3bb259ae..6dd5b3ef1db 100644 --- a/src/java.base/share/classes/java/lang/reflect/Proxy.java +++ b/src/java.base/share/classes/java/lang/reflect/Proxy.java @@ -1314,6 +1314,46 @@ public class Proxy implements java.io.Serializable { }); } + /* + * Invoke the default method of the given proxy with an explicit caller class. + * + * @throws IllegalAccessException if the proxy interface is inaccessible to the caller + * if caller is non-null + */ + static Object invokeDefault(Object proxy, Method method, Object[] args, Class caller) + throws Throwable { + // verify that the object is actually a proxy instance + if (!Proxy.isProxyClass(proxy.getClass())) { + throw new IllegalArgumentException("'proxy' is not a proxy instance"); + } + if (!method.isDefault()) { + throw new IllegalArgumentException("\"" + method + "\" is not a default method"); + } + @SuppressWarnings("unchecked") + Class proxyClass = (Class)proxy.getClass(); + + // skip access check if caller is null + if (caller != null) { + Class intf = method.getDeclaringClass(); + // access check on the default method + method.checkAccess(caller, intf, proxyClass, method.getModifiers()); + } + + MethodHandle mh = Proxy.defaultMethodHandle(proxyClass, method); + // invoke the super method + try { + // the args array can be null if the number of formal parameters required by + // the method is zero (consistent with Method::invoke) + Object[] params = args != null ? args : Proxy.EMPTY_ARGS; + return mh.invokeExact(proxy, params); + } catch (ClassCastException | NullPointerException e) { + throw new IllegalArgumentException(e.getMessage(), e); + } catch (Proxy.InvocationException e) { + // unwrap and throw the exception thrown by the default method + throw e.getCause(); + } + } + /** * Internal exception type to wrap the exception thrown by the default method * so that it can distinguish CCE and NPE thrown due to the arguments diff --git a/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java b/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java index 6ac890156b0..fa5a5d453ec 100644 --- a/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java +++ b/src/java.base/share/classes/java/lang/reflect/ReflectAccess.java @@ -127,4 +127,9 @@ class ReflectAccess implements jdk.internal.access.JavaLangReflectAccess { { return ctor.newInstanceWithCaller(args, true, caller); } + + public Object invokeDefault(Object proxy, Method method, Object[] args, Class caller) + throws Throwable { + return Proxy.invokeDefault(proxy, method, args, caller); + } } diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java index 4082fae336f..9e3ce846f02 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangReflectAccess.java @@ -102,4 +102,11 @@ public interface JavaLangReflectAccess { /** Returns a new instance created by the given constructor with access check */ public T newInstance(Constructor ctor, Object[] args, Class caller) throws IllegalAccessException, InstantiationException, InvocationTargetException; + + /** Invokes the given default method if the method's declaring interface is + * accessible to the given caller. Otherwise, IllegalAccessException will + * be thrown. If the caller is null, no access check is performed. + */ + public Object invokeDefault(Object proxy, Method method, Object[] args, Class caller) + throws Throwable; } diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java b/test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java new file mode 100644 index 00000000000..6acd4fb30e1 --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/Driver.java @@ -0,0 +1,32 @@ +/* + * 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. + * + * 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 8280377 + * @build m1/* m2/* Unnamed + * @run testng/othervm m1/p1.Main + * @run testng/othervm Unnamed + * @summary Test MethodHandleProxies::asInterfaceInstance with a default + * method with varargs + */ diff --git a/test/jdk/java/lang/invoke/MethodHandlesProxiesTest.java b/test/jdk/java/lang/invoke/MethodHandleProxies/MethodHandlesProxiesTest.java similarity index 100% rename from test/jdk/java/lang/invoke/MethodHandlesProxiesTest.java rename to test/jdk/java/lang/invoke/MethodHandleProxies/MethodHandlesProxiesTest.java diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java b/test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java new file mode 100644 index 00000000000..f42071f0427 --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/Unnamed.java @@ -0,0 +1,45 @@ +/* + * 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. + * + * 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.invoke.MethodHandle; +import java.lang.invoke.MethodHandleProxies; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Method; + +import static org.testng.Assert.*; + +/* + * Test MethodHandleProxies::asInterfaceInstance with an inaccessible interface + */ +public class Unnamed { + public static void main(String... args) throws Throwable { + MethodHandle target = MethodHandles.constant(String.class, "test"); + Class intf = Class.forName("p2.TestIntf"); + Object t = MethodHandleProxies.asInterfaceInstance(intf, target); + + // verify that the caller has no access to the proxy created on an + // inaccessible interface + Method m = intf.getMethod("test", Object[].class); + assertFalse(m.canAccess(null)); + } +} diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java new file mode 100644 index 00000000000..1bdeddce28f --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/module-info.java @@ -0,0 +1,27 @@ +/* + * 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. + * + * 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 m1 { + requires m2; + requires org.testng; + exports p1; +} diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java new file mode 100644 index 00000000000..df71809996b --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m1/p1/Main.java @@ -0,0 +1,80 @@ +/* + * 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. + * + * 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 p1; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandleProxies; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.Arrays; +import java.util.stream.Collectors; + +import p2.TestIntf; + +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class Main { + public interface A { + default String aConcat(Object... objs) { return Arrays.deepToString(objs); } + } + + public interface B { + default String bConcat(Object[] objs) { return Arrays.deepToString(objs); } + } + + public interface C extends A, B { + String c(Object... objs); + } + + private static String concat(Object... objs) { + return Arrays.stream(objs).map(Object::toString).collect(Collectors.joining()); + } + + /* + * Test the invocation of default methods with varargs + */ + @Test + public static void testVarargsMethods() throws Throwable { + MethodHandle target = MethodHandles.lookup().findStatic(Main.class, + "concat", MethodType.methodType(String.class, Object[].class)); + C proxy = MethodHandleProxies.asInterfaceInstance(C.class, target); + + assertEquals(proxy.c("a", "b", "c"), "abc"); + assertEquals(proxy.aConcat("a", "b", "c"), "[a, b, c]"); + assertEquals(proxy.aConcat(new Object[] { "a", "b", "c" }), "[a, b, c]"); + assertEquals(proxy.bConcat(new Object[] { "a", "b", "c" }), "[a, b, c]"); + } + + /* + * Test the invocation of a default method of an accessible interface + */ + @Test + public static void modulePrivateInterface() { + MethodHandle target = MethodHandles.constant(String.class, "test"); + TestIntf t = MethodHandleProxies.asInterfaceInstance(TestIntf.class, target); + assertEquals(t.test(), "test"); + } +} diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/m2/module-info.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m2/module-info.java new file mode 100644 index 00000000000..1015757fc9c --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m2/module-info.java @@ -0,0 +1,25 @@ +/* + * 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. + * + * 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 m2 { + exports p2 to m1; +} diff --git a/test/jdk/java/lang/invoke/MethodHandleProxies/m2/p2/TestIntf.java b/test/jdk/java/lang/invoke/MethodHandleProxies/m2/p2/TestIntf.java new file mode 100644 index 00000000000..a87d248e0c8 --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandleProxies/m2/p2/TestIntf.java @@ -0,0 +1,27 @@ +/* + * 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. + * + * 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 p2; + +public interface TestIntf { + String test(); +} -- GitLab From 2c64a7f2e30dc83701456595814a831e41e5f628 Mon Sep 17 00:00:00 2001 From: Hamlin Li Date: Wed, 26 Jan 2022 06:11:04 +0000 Subject: [PATCH 036/400] 8280374: G1: Remove unnecessary prev bitmap mark Reviewed-by: tschatzl, ayang --- src/hotspot/share/gc/g1/g1EvacFailure.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1EvacFailure.cpp b/src/hotspot/share/gc/g1/g1EvacFailure.cpp index 75fa7aee9db..8c6a68ad5ab 100644 --- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp +++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp @@ -104,7 +104,8 @@ public: } // Fill the memory area from start to end with filler objects, and update the BOT - // and the mark bitmap accordingly. + // accordingly. Since we clear and use the prev bitmap for marking objects that + // failed evacuation, there is no work to be done there. void zap_dead_objects(HeapWord* start, HeapWord* end) { if (start == end) { return; @@ -133,7 +134,7 @@ public: #endif } } - _cm->clear_range_in_prev_bitmap(mr); + assert(!_cm->is_marked_in_prev_bitmap(cast_to_oop(start)), "should not be marked in prev bitmap"); } void zap_remainder() { -- GitLab From e72eefd9f66e63a1e11d582e4916374840111928 Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Wed, 26 Jan 2022 06:52:12 +0000 Subject: [PATCH 037/400] 8280531: Remove unused DeferredCloseInputStream Reviewed-by: bpb, rriggs, iris --- .../unix/classes/java/lang/ProcessImpl.java | 108 +----------------- 1 file changed, 2 insertions(+), 106 deletions(-) diff --git a/src/java.base/unix/classes/java/lang/ProcessImpl.java b/src/java.base/unix/classes/java/lang/ProcessImpl.java index 2bf36f8f136..0a3f4e34783 100644 --- a/src/java.base/unix/classes/java/lang/ProcessImpl.java +++ b/src/java.base/unix/classes/java/lang/ProcessImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -45,7 +45,6 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import java.util.Properties; import jdk.internal.access.JavaIOFileDescriptorAccess; import jdk.internal.access.SharedSecrets; import jdk.internal.util.StaticProperty; @@ -641,109 +640,6 @@ final class ProcessImpl extends Process { } } - // A FileInputStream that supports the deferment of the actual close - // operation until the last pending I/O operation on the stream has - // finished. This is required on Solaris because we must close the stdin - // and stdout streams in the destroy method in order to reclaim the - // underlying file descriptors. Doing so, however, causes any thread - // currently blocked in a read on one of those streams to receive an - // IOException("Bad file number"), which is incompatible with historical - // behavior. By deferring the close we allow any pending reads to see -1 - // (EOF) as they did before. - // - private static class DeferredCloseInputStream extends PipeInputStream { - DeferredCloseInputStream(FileDescriptor fd) { - super(fd); - } - - private Object lock = new Object(); // For the following fields - private boolean closePending = false; - private int useCount = 0; - private InputStream streamToClose; - - private void raise() { - synchronized (lock) { - useCount++; - } - } - - private void lower() throws IOException { - synchronized (lock) { - useCount--; - if (useCount == 0 && closePending) { - streamToClose.close(); - } - } - } - - // stc is the actual stream to be closed; it might be this object, or - // it might be an upstream object for which this object is downstream. - // - private void closeDeferred(InputStream stc) throws IOException { - synchronized (lock) { - if (useCount == 0) { - stc.close(); - } else { - closePending = true; - streamToClose = stc; - } - } - } - - public void close() throws IOException { - synchronized (lock) { - useCount = 0; - closePending = false; - } - super.close(); - } - - public int read() throws IOException { - raise(); - try { - return super.read(); - } finally { - lower(); - } - } - - public int read(byte[] b) throws IOException { - raise(); - try { - return super.read(b); - } finally { - lower(); - } - } - - public int read(byte[] b, int off, int len) throws IOException { - raise(); - try { - return super.read(b, off, len); - } finally { - lower(); - } - } - - public long skip(long n) throws IOException { - raise(); - try { - return super.skip(n); - } finally { - lower(); - } - } - - public int available() throws IOException { - raise(); - try { - return super.available(); - } finally { - lower(); - } - } - } - /** * A buffered input stream for a subprocess pipe file descriptor * that allows the underlying file descriptor to be reclaimed when @@ -757,7 +653,7 @@ final class ProcessImpl extends Process { * will block if another thread is at the same time blocked in a file * operation (e.g. 'read()') on the same file descriptor. We therefore * combine 'ProcessPipeInputStream' approach used on Linux and Bsd - * with the DeferredCloseInputStream approach used on Solaris. This means + * with the deferring 'close' of InputStream. This means * that every potentially blocking operation on the file descriptor * increments a counter before it is executed and decrements it once it * finishes. The 'close()' operation will only be executed if there are -- GitLab From a24f44d17de586c72c8343f8891e72ad8a514597 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 26 Jan 2022 08:31:49 +0000 Subject: [PATCH 038/400] 8280526: x86_32 Math.sqrt performance regression with -XX:UseSSE={0,1} Reviewed-by: kvn, neliasso --- src/hotspot/cpu/x86/x86.ad | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index 917a9ac84b7..a9dc2997e21 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -1608,9 +1608,14 @@ const bool Matcher::match_rule_supported(int opcode) { } break; case Op_SqrtD: +#ifdef _LP64 if (UseSSE < 2) { return false; } +#else + // x86_32.ad has a special match rule for SqrtD. + // Together with common x86 rules, this handles all UseSSE cases. +#endif break; } return true; // Match rules are supported by default. -- GitLab From c180070cb59b8e075376ae913c5db9a4ed868303 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Wed, 26 Jan 2022 08:41:37 +0000 Subject: [PATCH 039/400] 8280373: Update Xalan serializer / SystemIDResolver to align with JDK-8270492 Reviewed-by: yan, joehw --- .../xml/internal/serializer/utils/SystemIDResolver.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SystemIDResolver.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SystemIDResolver.java index f2c198c9f09..fa4e0c90126 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SystemIDResolver.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SystemIDResolver.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -42,6 +41,8 @@ import com.sun.org.apache.xml.internal.serializer.utils.URI.MalformedURIExceptio * used in com.sun.org.apache.xml.internal.serializer. * * @xsl.usage internal + * + * @LastModified: Jan 2022 */ public final class SystemIDResolver { @@ -282,7 +283,7 @@ public final class SystemIDResolver public static String getAbsoluteURI(String urlString, String base) throws TransformerException { - if (base == null) + if (base == null || base.length() == 0) return getAbsoluteURI(urlString); String absoluteBase = getAbsoluteURI(base); -- GitLab From ed0df2fa1f1cb019eadd0083a5006b3142ac0eb5 Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Wed, 26 Jan 2022 10:12:22 +0000 Subject: [PATCH 040/400] 8268033: compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java fails with "fatal error: Not compilable at tier 3: CodeBuffer overflow" Reviewed-by: kvn, neliasso, chagedorn --- test/hotspot/jtreg/ProblemList-Xcomp.txt | 2 -- .../jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList-Xcomp.txt b/test/hotspot/jtreg/ProblemList-Xcomp.txt index b56e43c4e92..23f25da41d0 100644 --- a/test/hotspot/jtreg/ProblemList-Xcomp.txt +++ b/test/hotspot/jtreg/ProblemList-Xcomp.txt @@ -27,8 +27,6 @@ # ############################################################################# -compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java 8268033 generic-x64 - vmTestbase/nsk/jvmti/SetFieldAccessWatch/setfldw001/TestDescription.java 8205957 generic-all vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8265295 linux-x64,windows-x64 diff --git a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java index 93f54bdef73..08f83e1b8f0 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java +++ b/test/hotspot/jtreg/compiler/intrinsics/bmi/verifycode/BzhiTestI2L.java @@ -31,6 +31,7 @@ * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox * @run main/bootclasspath/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+AbortVMOnCompilationFailure + * -XX:CompileCommand=compileonly,compiler.intrinsics.bmi.*::* * -XX:+IgnoreUnrecognizedVMOptions -XX:+UseBMI2Instructions * compiler.intrinsics.bmi.verifycode.BzhiTestI2L */ -- GitLab From a07e19d8336f8fbea8736ba169787aec6d812817 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Wed, 26 Jan 2022 11:05:30 +0000 Subject: [PATCH 041/400] 8278410: Improve argument processing around UseHeavyMonitors Reviewed-by: rehn, dholmes --- src/hotspot/share/runtime/arguments.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 6d1e55f4c9a..fd551f1ec22 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -2015,16 +2015,23 @@ bool Arguments::check_vm_args_consistency() { #if !defined(X86) && !defined(AARCH64) && !defined(PPC64) if (UseHeavyMonitors) { - warning("UseHeavyMonitors is not fully implemented on this architecture"); + jio_fprintf(defaultStream::error_stream(), + "UseHeavyMonitors is not fully implemented on this architecture"); + return false; } #endif #if (defined(X86) || defined(PPC64)) && !defined(ZERO) if (UseHeavyMonitors && UseRTMForStackLocks) { - fatal("-XX:+UseHeavyMonitors and -XX:+UseRTMForStackLocks are mutually exclusive"); + jio_fprintf(defaultStream::error_stream(), + "-XX:+UseHeavyMonitors and -XX:+UseRTMForStackLocks are mutually exclusive"); + + return false; } #endif if (VerifyHeavyMonitors && !UseHeavyMonitors) { - fatal("-XX:+VerifyHeavyMonitors requires -XX:+UseHeavyMonitors"); + jio_fprintf(defaultStream::error_stream(), + "-XX:+VerifyHeavyMonitors requires -XX:+UseHeavyMonitors"); + return false; } return status; -- GitLab From f34f8d4d6a9b3e24a93a322b985c1413c27311cc Mon Sep 17 00:00:00 2001 From: stsypanov Date: Wed, 26 Jan 2022 14:12:51 +0000 Subject: [PATCH 042/400] 8277983: Remove unused fields from sun.net.www.protocol.jar.JarURLConnection Reviewed-by: dfuchs --- .../www/protocol/jar/JarURLConnection.java | 42 +++++-------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java index 4ccf7819914..234827fb76f 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/JarURLConnection.java @@ -25,21 +25,17 @@ package sun.net.www.protocol.jar; -import java.io.InputStream; -import java.io.IOException; -import java.io.FileNotFoundException; import java.io.BufferedInputStream; -import java.net.URL; -import java.net.URLConnection; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.net.MalformedURLException; -import java.net.UnknownServiceException; -import java.util.Enumeration; -import java.util.Map; +import java.net.URL; +import java.security.Permission; import java.util.List; +import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import java.util.jar.Manifest; -import java.security.Permission; /** * @author Benjamin Renaud @@ -47,26 +43,10 @@ import java.security.Permission; */ public class JarURLConnection extends java.net.JarURLConnection { - private static final boolean debug = false; - /* the Jar file factory. It handles both retrieval and caching. */ private static final JarFileFactory factory = JarFileFactory.getInstance(); - /* the url for the Jar file */ - private URL jarFileURL; - - /* the permission to get this JAR file. This is the actual, ultimate, - * permission, returned by the jar file factory. - */ - private Permission permission; - - /* the url connection for the JAR file */ - private URLConnection jarFileURLConnection; - - /* the entry name, if any */ - private String entryName; - /* the JarEntry */ private JarEntry jarEntry; @@ -80,12 +60,10 @@ public class JarURLConnection extends java.net.JarURLConnection { throws MalformedURLException, IOException { super(url); - jarFileURL = getJarFileURL(); - jarFileURLConnection = jarFileURL.openConnection(); + jarFileURLConnection = getJarFileURL().openConnection(); // whether, or not, the embedded URL should use the cache will depend // on this instance's cache value jarFileURLConnection.setUseCaches(useCaches); - entryName = getEntryName(); } public JarFile getJarFile() throws IOException { @@ -120,7 +98,7 @@ public class JarURLConnection extends java.net.JarURLConnection { public void connect() throws IOException { if (!connected) { boolean useCaches = getUseCaches(); - String entryName = this.entryName; + String entryName = getEntryName(); /* the factory call will do the security checks */ URL url = getJarFileURL(); @@ -176,6 +154,7 @@ public class JarURLConnection extends java.net.JarURLConnection { InputStream result = null; + String entryName = getEntryName(); if (entryName == null) { throw new IOException("no entry name specified"); } else { @@ -216,7 +195,7 @@ public class JarURLConnection extends java.net.JarURLConnection { Object result = null; connect(); - if (entryName == null) { + if (getEntryName() == null) { result = jarFile; } else { result = super.getContent(); @@ -226,6 +205,7 @@ public class JarURLConnection extends java.net.JarURLConnection { public String getContentType() { if (contentType == null) { + String entryName = getEntryName(); if (entryName == null) { contentType = "x-java/jar"; } else { -- GitLab From e1d8f555644e7766811bda1468af3f7f3d3f4239 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 26 Jan 2022 17:06:50 +0000 Subject: [PATCH 043/400] 8280402: Add new convenience forms to HtmlTree Reviewed-by: hannesw --- .../formats/html/HtmlDocletWriter.java | 46 ++--- .../doclets/formats/html/markup/HtmlTree.java | 161 +++++++++++++----- .../internal/doclets/toolkit/Content.java | 21 +++ 3 files changed, 154 insertions(+), 74 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java index 1c325db50e9..7efa7b85992 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java @@ -27,6 +27,7 @@ package jdk.javadoc.internal.doclets.formats.html; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; @@ -263,7 +264,7 @@ public class HtmlDocletWriter { do { int match = docrootMatcher.start(); // append htmlstr up to start of next {@docroot} - buf.append(htmlstr.substring(prevEnd, match)); + buf.append(htmlstr, prevEnd, match); prevEnd = docrootMatcher.end(); if (options.docrootParent().length() > 0 && htmlstr.startsWith("/..", prevEnd)) { // Insert the absolute link if {@docRoot} is followed by "/..". @@ -549,8 +550,7 @@ public class HtmlDocletWriter { protected Content getNavLinkMainTree(String label) { Content mainTreeContent = links.createLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), Text.of(label)); - Content li = HtmlTree.LI(mainTreeContent); - return li; + return HtmlTree.LI(mainTreeContent); } /** @@ -623,7 +623,7 @@ public class HtmlDocletWriter { } else { flags = EnumSet.noneOf(ElementFlag.class); } - DocLink targetLink = null; + DocLink targetLink; if (included || packageElement == null) { targetLink = new DocLink(pathString(packageElement, DocPaths.PACKAGE_SUMMARY)); } else { @@ -1531,18 +1531,11 @@ public class HtmlDocletWriter { return false; } sb.append("="); - String quote; - switch (node.getValueKind()) { - case DOUBLE: - quote = "\""; - break; - case SINGLE: - quote = "'"; - break; - default: - quote = ""; - break; - } + String quote = switch (node.getValueKind()) { + case DOUBLE -> "\""; + case SINGLE -> "'"; + default -> ""; + }; sb.append(quote); result.add(sb); Content docRootContent = new ContentBuilder(); @@ -1794,9 +1787,9 @@ public class HtmlDocletWriter { if (detail.isEmpty() || detail.get().isEmpty()) { return HtmlTree.SPAN(HtmlStyle.invalidTag, Text.of(summary)); } - return new HtmlTree(TagName.DETAILS).addStyle(HtmlStyle.invalidTag) - .add(new HtmlTree(TagName.SUMMARY).add(Text.of(summary))) - .add(new HtmlTree(TagName.PRE).add(detail.get())); + return HtmlTree.DETAILS(HtmlStyle.invalidTag) + .add(HtmlTree.SUMMARY(Text.of(summary))) + .add(HtmlTree.PRE(detail.get())); } /** @@ -2226,17 +2219,13 @@ public class HtmlDocletWriter { for (Element e: chain) { String name; switch (e.getKind()) { - case MODULE: - case PACKAGE: + case MODULE, PACKAGE -> { name = ((QualifiedNameable) e).getQualifiedName().toString(); if (name.length() == 0) { name = ""; } - break; - - default: - name = e.getSimpleName().toString(); - break; + } + default -> name = e.getSimpleName().toString(); } if (sb.length() == 0) { @@ -2444,8 +2433,7 @@ public class HtmlDocletWriter { private Content withPreviewFeatures(String key, String className, String featureName, List features) { String[] sep = new String[] {""}; ContentBuilder featureCodes = new ContentBuilder(); - features.stream() - .forEach(c -> { + features.forEach(c -> { featureCodes.add(sep[0]); featureCodes.add(HtmlTree.CODE(new ContentBuilder().add(c))); sep[0] = ", "; @@ -2460,7 +2448,7 @@ public class HtmlDocletWriter { String[] sep = new String[] {""}; ContentBuilder links = new ContentBuilder(); elements.stream() - .sorted((te1, te2) -> te1.getSimpleName().toString().compareTo(te2.getSimpleName().toString())) + .sorted(Comparator.comparing(te -> te.getSimpleName().toString())) .distinct() .map(te -> getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.CLASS, te) .label(HtmlTree.CODE(Text.of(te.getSimpleName()))).skipPreview(true))) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java index 9d1ad310767..4b954ef1a31 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -27,14 +27,17 @@ package jdk.javadoc.internal.doclets.formats.html.markup; import java.io.IOException; import java.io.Writer; +import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.BitSet; +import java.util.Collection; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.function.Function; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr.Role; import jdk.javadoc.internal.doclets.toolkit.Content; @@ -222,6 +225,20 @@ public class HtmlTree extends Content { return this; } + /** + * Adds each of a collection of items, using a map function to create the content for each item. + * + * @param items the items + * @param mapper the map function to generate the content for each item + * + * @return this object + */ + @Override + public HtmlTree addAll(Collection items, Function mapper) { + items.forEach(item -> add(mapper.apply(item))); + return this; + } + @Override public int charCount() { int n = 0; @@ -301,6 +318,7 @@ public class HtmlTree extends Content { /** * Creates an HTML {@code A} element. + * The {@code ref} argument will be URL-encoded for use as the attribute value. * * @param ref the value for the {@code href} attribute} * @param body the content for element @@ -312,6 +330,22 @@ public class HtmlTree extends Content { .add(body); } + /** + * Creates an HTML {@code A} element. + * The {@code ref} argument is assumed to be already suitably encoded, + * and will not be additionally URL-encoded, but will be + * {@link URI#toASCIIString() converted} to ASCII for use as the attribute value. + * + * @param ref the value for the {@code href} attribute} + * @param body the content for element + * @return the element + */ + public static HtmlTree A(URI ref, Content body) { + return new HtmlTree(TagName.A) + .put(HtmlAttr.HREF, ref.toASCIIString()) + .add(body); + } + /** * Creates an HTML {@code CAPTION} element with the given content. * @@ -345,6 +379,16 @@ public class HtmlTree extends Content { .add(body); } + /** + * Creates an HTML {@code DETAILS} element. + * + * @return the element + */ + public static HtmlTree DETAILS(HtmlStyle style) { + return new HtmlTree(TagName.DETAILS) + .setStyle(style); + } + /** * Creates an HTML {@code DL} element with the given style. * @@ -495,12 +539,10 @@ public class HtmlTree extends Content { } private static TagName checkHeading(TagName headingTag) { - switch (headingTag) { - case H1: case H2: case H3: case H4: case H5: case H6: - return headingTag; - default: - throw new IllegalArgumentException(headingTag.toString()); - } + return switch (headingTag) { + case H1, H2, H3, H4, H5, H6 -> headingTag; + default -> throw new IllegalArgumentException(headingTag.toString()); + }; } /** @@ -682,6 +724,16 @@ public class HtmlTree extends Content { .setStyle(style); } + /** + * Creates an HTML {@code PRE} element with some content. + * + * @param body the content + * @return the element + */ + public static HtmlTree PRE(Content body) { + return new HtmlTree(TagName.PRE).add(body); + } + /** * Creates an HTML {@code SCRIPT} element with some script content. * The type of the script is set to {@code text/javascript}. @@ -782,6 +834,17 @@ public class HtmlTree extends Content { .add(body); } + /** + * Creates an HTML {@code SUMMARY} element with the given content. + * + * @param body the content + * @return the element + */ + public static HtmlTree SUMMARY(Content body) { + return new HtmlTree(TagName.SUMMARY) + .add(body); + } + /** * Creates an HTML {@code SUP} element with the given content. * @@ -874,6 +937,21 @@ public class HtmlTree extends Content { return htmlTree; } + /** + * Creates an HTML {@code UL} element with the given style and content generated + * from a collection of items.. + * + * @param style the style + * @param items the items to be added to the list + * @param mapper a mapper to create the content for each item + * @return the element + */ + public static HtmlTree UL(HtmlStyle style, Collection items, Function mapper) { + return new HtmlTree(TagName.UL) + .setStyle(style) + .addAll(items, mapper); + } + @Override public boolean isEmpty() { return (!hasContent() && !hasAttrs()); @@ -916,30 +994,29 @@ public class HtmlTree extends Content { */ @Override public boolean isValid() { - switch (tagName) { - case A: - return (hasAttr(HtmlAttr.ID) || (hasAttr(HtmlAttr.HREF) && hasContent())); - case BR: - return (!hasContent() && (!hasAttrs() || hasAttr(HtmlAttr.CLEAR))); - case HR: - case INPUT: - return (!hasContent()); - case IMG: - return (hasAttr(HtmlAttr.SRC) && hasAttr(HtmlAttr.ALT) && !hasContent()); - case LINK: - return (hasAttr(HtmlAttr.HREF) && !hasContent()); - case META: - return (hasAttr(HtmlAttr.CONTENT) && !hasContent()); - case SCRIPT: - return ((hasAttr(HtmlAttr.TYPE) && hasAttr(HtmlAttr.SRC) && !hasContent()) || - (hasAttr(HtmlAttr.TYPE) && hasContent())); - case SPAN: - return (hasAttr(HtmlAttr.ID) || hasContent()); - case WBR: - return (!hasContent()); - default : - return hasContent(); - } + return switch (tagName) { + case A -> + hasAttr(HtmlAttr.ID) || (hasAttr(HtmlAttr.HREF) && hasContent()); + case BR -> + !hasContent() && (!hasAttrs() || hasAttr(HtmlAttr.CLEAR)); + case HR, INPUT -> + !hasContent(); + case IMG -> + hasAttr(HtmlAttr.SRC) && hasAttr(HtmlAttr.ALT) && !hasContent(); + case LINK -> + hasAttr(HtmlAttr.HREF) && !hasContent(); + case META -> + hasAttr(HtmlAttr.CONTENT) && !hasContent(); + case SCRIPT -> + (hasAttr(HtmlAttr.TYPE) && hasAttr(HtmlAttr.SRC) && !hasContent()) + || (hasAttr(HtmlAttr.TYPE) && hasContent()); + case SPAN -> + hasAttr(HtmlAttr.ID) || hasContent(); + case WBR -> + !hasContent(); + default -> + hasContent(); + }; } /** @@ -950,14 +1027,10 @@ public class HtmlTree extends Content { * @see Phrasing Content */ public boolean isInline() { - switch (tagName) { - case A: case BUTTON: case BR: case CODE: case EM: case I: case IMG: - case LABEL: case SMALL: case SPAN: case STRONG: case SUB: case SUP: - case WBR: - return true; - default: - return false; - } + return switch (tagName) { + case A, BUTTON, BR, CODE, EM, I, IMG, LABEL, SMALL, SPAN, STRONG, SUB, SUP, WBR -> true; + default -> false; + }; } /** @@ -968,12 +1041,10 @@ public class HtmlTree extends Content { * @see Void Elements */ public boolean isVoid() { - switch (tagName) { - case BR: case HR: case IMG: case INPUT: case LINK: case META: case WBR: - return true; - default: - return false; - } + return switch (tagName) { + case BR, HR, IMG, INPUT, LINK, META, WBR -> true; + default -> false; + }; } @Override diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Content.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Content.java index 84cc66912b4..80dd9c48587 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Content.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Content.java @@ -28,6 +28,8 @@ package jdk.javadoc.internal.doclets.toolkit; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; +import java.util.Collection; +import java.util.function.Function; /** * A class to create content for javadoc output pages. @@ -89,6 +91,25 @@ public abstract class Content { throw new UnsupportedOperationException(); } + /** + * Adds content to the existing content, generated from a collection of items + * This is an optional operation. + * + * @implSpec This implementation delegates to {@link #add(Content)}. + * + * @param items the items to be added + * @param mapper the function to create content for each item + * + * @return this object + * @throws UnsupportedOperationException if this operation is not supported by + * a particular implementation + * @throws IllegalArgumentException if the content is not suitable to be added + */ + public Content addAll(Collection items, Function mapper) { + items.forEach(item -> add(mapper.apply(item))); + return this; + } + /** * Writes content to a writer. * -- GitLab From 4b2370e57698e7413fef053afe9d22bb0bc86041 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Wed, 26 Jan 2022 17:07:53 +0000 Subject: [PATCH 044/400] 8279294: NonblockingQueue::try_pop may improperly indicate queue is empty Reviewed-by: iwalulya, tschatzl --- .../utilities/nonblockingQueue.inline.hpp | 62 ++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/src/hotspot/share/utilities/nonblockingQueue.inline.hpp b/src/hotspot/share/utilities/nonblockingQueue.inline.hpp index 355b2120902..2fbd26f2dca 100644 --- a/src/hotspot/share/utilities/nonblockingQueue.inline.hpp +++ b/src/hotspot/share/utilities/nonblockingQueue.inline.hpp @@ -135,28 +135,46 @@ bool NonblockingQueue::try_pop(T** node_ptr) { } T* next_node = Atomic::load_acquire(next_ptr(*result)); - if (next_node == NULL) { - // A concurrent try_pop already claimed what was the last entry. That - // operation may not have cleared queue head yet, but we should still - // treat the queue as empty until a push/append operation changes head - // to an entry with a non-NULL next value. - *node_ptr = NULL; - return true; - - } else if (!is_end(next_node)) { - // The next_node is not at the end of the queue's list. Use the "usual" - // lock-free pop from the head of a singly linked list to try to take it. - if (result == Atomic::cmpxchg(&_head, result, next_node)) { - // Former head successfully taken. + if (!is_end(next_node)) { + // [Clause 1] + // There are several cases for next_node. + // (1) next_node is the extension of the queue's list. + // (2) next_node is NULL, because a competing try_pop took result. + // (3) next_node is the extension of some unrelated list, because a + // competing try_pop took result and put it in some other list. + // + // Attempt to advance the list, replacing result with next_node in + // _head. The success or failure of that attempt, along with the value + // of next_node, are used to partially determine which case we're in and + // how to proceed. In particular, advancement will fail for case (3). + if (result != Atomic::cmpxchg(&_head, result, next_node)) { + // [Clause 1a] + // The cmpxchg to advance the list failed; a concurrent try_pop won + // the race and claimed result. This can happen for any of the + // next_node cases. + return false; + } else if (next_node == NULL) { + // [Clause 1b] + // The cmpxchg to advance the list succeeded, but a concurrent try_pop + // has already claimed result (see [Clause 2] - result was the last + // entry in the list) by nulling result's next field. The advance set + // _head to NULL, "helping" the competing try_pop. _head will remain + // NULL until a subsequent push/append. This is a lost race, and we + // report it as such for consistency, though we could report the queue + // was empty. + return false; + } else { + // [Clause 1c] + // Successfully advanced the list and claimed result. next_node was + // in the extension of the queue's list. Return result after + // unlinking it from next_node. set_next(*result, NULL); *node_ptr = result; return true; - } else { - // Lost race to take result from the head of the list. - return false; } - } else if (is_end(Atomic::cmpxchg(next_ptr(*result), end_marker(), (T*)NULL))) { + } else if (is_end(Atomic::cmpxchg(next_ptr(*result), next_node, (T*)NULL))) { + // [Clause 2] // Result was the last entry and we've claimed it by setting its next // value to NULL. However, this leaves the queue in disarray. Fix up // the queue, possibly in conjunction with other concurrent operations. @@ -170,7 +188,8 @@ bool NonblockingQueue::try_pop(T** node_ptr) { Atomic::cmpxchg(&_tail, result, (T*)NULL); // Attempt to change the queue head from result to NULL. Failure of the - // cmpxchg indicates a concurrent push/append updated the head first. + // cmpxchg indicates a concurrent operation updated _head first. That + // could be either a push/extend or a try_pop in [Clause 1b]. Atomic::cmpxchg(&_head, result, (T*)NULL); // The queue has been restored to order, and we can return the result. @@ -178,9 +197,10 @@ bool NonblockingQueue::try_pop(T** node_ptr) { return true; } else { - // Result was the last entry in the list, but either a concurrent pop - // claimed it first or a concurrent push/append extended the list from - // it. Either way, we lost the race. + // [Clause 3] + // Result was the last entry in the list, but either a concurrent + // try_pop claimed it first or a concurrent push/append extended the + // list from it. Either way, we lost the race to claim it. return false; } } -- GitLab From b8365aa48599a318c426c2ec4ffb3f296ffdbd73 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Wed, 26 Jan 2022 17:10:45 +0000 Subject: [PATCH 045/400] 8268978: Document the javadoc software stack Reviewed-by: hannesw --- .../jdk/javadoc/internal/package-info.java | 139 +++++++++++++++++- 1 file changed, 132 insertions(+), 7 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/package-info.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/package-info.java index 473e44ff421..4d7da0ba7cd 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/package-info.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,21 +24,146 @@ */ /** - * The implementation of the javadoc tool, and associated doclets. + * The implementation of the javadoc tool and associated doclets. * - *

    Internally, javadoc is composed of two primary parts: + *

    Internally, javadoc is composed of two primary parts: * the {@link jdk.javadoc.internal.tool tool}, and a series of * {@link jdk.javadoc.internal.doclets doclets}. * - * The tool provides a common infrastructure for command-line processing, - * and for reading the documentation comments in Java source files, + *

    The tool provides a common infrastructure for command-line processing, + * and for reading the declarations and documentation comments in Java source files, * while doclets provide a user-selectable backend for determining - * how to process the documentation comments. + * how to process the declarations and their documentation comments. + * + *

    The following provides a top-down description of the overall javadoc + * software stack. + * + *

    + *
    Doclets + *
    + *
    + *
    The Standard Doclet + *

    + * The {@link jdk.javadoc.doclet.StandardDoclet} is a thin public wrapper + * around the internal HTML doclet. + * + *

    The HTML Doclet + *

    + * The {@link jdk.javadoc.internal.doclets.formats.html.HtmlDoclet} class + * and other classes in the + * {@link jdk.javadoc.internal.doclets.formats.html formats.html} package + * customize the abstract pages generated by the toolkit layer to generate + * HTML pages. Some pages are specific to the HTML output format, + * and do not have an abstract builder in the toolkit layer. + * + *

    Individual pages of output are generated by page-specific subtypes of + * {@link jdk.javadoc.internal.doclets.formats.html.HtmlDocletWriter}. + * + *

    The {@link jdk.javadoc.internal.doclets.formats.html.HtmlConfiguration} class + * provides configuration information that is relevant to all the generated pages. + * The class extends the {@link jdk.javadoc.internal.doclets.toolkit.BaseConfiguration} + * class provided by the toolkit layer. + * + *

    The classes in the {@code formats.html} package use an internal + * library in the + * {@link jdk.javadoc.internal.doclets.formats.html.markup formats.html.markup} package, + * to create trees (or acyclic graphs) of + * {@linkplain jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree HTML tree nodes}. + * Apart from using a common format-neutral supertype, + * {@link jdk.javadoc.internal.doclets.toolkit.Content}, the {@code markup} library + * is mostly independent of the rest of the javadoc software stack. + * + *

    Toolkit + *

    + * The {@link jdk.javadoc.internal.doclets.toolkit toolkit} package provides + * support for a format-neutral + * {@linkplain jdk.javadoc.internal.doclets.toolkit.AbstractDoclet abstract doclet}, + * which uses + * {@linkplain jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder builders} + * to generate pages of abstract + * {@linkplain jdk.javadoc.internal.doclets.toolkit.Content content}. + * + *

    The format-specific content for each page is provided by implementations + * of various writer interfaces, created by a format-specific + * {@linkplain jdk.javadoc.internal.doclets.toolkit.WriterFactory writer factory}. + * + *

    The {@link jdk.javadoc.internal.doclets.toolkit.BaseConfiguration} provides + * configuration information that is relevant to all the generated pages. + * Some of the information is provided by abstract methods which are implemented + * in format-specific subtypes of the class. + * + *

    The toolkit layer also provides + * {@linkplain jdk.javadoc.internal.doclets.toolkit.util utility classes} + * used by this layer and by format-specific layers. + * + *

    Generally, it is intended that doclets should use the + * {@link javax.lang.model Language Model API} to navigate the structure of a Java program, + * without needing to access any internal details of the underlying javac implementation. + * However, there are still some shortcomings of the Language Model API, + * and so it is still necessary to provide limited access to some of those internal details. + * Although not enforceable by the module system, by design the access to javac + * internal details by doclets based on {@code AbstractDoclet} is restricted to the aptly-named + * {@link jdk.javadoc.internal.doclets.toolkit.WorkArounds} class. + * + *

    Other Doclets + *

    + * Doclets are obviously not required to use + * {@link jdk.javadoc.internal.doclets.toolkit.AbstractDoclet} and other classes in + * the toolkit layer. In times past, it was common to write doclets to analyze + * code using the then-current API as an early version of a Java language model. + * That old API has been replaced by the {@link javax.lang.model Language Model API}, + * and tools that wish to use that API to analyze Java programs have a choice of + * how to invoke it, using the javac support for + * {@linkplain javax.annotation.processing annotation processing}, + * or {@linkplain com.sun.source.util.Plugin plugins}, as well as doclets. + * Which is best for any application will depend of the circumstances, but + * if a tool does not need access to the documentation comments in a program, + * it is possible that one of the other invocation mechanisms will be more convenient. + * + *

    + * + *
    The Doclet Interface + *

    + * The {@linkplain jdk.javadoc.doclet Doclet API} is the interface layer between + * the javadoc tool and the code to process the elements specified to the tool. + * + *

    Above this layer, in any doclet, the code is expected to use the + * {@linkplain javax.lang.model Language Model API} to navigate around the specified + * elements, and/or the {@linkplain com.sun.source.doctree DocTree API} to examine + * the corresponding documentation comments. + * + *

    The javadoc Tool + *

    + * After reading the command-line options, the tool uses a modified javac + * front end to read the necessary files and thus instantiate the + * {@linkplain javax.lang.model.element.Element elements} to be made available to + * the doclet that will be used to process them. + * + * The tool uses an internal feature of the javac architecture, which + * allows various components to be replaced by subtypes with modified behavior. + * This is done by pre-registering the desired components in the javac + * {@code Context}. + * The tool uses this mechanism to do the following: + *

      + *
    • although source files are parsed in their entirety, the + * content of method bodies is quickly discarded as unnecessary; + *
    • the class reader is updated to handle {@code package.html} + * files in any package directories that are read; and + *
    • the compilation pipeline for each source file is terminated + * after the parse and enter phases, meaning that + * the files are processed enough to instantiate the elements to + * be made available to the doclet, but no more. + *
    + *
    * * *

    This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk. * This code and its internal interfaces are subject to change or * deletion without notice. + * + * @see JavaDoc Architecture + * @see Using the new Doclet API + * @see Processing Code */ -package jdk.javadoc.internal; +package jdk.javadoc.internal; \ No newline at end of file -- GitLab From 0c42e43f77b91a50fedc3fddb74e17f910d8df2a Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 26 Jan 2022 17:25:30 +0000 Subject: [PATCH 046/400] 8280550: SplittableRandom#nextDouble(double,double) can return result >= bound Reviewed-by: jlaskey, psandoz --- .../internal/util/random/RandomSupport.java | 4 +- .../util/Random/RandomNextDoubleBoundary.java | 52 +++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 test/jdk/java/util/Random/RandomNextDoubleBoundary.java diff --git a/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java b/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java index d47043b89aa..99ca3da322d 100644 --- a/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java +++ b/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java @@ -645,7 +645,7 @@ public class RandomSupport { if (origin < bound) { r = r * (bound - origin) + origin; if (r >= bound) // may need to correct a rounding problem - r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1); + r = Math.nextAfter(r, origin); } return r; } @@ -677,7 +677,7 @@ public class RandomSupport { double r = rng.nextDouble(); r = r * bound; if (r >= bound) // may need to correct a rounding problem - r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1); + r = Math.nextDown(r); return r; } diff --git a/test/jdk/java/util/Random/RandomNextDoubleBoundary.java b/test/jdk/java/util/Random/RandomNextDoubleBoundary.java new file mode 100644 index 00000000000..511f251aed6 --- /dev/null +++ b/test/jdk/java/util/Random/RandomNextDoubleBoundary.java @@ -0,0 +1,52 @@ +/* + * 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. + * + * 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 Verify nextDouble stays within range + * @bug 8280550 + */ + +import java.util.SplittableRandom; + +public class RandomNextDoubleBoundary { + public static void main(String... args) { + // Both bounds are negative + double lowerBound = -1.0000000000000002; + double upperBound = -1.0; + var sr = new SplittableRandom(42L); + var r = sr.nextDouble(lowerBound, upperBound); + + if (r >= upperBound) { + System.err.println("r = " + r + "\t" + Double.toHexString(r)); + System.err.println("ub = " + upperBound + "\t" + Double.toHexString(upperBound)); + throw new RuntimeException("Greater than upper bound"); + } + + if (r < lowerBound) { + System.err.println("r = " + r + "\t" + Double.toHexString(r)); + System.err.println("lb = " + lowerBound + "\t" + Double.toHexString(lowerBound)); + throw new RuntimeException("Less than lower bound"); + } + } +} -- GitLab From b5de2cc9d36e1fad7d0bf70f7c83ff829e16b7f3 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Wed, 26 Jan 2022 17:40:17 +0000 Subject: [PATCH 047/400] 8280546: Remove hard-coded 127.0.0.1 loopback address Reviewed-by: mullan --- test/jdk/javax/net/ssl/TLS/TestJSSE.java | 3 ++- test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/test/jdk/javax/net/ssl/TLS/TestJSSE.java b/test/jdk/javax/net/ssl/TLS/TestJSSE.java index 2c5a2c6274d..29631064011 100644 --- a/test/jdk/javax/net/ssl/TLS/TestJSSE.java +++ b/test/jdk/javax/net/ssl/TLS/TestJSSE.java @@ -21,12 +21,13 @@ * questions. */ +import java.net.InetAddress; import java.security.Provider; import java.security.Security; public class TestJSSE { - private static final String LOCAL_IP = "127.0.0.1"; + private static final String LOCAL_IP = InetAddress.getLoopbackAddress().getHostAddress(); public static void main(String... args) throws Exception { // reset the security property to make sure that the algorithms diff --git a/test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java b/test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java index 2207749302d..21416f0aaef 100644 --- a/test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java +++ b/test/jdk/javax/net/ssl/sanity/interop/JSSEClient.java @@ -23,6 +23,7 @@ import java.io.InputStream; import java.io.OutputStream; +import java.net.InetAddress; import java.security.cert.Certificate; import javax.net.ssl.KeyManager; @@ -52,7 +53,8 @@ class JSSEClient extends CipherTest.Client { new TrustManager[] { CipherTest.trustManager }, CipherTest.secureRandom); SSLSocketFactory factory = (SSLSocketFactory)sslContext.getSocketFactory(); - socket = (SSLSocket)factory.createSocket("127.0.0.1", CipherTest.serverPort); + socket = (SSLSocket)factory.createSocket( + InetAddress.getLoopbackAddress().getHostAddress(), CipherTest.serverPort); socket.setSoTimeout(CipherTest.TIMEOUT); socket.setEnabledCipherSuites(new String[] { params.cipherSuite.name() }); socket.setEnabledProtocols(new String[] { params.protocol.name }); -- GitLab From d2a50a64920d22bbbd19ac7fa8681ff177799faf Mon Sep 17 00:00:00 2001 From: Alexandre Iline Date: Wed, 26 Jan 2022 18:05:15 +0000 Subject: [PATCH 048/400] 8279636: Update JCov version to 3.0.12 Reviewed-by: alanb, erikj --- make/conf/jib-profiles.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index 5603678d4b8..e0041e91851 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -1169,15 +1169,8 @@ var getJibProfilesDependencies = function (input, common) { }, jcov: { - // Use custom build of JCov - // See CODETOOLS-7902734 for more info. - // server: "jpg", - // product: "jcov", - // version: "3.0", - // build_number: "b07", - // file: "bundles/jcov-3_0.zip", organization: common.organization, - revision: "3.0-9-jdk-asm+1.0", + revision: "3.0-12-jdk-asm+1.0", ext: "zip", environment_name: "JCOV_HOME", }, -- GitLab From 16e0ad0ad088af3ba1c9903ed8df60799a1ba651 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Wed, 26 Jan 2022 18:06:05 +0000 Subject: [PATCH 049/400] 8270199: Most SA tests are skipped on macosx-aarch64 because all executables are signed Reviewed-by: dholmes, kevinw --- test/hotspot/jtreg/ProblemList.txt | 8 +-- ...stMutuallyExclusivePlatformPredicates.java | 4 +- test/lib/jdk/test/lib/Platform.java | 65 +++++++++++-------- test/lib/jdk/test/lib/SA/SATestUtils.java | 6 +- test/lib/jdk/test/lib/util/CoreUtils.java | 8 +-- 5 files changed, 50 insertions(+), 41 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index b05f3317527..e08217cd776 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 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 @@ -121,10 +121,10 @@ serviceability/dcmd/gc/RunFinalizationTest.java 8227120 linux-all,windows-x64 serviceability/sa/ClhsdbCDSCore.java 8269982,8267433 macosx-aarch64,macosx-x64 serviceability/sa/ClhsdbFindPC.java#xcomp-core 8269982,8267433 macosx-aarch64,macosx-x64 serviceability/sa/ClhsdbFindPC.java#no-xcomp-core 8269982,8267433 macosx-aarch64,macosx-x64 -serviceability/sa/ClhsdbPmap.java#core 8267433 macosx-x64 +serviceability/sa/ClhsdbPmap.java#core 8269982,8267433 macosx-aarch64,macosx-x64 serviceability/sa/ClhsdbPstack.java#core 8269982,8267433 macosx-aarch64,macosx-x64 -serviceability/sa/TestJmapCore.java 8267433 macosx-x64 -serviceability/sa/TestJmapCoreMetaspace.java 8267433 macosx-x64 +serviceability/sa/TestJmapCore.java 8269982,8267433 macosx-aarch64,macosx-x64 +serviceability/sa/TestJmapCoreMetaspace.java 8269982,8267433 macosx-aarch64,macosx-x64 ############################################################################# diff --git a/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java b/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java index 4be69a6566c..3ca1de653a4 100644 --- a/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java +++ b/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -53,7 +53,7 @@ public class TestMutuallyExclusivePlatformPredicates { IGNORED("isEmulatedClient", "isDebugBuild", "isFastDebugBuild", "isSlowDebugBuild", "hasSA", "isRoot", "isTieredSupported", "areCustomLoadersSupportedForCDS", "isDefaultCDSArchiveSupported", - "isSignedOSX"); + "isHardenedOSX"); public final List methodNames; diff --git a/test/lib/jdk/test/lib/Platform.java b/test/lib/jdk/test/lib/Platform.java index 7666fdcc459..a8405c93722 100644 --- a/test/lib/jdk/test/lib/Platform.java +++ b/test/lib/jdk/test/lib/Platform.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -23,8 +23,10 @@ package jdk.test.lib; +import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -242,13 +244,13 @@ public class Platform { } /** - * Return true if the test JDK is signed, otherwise false. Only valid on OSX. + * Return true if the test JDK is hardened, otherwise false. Only valid on OSX. */ - public static boolean isSignedOSX() throws IOException { - // We only care about signed binaries for 10.14 and later (actually 10.14.5, but + public static boolean isHardenedOSX() throws IOException { + // We only care about hardened binaries for 10.14 and later (actually 10.14.5, but // for simplicity we'll also include earlier 10.14 versions). if (getOsVersionMajor() == 10 && getOsVersionMinor() < 14) { - return false; // assume not signed + return false; // assume not hardened } // Find the path to the java binary. @@ -260,38 +262,45 @@ public class Platform { } // Run codesign on the java binary. - ProcessBuilder pb = new ProcessBuilder("codesign", "-d", "-v", javaFileName); - pb.redirectError(ProcessBuilder.Redirect.DISCARD); - pb.redirectOutput(ProcessBuilder.Redirect.DISCARD); + ProcessBuilder pb = new ProcessBuilder("codesign", "--display", "--verbose", javaFileName); + pb.redirectErrorStream(true); // redirect stderr to stdout Process codesignProcess = pb.start(); + BufferedReader is = new BufferedReader(new InputStreamReader(codesignProcess.getInputStream())); + String line; + boolean isHardened = false; + boolean hardenedStatusConfirmed = false; // set true when we confirm whether or not hardened + while ((line = is.readLine()) != null) { + System.out.println("STDOUT: " + line); + if (line.indexOf("flags=0x10000(runtime)") != -1 ) { + hardenedStatusConfirmed = true; + isHardened = true; + System.out.println("Target JDK is hardened. Some tests may be skipped."); + } else if (line.indexOf("flags=0x20002(adhoc,linker-signed)") != -1 ) { + hardenedStatusConfirmed = true; + isHardened = false; + System.out.println("Target JDK is adhoc signed, but not hardened."); + } else if (line.indexOf("code object is not signed at all") != -1) { + hardenedStatusConfirmed = true; + isHardened = false; + System.out.println("Target JDK is not signed, therefore not hardened."); + } + } + if (!hardenedStatusConfirmed) { + System.out.println("Could not confirm if TargetJDK is hardened. Assuming not hardened."); + isHardened = false; + } + try { if (codesignProcess.waitFor(10, TimeUnit.SECONDS) == false) { - System.err.println("Timed out waiting for the codesign process to complete. Assuming not signed."); + System.err.println("Timed out waiting for the codesign process to complete. Assuming not hardened."); codesignProcess.destroyForcibly(); - return false; // assume not signed + return false; // assume not hardened } } catch (InterruptedException e) { throw new RuntimeException(e); } - // Check codesign result to see if java binary is signed. Here are the - // exit code meanings: - // 0: signed - // 1: not signed - // 2: invalid arguments - // 3: only has meaning with the -R argument. - // So we should always get 0 or 1 as an exit value. - if (codesignProcess.exitValue() == 0) { - System.out.println("Target JDK is signed. Some tests may be skipped."); - return true; // signed - } else if (codesignProcess.exitValue() == 1) { - System.out.println("Target JDK is not signed."); - return false; // not signed - } else { - System.err.println("Executing codesign failed. Assuming unsigned: " + - codesignProcess.exitValue()); - return false; // not signed - } + return isHardened; } private static boolean isArch(String archnameRE) { diff --git a/test/lib/jdk/test/lib/SA/SATestUtils.java b/test/lib/jdk/test/lib/SA/SATestUtils.java index 0ba91f2a994..d4daf5ef145 100644 --- a/test/lib/jdk/test/lib/SA/SATestUtils.java +++ b/test/lib/jdk/test/lib/SA/SATestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -63,8 +63,8 @@ public class SATestUtils { throw new SkippedException("SA Attach not expected to work. Ptrace attach not supported."); } } else if (Platform.isOSX()) { - if (Platform.isSignedOSX()) { - throw new SkippedException("SA Attach not expected to work. JDK is signed."); + if (Platform.isHardenedOSX()) { + throw new SkippedException("SA Attach not expected to work. JDK is hardened."); } if (!Platform.isRoot() && !canAddPrivileges()) { throw new SkippedException("SA Attach not expected to work. Insufficient privileges (not root and can't use sudo)."); diff --git a/test/lib/jdk/test/lib/util/CoreUtils.java b/test/lib/jdk/test/lib/util/CoreUtils.java index 15de012534b..c9335792593 100644 --- a/test/lib/jdk/test/lib/util/CoreUtils.java +++ b/test/lib/jdk/test/lib/util/CoreUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -138,12 +138,12 @@ public class CoreUtils { if (!coresDir.canWrite()) { throw new SkippedException("Directory \"" + coresDir + "\" is not writable"); } - if (Platform.isSignedOSX()) { + if (Platform.isHardenedOSX()) { if (Platform.getOsVersionMajor() > 10 || (Platform.getOsVersionMajor() == 10 && Platform.getOsVersionMinor() >= 15)) { - // We can't generate cores files with signed binaries on OSX 10.15 and later. - throw new SkippedException("Cannot produce core file with signed binary on OSX 10.15 and later"); + // We can't generate cores files with hardened binaries on OSX 10.15 and later. + throw new SkippedException("Cannot produce core file with hardened binary on OSX 10.15 and later"); } } } else if (Platform.isLinux()) { -- GitLab From c2ee1b33c37e6f2848dc8b3e5417b93b1dac1112 Mon Sep 17 00:00:00 2001 From: Hai-May Chao Date: Wed, 26 Jan 2022 20:31:04 +0000 Subject: [PATCH 050/400] 8273236: keytool does not accurately warn about algorithms that are disabled but have additional constraints Reviewed-by: mullan --- .../sun/security/tools/keytool/Main.java | 423 +++++++++++++++--- .../sun/security/tools/keytool/Resources.java | 4 +- .../security/tools/keytool/TestSha1Usage.java | 60 +++ 3 files changed, 432 insertions(+), 55 deletions(-) create mode 100644 test/jdk/sun/security/tools/keytool/TestSha1Usage.java diff --git a/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/src/java.base/share/classes/sun/security/tools/keytool/Main.java index 8cf77c96e69..de13f75aea9 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -31,10 +31,14 @@ import java.nio.file.Path; import java.security.*; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; +import java.security.cert.CertPathValidatorException; +import java.security.cert.CertPathValidatorException.BasicReason; import java.security.cert.CertStoreException; import java.security.cert.CRL; import java.security.cert.X509Certificate; import java.security.cert.CertificateException; +import java.security.cert.CertificateParsingException; +import java.security.cert.TrustAnchor; import java.security.cert.URICertStoreParameters; @@ -43,6 +47,8 @@ import java.security.interfaces.EdECKey; import java.security.spec.ECParameterSpec; import java.text.Collator; import java.text.MessageFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.*; import java.util.function.BiFunction; import java.util.jar.JarEntry; @@ -60,6 +66,7 @@ import javax.security.auth.x500.X500Principal; import java.util.Base64; import sun.security.pkcs12.PKCS12KeyStore; +import sun.security.provider.certpath.CertPathConstraintsParameters; import sun.security.util.ECKeySizeParameterSpec; import sun.security.util.KeyUtil; import sun.security.util.NamedCurve; @@ -83,6 +90,7 @@ import sun.security.tools.KeyStoreUtil; import sun.security.tools.PathList; import sun.security.util.DerValue; import sun.security.util.Pem; +import sun.security.validator.Validator; import sun.security.x509.*; import static java.security.KeyStore.*; @@ -178,6 +186,8 @@ public final class Main { // Warnings on weak algorithms etc private List weakWarnings = new ArrayList<>(); + private Set trustedCerts = new HashSet<>(); + private static final DisabledAlgorithmConstraints DISABLED_CHECK = new DisabledAlgorithmConstraints( DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS); @@ -1118,6 +1128,7 @@ public final class Main { } } + KeyStore cakstore = buildTrustedCerts(); // -trustcacerts can be specified on -importcert, -printcert or -printcrl. // Reset it so that warnings on CA cert will remain for other command. if (command != IMPORTCERT && command != PRINTCERT @@ -1126,7 +1137,13 @@ public final class Main { } if (trustcacerts) { - caks = KeyStoreUtil.getCacertsKeyStore(); + if (cakstore != null) { + caks = cakstore; + } else { + // try to load cacerts again, and let exception propagate + // if it cannot be loaded + caks = KeyStoreUtil.getCacertsKeyStore(); + } } // Perform the specified command @@ -1485,7 +1502,9 @@ public final class Main { byte[] rawReq = Pem.decode(new String(sb)); PKCS10 req = new PKCS10(rawReq); - checkWeak(rb.getString("the.certificate.request"), req); + CertPathConstraintsParameters cpcp = new CertPathConstraintsParameters( + req.getSubjectPublicKeyInfo(), null, null, null); + checkWeakConstraint(rb.getString("the.certificate.request"), req, cpcp); info.set(X509CertInfo.KEY, new CertificateX509Key(req.getSubjectPublicKeyInfo())); info.set(X509CertInfo.SUBJECT, @@ -1542,8 +1561,11 @@ public final class Main { } } - checkWeak(rb.getString("the.issuer"), keyStore.getCertificateChain(alias)); - checkWeak(rb.getString("the.generated.certificate"), cert); + checkWeakConstraint(rb.getString("the.issuer"), + keyStore.getCertificateChain(alias)); + cpcp = buildCertPathConstraint(cert, null); + checkWeakConstraint(rb.getString("the.generated.certificate"), + cert, cpcp); } private void doGenCRL(PrintStream out) @@ -1592,7 +1614,10 @@ public final class Main { } else { out.write(crl.getEncodedInternal()); } - checkWeak(rb.getString("the.generated.crl"), crl, privateKey); + CertPathConstraintsParameters cpcp = new CertPathConstraintsParameters( + privateKey, null, null, null); + checkWeakConstraint(rb.getString("the.generated.crl"), crl, privateKey, + cpcp); } /** @@ -1638,7 +1663,10 @@ public final class Main { request.encodeAndSign(subject, privKey, sigAlgName); request.print(out); - checkWeak(rb.getString("the.generated.certificate.request"), request); + CertPathConstraintsParameters cpcp = new CertPathConstraintsParameters( + request.getSubjectPublicKeyInfo(), null, null, null); + checkWeakConstraint(rb.getString("the.generated.certificate.request"), + request, cpcp); } /** @@ -1683,7 +1711,9 @@ public final class Main { throw new Exception(form.format(source)); } dumpCert(cert, out); - checkWeak(rb.getString("the.certificate"), cert); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint(cert, null); + checkWeakConstraint(rb.getString("the.certificate"), cert, cpcp); } /** @@ -2021,7 +2051,8 @@ public final class Main { } else { finalChain = new Certificate[] { newCert }; } - checkWeak(rb.getString("the.generated.certificate"), finalChain); + checkWeakConstraint(rb.getString("the.generated.certificate"), + finalChain); keyStore.setKeyEntry(alias, privKey, keyPass, finalChain); } @@ -2114,6 +2145,7 @@ public final class Main { private void doPrintEntry(String label, String alias, PrintStream out) throws Exception { + CertPathConstraintsParameters cpcp; if (keyStore.containsAlias(alias) == false) { MessageFormat form = new MessageFormat (rb.getString("Alias.alias.does.not.exist")); @@ -2170,6 +2202,10 @@ public final class Main { if (verbose || rfc || debug) { out.println(rb.getString ("Certificate.chain.length.") + chain.length); + + X509Certificate[] xcerts = convertCerts(chain); + List certs = Arrays.asList(xcerts); + TrustAnchor anchor = findTrustAnchor(certs); for (int i = 0; i < chain.length; i ++) { MessageFormat form = new MessageFormat (rb.getString("Certificate.i.1.")); @@ -2182,14 +2218,26 @@ public final class Main { } else { dumpCert(chain[i], out); } - checkWeak(label, chain[i]); + + if (i == 0 && + ((X509Certificate)chain[0]). + getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint((X509Certificate) chain[i], anchor); + } else { + cpcp = new CertPathConstraintsParameters( + (X509Certificate)chain[i], null, anchor, + null); + } + + checkWeakConstraint(label, chain[i], cpcp); } } else { // Print the digest of the user cert only out.println (rb.getString("Certificate.fingerprint.SHA.256.") + getCertFingerPrint("SHA-256", chain[0])); - checkWeak(label, chain); + checkWeakConstraint(label, chain); } } else { out.println(rb.getString @@ -2215,7 +2263,8 @@ public final class Main { out.println(rb.getString("Certificate.fingerprint.SHA.256.") + getCertFingerPrint("SHA-256", cert)); } - checkWeak(label, cert); + cpcp = buildCertPathConstraint((X509Certificate)cert, null); + checkWeakConstraint(label, cert, cpcp); } else { out.println(rb.getString("Unknown.Entry.Type")); } @@ -2442,7 +2491,9 @@ public final class Main { try { Certificate c = srckeystore.getCertificate(alias); if (c != null) { - checkWeak("<" + newAlias + ">", c); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)c, null); + checkWeakConstraint("<" + newAlias + ">", c, cpcp); } keyStore.setEntry(newAlias, entry, pp); // Place the check so that only successful imports are blocked. @@ -2639,11 +2690,14 @@ public final class Main { issuer = verifyCRL(caks, crl); if (issuer != null) { signer = caks.getCertificate(issuer); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)signer, + null); out.printf(rb.getString( "verified.by.s.in.s.weak"), issuer, "cacerts", - withWeak(signer.getPublicKey())); + withWeakConstraint(signer.getPublicKey(), cpcp)); out.println(); } } @@ -2651,11 +2705,14 @@ public final class Main { issuer = verifyCRL(keyStore, crl); if (issuer != null) { signer = keyStore.getCertificate(issuer); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)signer, + null); out.printf(rb.getString( "verified.by.s.in.s.weak"), issuer, "keystore", - withWeak(signer.getPublicKey())); + withWeakConstraint(signer.getPublicKey(), cpcp)); out.println(); } } @@ -2672,7 +2729,15 @@ public final class Main { out.println(rb.getString ("STARNN")); } - checkWeak(rb.getString("the.crl"), crl, signer == null ? null : signer.getPublicKey()); + + if (signer != null) { + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)signer, null); + checkWeakConstraint(rb.getString("the.crl"), crl, + signer.getPublicKey(), cpcp); + } else { + checkWeak(rb.getString("the.crl"), crl, null); + } } } @@ -2718,10 +2783,12 @@ public final class Main { PKCS10 req = new PKCS10(Pem.decode(new String(sb))); PublicKey pkey = req.getSubjectPublicKeyInfo(); + CertPathConstraintsParameters cpcp = + new CertPathConstraintsParameters(pkey, null, null, null); out.printf(rb.getString("PKCS.10.with.weak"), req.getSubjectName(), pkey.getFormat(), - withWeak(pkey), + withWeakConstraint(pkey, cpcp), withWeak(req.getSigAlg())); for (PKCS10Attribute attr: req.getAttributes().getAttributes()) { ObjectIdentifier oid = attr.getAttributeId(); @@ -2745,7 +2812,12 @@ public final class Main { if (debug) { out.println(req); // Just to see more, say, public key length... } - checkWeak(rb.getString("the.certificate.request"), req); + + CertPathConstraintsParameters cpcp1 = + new CertPathConstraintsParameters( + req.getSubjectPublicKeyInfo(), null, null, null); + checkWeakConstraint(rb.getString("the.certificate.request"), req, + cpcp1); } /** @@ -2765,6 +2837,9 @@ public final class Main { throw new Exception(rb.getString("Empty.input")); } Certificate[] certs = c.toArray(new Certificate[c.size()]); + X509Certificate[] xcerts = convertCerts(certs); + List chain = Arrays.asList(xcerts); + TrustAnchor anchor = findTrustAnchor(chain); for (int i=0; i certs = signer.getSignerCertPath().getCertificates(); + @SuppressWarnings("unchecked") + List chain = + (List)certs; + TrustAnchor anchor = findTrustAnchor(chain); + CertPathConstraintsParameters cpcp; int cc = 0; for (Certificate cert: certs) { out.printf(rb.getString("Certificate.d."), ++cc); @@ -2913,16 +3003,27 @@ public final class Main { printX509Cert(x, out); } out.println(); - checkWeak(oneInManys(rb.getString( + if (cc == 0 && x.getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint(x, anchor); + } else { + cpcp = new CertPathConstraintsParameters( + x, null, anchor, null); + } + checkWeakConstraint(oneInManys(rb.getString( "the.certificate"), cc, certs.size(), pos, - ss.size()), x); + ss.size()), x, cpcp); } Timestamp ts = signer.getTimestamp(); if (ts != null) { out.println(rb.getString("Timestamp.")); out.println(); certs = ts.getSignerCertPath().getCertificates(); + @SuppressWarnings("unchecked") + List tschain = + (List)certs; + anchor = findTrustAnchor(tschain); cc = 0; for (Certificate cert: certs) { out.printf(rb.getString("Certificate.d."), ++cc); @@ -2935,10 +3036,18 @@ public final class Main { printX509Cert(x, out); } out.println(); - checkWeak(oneInManys(rb.getString( + if (cc == 0 && + x.getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint(x, anchor); + } else { + cpcp = new CertPathConstraintsParameters( + x, null, anchor, null); + } + checkWeakConstraint(oneInManys(rb.getString( "the.tsa.certificate"), cc, certs.size(), pos, - ss.size()), x); + ss.size()), x, cpcp); } } } @@ -2968,6 +3077,9 @@ public final class Main { } int i = 0; + @SuppressWarnings("unchecked") + List xcerts = (List)chain; + TrustAnchor anchor = findTrustAnchor(xcerts); for (Certificate cert : chain) { try { if (rfc) { @@ -2978,7 +3090,17 @@ public final class Main { printX509Cert((X509Certificate)cert, out); out.println(); } - checkWeak(oneInMany(rb.getString("the.certificate"), i++, chain.size()), cert); + X509Certificate x = (X509Certificate)cert; + CertPathConstraintsParameters cpcp; + if (i == 0 && x.getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint(x, anchor); + } else { + cpcp = new CertPathConstraintsParameters( + x, null, anchor, null); + } + checkWeakConstraint(oneInMany(rb.getString( + "the.certificate"), i++, chain.size()), x, cpcp); } catch (Exception e) { if (debug) { e.printStackTrace(); @@ -3202,8 +3324,11 @@ public final class Main { throw new Exception(rb.getString("Input.not.an.X.509.certificate")); } + CertPathConstraintsParameters cpcp = + buildCertPathConstraint(cert, null); + if (noprompt) { - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); keyStore.setCertificateEntry(alias, cert); return true; } @@ -3223,7 +3348,7 @@ public final class Main { ("Certificate.already.exists.in.keystore.under.alias.trustalias.")); Object[] source = {trustalias}; System.err.println(form.format(source)); - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); printWeakWarnings(true); reply = getYesNoReply (rb.getString("Do.you.still.want.to.add.it.no.")); @@ -3234,7 +3359,7 @@ public final class Main { ("Certificate.already.exists.in.system.wide.CA.keystore.under.alias.trustalias.")); Object[] source = {trustalias}; System.err.println(form.format(source)); - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); printWeakWarnings(true); reply = getYesNoReply (rb.getString("Do.you.still.want.to.add.it.to.your.own.keystore.no.")); @@ -3243,7 +3368,7 @@ public final class Main { // Print the cert and ask user if they really want to add // it to their keystore printX509Cert(cert, System.out); - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); printWeakWarnings(true); reply = getYesNoReply (rb.getString("Trust.this.certificate.no.")); @@ -3270,7 +3395,7 @@ public final class Main { // Print the cert and ask user if they really want to add it to // their keystore printX509Cert(cert, System.out); - checkWeak(rb.getString("the.input"), cert); + checkWeakConstraint(rb.getString("the.input"), cert, cpcp); printWeakWarnings(true); reply = getYesNoReply (rb.getString("Trust.this.certificate.no.")); @@ -3410,6 +3535,21 @@ public final class Main { return keyPass; } + private String withWeakConstraint(String alg, + CertPathConstraintsParameters cpcp) { + try { + DISABLED_CHECK.permits(alg, cpcp, false); + } catch (CertPathValidatorException e) { + return String.format(rb.getString("with.disabled"), alg); + } + try { + LEGACY_CHECK.permits(alg, cpcp, false); + return alg; + } catch (CertPathValidatorException e) { + return String.format(rb.getString("with.weak"), alg); + } + } + private String withWeak(String alg) { if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) { if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, alg, null)) { @@ -3436,21 +3576,24 @@ public final class Main { return result; } - private String withWeak(Key key) { + private String withWeakConstraint(Key key, + CertPathConstraintsParameters cpcp) { int kLen = KeyUtil.getKeySize(key); String displayAlg = fullDisplayAlgName(key); - if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - if (LEGACY_CHECK.permits(SIG_PRIMITIVE_SET, key)) { - if (kLen >= 0) { - return String.format(rb.getString("key.bit"), kLen, displayAlg); - } else { - return String.format(rb.getString("unknown.size.1"), displayAlg); - } + try { + DISABLED_CHECK.permits(key.getAlgorithm(), cpcp, true); + } catch (CertPathValidatorException e) { + return String.format(rb.getString("key.bit.disabled"), kLen, displayAlg); + } + try { + LEGACY_CHECK.permits(key.getAlgorithm(), cpcp, true); + if (kLen >= 0) { + return String.format(rb.getString("key.bit"), kLen, displayAlg); } else { - return String.format(rb.getString("key.bit.weak"), kLen, displayAlg); + return String.format(rb.getString("unknown.size.1"), displayAlg); } - } else { - return String.format(rb.getString("key.bit.disabled"), kLen, displayAlg); + } catch (CertPathValidatorException e) { + return String.format(rb.getString("key.bit.weak"), kLen, displayAlg); } } @@ -3465,9 +3608,11 @@ public final class Main { (rb.getString(".PATTERN.printX509Cert.with.weak")); PublicKey pkey = cert.getPublicKey(); String sigName = cert.getSigAlgName(); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint(cert, null); // No need to warn about sigalg of a trust anchor if (!isTrustedCert(cert)) { - sigName = withWeak(sigName); + sigName = withWeakConstraint(sigName, cpcp); } Object[] source = {cert.getSubjectX500Principal().toString(), cert.getIssuerX500Principal().toString(), @@ -3477,7 +3622,7 @@ public final class Main { getCertFingerPrint("SHA-1", cert), getCertFingerPrint("SHA-256", cert), sigName, - withWeak(pkey), + withWeakConstraint(pkey, cpcp), cert.getVersion() }; out.println(form.format(source)); @@ -3801,7 +3946,7 @@ public final class Main { throws Exception { - checkWeak(rb.getString("reply"), replyCerts); + checkWeakConstraint(rb.getString("reply"), replyCerts); // order the certs in the reply (bottom-up). // we know that all certs in the reply are of type X.509, because @@ -3883,11 +4028,14 @@ public final class Main { replyCerts.length); tmpCerts[tmpCerts.length-1] = root.snd; replyCerts = tmpCerts; - checkWeak(String.format(fromKeyStore + CertPathConstraintsParameters cpcp = + buildCertPathConstraint((X509Certificate)root.snd, + null); + checkWeakConstraint(String.format(fromKeyStore ? rb.getString("alias.in.keystore") : rb.getString("alias.in.cacerts"), root.fst), - root.snd); + root.snd, cpcp); } } return replyCerts; @@ -3952,7 +4100,9 @@ public final class Main { (X509Certificate) certToVerify), chain, certs)) { for (Pair p : chain) { - checkWeak(p.fst, p.snd); + CertPathConstraintsParameters cpcp = + buildCertPathConstraint(p.snd, null); + checkWeakConstraint(p.fst, p.snd, cpcp); } Certificate[] newChain = new Certificate[chain.size()]; @@ -4748,6 +4898,78 @@ public final class Main { } } + private void checkWeakConstraint(String label, String sigAlg, Key key, + CertPathConstraintsParameters cpcp) throws Exception { + if (sigAlg != null) { + try { + DISABLED_CHECK.permits(sigAlg, cpcp, false); + try { + LEGACY_CHECK.permits(sigAlg, cpcp, false); + } catch (CertPathValidatorException e) { + weakWarnings.add(String.format( + rb.getString("whose.sigalg.weak"), label, sigAlg)); + } + } catch (CertPathValidatorException e) { + String eMessage = e.getMessage(); + if (eMessage.contains("denyAfter constraint check failed") && + e.getReason() == BasicReason.ALGORITHM_CONSTRAINED) { + String startSeparator = "Constraint date: "; + int startSepPos = eMessage.indexOf(startSeparator); + String endSeparator = "; params date"; + int endSepPos = eMessage.indexOf(endSeparator); + String denyAfterDate = null; + try { + denyAfterDate = eMessage.substring(startSepPos + startSeparator.length(), + endSepPos); + } catch (IndexOutOfBoundsException e1) { + throw new Exception(rb.getString( + "Unable.to.parse.denyAfter.string.in.exception.message")); + } + + SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy"); + Date dateObj = null; + try { + dateObj = formatter.parse(denyAfterDate); + } catch (ParseException e2) { + throw new Exception(rb.getString( + "Unable.to.parse.denyAfter.string.in.exception.message")); + } + formatter = new SimpleDateFormat("yyyy-MM-dd"); + denyAfterDate = formatter.format(dateObj); + + weakWarnings.add(String.format( + rb.getString("whose.sigalg.usagesignedjar"), label, sigAlg, + denyAfterDate)); + } else { + weakWarnings.add(String.format( + rb.getString("whose.sigalg.disabled"), label, sigAlg)); + } + if (debug) { + e.printStackTrace(); + } + } + } + + if (key != null) { + try { + DISABLED_CHECK.permits(key.getAlgorithm(), cpcp, true); + try { + LEGACY_CHECK.permits(key.getAlgorithm(), cpcp, true); + } catch (CertPathValidatorException e) { + weakWarnings.add(String.format( + rb.getString("whose.key.weak"), label, + String.format(rb.getString("key.bit"), + KeyUtil.getKeySize(key), fullDisplayAlgName(key)))); + } + } catch (CertPathValidatorException e) { + weakWarnings.add(String.format( + rb.getString("whose.key.disabled"), label, + String.format(rb.getString("key.bit"), + KeyUtil.getKeySize(key), fullDisplayAlgName(key)))); + } + } + } + private void checkWeak(String label, String sigAlg, Key key) { if (sigAlg != null) { if (!DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, sigAlg, null)) { @@ -4774,8 +4996,11 @@ public final class Main { } } - private void checkWeak(String label, Certificate[] certs) - throws KeyStoreException { + private void checkWeakConstraint(String label, Certificate[] certs) + throws KeyStoreException, Exception { + X509Certificate[] xcerts = convertCerts(certs); + List chain = Arrays.asList(xcerts); + TrustAnchor anchor = findTrustAnchor(chain); for (int i = 0; i < certs.length; i++) { Certificate cert = certs[i]; if (cert instanceof X509Certificate) { @@ -4784,23 +5009,43 @@ public final class Main { if (certs.length > 1) { fullLabel = oneInMany(label, i, certs.length); } - checkWeak(fullLabel, xc); + + CertPathConstraintsParameters cpcp = null; + if (i == 0 && xc.getBasicConstraints() == -1) { + // this is an EE + cpcp = buildCertPathConstraint(xc, anchor); + } else { + cpcp = new CertPathConstraintsParameters( + xc, null, anchor, null); + } + checkWeakConstraint(fullLabel, xc, cpcp); } } } - private void checkWeak(String label, Certificate cert) - throws KeyStoreException { + private void checkWeakConstraint(String label, Certificate cert, + CertPathConstraintsParameters cpcp) + throws KeyStoreException, Exception { if (cert instanceof X509Certificate) { X509Certificate xc = (X509Certificate)cert; // No need to check the sigalg of a trust anchor String sigAlg = isTrustedCert(cert) ? null : xc.getSigAlgName(); - checkWeak(label, sigAlg, xc.getPublicKey()); + checkWeakConstraint(label, sigAlg, xc.getPublicKey(), cpcp); } } - private void checkWeak(String label, PKCS10 p10) { - checkWeak(label, p10.getSigAlg(), p10.getSubjectPublicKeyInfo()); + private void checkWeakConstraint(String label, PKCS10 p10, + CertPathConstraintsParameters cpcp) throws Exception { + checkWeakConstraint(label, p10.getSigAlg(), + p10.getSubjectPublicKeyInfo(), cpcp); + } + + private void checkWeakConstraint(String label, CRL crl, Key key, + CertPathConstraintsParameters cpcp) throws Exception { + if (crl instanceof X509CRLImpl) { + X509CRLImpl impl = (X509CRLImpl)crl; + checkWeakConstraint(label, impl.getSigAlgName(), key, cpcp); + } } private void checkWeak(String label, CRL crl, Key key) { @@ -4810,6 +5055,76 @@ public final class Main { } } + private KeyStore buildTrustedCerts() { + KeyStore caks = null; + try { + caks = KeyStoreUtil.getCacertsKeyStore(); + if (caks != null) { + Enumeration aliases = caks.aliases(); + while (aliases.hasMoreElements()) { + String a = aliases.nextElement(); + try { + trustedCerts.add((X509Certificate)caks.getCertificate(a)); + } catch (Exception e2) { + // ignore, if the keystore has not been loaded/initialized properly + } + } + } + } catch (Exception e) { + // Ignore, if cacerts cannot be loaded + } + return caks; + } + + private TrustAnchor findTrustAnchor(List chain) { + if (chain.isEmpty()) { + return null; + } + + X509Certificate last = chain.get(chain.size() - 1); + Optional trusted = + trustedCerts.stream() + .filter(c -> c.getSubjectX500Principal().equals(last.getIssuerX500Principal())) + .findFirst(); + return trusted.isPresent() ? new TrustAnchor(trusted.get(), null) : null; + } + + private X509Certificate[] convertCerts(Certificate[] certs) { + X509Certificate[] xcerts = new X509Certificate[certs.length]; + + for (int i = 0; i < certs.length; i++) { + if (certs[i] instanceof X509Certificate) { + xcerts[i] = (X509Certificate) certs[i]; + } + } + return xcerts; + } + + private CertPathConstraintsParameters buildCertPathConstraint( + X509Certificate xcert, TrustAnchor anchor) throws Exception{ + List eku = xcert.getExtendedKeyUsage(); + if (eku == null) { + return new CertPathConstraintsParameters(xcert, null, + anchor, null); + } + + if (eku.contains(KnownOIDs.codeSigning.value())) { + return new CertPathConstraintsParameters(xcert, + Validator.VAR_CODE_SIGNING, anchor, null); + } else if (eku.contains(KnownOIDs.clientAuth.value())) { + return new CertPathConstraintsParameters(xcert, + Validator.VAR_TLS_CLIENT, anchor, null); + } else if (eku.contains(KnownOIDs.serverAuth.value())) { + return new CertPathConstraintsParameters(xcert, + Validator.VAR_TLS_SERVER, anchor, null); + } else if (eku.contains(KnownOIDs.KP_TimeStamping.value())) { + return new CertPathConstraintsParameters(xcert, + Validator.VAR_TSA_SERVER, anchor, null); + } + return new CertPathConstraintsParameters(xcert, Validator.VAR_GENERIC, + anchor, null); + } + private void printWeakWarnings(boolean newLine) { if (!weakWarnings.isEmpty() && !nowarn) { System.err.println("\nWarning:"); diff --git a/src/java.base/share/classes/sun/security/tools/keytool/Resources.java b/src/java.base/share/classes/sun/security/tools/keytool/Resources.java index df0147e529d..f26b2a13bd8 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/Resources.java +++ b/src/java.base/share/classes/sun/security/tools/keytool/Resources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -483,6 +483,8 @@ public class Resources extends java.util.ListResourceBundle { "Subject: %1$s\nFormat: %2$s\nPublic Key: %3$s\nSignature algorithm: %4$s\n"}, {"verified.by.s.in.s.weak", "Verified by %1$s in %2$s with a %3$s"}, {"whose.sigalg.disabled", "%1$s uses the %2$s signature algorithm which is considered a security risk and is disabled."}, + {"whose.sigalg.usagesignedjar", "%1$s uses the %2$s signature algorithm which is considered a security risk and cannot be used to sign JARs after %3$s."}, + {"Unable.to.parse.denyAfter.string.in.exception.message", "Unable to parse denyAfter date string in exception message"}, {"whose.sigalg.weak", "%1$s uses the %2$s signature algorithm which is considered a security risk. This algorithm will be disabled in a future update."}, {"whose.key.disabled", "%1$s uses a %2$s which is considered a security risk and is disabled."}, {"whose.key.weak", "%1$s uses a %2$s which is considered a security risk. This key size will be disabled in a future update."}, diff --git a/test/jdk/sun/security/tools/keytool/TestSha1Usage.java b/test/jdk/sun/security/tools/keytool/TestSha1Usage.java new file mode 100644 index 00000000000..0cbece46e14 --- /dev/null +++ b/test/jdk/sun/security/tools/keytool/TestSha1Usage.java @@ -0,0 +1,60 @@ +/* + * 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. + * + * 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 8273236 + * @summary Test SHA1 usage SignedJAR + * @library /test/lib + */ + +import jdk.test.lib.SecurityTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class TestSha1Usage { + + static OutputAnalyzer kt(String cmd, String ks) throws Exception { + return SecurityTools.keytool("-storepass changeit " + cmd + + " -keystore " + ks); + } + + public static void main(String[] args) throws Exception { + + SecurityTools.keytool("-keystore ks -storepass changeit " + + "-genkeypair -keyalg rsa -alias ca -dname CN=CA " + + "-ext eku=codeSigning -sigalg SHA1withRSA") + .shouldContain("Warning:") + .shouldMatch("The generated certificate.*SHA1withRSA.*considered a security risk") + .shouldMatch("cannot be used to sign JARs") + .shouldHaveExitValue(0); + + kt("-genkeypair -keyalg rsa -alias e1 -dname CN=E1", "ks"); + kt("-certreq -alias e1 -file tmp.req", "ks"); + SecurityTools.keytool("-keystore ks -storepass changeit " + + "-gencert -alias ca -infile tmp.req -outfile tmp.cert") + .shouldContain("Warning:") + .shouldMatch("The issuer.*SHA1withRSA.*considered a security risk") + .shouldMatch("cannot be used to sign JARs") + .shouldHaveExitValue(0); + } +} -- GitLab From 890830196dea3dfacef231b458fa4a459791c2bb Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Thu, 27 Jan 2022 03:57:28 +0000 Subject: [PATCH 051/400] 8076089: Cleanup: Inline & remove sun.management.Util.newException Reviewed-by: kevinw, amenkov, dfuchs, sspitsyn --- .../share/classes/sun/management/LockInfoCompositeData.java | 6 +++--- .../classes/sun/management/ManagementFactoryHelper.java | 6 +++--- src/java.management/share/classes/sun/management/Util.java | 6 +----- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/java.management/share/classes/sun/management/LockInfoCompositeData.java b/src/java.management/share/classes/sun/management/LockInfoCompositeData.java index 087ce3d780e..bafdff2dbfb 100644 --- a/src/java.management/share/classes/sun/management/LockInfoCompositeData.java +++ b/src/java.management/share/classes/sun/management/LockInfoCompositeData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -68,7 +68,7 @@ public class LockInfoCompositeData extends LazyCompositeData { return new CompositeDataSupport(LOCK_INFO_COMPOSITE_TYPE, items); } catch (OpenDataException e) { // Should never reach here - throw Util.newException(e); + throw new RuntimeException(e); } } @@ -79,7 +79,7 @@ public class LockInfoCompositeData extends LazyCompositeData { MappedMXBeanType.toOpenType(LockInfo.class); } catch (OpenDataException e) { // Should never reach here - throw Util.newException(e); + throw new RuntimeException(e); } } diff --git a/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java b/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java index 7e5c1d87640..3746cd311b2 100644 --- a/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java +++ b/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -482,7 +482,7 @@ public class ManagementFactoryHelper { } }); } catch (PrivilegedActionException e) { - throw Util.newException(e.getException()); + throw new RuntimeException(e.getException()); } } @@ -540,7 +540,7 @@ public class ManagementFactoryHelper { } }); } catch (PrivilegedActionException e) { - throw Util.newException(e.getException()); + throw new RuntimeException(e.getException()); } } diff --git a/src/java.management/share/classes/sun/management/Util.java b/src/java.management/share/classes/sun/management/Util.java index 9ce1a5d31ee..94bab86140c 100644 --- a/src/java.management/share/classes/sun/management/Util.java +++ b/src/java.management/share/classes/sun/management/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -34,10 +34,6 @@ import javax.management.MalformedObjectNameException; public class Util { private Util() {} // there are no instances of this class - static RuntimeException newException(Exception e) { - throw new RuntimeException(e); - } - private static final String[] EMPTY_STRING_ARRAY = new String[0]; static String[] toStringArray(List list) { return list.toArray(EMPTY_STRING_ARRAY); -- GitLab From 2ea0edf2c40edde4c191864a40e7a4d741ac0b8e Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Thu, 27 Jan 2022 07:00:56 +0000 Subject: [PATCH 052/400] 8279673: AudioClip.play doesn't work due to NullPointerException when creating DataPusher Reviewed-by: prr, serb --- .../com/sun/media/sound/DataPusher.java | 4 +- .../sun/media/sound/JSSecurityManager.java | 3 +- .../sampled/Clip/DataPusherThreadCheck.java | 89 +++++++++++++++++++ 3 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 test/jdk/javax/sound/sampled/Clip/DataPusherThreadCheck.java diff --git a/src/java.desktop/share/classes/com/sun/media/sound/DataPusher.java b/src/java.desktop/share/classes/com/sun/media/sound/DataPusher.java index 8944df836ae..d40c2cd8c31 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/DataPusher.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/DataPusher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -108,7 +108,7 @@ public final class DataPusher implements Runnable { source.start(); if (pushThread == null) { pushThread = JSSecurityManager.createThread(this, - null, // name + "DataPusher", // name false, // daemon -1, // priority true); // doStart diff --git a/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java b/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java index f593ed8b897..51482b24aea 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -112,7 +112,6 @@ final class JSSecurityManager { final boolean isDaemon, final int priority, final boolean doStart) { - String name = (threadName != null) ? threadName : "JSSM Thread"; Thread thread = new Thread(null, runnable, threadName, 0, false); thread.setDaemon(isDaemon); diff --git a/test/jdk/javax/sound/sampled/Clip/DataPusherThreadCheck.java b/test/jdk/javax/sound/sampled/Clip/DataPusherThreadCheck.java new file mode 100644 index 00000000000..733a317ab37 --- /dev/null +++ b/test/jdk/javax/sound/sampled/Clip/DataPusherThreadCheck.java @@ -0,0 +1,89 @@ +/* + * 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. + * + * 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 static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED; +import static javax.sound.sampled.AudioSystem.NOT_SPECIFIED; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import java.applet.AudioClip; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; + +/* + * @test + * @key headful + * @bug 8279673 + * @summary Verify no NPE creating threads + * @run main/othervm DataPusherThreadCheck + */ +public class DataPusherThreadCheck { + + public static void main(String[] args) throws Exception { + // Prepare the audio file + File file = new File("audio.wav"); + try { + AudioFormat format = + new AudioFormat(PCM_SIGNED, 44100, 8, 1, 1, 44100, false); + int dataSize = 6000*1000 * format.getFrameSize(); + InputStream in = new ByteArrayInputStream(new byte[dataSize]); + AudioInputStream audioStream = new AudioInputStream(in, format, NOT_SPECIFIED); + AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE, file); + } catch (Exception ignored) { + return; // the test is not applicable + } + try { + checkThread(file); + } finally { + Files.delete(file.toPath()); + } + } + + private static void checkThread(File file) throws Exception { + AudioClip clip = (AudioClip) file.toURL().getContent(); + clip.loop(); + try { + Thread.sleep(2000); + } catch (InterruptedException ignored) { + } + boolean found = isDataPushedThreadExist(); + clip.stop(); + if (!found) { + throw new RuntimeException("Thread 'DataPusher' isn't found"); + } + } + + private static boolean isDataPushedThreadExist() { + for (Thread t : Thread.getAllStackTraces().keySet()) { + if (t.getName().equals("DataPusher")) { + return true; + } + } + return false; + } + +} -- GitLab From 0dba1707910734d03c318424764b8682b028a8e0 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Thu, 27 Jan 2022 08:44:58 +0000 Subject: [PATCH 053/400] 8278518: String(byte[], int, int, Charset) constructor and String.translateEscapes() miss bounds check elimination Co-authored-by: Sergey Tsypanov Reviewed-by: kvn, jrose --- src/hotspot/share/ci/ciTypeFlow.cpp | 111 ++++++++++++++++-- src/hotspot/share/ci/ciTypeFlow.hpp | 7 +- .../bench/vm/compiler/SharedLoopHeader.java | 65 ++++++++++ .../compiler/StringConstructorBenchmark.java | 58 +++++++++ 4 files changed, 232 insertions(+), 9 deletions(-) create mode 100644 test/micro/org/openjdk/bench/vm/compiler/SharedLoopHeader.java create mode 100644 test/micro/org/openjdk/bench/vm/compiler/StringConstructorBenchmark.java diff --git a/src/hotspot/share/ci/ciTypeFlow.cpp b/src/hotspot/share/ci/ciTypeFlow.cpp index 802ba97db2e..240cb654380 100644 --- a/src/hotspot/share/ci/ciTypeFlow.cpp +++ b/src/hotspot/share/ci/ciTypeFlow.cpp @@ -2202,10 +2202,10 @@ bool ciTypeFlow::can_trap(ciBytecodeStream& str) { // ciTypeFlow::clone_loop_heads // // Clone the loop heads -bool ciTypeFlow::clone_loop_heads(Loop* lp, StateVector* temp_vector, JsrSet* temp_set) { +bool ciTypeFlow::clone_loop_heads(StateVector* temp_vector, JsrSet* temp_set) { bool rslt = false; for (PreorderLoops iter(loop_tree_root()); !iter.done(); iter.next()) { - lp = iter.current(); + Loop* lp = iter.current(); Block* head = lp->head(); if (lp == loop_tree_root() || lp->is_irreducible() || @@ -2450,6 +2450,103 @@ void ciTypeFlow::PreorderLoops::next() { } } +// If the tail is a branch to the head, retrieve how many times that path was taken from profiling +int ciTypeFlow::profiled_count(ciTypeFlow::Loop* loop) { + ciMethodData* methodData = method()->method_data(); + if (!methodData->is_mature()) { + return 0; + } + ciTypeFlow::Block* tail = loop->tail(); + if (tail->control() == -1) { + return 0; + } + + ciProfileData* data = methodData->bci_to_data(tail->control()); + assert(data != NULL, "some profile data expected at branch"); + + if (!data->is_JumpData()) { + return 0; + } + + ciBytecodeStream iter(method()); + iter.reset_to_bci(tail->control()); + + bool is_an_if = false; + bool wide = false; + Bytecodes::Code bc = iter.next(); + switch (bc) { + case Bytecodes::_ifeq: + case Bytecodes::_ifne: + case Bytecodes::_iflt: + case Bytecodes::_ifge: + case Bytecodes::_ifgt: + case Bytecodes::_ifle: + case Bytecodes::_if_icmpeq: + case Bytecodes::_if_icmpne: + case Bytecodes::_if_icmplt: + case Bytecodes::_if_icmpge: + case Bytecodes::_if_icmpgt: + case Bytecodes::_if_icmple: + case Bytecodes::_if_acmpeq: + case Bytecodes::_if_acmpne: + case Bytecodes::_ifnull: + case Bytecodes::_ifnonnull: + is_an_if = true; + break; + case Bytecodes::_goto_w: + case Bytecodes::_jsr_w: + wide = true; + break; + case Bytecodes::_goto: + case Bytecodes::_jsr: + break; + default: + fatal(" invalid bytecode: %s", Bytecodes::name(iter.cur_bc())); + } + + GrowableArray* succs = tail->successors(); + + if (!is_an_if) { + assert(((wide ? iter.get_far_dest() : iter.get_dest()) == loop->head()->start()) == (succs->at(ciTypeFlow::GOTO_TARGET) == loop->head()), "branch should lead to loop head"); + if (succs->at(ciTypeFlow::GOTO_TARGET) == loop->head()) { + return method()->scale_count(data->as_JumpData()->taken()); + } + } else { + assert((iter.get_dest() == loop->head()->start()) == (succs->at(ciTypeFlow::IF_TAKEN) == loop->head()), "bytecode and CFG not consistent"); + assert((tail->limit() == loop->head()->start()) == (succs->at(ciTypeFlow::IF_NOT_TAKEN) == loop->head()), "bytecode and CFG not consistent"); + if (succs->at(ciTypeFlow::IF_TAKEN) == loop->head()) { + return method()->scale_count(data->as_JumpData()->taken()); + } else if (succs->at(ciTypeFlow::IF_NOT_TAKEN) == loop->head()) { + return method()->scale_count(data->as_BranchData()->not_taken()); + } + } + + return 0; +} + +bool ciTypeFlow::Loop::at_insertion_point(Loop* lp, Loop* current) { + int lp_pre_order = lp->head()->pre_order(); + if (current->head()->pre_order() < lp_pre_order) { + return true; + } else if (current->head()->pre_order() > lp_pre_order) { + return false; + } + // In the case of a shared head, make the most frequent head/tail (as reported by profiling) the inner loop + if (current->head() == lp->head()) { + int lp_count = outer()->profiled_count(lp); + int current_count = outer()->profiled_count(current); + if (current_count < lp_count) { + return true; + } else if (current_count > lp_count) { + return false; + } + } + if (current->tail()->pre_order() > lp->tail()->pre_order()) { + return true; + } + return false; +} + // ------------------------------------------------------------------ // ciTypeFlow::Loop::sorted_merge // @@ -2467,12 +2564,10 @@ ciTypeFlow::Loop* ciTypeFlow::Loop::sorted_merge(Loop* lp) { int lp_pre_order = lp->head()->pre_order(); // Find insertion point for "lp" while (current != NULL) { - if (current == lp) + if (current == lp) { return leaf; // Already in list - if (current->head()->pre_order() < lp_pre_order) - break; - if (current->head()->pre_order() == lp_pre_order && - current->tail()->pre_order() > lp->tail()->pre_order()) { + } + if (at_insertion_point(lp, current)) { break; } prev = current; @@ -2732,7 +2827,7 @@ void ciTypeFlow::flow_types() { env()->comp_level() >= CompLevel_full_optimization) { // Loop optimizations are not performed on Tier1 compiles. - bool changed = clone_loop_heads(loop_tree_root(), temp_vector, temp_set); + bool changed = clone_loop_heads(temp_vector, temp_set); // If some loop heads were cloned, recompute postorder and loop tree if (changed) { diff --git a/src/hotspot/share/ci/ciTypeFlow.hpp b/src/hotspot/share/ci/ciTypeFlow.hpp index 907897fe310..b733a694f38 100644 --- a/src/hotspot/share/ci/ciTypeFlow.hpp +++ b/src/hotspot/share/ci/ciTypeFlow.hpp @@ -717,6 +717,9 @@ public: bool _irreducible; LocalSet _def_locals; + ciTypeFlow* outer() const { return head()->outer(); } + bool at_insertion_point(Loop* lp, Loop* current); + public: Loop(Block* head, Block* tail) : _parent(NULL), _sibling(NULL), _child(NULL), @@ -795,7 +798,7 @@ private: bool can_trap(ciBytecodeStream& str); // Clone the loop heads. Returns true if any cloning occurred. - bool clone_loop_heads(Loop* lp, StateVector* temp_vector, JsrSet* temp_set); + bool clone_loop_heads(StateVector* temp_vector, JsrSet* temp_set); // Clone lp's head and replace tail's successors with clone. Block* clone_loop_head(Loop* lp, StateVector* temp_vector, JsrSet* temp_set); @@ -913,6 +916,8 @@ private: // Create the block map, which indexes blocks in pre_order. void map_blocks(); + int profiled_count(ciTypeFlow::Loop* loop); + public: // Perform type inference flow analysis. void do_flow(); diff --git a/test/micro/org/openjdk/bench/vm/compiler/SharedLoopHeader.java b/test/micro/org/openjdk/bench/vm/compiler/SharedLoopHeader.java new file mode 100644 index 00000000000..e84ca35ab27 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/SharedLoopHeader.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Mode; +import java.util.concurrent.TimeUnit; + +@State(Scope.Thread) +public class SharedLoopHeader { + + private static final int size = 1000; + private static final boolean branch[] = new boolean[size]; + private static final int count[] = new int[size]; + + @Setup + public void setup() { + for (int i = 0; i < branch.length; i++) { + branch[i] = ((i % 10) != 0); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void sharedHeader() { + int i = 0; + while (i < branch.length) { + if (branch[i]) { + // common branch + count[i]++; + i++; + continue; + } + i += 2; + } + } + +} diff --git a/test/micro/org/openjdk/bench/vm/compiler/StringConstructorBenchmark.java b/test/micro/org/openjdk/bench/vm/compiler/StringConstructorBenchmark.java new file mode 100644 index 00000000000..4763c59629c --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/StringConstructorBenchmark.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.Setup; +import java.util.concurrent.TimeUnit; +import java.nio.charset.StandardCharsets; + +@State(Scope.Thread) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +public class StringConstructorBenchmark { + private byte[] array; + private String str; + + @Setup + public void setup() { + str = "Quizdeltagerne spiste jordb\u00e6r med fl\u00f8de, mens cirkusklovnen. \u042f";//Latin1 ending with Russian + array = str.getBytes(StandardCharsets.UTF_8); + } + + @Benchmark + public String newString() { + return new String(array, 0, array.length, StandardCharsets.UTF_8); + } + + @Benchmark + public String translateEscapes() { + return str.translateEscapes(); + } +} -- GitLab From 94380d0e464a491977ed2b5f1998a55cfe73c3c6 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Thu, 27 Jan 2022 08:59:34 +0000 Subject: [PATCH 054/400] 8278232: [macos] Wrong chars emitted when entering certain char-sequence of Indic language Reviewed-by: prr --- .../macosx/native/libawt_lwawt/awt/AWTView.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m index 8e44052333c..15be2ae90f2 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m @@ -546,12 +546,13 @@ static BOOL shouldUsePressAndHold() { -(BOOL) isCodePointInUnicodeBlockNeedingIMEvent: (unichar) codePoint { if ((codePoint == 0x0024) || (codePoint == 0x00A3) || (codePoint == 0x00A5) || + ((codePoint >= 0x900) && (codePoint <= 0x97F)) || ((codePoint >= 0x20A3) && (codePoint <= 0x20BF)) || ((codePoint >= 0x3000) && (codePoint <= 0x303F)) || ((codePoint >= 0xFF00) && (codePoint <= 0xFFEF))) { // Code point is in 'CJK Symbols and Punctuation' or // 'Halfwidth and Fullwidth Forms' Unicode block or - // currency symbols unicode + // currency symbols unicode or Devanagari script return YES; } return NO; @@ -957,11 +958,17 @@ static jclass jc_CInputMethod = NULL; #ifdef IM_DEBUG NSLog(@"insertText kbdlayout %@ ",(NSString *)kbdLayout); + + NSLog(@"utf8Length %lu utf16Length %lu", (unsigned long)utf8Length, (unsigned long)utf16Length); + NSLog(@"codePoint %x", codePoint); #endif // IM_DEBUG if ((utf16Length > 2) || ((utf8Length > 1) && [self isCodePointInUnicodeBlockNeedingIMEvent:codePoint]) || ((codePoint == 0x5c) && ([(NSString *)kbdLayout containsString:@"Kotoeri"]))) { +#ifdef IM_DEBUG + NSLog(@"string complex "); +#endif aStringIsComplex = YES; } -- GitLab From 7f68759c60d026eba3ad0a7f775497886c727384 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Thu, 27 Jan 2022 09:06:13 +0000 Subject: [PATCH 055/400] 8280719: G1: Remove outdated comment in RemoveSelfForwardPtrObjClosure::apply Reviewed-by: ayang, mli --- src/hotspot/share/gc/g1/g1EvacFailure.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hotspot/share/gc/g1/g1EvacFailure.cpp b/src/hotspot/share/gc/g1/g1EvacFailure.cpp index 8c6a68ad5ab..dbad25955ae 100644 --- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp +++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp @@ -77,7 +77,6 @@ public: zap_dead_objects(_last_forwarded_object_end, obj_addr); - // Zapping clears the bitmap, make sure it didn't clear too much. assert(_cm->is_marked_in_prev_bitmap(obj), "should be correctly marked"); if (_during_concurrent_start) { // For the next marking info we'll only mark the -- GitLab From cab590517bf705418c7376edd5d7066b13b6dde8 Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Thu, 27 Jan 2022 09:18:17 +0000 Subject: [PATCH 056/400] 8280583: Always build NMT Reviewed-by: shade, ihse, zgu --- make/autoconf/jvm-features.m4 | 11 +--- make/hotspot/lib/JvmFeatures.gmk | 9 +-- src/hotspot/share/memory/allocation.hpp | 10 +-- .../share/memory/metaspace/metaspaceDCmd.cpp | 6 +- src/hotspot/share/prims/whitebox.cpp | 14 ++--- src/hotspot/share/runtime/arguments.cpp | 8 --- src/hotspot/share/runtime/mutexLocker.cpp | 7 +-- src/hotspot/share/runtime/mutexLocker.hpp | 4 +- src/hotspot/share/runtime/os.cpp | 25 +++----- src/hotspot/share/runtime/thread.cpp | 4 -- src/hotspot/share/runtime/thread.hpp | 4 +- .../share/services/mallocSiteTable.hpp | 8 +-- src/hotspot/share/services/mallocTracker.hpp | 5 -- src/hotspot/share/services/memBaseline.hpp | 6 +- src/hotspot/share/services/memReporter.hpp | 6 +- src/hotspot/share/services/memTracker.hpp | 62 +------------------ src/hotspot/share/services/nmtDCmd.hpp | 6 +- src/hotspot/share/services/nmtPreInit.cpp | 8 +-- src/hotspot/share/services/nmtPreInit.hpp | 8 +-- .../share/services/threadStackTracker.hpp | 4 +- .../share/services/virtualMemoryTracker.hpp | 5 +- src/hotspot/share/utilities/debug.cpp | 3 - src/hotspot/share/utilities/macros.hpp | 18 +----- .../test_nmt_buffer_overflow_detection.cpp | 10 +-- test/hotspot/gtest/nmt/test_nmtpreinit.cpp | 8 +-- test/hotspot/gtest/nmt/test_nmtpreinitmap.cpp | 8 +-- .../runtime/test_committed_virtualmemory.cpp | 6 +- .../runtime/test_virtualMemoryTracker.cpp | 11 +--- 28 files changed, 51 insertions(+), 233 deletions(-) diff --git a/make/autoconf/jvm-features.m4 b/make/autoconf/jvm-features.m4 index 906a2857877..70457149edc 100644 --- a/make/autoconf/jvm-features.m4 +++ b/make/autoconf/jvm-features.m4 @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -45,7 +45,7 @@ m4_define(jvm_features_valid, m4_normalize( \ ifdef([custom_jvm_features_valid], custom_jvm_features_valid) \ \ cds compiler1 compiler2 dtrace epsilongc g1gc jfr jni-check \ - jvmci jvmti link-time-opt management minimal nmt opt-size parallelgc \ + jvmci jvmti link-time-opt management minimal opt-size parallelgc \ serialgc services shenandoahgc static-build vm-structs zero zgc \ )) @@ -68,7 +68,6 @@ m4_define(jvm_feature_desc_jvmti, [enable Java Virtual Machine Tool Interface (J m4_define(jvm_feature_desc_link_time_opt, [enable link time optimization]) m4_define(jvm_feature_desc_management, [enable java.lang.management API support]) m4_define(jvm_feature_desc_minimal, [support building variant 'minimal']) -m4_define(jvm_feature_desc_nmt, [include native memory tracking (NMT)]) m4_define(jvm_feature_desc_opt_size, [optimize the JVM library for size]) m4_define(jvm_feature_desc_parallelgc, [include the parallel garbage collector]) m4_define(jvm_feature_desc_serialgc, [include the serial garbage collector]) @@ -443,7 +442,7 @@ AC_DEFUN([JVM_FEATURES_PREPARE_VARIANT], JVM_FEATURES_VARIANT_FILTER="compiler2 jvmci link-time-opt opt-size" elif test "x$variant" = "xminimal"; then JVM_FEATURES_VARIANT_FILTER="cds compiler2 dtrace epsilongc g1gc \ - jfr jni-check jvmci jvmti management nmt parallelgc services \ + jfr jni-check jvmci jvmti management parallelgc services \ shenandoahgc vm-structs zgc" if test "x$OPENJDK_TARGET_CPU" = xarm ; then JVM_FEATURES_VARIANT_FILTER="$JVM_FEATURES_VARIANT_FILTER opt-size" @@ -538,10 +537,6 @@ AC_DEFUN([JVM_FEATURES_VERIFY], AC_MSG_ERROR([Specified JVM feature 'jvmti' requires feature 'services' for variant '$variant']) fi - if JVM_FEATURES_IS_ACTIVE(management) && ! JVM_FEATURES_IS_ACTIVE(nmt); then - AC_MSG_ERROR([Specified JVM feature 'management' requires feature 'nmt' for variant '$variant']) - fi - # For backwards compatibility, disable a feature "globally" if one variant # is missing the feature. if ! JVM_FEATURES_IS_ACTIVE(cds); then diff --git a/make/hotspot/lib/JvmFeatures.gmk b/make/hotspot/lib/JvmFeatures.gmk index ab555f9d82d..07ce6feaf6f 100644 --- a/make/hotspot/lib/JvmFeatures.gmk +++ b/make/hotspot/lib/JvmFeatures.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2013, 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 @@ -130,13 +130,6 @@ ifneq ($(call check-jvm-feature, cds), true) JVM_EXCLUDE_PATTERNS += cds/ endif -ifneq ($(call check-jvm-feature, nmt), true) - JVM_CFLAGS_FEATURES += -DINCLUDE_NMT=0 - JVM_EXCLUDE_FILES += \ - memBaseline.cpp memReporter.cpp mallocTracker.cpp virtualMemoryTracker.cpp nmtCommon.cpp \ - memTracker.cpp nmtDCmd.cpp mallocSiteTable.cpp threadStackTracker.cpp -endif - ifneq ($(call check-jvm-feature, g1gc), true) JVM_CFLAGS_FEATURES += -DINCLUDE_G1GC=0 JVM_EXCLUDE_PATTERNS += gc/g1 diff --git a/src/hotspot/share/memory/allocation.hpp b/src/hotspot/share/memory/allocation.hpp index 0562a44063d..8503942f21f 100644 --- a/src/hotspot/share/memory/allocation.hpp +++ b/src/hotspot/share/memory/allocation.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -170,16 +170,8 @@ MEMORY_TYPES_DO(MEMORY_TYPE_SHORTNAME) // Make an int version of the sentinel end value. constexpr int mt_number_of_types = static_cast(MEMFLAGS::mt_number_of_types); -#if INCLUDE_NMT - extern bool NMT_track_callsite; -#else - -const bool NMT_track_callsite = false; - -#endif // INCLUDE_NMT - class NativeCallStack; diff --git a/src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp b/src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp index 96814781377..c4eea087b37 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp +++ b/src/hotspot/share/memory/metaspace/metaspaceDCmd.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, 2020 SAP SE. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022 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 @@ -77,7 +77,7 @@ void MetaspaceDCmd::execute(DCmdSource source, TRAPS) { if (strcasecmp("dynamic", scale_value) == 0) { scale = 0; } else { - scale = NMT_ONLY(NMTUtil::scale_from_name(scale_value)) NOT_NMT(0); + scale = NMTUtil::scale_from_name(scale_value); if (scale == 0) { output()->print_cr("Invalid scale: \"%s\". Will use dynamic scaling.", scale_value); } diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index 3e569f8b8cd..b990ea55640 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -87,12 +87,15 @@ #include "runtime/threadSMR.hpp" #include "runtime/vframe.hpp" #include "runtime/vm_version.hpp" +#include "services/mallocSiteTable.hpp" #include "services/memoryService.hpp" +#include "services/memTracker.hpp" #include "utilities/align.hpp" #include "utilities/debug.hpp" #include "utilities/elfFile.hpp" #include "utilities/exceptions.hpp" #include "utilities/macros.hpp" +#include "utilities/nativeCallStack.hpp" #include "utilities/ostream.hpp" #if INCLUDE_G1GC #include "gc/g1/g1Arguments.hpp" @@ -105,11 +108,6 @@ #if INCLUDE_PARALLELGC #include "gc/parallel/parallelScavengeHeap.inline.hpp" #endif // INCLUDE_PARALLELGC -#if INCLUDE_NMT -#include "services/mallocSiteTable.hpp" -#include "services/memTracker.hpp" -#include "utilities/nativeCallStack.hpp" -#endif // INCLUDE_NMT #if INCLUDE_JVMCI #include "jvmci/jvmciEnv.hpp" #include "jvmci/jvmciRuntime.hpp" @@ -646,7 +644,6 @@ WB_END #endif // INCLUDE_G1GC -#if INCLUDE_NMT // Alloc memory using the test memory type so that we can use that to see if // NMT picks it up correctly WB_ENTRY(jlong, WB_NMTMalloc(JNIEnv* env, jobject o, jlong size)) @@ -724,7 +721,6 @@ WB_ENTRY(void, WB_NMTArenaMalloc(JNIEnv* env, jobject o, jlong arena, jlong size Arena* a = (Arena*)arena; a->Amalloc(size_t(size)); WB_END -#endif // INCLUDE_NMT static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) { assert(method != NULL, "method should not be null"); @@ -2545,7 +2541,6 @@ static JNINativeMethod methods[] = { {CC"psVirtualSpaceAlignment",CC"()J", (void*)&WB_PSVirtualSpaceAlignment}, {CC"psHeapGenerationAlignment",CC"()J", (void*)&WB_PSHeapGenerationAlignment}, #endif -#if INCLUDE_NMT {CC"NMTMalloc", CC"(J)J", (void*)&WB_NMTMalloc }, {CC"NMTMallocWithPseudoStack", CC"(JI)J", (void*)&WB_NMTMallocWithPseudoStack}, {CC"NMTMallocWithPseudoStackAndType", CC"(JII)J", (void*)&WB_NMTMallocWithPseudoStackAndType}, @@ -2559,7 +2554,6 @@ static JNINativeMethod methods[] = { {CC"NMTNewArena", CC"(J)J", (void*)&WB_NMTNewArena }, {CC"NMTFreeArena", CC"(J)V", (void*)&WB_NMTFreeArena }, {CC"NMTArenaMalloc", CC"(JJ)V", (void*)&WB_NMTArenaMalloc }, -#endif // INCLUDE_NMT {CC"deoptimizeFrames", CC"(Z)I", (void*)&WB_DeoptimizeFrames }, {CC"isFrameDeoptimized", CC"(I)Z", (void*)&WB_IsFrameDeoptimized}, {CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll }, diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index fd551f1ec22..c0f78eaaccf 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -4019,7 +4019,6 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) { no_shared_spaces("CDS Disabled"); #endif // INCLUDE_CDS -#if INCLUDE_NMT // Verify NMT arguments const NMT_TrackingLevel lvl = NMTUtil::parse_tracking_level(NativeMemoryTracking); if (lvl == NMT_unknown) { @@ -4031,13 +4030,6 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) { warning("PrintNMTStatistics is disabled, because native memory tracking is not enabled"); FLAG_SET_DEFAULT(PrintNMTStatistics, false); } -#else - if (!FLAG_IS_DEFAULT(NativeMemoryTracking) || PrintNMTStatistics) { - warning("Native Memory Tracking is not supported in this VM"); - FLAG_SET_DEFAULT(NativeMemoryTracking, "off"); - FLAG_SET_DEFAULT(PrintNMTStatistics, false); - } -#endif // INCLUDE_NMT if (TraceDependencies && VerifyDependencies) { if (!FLAG_IS_DEFAULT(TraceDependencies)) { diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index 257f853fb92..2d5c34cd215 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -137,9 +137,8 @@ Monitor* ThreadsSMRDelete_lock = NULL; Mutex* ThreadIdTableCreate_lock = NULL; Mutex* SharedDecoder_lock = NULL; Mutex* DCmdFactory_lock = NULL; -#if INCLUDE_NMT Mutex* NMTQuery_lock = NULL; -#endif + #if INCLUDE_CDS #if INCLUDE_JVMTI Mutex* CDSClassFileStream_lock = NULL; @@ -320,9 +319,7 @@ void mutex_init() { def(ThreadIdTableCreate_lock , PaddedMutex , safepoint); def(SharedDecoder_lock , PaddedMutex , tty-1); def(DCmdFactory_lock , PaddedMutex , nosafepoint); -#if INCLUDE_NMT def(NMTQuery_lock , PaddedMutex , safepoint); -#endif #if INCLUDE_CDS #if INCLUDE_JVMTI def(CDSClassFileStream_lock , PaddedMutex , safepoint); diff --git a/src/hotspot/share/runtime/mutexLocker.hpp b/src/hotspot/share/runtime/mutexLocker.hpp index a40b0592cc4..cd415e945a5 100644 --- a/src/hotspot/share/runtime/mutexLocker.hpp +++ b/src/hotspot/share/runtime/mutexLocker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -114,9 +114,7 @@ extern Monitor* ThreadsSMRDelete_lock; // Used by ThreadsSMRSupport to extern Mutex* ThreadIdTableCreate_lock; // Used by ThreadIdTable to lazily create the thread id table extern Mutex* SharedDecoder_lock; // serializes access to the decoder during normal (not error reporting) use extern Mutex* DCmdFactory_lock; // serialize access to DCmdFactory information -#if INCLUDE_NMT extern Mutex* NMTQuery_lock; // serialize NMT Dcmd queries -#endif #if INCLUDE_CDS #if INCLUDE_JVMTI extern Mutex* CDSClassFileStream_lock; // FileMapInfo::open_stream_for_jvmti diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index 48a0f8398be..29a3d7622f6 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -631,14 +631,11 @@ void* os::malloc(size_t size, MEMFLAGS flags) { void* os::malloc(size_t size, MEMFLAGS memflags, const NativeCallStack& stack) { -#if INCLUDE_NMT - { - void* rc = NULL; - if (NMTPreInit::handle_malloc(&rc, size)) { - return rc; - } + // Special handling for NMT preinit phase before arguments are parsed + void* rc = NULL; + if (NMTPreInit::handle_malloc(&rc, size)) { + return rc; } -#endif DEBUG_ONLY(check_crash_protection()); @@ -677,14 +674,11 @@ void* os::realloc(void *memblock, size_t size, MEMFLAGS flags) { void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCallStack& stack) { -#if INCLUDE_NMT - { - void* rc = NULL; - if (NMTPreInit::handle_realloc(&rc, memblock, size)) { - return rc; - } + // Special handling for NMT preinit phase before arguments are parsed + void* rc = NULL; + if (NMTPreInit::handle_realloc(&rc, memblock, size)) { + return rc; } -#endif if (memblock == NULL) { return os::malloc(size, memflags, stack); @@ -723,11 +717,10 @@ void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, const NativeCa void os::free(void *memblock) { -#if INCLUDE_NMT + // Special handling for NMT preinit phase before arguments are parsed if (NMTPreInit::handle_free(memblock)) { return; } -#endif if (memblock == NULL) { return; diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp index e25d44f4f06..0ec50849f5a 100644 --- a/src/hotspot/share/runtime/thread.cpp +++ b/src/hotspot/share/runtime/thread.cpp @@ -317,7 +317,6 @@ void Thread::record_stack_base_and_size() { } } -#if INCLUDE_NMT void Thread::register_thread_stack_with_NMT() { MemTracker::record_thread_stack(stack_end(), stack_size()); } @@ -325,7 +324,6 @@ void Thread::register_thread_stack_with_NMT() { void Thread::unregister_thread_stack_with_NMT() { MemTracker::release_thread_stack(stack_end(), stack_size()); } -#endif // INCLUDE_NMT void Thread::call_run() { DEBUG_ONLY(_run_state = CALL_RUN;) @@ -2704,10 +2702,8 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { jint parse_result = Arguments::parse(args); if (parse_result != JNI_OK) return parse_result; -#if INCLUDE_NMT // Initialize NMT right after argument parsing to keep the pre-NMT-init window small. MemTracker::initialize(); -#endif // INCLUDE_NMT os::init_before_ergo(); diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index 71100dbe637..9ceb17f7af1 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -550,8 +550,8 @@ protected: void set_stack_size(size_t size) { _stack_size = size; } address stack_end() const { return stack_base() - stack_size(); } void record_stack_base_and_size(); - void register_thread_stack_with_NMT() NOT_NMT_RETURN; - void unregister_thread_stack_with_NMT() NOT_NMT_RETURN; + void register_thread_stack_with_NMT(); + void unregister_thread_stack_with_NMT(); int lgrp_id() const { return _lgrp_id; } void set_lgrp_id(int value) { _lgrp_id = value; } diff --git a/src/hotspot/share/services/mallocSiteTable.hpp b/src/hotspot/share/services/mallocSiteTable.hpp index 6e026f9704c..814b70c6473 100644 --- a/src/hotspot/share/services/mallocSiteTable.hpp +++ b/src/hotspot/share/services/mallocSiteTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -25,15 +25,12 @@ #ifndef SHARE_SERVICES_MALLOCSITETABLE_HPP #define SHARE_SERVICES_MALLOCSITETABLE_HPP -#include "utilities/macros.hpp" - -#if INCLUDE_NMT - #include "memory/allocation.hpp" #include "runtime/atomic.hpp" #include "services/allocationSite.hpp" #include "services/mallocTracker.hpp" #include "services/nmtCommon.hpp" +#include "utilities/macros.hpp" #include "utilities/nativeCallStack.hpp" // MallocSite represents a code path that eventually calls @@ -199,5 +196,4 @@ class MallocSiteTable : AllStatic { static const MallocSiteHashtableEntry* _hash_entry_allocation_site; }; -#endif // INCLUDE_NMT #endif // SHARE_SERVICES_MALLOCSITETABLE_HPP diff --git a/src/hotspot/share/services/mallocTracker.hpp b/src/hotspot/share/services/mallocTracker.hpp index a0953c2b186..ac8eaf17c5c 100644 --- a/src/hotspot/share/services/mallocTracker.hpp +++ b/src/hotspot/share/services/mallocTracker.hpp @@ -25,8 +25,6 @@ #ifndef SHARE_SERVICES_MALLOCTRACKER_HPP #define SHARE_SERVICES_MALLOCTRACKER_HPP -#if INCLUDE_NMT - #include "memory/allocation.hpp" #include "runtime/atomic.hpp" #include "runtime/threadCritical.hpp" @@ -448,7 +446,4 @@ class MallocTracker : AllStatic { } }; -#endif // INCLUDE_NMT - - #endif // SHARE_SERVICES_MALLOCTRACKER_HPP diff --git a/src/hotspot/share/services/memBaseline.hpp b/src/hotspot/share/services/memBaseline.hpp index c43c937abb1..ef801373464 100644 --- a/src/hotspot/share/services/memBaseline.hpp +++ b/src/hotspot/share/services/memBaseline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,8 +25,6 @@ #ifndef SHARE_SERVICES_MEMBASELINE_HPP #define SHARE_SERVICES_MEMBASELINE_HPP -#if INCLUDE_NMT - #include "memory/metaspaceStats.hpp" #include "runtime/mutex.hpp" #include "services/mallocSiteTable.hpp" @@ -212,6 +210,4 @@ class MemBaseline { void virtual_memory_sites_to_reservation_site_order(); }; -#endif // INCLUDE_NMT - #endif // SHARE_SERVICES_MEMBASELINE_HPP diff --git a/src/hotspot/share/services/memReporter.hpp b/src/hotspot/share/services/memReporter.hpp index 77fb1d70a00..2051ab88e3c 100644 --- a/src/hotspot/share/services/memReporter.hpp +++ b/src/hotspot/share/services/memReporter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,8 +25,6 @@ #ifndef SHARE_SERVICES_MEMREPORTER_HPP #define SHARE_SERVICES_MEMREPORTER_HPP -#if INCLUDE_NMT - #include "memory/metaspace.hpp" #include "oops/instanceKlass.hpp" #include "services/memBaseline.hpp" @@ -239,6 +237,4 @@ class MemDetailDiffReporter : public MemSummaryDiffReporter { size_t current_committed, size_t early_reserved, size_t early_committed, MEMFLAGS flag) const; }; -#endif // INCLUDE_NMT - #endif // SHARE_SERVICES_MEMREPORTER_HPP diff --git a/src/hotspot/share/services/memTracker.hpp b/src/hotspot/share/services/memTracker.hpp index 1c81c3f7928..06d5c0c94a8 100644 --- a/src/hotspot/share/services/memTracker.hpp +++ b/src/hotspot/share/services/memTracker.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,67 +25,13 @@ #ifndef SHARE_SERVICES_MEMTRACKER_HPP #define SHARE_SERVICES_MEMTRACKER_HPP -#include "services/nmtCommon.hpp" -#include "utilities/nativeCallStack.hpp" - - -#if !INCLUDE_NMT - -#define CURRENT_PC NativeCallStack::empty_stack() -#define CALLER_PC NativeCallStack::empty_stack() - -class Tracker : public StackObj { - public: - enum TrackerType { - uncommit, - release - }; - Tracker(enum TrackerType type) : _type(type) { } - void record(address addr, size_t size) { } - private: - enum TrackerType _type; -}; - -class MemTracker : AllStatic { - public: - static inline NMT_TrackingLevel tracking_level() { return NMT_off; } - static inline bool enabled() { return false; } - static inline void init() { } - static bool check_launcher_nmt_support(const char* value) { return true; } - static bool verify_nmt_option() { return true; } - - static inline void* record_malloc(void* mem_base, size_t size, MEMFLAGS flag, - const NativeCallStack& stack, NMT_TrackingLevel level) { return mem_base; } - static inline size_t malloc_header_size(NMT_TrackingLevel level) { return 0; } - static inline size_t malloc_header_size(void* memblock) { return 0; } - static inline size_t malloc_footer_size(NMT_TrackingLevel level) { return 0; } - static inline void* malloc_base(void* memblock) { return memblock; } - static inline void* record_free(void* memblock, NMT_TrackingLevel level) { return memblock; } - - static inline void record_new_arena(MEMFLAGS flag) { } - static inline void record_arena_free(MEMFLAGS flag) { } - static inline void record_arena_size_change(ssize_t diff, MEMFLAGS flag) { } - static inline void record_virtual_memory_reserve(void* addr, size_t size, const NativeCallStack& stack, - MEMFLAGS flag = mtNone) { } - static inline void record_virtual_memory_reserve_and_commit(void* addr, size_t size, - const NativeCallStack& stack, MEMFLAGS flag = mtNone) { } - static inline void record_virtual_memory_split_reserved(void* addr, size_t size, size_t split) { } - static inline void record_virtual_memory_commit(void* addr, size_t size, const NativeCallStack& stack) { } - static inline void record_virtual_memory_type(void* addr, MEMFLAGS flag) { } - static inline void record_thread_stack(void* addr, size_t size) { } - static inline void release_thread_stack(void* addr, size_t size) { } - - static void final_report(outputStream*) { } - static void error_report(outputStream*) { } -}; - -#else - #include "runtime/mutexLocker.hpp" #include "runtime/threadCritical.hpp" #include "services/mallocTracker.hpp" +#include "services/nmtCommon.hpp" #include "services/threadStackTracker.hpp" #include "services/virtualMemoryTracker.hpp" +#include "utilities/nativeCallStack.hpp" #define CURRENT_PC ((MemTracker::tracking_level() == NMT_detail) ? \ NativeCallStack(0) : NativeCallStack::empty_stack()) @@ -309,6 +255,4 @@ class MemTracker : AllStatic { static Mutex* _query_lock; }; -#endif // INCLUDE_NMT - #endif // SHARE_SERVICES_MEMTRACKER_HPP diff --git a/src/hotspot/share/services/nmtDCmd.hpp b/src/hotspot/share/services/nmtDCmd.hpp index 52c61d34c0c..23302b790a6 100644 --- a/src/hotspot/share/services/nmtDCmd.hpp +++ b/src/hotspot/share/services/nmtDCmd.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,8 +25,6 @@ #ifndef SHARE_SERVICES_NMTDCMD_HPP #define SHARE_SERVICES_NMTDCMD_HPP -#if INCLUDE_NMT - #include "services/diagnosticArgument.hpp" #include "services/diagnosticFramework.hpp" #include "services/memBaseline.hpp" @@ -71,6 +69,4 @@ class NMTDCmd: public DCmdWithParser { bool check_detail_tracking_level(outputStream* out); }; -#endif // INCLUDE_NMT - #endif // SHARE_SERVICES_NMTDCMD_HPP diff --git a/src/hotspot/share/services/nmtPreInit.cpp b/src/hotspot/share/services/nmtPreInit.cpp index 1fdf4ba9d9f..67eb3eef41f 100644 --- a/src/hotspot/share/services/nmtPreInit.cpp +++ b/src/hotspot/share/services/nmtPreInit.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021 SAP SE. All rights reserved. - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022 SAP SE. All rights reserved. + * 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 @@ -31,8 +31,6 @@ #include "utilities/ostream.hpp" #include "utilities/globalDefinitions.hpp" -#if INCLUDE_NMT - // Obviously we cannot use os::malloc for any dynamic allocation during pre-NMT-init, so we must use // raw malloc; to make this very clear, wrap them. static void* raw_malloc(size_t s) { return ::malloc(s); } @@ -190,5 +188,3 @@ void NMTPreInit::print_state(outputStream* st) { st->print_cr("pre-init mallocs: %u, pre-init reallocs: %u, pre-init frees: %u", _num_mallocs_pre, _num_reallocs_pre, _num_frees_pre); } - -#endif // INCLUDE_NMT diff --git a/src/hotspot/share/services/nmtPreInit.hpp b/src/hotspot/share/services/nmtPreInit.hpp index eed25191135..d65ebaf5dc3 100644 --- a/src/hotspot/share/services/nmtPreInit.hpp +++ b/src/hotspot/share/services/nmtPreInit.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021 SAP SE. All rights reserved. - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022 SAP SE. All rights reserved. + * 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 @@ -34,8 +34,6 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" -#if INCLUDE_NMT - class outputStream; // NMTPreInit is the solution to a specific problem: @@ -353,7 +351,5 @@ public: DEBUG_ONLY(static void verify();) }; -#endif // INCLUDE_NMT - #endif // SHARE_SERVICES_NMT_PREINIT_HPP diff --git a/src/hotspot/share/services/threadStackTracker.hpp b/src/hotspot/share/services/threadStackTracker.hpp index 74e2311b763..db7fc0e8569 100644 --- a/src/hotspot/share/services/threadStackTracker.hpp +++ b/src/hotspot/share/services/threadStackTracker.hpp @@ -25,8 +25,6 @@ #ifndef SHARE_SERVICES_THREADSTACKTRACKER_HPP #define SHARE_SERVICES_THREADSTACKTRACKER_HPP -#if INCLUDE_NMT - #include "services/allocationSite.hpp" #include "services/mallocSiteTable.hpp" #include "services/nmtCommon.hpp" @@ -84,5 +82,5 @@ public: static bool walk_simple_thread_stack_site(MallocSiteWalker* walker); }; -#endif // INCLUDE_NMT #endif // SHARE_SERVICES_THREADSTACKTRACKER_HPP + diff --git a/src/hotspot/share/services/virtualMemoryTracker.hpp b/src/hotspot/share/services/virtualMemoryTracker.hpp index 2f04503cf6e..15627470f78 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.hpp +++ b/src/hotspot/share/services/virtualMemoryTracker.hpp @@ -25,8 +25,6 @@ #ifndef SHARE_SERVICES_VIRTUALMEMORYTRACKER_HPP #define SHARE_SERVICES_VIRTUALMEMORYTRACKER_HPP -#if INCLUDE_NMT - #include "memory/allocation.hpp" #include "memory/metaspace.hpp" // For MetadataType #include "memory/metaspaceStats.hpp" @@ -396,6 +394,5 @@ class VirtualMemoryTracker : AllStatic { static SortedLinkedList* _reserved_regions; }; -#endif // INCLUDE_NMT - #endif // SHARE_SERVICES_VIRTUALMEMORYTRACKER_HPP + diff --git a/src/hotspot/share/utilities/debug.cpp b/src/hotspot/share/utilities/debug.cpp index c3c98d3067f..bb2a0446aee 100644 --- a/src/hotspot/share/utilities/debug.cpp +++ b/src/hotspot/share/utilities/debug.cpp @@ -483,8 +483,6 @@ extern "C" JNIEXPORT void pp(void* p) { oop obj = cast_to_oop(p); obj->print(); } else { -#if INCLUDE_NMT - // With NMT if (MemTracker::enabled()) { const NMT_TrackingLevel tracking_level = MemTracker::tracking_level(); ReservedMemoryRegion region(0, 0); @@ -517,7 +515,6 @@ extern "C" JNIEXPORT void pp(void* p) { } } } -#endif // INCLUDE_NMT tty->print(PTR_FORMAT, p2i(p)); } } diff --git a/src/hotspot/share/utilities/macros.hpp b/src/hotspot/share/utilities/macros.hpp index 9b362b88c11..9207e8a1739 100644 --- a/src/hotspot/share/utilities/macros.hpp +++ b/src/hotspot/share/utilities/macros.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -241,22 +241,6 @@ #define NOT_ZGC_RETURN_(code) { return code; } #endif // INCLUDE_ZGC -#ifndef INCLUDE_NMT -#define INCLUDE_NMT 1 -#endif // INCLUDE_NMT - -#if INCLUDE_NMT -#define NOT_NMT_RETURN /* next token must be ; */ -#define NOT_NMT_RETURN_(code) /* next token must be ; */ -#define NMT_ONLY(x) x -#define NOT_NMT(x) -#else -#define NOT_NMT_RETURN {} -#define NOT_NMT_RETURN_(code) { return code; } -#define NMT_ONLY(x) -#define NOT_NMT(x) x -#endif // INCLUDE_NMT - #ifndef INCLUDE_JFR #define INCLUDE_JFR 1 #endif diff --git a/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp b/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp index c1aeb3e845c..ce30fb8d61d 100644 --- a/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp +++ b/test/hotspot/gtest/nmt/test_nmt_buffer_overflow_detection.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021 SAP SE. All rights reserved. - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022 SAP SE. All rights reserved. + * 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 @@ -31,14 +31,10 @@ #include "unittest.hpp" #include "testutils.hpp" -#if INCLUDE_NMT - // This prefix shows up on any c heap corruption NMT detects. If unsure which assert will // come, just use this one. #define COMMON_NMT_HEAP_CORRUPTION_MESSAGE_PREFIX "NMT corruption" - - #define DEFINE_TEST(test_function, expected_assertion_message) \ TEST_VM_FATAL_ERROR_MSG(NMT, test_function, ".*" expected_assertion_message ".*") { \ if (MemTracker::tracking_level() > NMT_off) { \ @@ -165,5 +161,3 @@ TEST_VM(NMT, test_realloc) { } } } - -#endif // INCLUDE_NMT diff --git a/test/hotspot/gtest/nmt/test_nmtpreinit.cpp b/test/hotspot/gtest/nmt/test_nmtpreinit.cpp index 310cbb187b2..6475e865708 100644 --- a/test/hotspot/gtest/nmt/test_nmtpreinit.cpp +++ b/test/hotspot/gtest/nmt/test_nmtpreinit.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021 SAP SE. All rights reserved. - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022 SAP SE. All rights reserved. + * Copyright (c) 2021, 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 @@ -54,8 +54,6 @@ // us. So inside that scope VM initialization ran and with it the NMT initialization. // To be sure, we assert those assumptions. -#if INCLUDE_NMT - // Some shorts to save writing out the flags every time static void* os_malloc(size_t s) { return os::malloc(s, mtTest); } static void* os_realloc(void* old, size_t s) { return os::realloc(old, s, mtTest); } @@ -127,5 +125,3 @@ TEST_VM(NMTPreInit, pre_to_post_allocs) { g_test_allocations.test_post(); g_test_allocations.free_all(); } - -#endif // INCLUDE_NMT diff --git a/test/hotspot/gtest/nmt/test_nmtpreinitmap.cpp b/test/hotspot/gtest/nmt/test_nmtpreinitmap.cpp index 356c79a8d4a..e68d5ca069a 100644 --- a/test/hotspot/gtest/nmt/test_nmtpreinitmap.cpp +++ b/test/hotspot/gtest/nmt/test_nmtpreinitmap.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021 SAP SE. All rights reserved. - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022 SAP SE. All rights reserved. + * Copyright (c) 2021, 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 @@ -31,8 +31,6 @@ #include "utilities/ostream.hpp" #include "unittest.hpp" -#if INCLUDE_NMT - // This tests the NMTPreInitAllocationTable hash table used to store C-heap allocations before NMT initialization ran. static size_t small_random_nonzero_size() { @@ -132,5 +130,3 @@ TEST_VM_ASSERT_MSG(NMTPreInit, assert_on_lu_table_overflow, ".*NMT preinit looku table.verify(); } #endif // ASSERT - -#endif // INCLUDE_NMT diff --git a/test/hotspot/gtest/runtime/test_committed_virtualmemory.cpp b/test/hotspot/gtest/runtime/test_committed_virtualmemory.cpp index 0abc004a935..b95b86c1247 100644 --- a/test/hotspot/gtest/runtime/test_committed_virtualmemory.cpp +++ b/test/hotspot/gtest/runtime/test_committed_virtualmemory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -26,8 +26,6 @@ // Included early because the NMT flags don't include it. #include "utilities/macros.hpp" -#if INCLUDE_NMT - #include "runtime/thread.hpp" #include "services/memTracker.hpp" #include "services/virtualMemoryTracker.hpp" @@ -223,5 +221,3 @@ TEST_VM(CommittedVirtualMemoryTracker, test_committed_virtualmemory_region) { } } - -#endif // INCLUDE_NMT diff --git a/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp b/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp index ae4457f3e93..4aa058dc160 100644 --- a/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp +++ b/test/hotspot/gtest/runtime/test_virtualMemoryTracker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -32,16 +32,13 @@ #include "precompiled.hpp" -// Included early because the NMT flags don't include it. -#include "utilities/macros.hpp" - -#if INCLUDE_NMT - #include "memory/virtualspace.hpp" #include "services/memTracker.hpp" #include "services/virtualMemoryTracker.hpp" #include "utilities/globalDefinitions.hpp" +#include "utilities/macros.hpp" #include "unittest.hpp" + #include // #define LOG(...) printf(__VA_ARGS__); printf("\n"); fflush(stdout); @@ -566,5 +563,3 @@ TEST_VM(NMT_VirtualMemoryTracker, remove_uncommitted_region) { tty->print_cr("skipped."); } } - -#endif // INCLUDE_NMT -- GitLab From a3a0dcd9215beb6baf43c6e94f8e16fb6a2ccf68 Mon Sep 17 00:00:00 2001 From: Yumin Qi Date: Thu, 27 Jan 2022 18:58:49 +0000 Subject: [PATCH 057/400] 8280353: -XX:ArchiveClassesAtExit should print warning if base archive failed to load Reviewed-by: iklam, ccheung --- src/hotspot/share/cds/metaspaceShared.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index c79e8df4200..5070f7bf39a 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -955,6 +955,9 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() { } } else { set_shared_metaspace_range(NULL, NULL, NULL); + if (DynamicDumpSharedSpaces) { + warning("-XX:ArchiveClassesAtExit is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info."); + } UseSharedSpaces = false; // The base archive cannot be mapped. We cannot dump the dynamic shared archive. AutoCreateSharedArchive = false; -- GitLab From b94ebaa09c9ff788a37edcdbd043f9bb3998cede Mon Sep 17 00:00:00 2001 From: Xin Liu Date: Thu, 27 Jan 2022 19:31:19 +0000 Subject: [PATCH 058/400] 8280686: Remove Compile::print_method_impl Reviewed-by: neliasso, chagedorn, thartmann --- src/hotspot/share/opto/compile.cpp | 28 +++++++++------------------- src/hotspot/share/opto/compile.hpp | 6 ++---- src/hotspot/share/opto/vector.cpp | 10 +++++----- 3 files changed, 16 insertions(+), 28 deletions(-) diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index c730d1d9c98..9adda4961e5 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -1892,7 +1892,7 @@ bool Compile::inline_incrementally_one() { return false; } else if (inlining_progress()) { _late_inlines_pos = i+1; // restore the position in case new elements were inserted - print_method(PHASE_INCREMENTAL_INLINE_STEP, cg->call_node(), 3); + print_method(PHASE_INCREMENTAL_INLINE_STEP, 3, cg->call_node()); break; // process one call site at a time } } else { @@ -2357,7 +2357,7 @@ void Compile::inline_vector_reboxing_calls() { CallGenerator* cg = _vector_reboxing_late_inlines.pop(); cg->do_late_inline(); if (failing()) return; - print_method(PHASE_INLINE_VECTOR_REBOX, cg->call_node(), 3); + print_method(PHASE_INLINE_VECTOR_REBOX, 3, cg->call_node()); } _vector_reboxing_late_inlines.trunc_to(0); } @@ -4814,30 +4814,20 @@ void Compile::sort_macro_nodes() { } } -void Compile::print_method(CompilerPhaseType cpt, int level) { - print_method_impl(cpt, NOT_PRODUCT(CompilerPhaseTypeHelper::to_string(cpt) COMMA) level); -} - -void Compile::print_method(CompilerPhaseType cpt, Node* n, int level) { +void Compile::print_method(CompilerPhaseType cpt, int level, Node* n) { + EventCompilerPhase event; + if (event.should_commit()) { + CompilerEvent::PhaseEvent::post(event, C->_latest_stage_start_counter, cpt, C->_compile_id, level); + } #ifndef PRODUCT ResourceMark rm; stringStream ss; ss.print_raw(CompilerPhaseTypeHelper::to_string(cpt)); - if (n != NULL) { + if (n != nullptr) { ss.print(": %d %s ", n->_idx, NodeClassNames[n->Opcode()]); - } else { - ss.print_raw(": NULL"); } -#endif - C->print_method_impl(cpt, NOT_PRODUCT(ss.as_string() COMMA) level); -} -void Compile::print_method_impl(CompilerPhaseType cpt, NOT_PRODUCT(const char* name COMMA) int level) { - EventCompilerPhase event; - if (event.should_commit()) { - CompilerEvent::PhaseEvent::post(event, C->_latest_stage_start_counter, cpt, C->_compile_id, level); - } -#ifndef PRODUCT + const char* name = ss.as_string(); if (should_print_igv(level)) { _igv_printer->print_method(name, level); } diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp index 0bf6b88eb17..70480b0d06e 100644 --- a/src/hotspot/share/opto/compile.hpp +++ b/src/hotspot/share/opto/compile.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -655,9 +655,7 @@ class Compile : public Phase { void end_method(); bool should_print_igv(int level); - void print_method(CompilerPhaseType cpt, int level); - void print_method(CompilerPhaseType cpt, Node* n, int level); - void print_method_impl(CompilerPhaseType cpt, NOT_PRODUCT(const char* name COMMA) int level); + void print_method(CompilerPhaseType cpt, int level, Node* n = nullptr); #ifndef PRODUCT void igv_print_method_to_file(const char* phase_name = "Debug", bool append = false); diff --git a/src/hotspot/share/opto/vector.cpp b/src/hotspot/share/opto/vector.cpp index a1e324363db..137990ddc77 100644 --- a/src/hotspot/share/opto/vector.cpp +++ b/src/hotspot/share/opto/vector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -96,7 +96,7 @@ void PhaseVector::scalarize_vbox_nodes() { VectorBoxNode* vbox = static_cast(n); scalarize_vbox_node(vbox); if (C->failing()) return; - C->print_method(PHASE_SCALARIZE_VBOX, vbox, 3); + C->print_method(PHASE_SCALARIZE_VBOX, 3, vbox); } if (C->failing()) return; macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1); @@ -131,7 +131,7 @@ void PhaseVector::expand_vunbox_nodes() { VectorUnboxNode* vec_unbox = static_cast(n); expand_vunbox_node(vec_unbox); if (C->failing()) return; - C->print_method(PHASE_EXPAND_VUNBOX, vec_unbox, 3); + C->print_method(PHASE_EXPAND_VUNBOX, 3, vec_unbox); } if (C->failing()) return; macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1); @@ -149,7 +149,7 @@ void PhaseVector::eliminate_vbox_alloc_nodes() { VectorBoxAllocateNode* vbox_alloc = static_cast(n); eliminate_vbox_alloc_node(vbox_alloc); if (C->failing()) return; - C->print_method(PHASE_ELIMINATE_VBOX_ALLOC, vbox_alloc, 3); + C->print_method(PHASE_ELIMINATE_VBOX_ALLOC, 3, vbox_alloc); } if (C->failing()) return; macro_idx = MIN2(macro_idx - 1, C->macro_count() - 1); @@ -297,7 +297,7 @@ void PhaseVector::expand_vbox_node(VectorBoxNode* vec_box) { Node* vect = vec_box->in(VectorBoxNode::Value); Node* result = expand_vbox_node_helper(vbox, vect, vec_box->box_type(), vec_box->vec_type()); C->gvn_replace_by(vec_box, result); - C->print_method(PHASE_EXPAND_VBOX, vec_box, 3); + C->print_method(PHASE_EXPAND_VBOX, 3, vec_box); } C->remove_macro_node(vec_box); } -- GitLab From ece89c6df167e9a7f99b00e3f89c2c41c10ab31b Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 27 Jan 2022 21:00:45 +0000 Subject: [PATCH 059/400] 8280366: (fs) Restore Files.createTempFile javadoc Reviewed-by: alanb, lancea --- src/java.base/share/classes/java/nio/file/Files.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/nio/file/Files.java b/src/java.base/share/classes/java/nio/file/Files.java index b0184395af0..0d9bba9cbca 100644 --- a/src/java.base/share/classes/java/nio/file/Files.java +++ b/src/java.base/share/classes/java/nio/file/Files.java @@ -823,11 +823,12 @@ public final class Files { * names in the same manner as the {@link * java.io.File#createTempFile(String,String,File)} method. * - *

    The file may be opened using the {@link + *

    As with the {@code File.createTempFile} methods, this method is only + * part of a temporary-file facility. Where used as a work file, + * the resulting file may be opened using the {@link * StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} option so that the - * file is deleted when the appropriate {@code close} method is invoked - * either explicitly or via a try-with-resources statement. Alternatively, - * a {@link Runtime#addShutdownHook shutdown-hook}, or the + * file is deleted when the appropriate {@code close} method is invoked. + * Alternatively, a {@link Runtime#addShutdownHook shutdown-hook}, or the * {@link java.io.File#deleteOnExit} mechanism may be used to delete the * file automatically. * -- GitLab From 6d242e406539e97bdd4da82c478db901942b770f Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Thu, 27 Jan 2022 21:58:44 +0000 Subject: [PATCH 060/400] 8280835: jdk/javadoc/tool/CheckManPageOptions.java depends on source hierarchy Reviewed-by: hannesw --- .../jdk/javadoc/tool/CheckManPageOptions.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java b/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java index 5a0d83926c8..a5b853c7aa4 100644 --- a/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java +++ b/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java @@ -54,8 +54,14 @@ import java.util.stream.Collectors; * of the javadoc man page against the set of options declared in the source code. */ public class CheckManPageOptions { + static class SourceDirNotFound extends Error { } + public static void main(String... args) throws Exception { - new CheckManPageOptions().run(args); + try { + new CheckManPageOptions().run(args); + } catch (SourceDirNotFound e) { + System.err.println("NOTE: Cannot find src directory; test skipped"); + } } static final PrintStream out = System.err; @@ -143,7 +149,7 @@ public class CheckManPageOptions { } dir = dir.getParent(); } - throw new IllegalStateException("cannot find root dir"); + throw new SourceDirNotFound(); } List getToolOptions() throws Error { -- GitLab From 40a2ce20334207b542d18f52e26bf418bf29c9ca Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 27 Jan 2022 22:57:09 +0000 Subject: [PATCH 061/400] 8270476: Make floating-point test infrastructure more lambda and method reference friendly Reviewed-by: bpb --- test/jdk/java/lang/Math/Atan2Tests.java | 11 +- .../jdk/java/lang/Math/CeilAndFloorTests.java | 10 +- test/jdk/java/lang/Math/CubeRootTests.java | 20 +-- .../java/lang/Math/ExpCornerCaseTests.java | 6 +- test/jdk/java/lang/Math/Expm1Tests.java | 5 +- .../java/lang/Math/FusedMultiplyAddTests.java | 14 +- test/jdk/java/lang/Math/HyperbolicTests.java | 123 ++++++----------- test/jdk/java/lang/Math/HypotTests.java | 27 ++-- .../lang/Math/Ieee754SpecialCaseTests.java | 18 +-- .../java/lang/Math/IeeeRecommendedTests.java | 39 +++--- test/jdk/java/lang/Math/Log10Tests.java | 15 +- test/jdk/java/lang/Math/Log1pTests.java | 15 +- test/jdk/java/lang/Math/PowTests.java | 25 ++-- test/jdk/java/lang/Math/Rint.java | 16 +-- test/jdk/java/lang/Math/RoundTests.java | 28 ++-- .../lang/Math/SinCosCornerCasesTests.java | 7 +- test/jdk/java/lang/Math/TanTests.java | 11 +- test/jdk/java/lang/Math/Tests.java | 129 ++++++++++++++---- test/jdk/java/lang/Math/WorstCaseTests.java | 47 ++++--- .../java/lang/StrictMath/CubeRootTests.java | 7 +- test/jdk/java/lang/StrictMath/Expm1Tests.java | 7 +- .../java/lang/StrictMath/HyperbolicTests.java | 9 +- test/jdk/java/lang/StrictMath/HypotTests.java | 19 ++- test/jdk/java/lang/StrictMath/Log10Tests.java | 5 +- test/jdk/java/lang/StrictMath/Log1pTests.java | 5 +- test/jdk/java/lang/StrictMath/PowTests.java | 5 +- test/jdk/java/lang/StrictMath/Tests.java | 43 ++++-- 27 files changed, 320 insertions(+), 346 deletions(-) diff --git a/test/jdk/java/lang/Math/Atan2Tests.java b/test/jdk/java/lang/Math/Atan2Tests.java index d6ff8605ddd..7e5dca17f1b 100644 --- a/test/jdk/java/lang/Math/Atan2Tests.java +++ b/test/jdk/java/lang/Math/Atan2Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -25,7 +25,6 @@ * @test * @bug 4984407 * @summary Tests for {Math, StrictMath}.atan2 - * @author Joseph D. Darcy */ public class Atan2Tests { @@ -33,10 +32,8 @@ public class Atan2Tests { static int testAtan2Case(double input1, double input2, double expected) { int failures = 0; - failures += Tests.test("StrictMath.atan2(double, double)", input1, input2, - StrictMath.atan2(input1, input2), expected); - failures += Tests.test("Math.atan2(double, double)", input1, input2, - Math.atan2(input1, input2), expected); + failures += Tests.test("StrictMath.atan2", input1, input2, StrictMath::atan2, expected); + failures += Tests.test("Math.atan2", input1, input2, Math::atan2, expected); return failures; } @@ -55,7 +52,7 @@ public class Atan2Tests { return failures; } - public static void main(String [] argv) { + public static void main(String... argv) { int failures = 0; failures += testAtan2(); diff --git a/test/jdk/java/lang/Math/CeilAndFloorTests.java b/test/jdk/java/lang/Math/CeilAndFloorTests.java index d4508f839c8..6b75b2a8dcb 100644 --- a/test/jdk/java/lang/Math/CeilAndFloorTests.java +++ b/test/jdk/java/lang/Math/CeilAndFloorTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -30,15 +30,15 @@ public class CeilAndFloorTests { private static int testCeilCase(double input, double expected) { int failures = 0; - failures += Tests.test("Math.ceil", input, Math.ceil(input), expected); - failures += Tests.test("StrictMath.ceil", input, StrictMath.ceil(input), expected); + failures += Tests.test("Math.ceil", input, Math::ceil, expected); + failures += Tests.test("StrictMath.ceil", input, StrictMath::ceil, expected); return failures; } private static int testFloorCase(double input, double expected) { int failures = 0; - failures += Tests.test("Math.floor", input, Math.floor(input), expected); - failures += Tests.test("StrictMath.floor", input, StrictMath.floor(input), expected); + failures += Tests.test("Math.floor", input, Math::floor, expected); + failures += Tests.test("StrictMath.floor", input, StrictMath::floor, expected); return failures; } diff --git a/test/jdk/java/lang/Math/CubeRootTests.java b/test/jdk/java/lang/Math/CubeRootTests.java index 53ef270377f..a6350702d90 100644 --- a/test/jdk/java/lang/Math/CubeRootTests.java +++ b/test/jdk/java/lang/Math/CubeRootTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -28,7 +28,6 @@ * @run main CubeRootTests * @bug 4347132 4939441 8078672 * @summary Tests for {Math, StrictMath}.cbrt (use -Dseed=X to set PRNG seed) - * @author Joseph D. Darcy * @key randomness */ @@ -46,17 +45,10 @@ public class CubeRootTests { static int testCubeRootCase(double input, double expected) { int failures=0; - double minus_input = -input; - double minus_expected = -expected; - - failures+=Tests.test("Math.cbrt(double)", input, - Math.cbrt(input), expected); - failures+=Tests.test("Math.cbrt(double)", minus_input, - Math.cbrt(minus_input), minus_expected); - failures+=Tests.test("StrictMath.cbrt(double)", input, - StrictMath.cbrt(input), expected); - failures+=Tests.test("StrictMath.cbrt(double)", minus_input, - StrictMath.cbrt(minus_input), minus_expected); + failures+=Tests.test("Math.cbrt", input, Math::cbrt, expected); + failures+=Tests.test("Math.cbrt", -input, Math::cbrt, -expected); + failures+=Tests.test("StrictMath.cbrt", input, StrictMath::cbrt, expected); + failures+=Tests.test("StrictMath.cbrt", -input, StrictMath::cbrt, -expected); return failures; } @@ -324,7 +316,7 @@ public class CubeRootTests { return failures; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += testCubeRoot(); diff --git a/test/jdk/java/lang/Math/ExpCornerCaseTests.java b/test/jdk/java/lang/Math/ExpCornerCaseTests.java index 16168254378..e48f31beb91 100644 --- a/test/jdk/java/lang/Math/ExpCornerCaseTests.java +++ b/test/jdk/java/lang/Math/ExpCornerCaseTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -61,8 +61,8 @@ public class ExpCornerCaseTests { private static int testExp(double input, double expected) { int failures = 0; - failures += Tests.test("StrictMath.exp", input, StrictMath.exp(input), expected); - failures += Tests.test("Math.exp", input, Math.exp(input), expected); + failures += Tests.test("StrictMath.exp", input, StrictMath::exp, expected); + failures += Tests.test("Math.exp", input, Math::exp, expected); return failures; } } diff --git a/test/jdk/java/lang/Math/Expm1Tests.java b/test/jdk/java/lang/Math/Expm1Tests.java index 5bf267d15fd..204fe44ef15 100644 --- a/test/jdk/java/lang/Math/Expm1Tests.java +++ b/test/jdk/java/lang/Math/Expm1Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,6 @@ * @test * @bug 4851638 4900189 4939441 * @summary Tests for {Math, StrictMath}.expm1 - * @author Joseph D. Darcy */ /* @@ -214,7 +213,7 @@ public class Expm1Tests { return failures; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += testExpm1(); diff --git a/test/jdk/java/lang/Math/FusedMultiplyAddTests.java b/test/jdk/java/lang/Math/FusedMultiplyAddTests.java index 03e164c2198..61a3bfb0de1 100644 --- a/test/jdk/java/lang/Math/FusedMultiplyAddTests.java +++ b/test/jdk/java/lang/Math/FusedMultiplyAddTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -365,16 +365,12 @@ public class FusedMultiplyAddTests { private static int testFusedMacCase(double input1, double input2, double input3, double expected) { int failures = 0; - failures += Tests.test("Math.fma(double)", input1, input2, input3, - Math.fma(input1, input2, input3), expected); - failures += Tests.test("StrictMath.fma(double)", input1, input2, input3, - StrictMath.fma(input1, input2, input3), expected); + failures += Tests.test("Math.fma", input1, input2, input3, Math::fma, expected); + failures += Tests.test("StrictMath.fma", input1, input2, input3, StrictMath::fma, expected); // Permute first two inputs - failures += Tests.test("Math.fma(double)", input2, input1, input3, - Math.fma(input2, input1, input3), expected); - failures += Tests.test("StrictMath.fma(double)", input2, input1, input3, - StrictMath.fma(input2, input1, input3), expected); + failures += Tests.test("Math.fma", input2, input1, input3, Math::fma, expected); + failures += Tests.test("StrictMath.fma", input2, input1, input3, StrictMath::fma, expected); return failures; } diff --git a/test/jdk/java/lang/Math/HyperbolicTests.java b/test/jdk/java/lang/Math/HyperbolicTests.java index 0df493698fe..8309606f63d 100644 --- a/test/jdk/java/lang/Math/HyperbolicTests.java +++ b/test/jdk/java/lang/Math/HyperbolicTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,6 @@ * @test * @bug 4851625 4900189 4939441 * @summary Tests for {Math, StrictMath}.{sinh, cosh, tanh} - * @author Joseph D. Darcy */ public class HyperbolicTests { @@ -33,6 +32,20 @@ public class HyperbolicTests { static final double NaNd = Double.NaN; + public static void main(String... argv) { + int failures = 0; + + failures += testSinh(); + failures += testCosh(); + failures += testTanh(); + + if (failures > 0) { + System.err.println("Testing the hyperbolic functions incurred " + + failures + " failures."); + throw new RuntimeException(); + } + } + /** * Test accuracy of {Math, StrictMath}.sinh. The specified * accuracy is 2.5 ulps. @@ -355,19 +368,11 @@ public class HyperbolicTests { double expected, double tolerance) { int failures = 0; - failures += Tests.testTolerance("Math.sinh(double)", - input, Math.sinh(input), - expected, tolerance); - failures += Tests.testTolerance("Math.sinh(double)", - -input, Math.sinh(-input), - -expected, tolerance); + failures += Tests.testTolerance("Math.sinh", input, Math::sinh, expected, tolerance); + failures += Tests.testTolerance("Math.sinh", -input, Math::sinh, -expected, tolerance); - failures += Tests.testTolerance("StrictMath.sinh(double)", - input, StrictMath.sinh(input), - expected, tolerance); - failures += Tests.testTolerance("StrictMath.sinh(double)", - -input, StrictMath.sinh(-input), - -expected, tolerance); + failures += Tests.testTolerance("StrictMath.sinh", input, StrictMath::sinh, expected, tolerance); + failures += Tests.testTolerance("StrictMath.sinh", -input, StrictMath::sinh, -expected, tolerance); return failures; } @@ -375,23 +380,14 @@ public class HyperbolicTests { double expected, double ulps) { int failures = 0; - failures += Tests.testUlpDiff("Math.sinh(double)", - input, Math.sinh(input), - expected, ulps); - failures += Tests.testUlpDiff("Math.sinh(double)", - -input, Math.sinh(-input), - -expected, ulps); - - failures += Tests.testUlpDiff("StrictMath.sinh(double)", - input, StrictMath.sinh(input), - expected, ulps); - failures += Tests.testUlpDiff("StrictMath.sinh(double)", - -input, StrictMath.sinh(-input), - -expected, ulps); + failures += Tests.testUlpDiff("Math.sinh", input, Math::sinh, expected, ulps); + failures += Tests.testUlpDiff("Math.sinh", -input, Math::sinh, -expected, ulps); + + failures += Tests.testUlpDiff("StrictMath.sinh", input, StrictMath::sinh, expected, ulps); + failures += Tests.testUlpDiff("StrictMath.sinh", -input, StrictMath::sinh, -expected, ulps); return failures; } - /** * Test accuracy of {Math, StrictMath}.cosh. The specified * accuracy is 2.5 ulps. @@ -594,7 +590,6 @@ public class HyperbolicTests { 3.0); } - double [][] specialTestCases = { {0.0, 1.0}, {NaNd, NaNd}, @@ -733,23 +728,14 @@ public class HyperbolicTests { double expected, double ulps) { int failures = 0; - failures += Tests.testUlpDiff("Math.cosh(double)", - input, Math.cosh(input), - expected, ulps); - failures += Tests.testUlpDiff("Math.cosh(double)", - -input, Math.cosh(-input), - expected, ulps); - - failures += Tests.testUlpDiff("StrictMath.cosh(double)", - input, StrictMath.cosh(input), - expected, ulps); - failures += Tests.testUlpDiff("StrictMath.cosh(double)", - -input, StrictMath.cosh(-input), - expected, ulps); + failures += Tests.testUlpDiff("Math.cosh", input, Math::cosh, expected, ulps); + failures += Tests.testUlpDiff("Math.cosh", -input, Math::cosh, expected, ulps); + + failures += Tests.testUlpDiff("StrictMath.cosh", input, StrictMath::cosh, expected, ulps); + failures += Tests.testUlpDiff("StrictMath.cosh", -input, StrictMath::cosh, expected, ulps); return failures; } - /** * Test accuracy of {Math, StrictMath}.tanh. The specified * accuracy is 2.5 ulps. @@ -952,7 +938,6 @@ public class HyperbolicTests { 3.0); } - double [][] specialTestCases = { {0.0, 0.0}, {NaNd, NaNd}, @@ -1007,19 +992,11 @@ public class HyperbolicTests { double expected, double tolerance) { int failures = 0; - failures += Tests.testTolerance("Math.tanh(double", - input, Math.tanh(input), - expected, tolerance); - failures += Tests.testTolerance("Math.tanh(double", - -input, Math.tanh(-input), - -expected, tolerance); + failures += Tests.testTolerance("Math.tanh", input, Math::tanh, expected, tolerance); + failures += Tests.testTolerance("Math.tanh", -input, Math::tanh, -expected, tolerance); - failures += Tests.testTolerance("StrictMath.tanh(double", - input, StrictMath.tanh(input), - expected, tolerance); - failures += Tests.testTolerance("StrictMath.tanh(double", - -input, StrictMath.tanh(-input), - -expected, tolerance); + failures += Tests.testTolerance("StrictMath.tanh", input, StrictMath::tanh, expected, tolerance); + failures += Tests.testTolerance("StrictMath.tanh", -input, StrictMath::tanh, -expected, tolerance); return failures; } @@ -1028,35 +1005,11 @@ public class HyperbolicTests { double ulps) { int failures = 0; - failures += Tests.testUlpDiffWithAbsBound("Math.tanh(double)", - input, Math.tanh(input), - expected, ulps, 1.0); - failures += Tests.testUlpDiffWithAbsBound("Math.tanh(double)", - -input, Math.tanh(-input), - -expected, ulps, 1.0); - - failures += Tests.testUlpDiffWithAbsBound("StrictMath.tanh(double)", - input, StrictMath.tanh(input), - expected, ulps, 1.0); - failures += Tests.testUlpDiffWithAbsBound("StrictMath.tanh(double)", - -input, StrictMath.tanh(-input), - -expected, ulps, 1.0); - return failures; - } - - - public static void main(String argv[]) { - int failures = 0; + failures += Tests.testUlpDiffWithAbsBound("Math.tanh", input, Math::tanh, expected, ulps, 1.0); + failures += Tests.testUlpDiffWithAbsBound("Math.tanh", -input, Math::tanh, -expected, ulps, 1.0); - failures += testSinh(); - failures += testCosh(); - failures += testTanh(); - - if (failures > 0) { - System.err.println("Testing the hyperbolic functions incurred " - + failures + " failures."); - throw new RuntimeException(); - } + failures += Tests.testUlpDiffWithAbsBound("StrictMath.tanh", input, StrictMath::tanh, expected, ulps, 1.0); + failures += Tests.testUlpDiffWithAbsBound("StrictMath.tanh", -input, StrictMath::tanh, -expected, ulps, 1.0); + return failures; } - } diff --git a/test/jdk/java/lang/Math/HypotTests.java b/test/jdk/java/lang/Math/HypotTests.java index d7e562ca5fd..e09799e34a4 100644 --- a/test/jdk/java/lang/Math/HypotTests.java +++ b/test/jdk/java/lang/Math/HypotTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -28,7 +28,6 @@ * @run main HypotTests * @bug 4851638 4939441 8078672 8240632 * @summary Tests for {Math, StrictMath}.hypot (use -Dseed=X to set PRNG seed) - * @author Joseph D. Darcy * @key randomness */ @@ -51,7 +50,6 @@ public class HypotTests { long N = n; long result[] = new long[3]; - result[0] = Math.abs(M*M - N*N); result[1] = Math.abs(2*M*N); result[2] = Math.abs(M*M + N*N); @@ -188,13 +186,11 @@ public class HypotTests { pcNeighborsStrictHypot[j+1] ); } - } } } - return failures; } @@ -221,26 +217,22 @@ public class HypotTests { // each input negated singly, and both inputs negated. Also // test inputs in reversed order. - for(int i = -1; i <= 1; i+=2) { - for(int j = -1; j <= 1; j+=2) { + for(int i = -1; i <= 1; i += 2) { + for(int j = -1; j <= 1; j += 2) { double x = i * input1; double y = j * input2; - failures += Tests.testUlpDiff("Math.hypot", x, y, - Math.hypot(x, y), expected, ulps); - failures += Tests.testUlpDiff("Math.hypot", y, x, - Math.hypot(y, x ), expected, ulps); - - failures += Tests.testUlpDiff("StrictMath.hypot", x, y, - StrictMath.hypot(x, y), expected, ulps); - failures += Tests.testUlpDiff("StrictMath.hypot", y, x, - StrictMath.hypot(y, x), expected, ulps); + failures += Tests.testUlpDiff("Math.hypot", x, y, Math::hypot, expected, ulps); + failures += Tests.testUlpDiff("Math.hypot", y, x, Math::hypot, expected, ulps); + + failures += Tests.testUlpDiff("StrictMath.hypot", x, y, StrictMath::hypot, expected, ulps); + failures += Tests.testUlpDiff("StrictMath.hypot", y, x, StrictMath::hypot, expected, ulps); } } return failures; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += testHypot(); @@ -252,5 +244,4 @@ public class HypotTests { throw new RuntimeException(); } } - } diff --git a/test/jdk/java/lang/Math/Ieee754SpecialCaseTests.java b/test/jdk/java/lang/Math/Ieee754SpecialCaseTests.java index d8192f2fee3..f53f2314647 100644 --- a/test/jdk/java/lang/Math/Ieee754SpecialCaseTests.java +++ b/test/jdk/java/lang/Math/Ieee754SpecialCaseTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -62,8 +62,8 @@ public class Ieee754SpecialCaseTests { private static int testCosCase(double input, double expected) { int failures = 0; - failures += Tests.test("Math.cos", input, Math.cos(input), expected); - failures += Tests.test("StrictMath.cos", input, StrictMath.cos(input), expected); + failures += Tests.test("Math.cos", input, Math::cos, expected); + failures += Tests.test("StrictMath.cos", input, StrictMath::cos, expected); return failures; } @@ -82,8 +82,8 @@ public class Ieee754SpecialCaseTests { private static int testAcosCase(double input, double expected) { int failures = 0; - failures += Tests.test("Math.acos", input, Math.acos(input), expected); - failures += Tests.test("StrictMath.acos", input, StrictMath.acos(input), expected); + failures += Tests.test("Math.acos", input, Math::acos, expected); + failures += Tests.test("StrictMath.acos", input, StrictMath::acos, expected); return failures; } @@ -103,8 +103,8 @@ public class Ieee754SpecialCaseTests { private static int testAtanCase(double input, double expected) { int failures = 0; - failures += Tests.test("Math.atan", input, Math.atan(input), expected); - failures += Tests.test("StrictMath.atan", input, StrictMath.atan(input), expected); + failures += Tests.test("Math.atan", input, Math::atan, expected); + failures += Tests.test("StrictMath.atan", input, StrictMath::atan, expected); return failures; } @@ -123,8 +123,8 @@ public class Ieee754SpecialCaseTests { private static int testLogCase(double input, double expected) { int failures = 0; - failures += Tests.test("Math.log", input, Math.log(input), expected); - failures += Tests.test("StrictMath.log", input, StrictMath.log(input), expected); + failures += Tests.test("Math.log", input, Math::log, expected); + failures += Tests.test("StrictMath.log", input, StrictMath::log, expected); return failures; } } diff --git a/test/jdk/java/lang/Math/IeeeRecommendedTests.java b/test/jdk/java/lang/Math/IeeeRecommendedTests.java index 830b16d765a..8570508ff44 100644 --- a/test/jdk/java/lang/Math/IeeeRecommendedTests.java +++ b/test/jdk/java/lang/Math/IeeeRecommendedTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -28,7 +28,6 @@ * @run main IeeeRecommendedTests * @bug 4860891 4826732 4780454 4939441 4826652 8078672 * @summary Tests for IEEE 754[R] recommended functions and similar methods (use -Dseed=X to set PRNG seed) - * @author Joseph D. Darcy * @key randomness */ @@ -364,14 +363,14 @@ public class IeeeRecommendedTests { double minus_expected = -expected; failures+=Tests.test("Math.nextAfter(double,double)", start, direction, - Math.nextAfter(start, direction), expected); + Math::nextAfter, expected); failures+=Tests.test("Math.nextAfter(double,double)", minus_start, minus_direction, - Math.nextAfter(minus_start, minus_direction), minus_expected); + Math::nextAfter, minus_expected); failures+=Tests.test("StrictMath.nextAfter(double,double)", start, direction, - StrictMath.nextAfter(start, direction), expected); + StrictMath::nextAfter, expected); failures+=Tests.test("StrictMath.nextAfter(double,double)", minus_start, minus_direction, - StrictMath.nextAfter(minus_start, minus_direction), minus_expected); + StrictMath::nextAfter, minus_expected); return failures; } @@ -586,10 +585,10 @@ public class IeeeRecommendedTests { for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("Math.nextUp(double)", - testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]); + testCases[i][0], Math::nextUp, testCases[i][1]); failures+=Tests.test("StrictMath.nextUp(double)", - testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]); + testCases[i][0], StrictMath::nextUp, testCases[i][1]); } return failures; @@ -665,10 +664,10 @@ public class IeeeRecommendedTests { for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("Math.nextDown(double)", - testCases[i][0], Math.nextDown(testCases[i][0]), testCases[i][1]); + testCases[i][0], Math::nextDown, testCases[i][1]); failures+=Tests.test("StrictMath.nextDown(double)", - testCases[i][0], StrictMath.nextDown(testCases[i][0]), testCases[i][1]); + testCases[i][0], StrictMath::nextDown, testCases[i][1]); } return failures; @@ -906,12 +905,12 @@ public class IeeeRecommendedTests { // copySign(magnitude, sign) failures+=Tests.test("MathcopySign(double,double)", testCases[i][m],testCases[j][n], - Math.copySign(testCases[i][m], testCases[j][n]), + Math::copySign, (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) ); failures+=Tests.test("StrictMath.copySign(double,double)", testCases[i][m],testCases[j][n], - StrictMath.copySign(testCases[i][m], testCases[j][n]), + StrictMath::copySign, (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) ); } } @@ -932,7 +931,7 @@ public class IeeeRecommendedTests { failures+=Tests.test("StrictMath.copySign(double,double)", testCases[i][m], NaNs[j], - StrictMath.copySign(testCases[i][m], NaNs[j]), + StrictMath::copySign, Math.abs(testCases[i][m]) ); } } @@ -1384,13 +1383,13 @@ public class IeeeRecommendedTests { int failures=0; failures+=Tests.test("Math.ulp(double)", d, - Math.ulp(d), expected); + Math::ulp, expected); failures+=Tests.test("Math.ulp(double)", minus_d, - Math.ulp(minus_d), expected); + Math::ulp, expected); failures+=Tests.test("StrictMath.ulp(double)", d, - StrictMath.ulp(d), expected); + StrictMath::ulp, expected); failures+=Tests.test("StrictMath.ulp(double)", minus_d, - StrictMath.ulp(minus_d), expected); + StrictMath::ulp, expected); return failures; } @@ -1664,16 +1663,16 @@ public class IeeeRecommendedTests { for(int i = 0; i < testCases.length; i++) { failures+=Tests.test("Math.signum(double)", - testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]); + testCases[i][0], Math::signum, testCases[i][1]); failures+=Tests.test("StrictMath.signum(double)", - testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]); + testCases[i][0], StrictMath::signum, testCases[i][1]); } return failures; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += testFloatGetExponent(); diff --git a/test/jdk/java/lang/Math/Log10Tests.java b/test/jdk/java/lang/Math/Log10Tests.java index 7bc75644f2b..dbdd7c14179 100644 --- a/test/jdk/java/lang/Math/Log10Tests.java +++ b/test/jdk/java/lang/Math/Log10Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,6 @@ * @test * @bug 4074599 4939441 * @summary Tests for {Math, StrictMath}.log10 - * @author Joseph D. Darcy */ public class Log10Tests { @@ -41,11 +40,8 @@ public class Log10Tests { static int testLog10Case(double input, double expected) { int failures=0; - failures+=Tests.test("Math.log10(double)", input, - Math.log10(input), expected); - - failures+=Tests.test("StrictMath.log10(double)", input, - StrictMath.log10(input), expected); + failures+=Tests.test("Math.log10", input, Math::log10, expected); + failures+=Tests.test("StrictMath.log10", input, StrictMath::log10, expected); return failures; } @@ -121,8 +117,6 @@ public class Log10Tests { "log(input)/log(10): log10(input) = " + result + "\tlog(input)/log(10) = " + expected); } - - } } } @@ -205,7 +199,7 @@ public class Log10Tests { return failures; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += testLog10(); @@ -216,5 +210,4 @@ public class Log10Tests { throw new RuntimeException(); } } - } diff --git a/test/jdk/java/lang/Math/Log1pTests.java b/test/jdk/java/lang/Math/Log1pTests.java index 021a651ed18..2fa7ddec442 100644 --- a/test/jdk/java/lang/Math/Log1pTests.java +++ b/test/jdk/java/lang/Math/Log1pTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -28,7 +28,6 @@ * @run main Log1pTests * @bug 4851638 4939441 8078672 * @summary Tests for {Math, StrictMath}.log1p (use -Dseed=X to set PRNG seed) - * @author Joseph D. Darcy * @key randomness */ @@ -167,9 +166,7 @@ public class Log1pTests { pcNeighborsStrictLog1p[j+1] ); } - } - } } @@ -185,16 +182,12 @@ public class Log1pTests { double expected, double ulps) { int failures = 0; - failures += Tests.testUlpDiff("Math.lop1p(double", - input, Math.log1p(input), - expected, ulps); - failures += Tests.testUlpDiff("StrictMath.log1p(double", - input, StrictMath.log1p(input), - expected, ulps); + failures += Tests.testUlpDiff("Math.lop1p", input, Math::log1p, expected, ulps); + failures += Tests.testUlpDiff("StrictMath.log1p", input, StrictMath::log1p, expected, ulps); return failures; } - public static void main(String argv[]) { + public static void main(String... argv) { int failures = 0; failures += testLog1p(); diff --git a/test/jdk/java/lang/Math/PowTests.java b/test/jdk/java/lang/Math/PowTests.java index 88221c5415a..8f8ea098bda 100644 --- a/test/jdk/java/lang/Math/PowTests.java +++ b/test/jdk/java/lang/Math/PowTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -25,7 +25,6 @@ * @test * @bug 4984407 5033578 8134795 * @summary Tests for {Math, StrictMath}.pow - * @author Joseph D. Darcy */ public class PowTests { @@ -35,35 +34,29 @@ public class PowTests { static int testPowCase(double input1, double input2, double expected) { int failures = 0; - failures += Tests.test("StrictMath.pow(double, double)", input1, input2, - StrictMath.pow(input1, input2), expected); - failures += Tests.test("Math.pow(double, double)", input1, input2, - Math.pow(input1, input2), expected); + failures += Tests.test("StrictMath.pow", input1, input2, StrictMath::pow, expected); + failures += Tests.test("Math.pow", input1, input2, Math::pow, expected); return failures; } - static int testStrictPowCase(double input1, double input2, double expected) { int failures = 0; - failures += Tests.test("StrictMath.pow(double, double)", input1, input2, - StrictMath.pow(input1, input2), expected); + failures += Tests.test("StrictMath.pow", input1, input2, + StrictMath::pow, expected); return failures; } static int testNonstrictPowCase(double input1, double input2, double expected) { int failures = 0; - failures += Tests.test("Math.pow(double, double)", input1, input2, - Math.pow(input1, input2), expected); + failures += Tests.test("Math.pow", input1, input2, + Math::pow, expected); return failures; } static int testStrictVsNonstrictPowCase(double input1, double input2) { - double smResult = StrictMath.pow(input1, input2); - double mResult = Math.pow(input1, input2); return Tests.testUlpDiff( "StrictMath.pow(double, double) vs Math.pow(double, double)", - input1, input2, mResult, smResult, 2.0 - ); + input1, input2, Math::pow, StrictMath.pow(input1, input2), 2.0); } /* @@ -313,7 +306,7 @@ public class PowTests { } } - public static void main(String [] argv) { + public static void main(String... argv) { int failures = 0; failures += testPow(); diff --git a/test/jdk/java/lang/Math/Rint.java b/test/jdk/java/lang/Math/Rint.java index 53e4d26b131..a9c6952b90b 100644 --- a/test/jdk/java/lang/Math/Rint.java +++ b/test/jdk/java/lang/Math/Rint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -32,17 +32,14 @@ public class Rint { static int testRintCase(double input, double expected) { int failures = 0; double result; - failures += Tests.test("Math.rint", input, Math.rint(input), expected); - failures += Tests.test("Math.rint", -input, Math.rint(-input), -expected); - failures += Tests.test("StrictMath.rint", - input, StrictMath.rint(input), expected); - failures += Tests.test("StrictMath.rint", -input, - StrictMath.rint(-input), -expected); + failures += Tests.test("Math.rint", input, Math::rint, expected); + failures += Tests.test("Math.rint", -input, Math::rint, -expected); + failures += Tests.test("StrictMath.rint", input, StrictMath::rint, expected); + failures += Tests.test("StrictMath.rint", -input, StrictMath::rint, -expected); return failures; } - - public static void main(String args[]) { + public static void main(String... args) { int failures = 0; double twoToThe52 = Math.scalb(1.0, 52); // 2^52 @@ -97,7 +94,6 @@ public class Rint { }; - for(int i = 0; i < testCases.length; i++) { failures += testRintCase(testCases[i][0], testCases[i][1]); } diff --git a/test/jdk/java/lang/Math/RoundTests.java b/test/jdk/java/lang/Math/RoundTests.java index cae190f9770..0a51b426386 100644 --- a/test/jdk/java/lang/Math/RoundTests.java +++ b/test/jdk/java/lang/Math/RoundTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -64,8 +64,8 @@ public class RoundTests { private static int testNearHalfCases(double input, double expected) { int failures = 0; - failures += Tests.test("Math.round", input, Math.round(input), expected); - failures += Tests.test("StrictMath.round", input, StrictMath.round(input), expected); + failures += Tests.test("Math.round", input, Math::round, expected); + failures += Tests.test("StrictMath.round", input, StrictMath::round, expected); return failures; } @@ -145,20 +145,14 @@ public class RoundTests { failures += Tests.test("Math.round", -Float.MIN_VALUE, Math.round(-Float.MIN_VALUE), 0.0F); - failures += Tests.test("Math.round", Double.NaN, Math.round(Double.NaN), 0.0); - failures += Tests.test("Math.round", Double.POSITIVE_INFINITY, - Math.round(Double.POSITIVE_INFINITY), Long.MAX_VALUE); - failures += Tests.test("Math.round", Double.NEGATIVE_INFINITY, - Math.round(Double.NEGATIVE_INFINITY), Long.MIN_VALUE); - failures += Tests.test("Math.round", -(double)Long.MIN_VALUE, - Math.round(-(double)Long.MIN_VALUE), Long.MAX_VALUE); - failures += Tests.test("Math.round", (double) Long.MIN_VALUE, - Math.round((double) Long.MIN_VALUE), Long.MIN_VALUE); - failures += Tests.test("Math.round", 0, Math.round(0), 0.0); - failures += Tests.test("Math.round", Double.MIN_VALUE, - Math.round(Double.MIN_VALUE), 0.0); - failures += Tests.test("Math.round", -Double.MIN_VALUE, - Math.round(-Double.MIN_VALUE), 0.0); + failures += Tests.test("Math.round", Double.NaN, Math::round, 0.0); + failures += Tests.test("Math.round", Double.POSITIVE_INFINITY, Math::round, Long.MAX_VALUE); + failures += Tests.test("Math.round", Double.NEGATIVE_INFINITY, Math::round, Long.MIN_VALUE); + failures += Tests.test("Math.round", -(double)Long.MIN_VALUE, Math::round, Long.MAX_VALUE); + failures += Tests.test("Math.round", (double) Long.MIN_VALUE, Math::round, Long.MIN_VALUE); + failures += Tests.test("Math.round", 0, Math::round, 0.0); + failures += Tests.test("Math.round", Double.MIN_VALUE, Math::round, 0.0); + failures += Tests.test("Math.round", -Double.MIN_VALUE, Math::round, 0.0); return failures; } diff --git a/test/jdk/java/lang/Math/SinCosCornerCasesTests.java b/test/jdk/java/lang/Math/SinCosCornerCasesTests.java index e144857443f..225cdaebf0e 100644 --- a/test/jdk/java/lang/Math/SinCosCornerCasesTests.java +++ b/test/jdk/java/lang/Math/SinCosCornerCasesTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -28,7 +28,6 @@ * @build Tests * @build SinCosCornerCasesTests * @run main SinCosCornerCasesTests - * @author Vivek Deshpande */ public class SinCosCornerCasesTests { @@ -1502,7 +1501,7 @@ public class SinCosCornerCasesTests { private static int testSinCase(double input, double bound1, double bound2) { int failures = 0; - failures += Tests.testBounds("Math.sin", input, Math.sin(input), bound1, bound2); + failures += Tests.testBounds("Math.sin", input, Math::sin, bound1, bound2); return failures; } @@ -2921,7 +2920,7 @@ public class SinCosCornerCasesTests { private static int testCosCase(double input, double bound1, double bound2) { int failures = 0; - failures += Tests.testBounds("Math.cos", input, Math.cos(input), bound1, bound2); + failures += Tests.testBounds("Math.cos", input, Math::cos, bound1, bound2); return failures; } } diff --git a/test/jdk/java/lang/Math/TanTests.java b/test/jdk/java/lang/Math/TanTests.java index f4ad1872238..04ed7d47ed1 100644 --- a/test/jdk/java/lang/Math/TanTests.java +++ b/test/jdk/java/lang/Math/TanTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -25,7 +25,6 @@ * @test * @bug 5033578 * @summary Tests for {Math, StrictMath}.tan - * @author Joseph D. Darcy */ public class TanTests { @@ -33,10 +32,8 @@ public class TanTests { static int testTanCase(double input, double expected, double ulps) { int failures = 0; - failures += Tests.testUlpDiff("StrictMath.tan(double, double)", input, - StrictMath.tan(input), expected, ulps); - failures += Tests.testUlpDiff("Math.tan(double, double)", input, - Math.tan(input), expected, ulps); + failures += Tests.testUlpDiff("StrictMath.tan", input, StrictMath::tan, expected, ulps); + failures += Tests.testUlpDiff("Math.tan", input, Math::tan, expected, ulps); return failures; } @@ -173,7 +170,7 @@ public class TanTests { return failures; } - public static void main(String [] argv) { + public static void main(String... argv) { int failures = 0; failures += testTan(); diff --git a/test/jdk/java/lang/Math/Tests.java b/test/jdk/java/lang/Math/Tests.java index 98821142fc9..f1de6319a9e 100644 --- a/test/jdk/java/lang/Math/Tests.java +++ b/test/jdk/java/lang/Math/Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -21,6 +21,10 @@ * questions. */ +import java.util.function.DoubleBinaryOperator; +import java.util.function.DoubleUnaryOperator; +import java.util.function.DoubleToIntFunction; + /* * Shared static test methods for numerical tests. Sharing these * helper test methods avoids repeated functions in the various test @@ -235,9 +239,9 @@ public class Tests { "\texpected " + expected + "\n" + "\tgot " + result + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, double input, @@ -248,9 +252,9 @@ public class Tests { "\texpected " + expected + "\n" + "\tgot " + result + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, float input1, float input2, @@ -291,6 +295,13 @@ public class Tests { return 0; } + public static int test(String testName, + double input, + DoubleToIntFunction func, + int expected) { + return test(testName, input, func.applyAsInt(input), expected); + } + public static int test(String testName, double input, int result, int expected) { if (expected != result) { @@ -299,9 +310,9 @@ public class Tests { "\texpected " + expected + "\n" + "\tgot " + result + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, float input, @@ -312,11 +323,17 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } + public static int test(String testName, + double input, + DoubleUnaryOperator func, + double expected) { + return test(testName, input, func.applyAsDouble(input), expected); + } public static int test(String testName, double input, double result, double expected) { @@ -326,9 +343,9 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, @@ -341,9 +358,16 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } + } + + public static int test(String testName, + double input1, double input2, + DoubleBinaryOperator func, + double expected) { + return test(testName, input1, input2, func.applyAsDouble(input1, input2), expected); } public static int test(String testName, @@ -356,9 +380,9 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, @@ -371,9 +395,9 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, @@ -386,9 +410,9 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } public static int test(String testName, @@ -402,9 +426,21 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } + } + + @FunctionalInterface + public interface DoubleTernaryOperator { + double applyAsDouble(double input1, double input2, double input3); + } + + public static int test(String testName, + double input1, double input2, double input3, + DoubleTernaryOperator func, double expected) { + return test(testName, input1, input2, input3, func.applyAsDouble(input1, input2, input3), expected); + } public static int test(String testName, @@ -418,9 +454,9 @@ public class Tests { "\texpected " + expected + "\t(" + toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } static int testUlpCore(double result, double expected, double ulps) { @@ -442,14 +478,19 @@ public class Tests { // fail if greater than or unordered !(Math.abs( difference/Math.ulp(expected) ) <= Math.abs(ulps)) ) { return 1; - } - else + } else { return 0; + } } } } // One input argument. + public static int testUlpDiff(String testName, double input, + DoubleUnaryOperator func, double expected, double ulps) { + return testUlpDiff(testName, input, func.applyAsDouble(input), expected, ulps); + } + public static int testUlpDiff(String testName, double input, double result, double expected, double ulps) { int code = testUlpCore(result, expected, ulps); @@ -464,6 +505,11 @@ public class Tests { } // Two input arguments. + public static int testUlpDiff(String testName, double input1, double input2, + DoubleBinaryOperator func, double expected, double ulps) { + return testUlpDiff(testName, input1, input2, func.applyAsDouble(input1, input2), expected, ulps); + } + public static int testUlpDiff(String testName, double input1, double input2, double result, double expected, double ulps) { int code = testUlpCore(result, expected, ulps); @@ -481,6 +527,14 @@ public class Tests { // For a successful test, the result must be within the ulp bound of // expected AND the result must have absolute value less than or // equal to absBound. + public static int testUlpDiffWithAbsBound(String testName, double input, + DoubleUnaryOperator func, double expected, + double ulps, double absBound) { + return testUlpDiffWithAbsBound(testName, input, + func.applyAsDouble(input), expected, + ulps, absBound); + } + public static int testUlpDiffWithAbsBound(String testName, double input, double result, double expected, double ulps, double absBound) { @@ -506,6 +560,14 @@ public class Tests { // For a successful test, the result must be within the ulp bound of // expected AND the result must have absolute value greater than // or equal to the lowerBound. + public static int testUlpDiffWithLowerBound(String testName, double input, + DoubleUnaryOperator func, double expected, + double ulps, double lowerBound) { + return testUlpDiffWithLowerBound(testName, input, + func.applyAsDouble(input), expected, + ulps, lowerBound); + } + public static int testUlpDiffWithLowerBound(String testName, double input, double result, double expected, double ulps, double lowerBound) { @@ -513,8 +575,9 @@ public class Tests { if (!(result >= lowerBound) && !Double.isNaN(expected)) { code = 1; - } else + } else { code = testUlpCore(result, expected, ulps); + } if (code == 1) { System.err.println("Failure for " + testName + @@ -528,6 +591,11 @@ public class Tests { return code; } + public static int testTolerance(String testName, double input, + DoubleUnaryOperator func, double expected, double tolerance) { + return testTolerance(testName, input, func.applyAsDouble(input), expected, tolerance); + + } public static int testTolerance(String testName, double input, double result, double expected, double tolerance) { if (Double.compare(expected, result ) != 0) { @@ -544,13 +612,18 @@ public class Tests { return 1; } return 0; - } - else + } else { return 0; + } } // For a successful test, the result must be within the upper and // lower bounds. + public static int testBounds(String testName, double input, DoubleUnaryOperator func, + double bound1, double bound2) { + return testBounds(testName, input, func.applyAsDouble(input), bound1, bound2); + } + public static int testBounds(String testName, double input, double result, double bound1, double bound2) { if ((result >= bound1 && result <= bound2) || diff --git a/test/jdk/java/lang/Math/WorstCaseTests.java b/test/jdk/java/lang/Math/WorstCaseTests.java index be98d977aab..2cffa8fabfc 100644 --- a/test/jdk/java/lang/Math/WorstCaseTests.java +++ b/test/jdk/java/lang/Math/WorstCaseTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -29,7 +29,6 @@ * @build WorstCaseTests * @run main WorstCaseTests * @run main/othervm -Xcomp WorstCaseTests - * @author Joseph D. Darcy */ /** @@ -126,8 +125,8 @@ public class WorstCaseTests { private static int testExpCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.exp", input, Math.exp(input), expected, out); - failures += Tests.testBounds("StrictMath.exp", input, StrictMath.exp(input), expected, out); + failures += Tests.testBounds("Math.exp", input, Math::exp, expected, out); + failures += Tests.testBounds("StrictMath.exp", input, StrictMath::exp, expected, out); return failures; } @@ -158,8 +157,8 @@ public class WorstCaseTests { private static int testLogCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.log", input, Math.log(input), expected, out); - failures += Tests.testBounds("StrictMath.log", input, StrictMath.log(input), expected, out); + failures += Tests.testBounds("Math.log", input, Math::log, expected, out); + failures += Tests.testBounds("StrictMath.log", input, StrictMath::log, expected, out); return failures; } @@ -191,8 +190,8 @@ public class WorstCaseTests { private static int testSinCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.sin", input, Math.sin(input), expected, out); - failures += Tests.testBounds("StrictMath.sin", input, StrictMath.sin(input), expected, out); + failures += Tests.testBounds("Math.sin", input, Math::sin, expected, out); + failures += Tests.testBounds("StrictMath.sin", input, StrictMath::sin, expected, out); return failures; } @@ -223,8 +222,8 @@ public class WorstCaseTests { private static int testAsinCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.asin", input, Math.asin(input), expected, out); - failures += Tests.testBounds("StrictMath.asin", input, StrictMath.asin(input), expected, out); + failures += Tests.testBounds("Math.asin", input, Math::asin, expected, out); + failures += Tests.testBounds("StrictMath.asin", input, StrictMath::asin, expected, out); return failures; } @@ -256,8 +255,8 @@ public class WorstCaseTests { private static int testCosCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.cos", input, Math.cos(input), expected, out); - failures += Tests.testBounds("StrictMath.cos", input, StrictMath.cos(input), expected, out); + failures += Tests.testBounds("Math.cos", input, Math::cos, expected, out); + failures += Tests.testBounds("StrictMath.cos", input, StrictMath::cos, expected, out); return failures; } @@ -280,8 +279,8 @@ public class WorstCaseTests { private static int testAcosCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.acos", input, Math.acos(input), expected, out); - failures += Tests.testBounds("StrictMath.acos", input, StrictMath.acos(input), expected, out); + failures += Tests.testBounds("Math.acos", input, Math::acos, expected, out); + failures += Tests.testBounds("StrictMath.acos", input, StrictMath::acos, expected, out); return failures; } @@ -309,8 +308,8 @@ public class WorstCaseTests { private static int testTanCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.tan", input, Math.tan(input), expected, out); - failures += Tests.testBounds("StrictMath.tan", input, StrictMath.tan(input), expected, out); + failures += Tests.testBounds("Math.tan", input, Math::tan, expected, out); + failures += Tests.testBounds("StrictMath.tan", input, StrictMath::tan, expected, out); return failures; } @@ -341,8 +340,8 @@ public class WorstCaseTests { private static int testAtanCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.atan", input, Math.atan(input), expected, out); - failures += Tests.testBounds("StrictMath.atan", input, StrictMath.atan(input), expected, out); + failures += Tests.testBounds("Math.atan", input, Math::atan, expected, out); + failures += Tests.testBounds("StrictMath.atan", input, StrictMath::atan, expected, out); return failures; } @@ -367,8 +366,8 @@ public class WorstCaseTests { private static int testPow2Case(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.pow2", input, Math.pow(2, input), expected, out); - failures += Tests.testBounds("StrictMath.pow2", input, StrictMath.pow(2, input), expected, out); + failures += Tests.testBounds("Math.pow2", input, d -> Math.pow(2, d), expected, out); + failures += Tests.testBounds("StrictMath.pow2", input, d -> StrictMath.pow(2, d), expected, out); return failures; } @@ -400,8 +399,8 @@ public class WorstCaseTests { private static int testSinhCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.sinh", input, Math.sinh(input), expected, out); - failures += Tests.testBounds("StrictMath.sinh", input, StrictMath.sinh(input), expected, out); + failures += Tests.testBounds("Math.sinh", input, Math::sinh, expected, out); + failures += Tests.testBounds("StrictMath.sinh", input, StrictMath::sinh, expected, out); return failures; } @@ -428,8 +427,8 @@ public class WorstCaseTests { private static int testCoshCase(double input, double expected) { int failures = 0; double out = Tests.nextOut(expected); - failures += Tests.testBounds("Math.cosh", input, Math.cosh(input), expected, out); - failures += Tests.testBounds("StrictMath.cosh", input, StrictMath.cosh(input), expected, out); + failures += Tests.testBounds("Math.cosh", input, Math::cosh, expected, out); + failures += Tests.testBounds("StrictMath.cosh", input, StrictMath::cosh, expected, out); return failures; } } diff --git a/test/jdk/java/lang/StrictMath/CubeRootTests.java b/test/jdk/java/lang/StrictMath/CubeRootTests.java index f4a3978075d..0423f1ff087 100644 --- a/test/jdk/java/lang/StrictMath/CubeRootTests.java +++ b/test/jdk/java/lang/StrictMath/CubeRootTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -32,7 +32,6 @@ * @build CubeRootTests * @run main CubeRootTests * @summary Tests specifically for StrictMath.cbrt - * @author Joseph D. Darcy */ import jdk.test.lib.RandomFactory; @@ -71,9 +70,9 @@ public class CubeRootTests { double minus_expected = -expected; failures+=Tests.test("StrictMath.cbrt(double)", input, - StrictMath.cbrt(input), expected); + StrictMath::cbrt, expected); failures+=Tests.test("StrictMath.cbrt(double)", minus_input, - StrictMath.cbrt(minus_input), minus_expected); + StrictMath::cbrt, minus_expected); return failures; } diff --git a/test/jdk/java/lang/StrictMath/Expm1Tests.java b/test/jdk/java/lang/StrictMath/Expm1Tests.java index 368d1025993..e7d9696535d 100644 --- a/test/jdk/java/lang/StrictMath/Expm1Tests.java +++ b/test/jdk/java/lang/StrictMath/Expm1Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,8 @@ * @test * @bug 4851638 * @summary Tests for StrictMath.expm1 - * @author Joseph D. Darcy + * @compile -Xdiags:verbose Expm1Tests.java + * @run main Expm1Tests */ /** @@ -44,7 +45,7 @@ public class Expm1Tests { static int testExpm1Case(double input, double expected) { return Tests.test("StrictMath.expm1(double)", input, - StrictMath.expm1(input), expected); + StrictMath::expm1, expected); } static int testExpm1() { diff --git a/test/jdk/java/lang/StrictMath/HyperbolicTests.java b/test/jdk/java/lang/StrictMath/HyperbolicTests.java index 37b851dd795..4dfc7596d38 100644 --- a/test/jdk/java/lang/StrictMath/HyperbolicTests.java +++ b/test/jdk/java/lang/StrictMath/HyperbolicTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,6 @@ * @test * @bug 4851625 * @summary Tests for StrictMath.{sinh, cosh, tanh} - * @author Joseph D. Darcy */ /** @@ -45,17 +44,17 @@ public class HyperbolicTests { static int testSinhCase(double input, double expected) { return Tests.test("StrictMath.sinh(double)", input, - StrictMath.sinh(input), expected); + StrictMath::sinh, expected); } static int testCoshCase(double input, double expected) { return Tests.test("StrictMath.cosh(double)", input, - StrictMath.cosh(input), expected); + StrictMath::cosh, expected); } static int testTanhCase(double input, double expected) { return Tests.test("StrictMath.tanh(double)", input, - StrictMath.tanh(input), expected); + StrictMath::tanh, expected); } static int testSinh() { diff --git a/test/jdk/java/lang/StrictMath/HypotTests.java b/test/jdk/java/lang/StrictMath/HypotTests.java index 0b1dd41691f..c714dcf1499 100644 --- a/test/jdk/java/lang/StrictMath/HypotTests.java +++ b/test/jdk/java/lang/StrictMath/HypotTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -32,7 +32,6 @@ * @build FdlibmTranslit * @build HypotTests * @run main HypotTests - * @author Joseph D. Darcy */ import jdk.test.lib.RandomFactory; @@ -72,28 +71,28 @@ public class HypotTests { static int testHypotCase(double input1, double input2, double expected) { int failures = 0; failures += Tests.test("StrictMath.hypot(double)", input1, input2, - StrictMath.hypot(input1, input2), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", input2, input1, - StrictMath.hypot(input2, input1), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", -input1, input2, - StrictMath.hypot(-input1, input2), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", input2, -input1, - StrictMath.hypot(input2, -input1), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", input1, -input2, - StrictMath.hypot(input1, -input2), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", -input2, input1, - StrictMath.hypot(-input2, input1), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", -input1, -input2, - StrictMath.hypot(-input1, -input2), expected); + StrictMath::hypot, expected); failures += Tests.test("StrictMath.hypot(double)", -input2, -input1, - StrictMath.hypot(-input2, -input1), expected); + StrictMath::hypot, expected); return failures; } diff --git a/test/jdk/java/lang/StrictMath/Log10Tests.java b/test/jdk/java/lang/StrictMath/Log10Tests.java index af07eac7e66..eed6e8a5106 100644 --- a/test/jdk/java/lang/StrictMath/Log10Tests.java +++ b/test/jdk/java/lang/StrictMath/Log10Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,6 @@ * @test * @bug 4074599 * @summary Tests for StrictMath.log10 - * @author Joseph D. Darcy */ @@ -45,7 +44,7 @@ public class Log10Tests { static int testLog10Case(double input, double expected) { return Tests.test("StrictMath.log10(double)", input, - StrictMath.log10(input), expected); + StrictMath::log10, expected); } static int testLog10() { diff --git a/test/jdk/java/lang/StrictMath/Log1pTests.java b/test/jdk/java/lang/StrictMath/Log1pTests.java index 91b0835222c..9cd03d3306a 100644 --- a/test/jdk/java/lang/StrictMath/Log1pTests.java +++ b/test/jdk/java/lang/StrictMath/Log1pTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,6 @@ * @test * @bug 4851638 * @summary Tests for StrictMath.log1p - * @author Joseph D. Darcy */ /** @@ -44,7 +43,7 @@ public class Log1pTests { static int testLog1pCase(double input, double expected) { return Tests.test("StrictMath.log1p(double)", input, - StrictMath.log1p(input), expected); + StrictMath::log1p, expected); } static int testLog1p() { diff --git a/test/jdk/java/lang/StrictMath/PowTests.java b/test/jdk/java/lang/StrictMath/PowTests.java index 338cf42d54c..2936dfdf247 100644 --- a/test/jdk/java/lang/StrictMath/PowTests.java +++ b/test/jdk/java/lang/StrictMath/PowTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,7 +25,6 @@ * @test * @bug 8136874 * @summary Tests for StrictMath.pow - * @author Joseph D. Darcy */ /** @@ -295,7 +294,7 @@ public class PowTests { private static int testPowCase(double input1, double input2, double expected) { int failures = 0; failures += Tests.test("StrictMath.pow(double)", input1, input2, - StrictMath.pow(input1, input2), expected); + StrictMath::pow, expected); return failures; } } diff --git a/test/jdk/java/lang/StrictMath/Tests.java b/test/jdk/java/lang/StrictMath/Tests.java index 0513cb70d1e..a675b2e9617 100644 --- a/test/jdk/java/lang/StrictMath/Tests.java +++ b/test/jdk/java/lang/StrictMath/Tests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -21,33 +21,48 @@ * questions. */ +import java.util.function.DoubleBinaryOperator; +import java.util.function.DoubleUnaryOperator; + /* - * - * * Shared static test method for StrictMath tests. */ - public class Tests { private Tests(){} - static int test(String testName, - double input, - double result, - double expected) { + public static int test(String testName, + double input, + DoubleUnaryOperator func, + double expected) { + return test(testName, input, func.applyAsDouble(input), expected); + } + + public static int test(String testName, + double input, + double result, + double expected) { if (Double.compare(expected, result ) != 0) { System.err.println("Failure for " + testName + ":\n" + "\tFor input " + input + "\t(" + Double.toHexString(input) + ")\n" + "\texpected " + expected + "\t(" + Double.toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + Double.toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } + } + + public static int test(String testName, + double input1, + double input2, + DoubleBinaryOperator func, + double expected) { + return test(testName, input1, input2, func.applyAsDouble(input1, input2), expected); } - static int test(String testName, double input1, double input2, - double result, double expected) { + public static int test(String testName, double input1, double input2, + double result, double expected) { if (Double.compare(expected, result ) != 0) { System.err.println("Failure for " + testName + ":\n" + "\tFor input " + input1 + "\t(" + Double.toHexString(input1) + "), " + @@ -55,9 +70,9 @@ public class Tests { "\texpected " + expected + "\t(" + Double.toHexString(expected) + ")\n" + "\tgot " + result + "\t(" + Double.toHexString(result) + ")."); return 1; - } - else + } else { return 0; + } } /** -- GitLab From 78574057a4758fc3da5f39af77df09dc2232a9a1 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Fri, 28 Jan 2022 00:44:13 +0000 Subject: [PATCH 062/400] 8280744: Allow SuppressWarnings to be used in all declaration contexts Reviewed-by: iris --- .../classes/java/lang/SuppressWarnings.java | 63 +++++++++++++------ 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/src/java.base/share/classes/java/lang/SuppressWarnings.java b/src/java.base/share/classes/java/lang/SuppressWarnings.java index 09ab6c4724b..fd115fb8bef 100644 --- a/src/java.base/share/classes/java/lang/SuppressWarnings.java +++ b/src/java.base/share/classes/java/lang/SuppressWarnings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -29,21 +29,52 @@ import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; /** - * Indicates that the named compiler warnings should be suppressed in the - * annotated element (and in all program elements contained in the annotated - * element). Note that the set of warnings suppressed in a given element is - * a superset of the warnings suppressed in all containing elements. For - * example, if you annotate a class to suppress one warning and annotate a - * method to suppress another, both warnings will be suppressed in the method. - * However, note that if a warning is suppressed in a {@code - * module-info} file, the suppression applies to elements within the - * file and not to types contained within the module. + * Indicates the warnings to be suppressed at compile time in the + * annotated element, and in all elements contained in the annotated + * element. * - *

    As a matter of style, programmers should always use this annotation - * on the most deeply nested element where it is effective. If you want to + *

    The {@code SuppressWarnings} annotation interface is applicable + * in all declaration contexts, so an {@code @SuppressWarnings} + * annotation can be used on any element. As a matter of style, + * programmers should always use this annotation on the most deeply + * nested element where it is effective. For example, if you want to * suppress a warning in a particular method, you should annotate that * method rather than its class. * + *

    The set of warnings suppressed in a given element is a union of + * the warnings suppressed in all containing elements. For example, + * if you annotate a class to suppress one warning and annotate a + * method in the class to suppress another, both warnings will be + * suppressed in the method. However, note that if a warning is + * suppressed in a {@code module-info} file, the suppression applies + * to elements within the file and not to types contained + * within the module. Likewise, if a warning is suppressed in a + * {@code package-info} file, the suppression applies to elements + * within the file and not to types contained within the + * package. + * + *

    Java compilers must recognize all the kinds of warnings defined + * in the Java Language Specification (JLS section {@jls + * 9.6.4.5}) which include: + * + *

      + *
    • Unchecked warnings, specified by the string {@code "unchecked"}. + *
    • Deprecation warnings, specified by the string {@code "deprecation"}. + *
    • Removal warnings, specified by the string {@code "removal"}. + *
    • Preview warnings, specified by the string {@code "preview"}. + *
    + * + * Whether or not a Java compiler recognizes other strings is a + * quality of implementation concern. Compiler vendors should + * document the additional warning names they support. Vendors are + * encouraged to cooperate to ensure that the same names work across + * multiple compilers. + * + * @implNote + * In addition to the mandated suppression strings, the {@code javac} + * reference implementation recognizes compilation-related warning + * names documented in its {@code --help-lint} output. + * * @author Josh Bloch * @since 1.5 * @jls 4.8 Raw Types @@ -52,7 +83,7 @@ import static java.lang.annotation.ElementType.*; * @jls 5.5 Casting Contexts * @jls 9.6.4.5 @SuppressWarnings */ -@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE}) +// Implicitly target all declaration contexts by omitting a @Target annotation @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { /** @@ -63,12 +94,6 @@ public @interface SuppressWarnings { * ignore any warning names they do not recognize. They are, however, * free to emit a warning if an annotation contains an unrecognized * warning name. - * - *

    The string {@code "unchecked"} is used to suppress - * unchecked warnings. Compiler vendors should document the - * additional warning names they support in conjunction with this - * annotation type. They are encouraged to cooperate to ensure - * that the same names work across multiple compilers. * @return the set of warnings to be suppressed */ String[] value(); -- GitLab From 094db1a3eeb3709c8218d8d26f13699024ec2943 Mon Sep 17 00:00:00 2001 From: Denghui Dong Date: Fri, 28 Jan 2022 00:49:17 +0000 Subject: [PATCH 063/400] 8277948: AArch64: Print the correct native stack if -XX:+PreserveFramePointer when crash Reviewed-by: aph, adinn --- src/hotspot/cpu/aarch64/frame_aarch64.cpp | 20 ++++++++++++++----- src/hotspot/cpu/aarch64/frame_aarch64.hpp | 9 ++++++++- .../cpu/aarch64/frame_aarch64.inline.hpp | 6 +++++- .../linux_aarch64/thread_linux_aarch64.cpp | 6 ++++-- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.cpp b/src/hotspot/cpu/aarch64/frame_aarch64.cpp index 35cc1ee1f84..cb59e8b12af 100644 --- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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. * @@ -358,6 +358,7 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const { assert(map->include_argument_oops(), "should be set by clear"); vmassert(jfa->last_Java_pc() != NULL, "not walkable"); frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc()); + fr.set_sp_is_trusted(); return fr; } @@ -463,12 +464,21 @@ frame frame::sender_for_interpreter_frame(RegisterMap* map) const { //------------------------------------------------------------------------------ // frame::sender_for_compiled_frame frame frame::sender_for_compiled_frame(RegisterMap* map) const { - // we cannot rely upon the last fp having been saved to the thread - // in C2 code but it will have been pushed onto the stack. so we - // have to find it relative to the unextended sp + // When the sp of a compiled frame is correct, we can get the correct sender sp + // by unextended sp + frame size. + // For the following two scenarios, the sp of a compiled frame is correct: + // a) This compiled frame is built from the anchor. + // b) This compiled frame is built from a callee frame, and the callee frame can + // calculate its sp correctly. + // + // For b), if the callee frame is a native code frame (such as leaf call), the sp of + // the compiled frame cannot be calculated correctly. There is currently no suitable + // solution to solve this problem perfectly. But when PreserveFramePointer is enabled, + // we can get the correct sender sp by fp + 2 (that is sender_sp()). assert(_cb->frame_size() >= 0, "must have non-zero frame size"); - intptr_t* l_sender_sp = unextended_sp() + _cb->frame_size(); + intptr_t* l_sender_sp = (!PreserveFramePointer || _sp_is_trusted) ? unextended_sp() + _cb->frame_size() + : sender_sp(); intptr_t* unextended_sp = l_sender_sp; // the return_address is always the word on the stack diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.hpp b/src/hotspot/cpu/aarch64/frame_aarch64.hpp index 716c0ff9f1a..95f470befa0 100644 --- a/src/hotspot/cpu/aarch64/frame_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/frame_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -124,6 +124,11 @@ intptr_t* _unextended_sp; void adjust_unextended_sp(); + // true means _sp value is correct and we can use it to get the sender's sp + // of the compiled frame, otherwise, _sp value may be invalid and we can use + // _fp to get the sender's sp if PreserveFramePointer is enabled. + bool _sp_is_trusted; + intptr_t* ptr_at_addr(int offset) const { return (intptr_t*) addr_at(offset); } @@ -165,4 +170,6 @@ // returns the sending frame, without applying any barriers frame sender_raw(RegisterMap* map) const; + void set_sp_is_trusted() { _sp_is_trusted = true; } + #endif // CPU_AARCH64_FRAME_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp b/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp index 5be02aa57e7..b0fe436ca59 100644 --- a/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp +++ b/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,6 +41,7 @@ inline frame::frame() { _fp = NULL; _cb = NULL; _deopt_state = unknown; + _sp_is_trusted = false; } static int spin; @@ -64,6 +65,7 @@ inline void frame::init(intptr_t* sp, intptr_t* fp, address pc) { } else { _deopt_state = not_deoptimized; } + _sp_is_trusted = false; } inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) { @@ -91,6 +93,7 @@ inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address } else { _deopt_state = not_deoptimized; } + _sp_is_trusted = false; } inline frame::frame(intptr_t* sp, intptr_t* fp) { @@ -122,6 +125,7 @@ inline frame::frame(intptr_t* sp, intptr_t* fp) { } else { _deopt_state = not_deoptimized; } + _sp_is_trusted = false; } // Accessors diff --git a/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp index fca22629bc5..f584da5814a 100644 --- a/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,7 +29,9 @@ frame JavaThread::pd_last_frame() { assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); + frame f = frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); + f.set_sp_is_trusted(); + return f; } // For Forte Analyzer AsyncGetCallTrace profiling support - thread is -- GitLab From a1d1e4753b87dfc6ce179c389480dcf2c5a0dc2e Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Fri, 28 Jan 2022 01:55:16 +0000 Subject: [PATCH 064/400] 8280823: Remove NULL check in DumpTimeClassInfo::is_excluded Reviewed-by: minqi, ccheung --- src/hotspot/share/cds/dumpTimeClassInfo.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.hpp b/src/hotspot/share/cds/dumpTimeClassInfo.hpp index 04b0af221cf..28fe986ff7a 100644 --- a/src/hotspot/share/cds/dumpTimeClassInfo.hpp +++ b/src/hotspot/share/cds/dumpTimeClassInfo.hpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -135,8 +135,7 @@ public: } bool is_excluded() { - // _klass may become NULL due to DynamicArchiveBuilder::set_to_null - return _excluded || _failed_verification || _klass == NULL; + return _excluded || _failed_verification; } // Was this class loaded while JvmtiExport::is_early_phase()==true -- GitLab From 178ac7465360729628521a0d555253b9fb2ad7bf Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Fri, 28 Jan 2022 07:01:21 +0000 Subject: [PATCH 065/400] 8251466: test/java/io/File/GetXSpace.java fails on Windows with mapped network drives. Reviewed-by: bpb --- test/jdk/java/io/File/GetXSpace.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/jdk/java/io/File/GetXSpace.java b/test/jdk/java/io/File/GetXSpace.java index eacc7565227..ac80bdf68fd 100644 --- a/test/jdk/java/io/File/GetXSpace.java +++ b/test/jdk/java/io/File/GetXSpace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -34,7 +34,6 @@ import java.io.BufferedReader; import java.io.File; -import java.io.FilePermission; import java.io.InputStreamReader; import java.io.IOException; import java.nio.file.Files; @@ -108,8 +107,8 @@ public class GetXSpace { Space(String total, String free, String name) { try { - this.total = Long.valueOf(total) * KSIZE; - this.free = Long.valueOf(free) * KSIZE; + this.total = Long.parseLong(total) * KSIZE; + this.free = Long.parseLong(free) * KSIZE; } catch (NumberFormatException x) { throw new RuntimeException("the regex should have caught this", x); } @@ -157,7 +156,7 @@ public class GetXSpace { } al.add(new Space(m.group(2), m.group(3), name));; } - j = m.end() + 1; + j = m.end(); } else { throw new RuntimeException("unrecognized df output format: " + "charAt(" + j + ") = '" @@ -227,7 +226,7 @@ public class GetXSpace { // On Linux, ignore the NSFE if the path is one of the // /run/user/$UID mounts created by pam_systemd(8) as it // might be deleted during the test - if (!Platform.isLinux() || s.name().indexOf("/run/user") == -1) + if (!Platform.isLinux() || !s.name().contains("/run/user")) throw new RuntimeException(nsfe); } catch (IOException e) { throw new RuntimeException(e); -- GitLab From 55f180fb7dfecc859e59c7852d48aeab6c936a5d Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Fri, 28 Jan 2022 08:10:12 +0000 Subject: [PATCH 066/400] 8280004: DCmdArgument::parse_value() should handle NULL input Reviewed-by: dholmes, mbaesken --- src/hotspot/share/services/diagnosticArgument.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/services/diagnosticArgument.cpp b/src/hotspot/share/services/diagnosticArgument.cpp index f10fe6c4641..3dd75009175 100644 --- a/src/hotspot/share/services/diagnosticArgument.cpp +++ b/src/hotspot/share/services/diagnosticArgument.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -28,6 +28,7 @@ #include "memory/resourceArea.hpp" #include "runtime/thread.hpp" #include "services/diagnosticArgument.hpp" +#include "utilities/globalDefinitions.hpp" StringArrayArgument::StringArrayArgument() { _array = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray(32, mtServiceability); @@ -114,13 +115,12 @@ template <> void DCmdArgument::parse_value(const char* str, || sscanf(str, JLONG_FORMAT "%n", &_value, &scanned) != 1 || (size_t)scanned != len) { - ResourceMark rm; - - char* buf = NEW_RESOURCE_ARRAY(char, len + 1); - strncpy(buf, str, len); - buf[len] = '\0'; + const int maxprint = 64; Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(), - "Integer parsing error in command argument '%s'. Could not parse: %s.\n", _name, buf); + "Integer parsing error in command argument '%s'. Could not parse: %.*s%s.\n", _name, + MIN2((int)len, maxprint), + (str == NULL ? "" : str), + (len > maxprint ? "..." : "")); } } -- GitLab From 973dda5ce0747a8ea67ec3a34c2ef2a0b2b6b140 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Fri, 28 Jan 2022 08:11:44 +0000 Subject: [PATCH 067/400] 8280804: Parallel: Remove unused variables in PSPromotionManager::drain_stacks_depth Reviewed-by: tschatzl, mli --- src/hotspot/share/gc/parallel/psPromotionManager.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.cpp b/src/hotspot/share/gc/parallel/psPromotionManager.cpp index f7308366400..ad63244a299 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp @@ -244,12 +244,6 @@ void PSPromotionManager::restore_preserved_marks() { void PSPromotionManager::drain_stacks_depth(bool totally_drain) { totally_drain = totally_drain || _totally_drain; -#ifdef ASSERT - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - MutableSpace* to_space = heap->young_gen()->to_space(); - MutableSpace* old_space = heap->old_gen()->object_space(); -#endif /* ASSERT */ - PSScannerTasksQueue* const tq = claimed_stack_depth(); do { ScannerTask task; -- GitLab From 8a3cca09ba427282f2712bec7298b85bbacf076b Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Fri, 28 Jan 2022 09:06:06 +0000 Subject: [PATCH 068/400] 8280784: VM_Cleanup unnecessarily processes all thread oops Reviewed-by: eosterlund, shade --- src/hotspot/share/runtime/vmOperations.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hotspot/share/runtime/vmOperations.hpp b/src/hotspot/share/runtime/vmOperations.hpp index 3394d53fa98..b68b6fd728b 100644 --- a/src/hotspot/share/runtime/vmOperations.hpp +++ b/src/hotspot/share/runtime/vmOperations.hpp @@ -45,6 +45,10 @@ class VM_Cleanup: public VM_Operation { public: VMOp_Type type() const { return VMOp_Cleanup; } void doit() {}; + virtual bool skip_thread_oop_barriers() const { + // None of the safepoint cleanup tasks read oops in the Java threads. + return true; + } }; class VM_ClearICs: public VM_Operation { -- GitLab From ed826f2927457f73f058732c6d073acf54ee86f7 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Fri, 28 Jan 2022 09:16:43 +0000 Subject: [PATCH 069/400] 8280397: Factor out task queue statistics printing Reviewed-by: pliden, kbarrett, mli --- src/hotspot/share/gc/g1/g1YoungCollector.cpp | 46 +---------------- src/hotspot/share/gc/g1/g1YoungCollector.hpp | 9 +--- .../share/gc/parallel/psPromotionManager.cpp | 27 +++------- src/hotspot/share/gc/shared/taskqueue.hpp | 14 ++++- .../share/gc/shared/taskqueue.inline.hpp | 51 ++++++++++++++++++- 5 files changed, 72 insertions(+), 75 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1YoungCollector.cpp b/src/hotspot/share/gc/g1/g1YoungCollector.cpp index d476c981d71..1a73ed30e26 100644 --- a/src/hotspot/share/gc/g1/g1YoungCollector.cpp +++ b/src/hotspot/share/gc/g1/g1YoungCollector.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -59,47 +59,6 @@ #include "memory/resourceArea.hpp" #include "utilities/ticks.hpp" -#if TASKQUEUE_STATS -uint G1YoungCollector::num_task_queues() const { - return task_queues()->size(); -} - -void G1YoungCollector::print_taskqueue_stats_hdr(outputStream* const st) { - st->print_raw_cr("GC Task Stats"); - st->print_raw("thr "); TaskQueueStats::print_header(1, st); st->cr(); - st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr(); -} - -void G1YoungCollector::print_taskqueue_stats() const { - if (!log_is_enabled(Trace, gc, task, stats)) { - return; - } - Log(gc, task, stats) log; - ResourceMark rm; - LogStream ls(log.trace()); - outputStream* st = &ls; - - print_taskqueue_stats_hdr(st); - - TaskQueueStats totals; - const uint n = num_task_queues(); - for (uint i = 0; i < n; ++i) { - st->print("%3u ", i); _g1h->task_queue(i)->stats.print(st); st->cr(); - totals += _g1h->task_queue(i)->stats; - } - st->print_raw("tot "); totals.print(st); st->cr(); - - DEBUG_ONLY(totals.verify()); -} - -void G1YoungCollector::reset_taskqueue_stats() { - const uint n = num_task_queues(); - for (uint i = 0; i < n; ++i) { - _g1h->task_queue(i)->stats.reset(); - } -} -#endif // TASKQUEUE_STATS - // GCTraceTime wrapper that constructs the message according to GC pause type and // GC cause. // The code relies on the fact that GCTraceTimeWrapper stores the string passed @@ -1147,6 +1106,5 @@ void G1YoungCollector::collect() { policy()->record_young_collection_end(_concurrent_operation_is_full_mark, evacuation_failed()); } - TASKQUEUE_STATS_ONLY(print_taskqueue_stats()); - TASKQUEUE_STATS_ONLY(reset_taskqueue_stats()); + TASKQUEUE_STATS_ONLY(_g1h->task_queues()->print_and_reset_taskqueue_stats("Oop Queue");) } diff --git a/src/hotspot/share/gc/g1/g1YoungCollector.hpp b/src/hotspot/share/gc/g1/g1YoungCollector.hpp index 055803a3352..c5ad5c45235 100644 --- a/src/hotspot/share/gc/g1/g1YoungCollector.hpp +++ b/src/hotspot/share/gc/g1/g1YoungCollector.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -134,13 +134,6 @@ class G1YoungCollector { // True iff an evacuation has failed in the most-recent collection. bool evacuation_failed() const; -#if TASKQUEUE_STATS - uint num_task_queues() const; - static void print_taskqueue_stats_hdr(outputStream* const st); - void print_taskqueue_stats() const; - void reset_taskqueue_stats(); -#endif // TASKQUEUE_STATS - public: G1YoungCollector(GCCause::Cause gc_cause, double target_pause_time_ms); diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.cpp b/src/hotspot/share/gc/parallel/psPromotionManager.cpp index ad63244a299..0eef7667810 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -147,37 +147,24 @@ static const char* const pm_stats_hdr[] = { "--- ---------- ---------- ---------- ----------" }; -void -PSPromotionManager::print_taskqueue_stats() { +void PSPromotionManager::print_taskqueue_stats() { if (!log_is_enabled(Trace, gc, task, stats)) { return; } Log(gc, task, stats) log; ResourceMark rm; LogStream ls(log.trace()); - outputStream* out = &ls; - out->print_cr("== GC Tasks Stats, GC %3d", - ParallelScavengeHeap::heap()->total_collections()); - TaskQueueStats totals; - out->print("thr "); TaskQueueStats::print_header(1, out); out->cr(); - out->print("--- "); TaskQueueStats::print_header(2, out); out->cr(); - for (uint i = 0; i < ParallelGCThreads; ++i) { - TaskQueueStats& next = manager_array(i)->_claimed_stack_depth.stats; - out->print("%3d ", i); next.print(out); out->cr(); - totals += next; - } - out->print("tot "); totals.print(out); out->cr(); + stack_array_depth()->print_taskqueue_stats(&ls, "Oop Queue"); const uint hlines = sizeof(pm_stats_hdr) / sizeof(pm_stats_hdr[0]); - for (uint i = 0; i < hlines; ++i) out->print_cr("%s", pm_stats_hdr[i]); + for (uint i = 0; i < hlines; ++i) ls.print_cr("%s", pm_stats_hdr[i]); for (uint i = 0; i < ParallelGCThreads; ++i) { - manager_array(i)->print_local_stats(out, i); + manager_array(i)->print_local_stats(&ls, i); } } -void -PSPromotionManager::reset_stats() { +void PSPromotionManager::reset_stats() { claimed_stack_depth()->stats.reset(); _array_chunk_pushes = _array_chunk_steals = 0; _arrays_chunked = _array_chunks_processed = 0; @@ -216,8 +203,6 @@ void PSPromotionManager::reset() { // We need to get an assert in here to make sure the labs are always flushed. - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - // Do not prefill the LAB's, save heap wastage! HeapWord* lab_base = young_space()->top(); _young_lab.initialize(MemRegion(lab_base, (size_t)0)); diff --git a/src/hotspot/share/gc/shared/taskqueue.hpp b/src/hotspot/share/gc/shared/taskqueue.hpp index e2c21f1dc6d..dd2039ddf2a 100644 --- a/src/hotspot/share/gc/shared/taskqueue.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -473,6 +473,18 @@ public: virtual uint tasks() const; uint size() const { return _n; } + +#if TASKQUEUE_STATS +private: + static void print_taskqueue_stats_hdr(outputStream* const st, const char* label); +public: + void print_taskqueue_stats(outputStream* const st, const char* label); + void reset_taskqueue_stats(); + + // Prints taskqueue set statistics into gc+task+stats=trace and resets + // its statistics. + void print_and_reset_taskqueue_stats(const char* label); +#endif // TASKQUEUE_STATS }; template void diff --git a/src/hotspot/share/gc/shared/taskqueue.inline.hpp b/src/hotspot/share/gc/shared/taskqueue.inline.hpp index c0ea64ba165..1b47c4193d9 100644 --- a/src/hotspot/share/gc/shared/taskqueue.inline.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -27,11 +27,15 @@ #include "gc/shared/taskqueue.hpp" +#include "logging/log.hpp" +#include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" +#include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "utilities/debug.hpp" +#include "utilities/ostream.hpp" #include "utilities/stack.inline.hpp" template @@ -48,6 +52,51 @@ inline GenericTaskQueueSet::~GenericTaskQueueSet() { FREE_C_HEAP_ARRAY(T*, _queues); } +#if TASKQUEUE_STATS +template +void GenericTaskQueueSet::print_taskqueue_stats_hdr(outputStream* const st, const char* label) { + st->print_cr("GC Task Stats %s", label); + st->print("thr "); TaskQueueStats::print_header(1, st); st->cr(); + st->print("--- "); TaskQueueStats::print_header(2, st); st->cr(); +} + +template +void GenericTaskQueueSet::print_taskqueue_stats(outputStream* const st, const char* label) { + print_taskqueue_stats_hdr(st, label); + + TaskQueueStats totals; + const uint n = size(); + for (uint i = 0; i < n; ++i) { + st->print("%3u ", i); queue(i)->stats.print(st); st->cr(); + totals += queue(i)->stats; + } + st->print_raw("tot "); totals.print(st); st->cr(); + + DEBUG_ONLY(totals.verify()); +} + +template +void GenericTaskQueueSet::reset_taskqueue_stats() { + const uint n = size(); + for (uint i = 0; i < n; ++i) { + queue(i)->stats.reset(); + } +} + +template +inline void GenericTaskQueueSet::print_and_reset_taskqueue_stats(const char* label) { + if (!log_is_enabled(Trace, gc, task, stats)) { + return; + } + Log(gc, task, stats) log; + ResourceMark rm; + LogStream ls(log.trace()); + + print_taskqueue_stats(&ls, label); + reset_taskqueue_stats(); +} +#endif // TASKQUEUE_STATS + template inline GenericTaskQueue::GenericTaskQueue() : _elems(ArrayAllocator::allocate(N, F)), -- GitLab From 6de90ad9800b83c4a5f364c3645603fcb6828d6c Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Fri, 28 Jan 2022 12:45:43 +0000 Subject: [PATCH 070/400] 8280863: Update build README to reflect that MSYS2 is supported Reviewed-by: ihse --- doc/building.html | 4 ++-- doc/building.md | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/building.html b/doc/building.html index 6b99cf03ef2..9cb1807345c 100644 --- a/doc/building.html +++ b/doc/building.html @@ -196,7 +196,7 @@

    Windows

    Windows XP is not a supported platform, but all newer Windows should be able to build the JDK.

    On Windows, it is important that you pay attention to the instructions in the Special Considerations.

    -

    Windows is the only non-POSIX OS supported by the JDK, and as such, requires some extra care. A POSIX support layer is required to build on Windows. Currently, the only supported such layers are Cygwin and Windows Subsystem for Linux (WSL). (Msys is no longer supported due to a too old bash; msys2 would likely be possible to support in a future version but that would require effort to implement.)

    +

    Windows is the only non-POSIX OS supported by the JDK, and as such, requires some extra care. A POSIX support layer is required to build on Windows. Currently, the only supported such layers are Cygwin, Windows Subsystem for Linux (WSL), and MSYS2. (MSYS is no longer supported due to an outdated bash; While OpenJDK can be built with MSYS2, support for it is still experimental, so build failures and unusual errors are not uncommon.)

    Internally in the build system, all paths are represented as Unix-style paths, e.g. /cygdrive/c/git/jdk/Makefile rather than C:\git\jdk\Makefile. This rule also applies to input to the build system, e.g. in arguments to configure. So, use --with-msvcr-dll=/cygdrive/c/msvcr100.dll rather than --with-msvcr-dll=c:\msvcr100.dll. For details on this conversion, see the section on Fixpath.

    Cygwin

    A functioning Cygwin environment is required for building the JDK on Windows. If you have a 64-bit OS, we strongly recommend using the 64-bit version of Cygwin.

    @@ -298,7 +298,7 @@

    It is advisable to keep an older version of Xcode for building the JDK when updating Xcode. This blog page has good suggestions on managing multiple Xcode versions. To use a specific version of Xcode, use xcode-select -s before running configure, or use --with-toolchain-path to point to the version of Xcode to use, e.g. configure --with-toolchain-path=/Applications/Xcode8.app/Contents/Developer/usr/bin

    If you have recently (inadvertently) updated your OS and/or Xcode version, and the JDK can no longer be built, please see the section on Problems with the Build Environment, and Getting Help to find out if there are any recent, non-merged patches available for this update.

    Microsoft Visual Studio

    -

    For aarch64 machines running Windows the minimum accepted version is Visual Studio 2019 (16.8 or higher). For all other platforms the minimum accepted version of Visual Studio is 2017. Older versions will not be accepted by configure and will not work. For all platforms the maximum accepted version of Visual Studio is 2022.

    +

    For aarch64 machines running Windows the minimum accepted version is Visual Studio 2019 (16.8 or higher). For all other platforms the minimum accepted version of Visual Studio is 2017. Older versions will not be accepted by configure and will not work. For all platforms the maximum accepted version of Visual Studio is 2022.

    If you have multiple versions of Visual Studio installed, configure will by default pick the latest. You can request a specific version to be used by setting --with-toolchain-version, e.g. --with-toolchain-version=2017.

    If you have Visual Studio installed but configure fails to detect it, it may be because of spaces in path.

    IBM XL C/C++

    diff --git a/doc/building.md b/doc/building.md index 3ae4a28ac1f..459dbaa4c41 100644 --- a/doc/building.md +++ b/doc/building.md @@ -179,10 +179,10 @@ On Windows, it is important that you pay attention to the instructions in the Windows is the only non-POSIX OS supported by the JDK, and as such, requires some extra care. A POSIX support layer is required to build on Windows. -Currently, the only supported such layers are Cygwin and Windows Subsystem for -Linux (WSL). (Msys is no longer supported due to a too old bash; msys2 would -likely be possible to support in a future version but that would require effort -to implement.) +Currently, the only supported such layers are Cygwin, Windows Subsystem for +Linux (WSL), and MSYS2. (MSYS is no longer supported due to an outdated bash; +While OpenJDK can be built with MSYS2, support for it is still experimental, so +build failures and unusual errors are not uncommon.) Internally in the build system, all paths are represented as Unix-style paths, e.g. `/cygdrive/c/git/jdk/Makefile` rather than `C:\git\jdk\Makefile`. This -- GitLab From cb8a82ee24881113af4eea04d7ce5963d18e9b83 Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Fri, 28 Jan 2022 12:54:19 +0000 Subject: [PATCH 071/400] 8272317: jstatd has dependency on Security Manager which needs to be removed Reviewed-by: cjplummer, rriggs --- make/modules/jdk.jstatd/Launcher.gmk | 3 +-- .../share/classes/sun/tools/jstatd/Jstatd.java | 15 ++++++--------- test/jdk/sun/tools/jstatd/JstatdTest.java | 18 +++++++----------- test/jdk/sun/tools/jstatd/all.policy | 3 --- 4 files changed, 14 insertions(+), 25 deletions(-) delete mode 100644 test/jdk/sun/tools/jstatd/all.policy diff --git a/make/modules/jdk.jstatd/Launcher.gmk b/make/modules/jdk.jstatd/Launcher.gmk index 26813fa06e7..2137fddd9a0 100644 --- a/make/modules/jdk.jstatd/Launcher.gmk +++ b/make/modules/jdk.jstatd/Launcher.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -27,5 +27,4 @@ include LauncherCommon.gmk $(eval $(call SetupBuildLauncher, jstatd, \ MAIN_CLASS := sun.tools.jstatd.Jstatd, \ - JAVA_ARGS := -Djava.security.manager=allow, \ )) diff --git a/src/jdk.jstatd/share/classes/sun/tools/jstatd/Jstatd.java b/src/jdk.jstatd/share/classes/sun/tools/jstatd/Jstatd.java index 30fe303fa61..5dc7f1fa2fb 100644 --- a/src/jdk.jstatd/share/classes/sun/tools/jstatd/Jstatd.java +++ b/src/jdk.jstatd/share/classes/sun/tools/jstatd/Jstatd.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -25,6 +25,7 @@ package sun.tools.jstatd; +import java.io.ObjectInputFilter; import java.rmi.*; import java.rmi.server.*; import java.rmi.registry.Registry; @@ -47,6 +48,8 @@ public class Jstatd { private static boolean startRegistry = true; private static RemoteHost remoteHost; + private static final String rmiFilterPattern = "sun.jvmstat.monitor.remote.RemoteVm;com.sun.proxy.jdk.proxy*;java.lang.reflect.Proxy;java.rmi.server.RemoteObjectInvocationHandler;java.rmi.server.RemoteObject;!*"; + private static void printUsage() { System.err.println("usage: jstatd [-nr] [-p port] [-r rmiport] [-n rminame]\n" + " jstatd -?|-h|--help"); @@ -72,7 +75,6 @@ public class Jstatd { } } - @SuppressWarnings({"removal","deprecation"}) // Use of RMISecurityManager public static void main(String[] args) { String rminame = null; int rmiPort = 0; @@ -132,10 +134,6 @@ public class Jstatd { System.exit(1); } - if (System.getSecurityManager() == null) { - System.setSecurityManager(new RMISecurityManager()); - } - StringBuilder name = new StringBuilder(); if (port >= 0) { @@ -149,11 +147,10 @@ public class Jstatd { name.append("/").append(rminame); try { - // use 1.5.0 dynamically generated subs. - System.setProperty("java.rmi.server.ignoreSubClasses", "true"); remoteHost = new RemoteHostImpl(rmiPort); + ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(rmiFilterPattern); RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject( - remoteHost, rmiPort); + remoteHost, rmiPort, filter); bind(name.toString(), stub); System.out.println("jstatd started (bound to " + name.toString() + ")"); System.out.flush(); diff --git a/test/jdk/sun/tools/jstatd/JstatdTest.java b/test/jdk/sun/tools/jstatd/JstatdTest.java index 56c86cbfa07..9eb1ccb3748 100644 --- a/test/jdk/sun/tools/jstatd/JstatdTest.java +++ b/test/jdk/sun/tools/jstatd/JstatdTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -43,7 +43,7 @@ import jdk.test.lib.thread.ProcessThread; *
      * {@code
      * // start jstatd process
    - * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy
    + * jstatd -J-XX:+UsePerfData
      *
      * // run jps and verify its output
      * jps -J-XX:+UsePerfData hostname
    @@ -244,20 +244,16 @@ public final class JstatdTest {
         /**
          * Depending on test settings command line can look like:
          *
    -     * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy
    -     * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -p port
    -     * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -p port -r rmiport
    -     * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -n serverName
    -     * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -p port -n serverName
    +     * jstatd -J-XX:+UsePerfData
    +     * jstatd -J-XX:+UsePerfData -p port
    +     * jstatd -J-XX:+UsePerfData -p port -r rmiport
    +     * jstatd -J-XX:+UsePerfData -n serverName
    +     * jstatd -J-XX:+UsePerfData -p port -n serverName
          */
         private String[] getJstatdCmd() throws Exception {
             JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstatd");
             launcher.addVMArg("-XX:+UsePerfData");
             String testSrc = System.getProperty("test.src");
    -        File policy = new File(testSrc, "all.policy");
    -        assertTrue(policy.exists() && policy.isFile(),
    -                "Security policy " + policy.getAbsolutePath() + " does not exist or not a file");
    -        launcher.addVMArg("-Djava.security.policy=" + policy.getAbsolutePath());
             if (port != null) {
                 addToolArg(launcher,"-p", port);
             }
    diff --git a/test/jdk/sun/tools/jstatd/all.policy b/test/jdk/sun/tools/jstatd/all.policy
    deleted file mode 100644
    index e202e4e91b6..00000000000
    --- a/test/jdk/sun/tools/jstatd/all.policy
    +++ /dev/null
    @@ -1,3 +0,0 @@
    -grant {
    -   permission java.security.AllPermission;
    -};
    -- 
    GitLab
    
    
    From 409382ba4b43bf48ed0086020dd20641effd35b6 Mon Sep 17 00:00:00 2001
    From: Sebastian Stenzel 
    Date: Fri, 28 Jan 2022 16:42:42 +0000
    Subject: [PATCH 072/400] 8280703: CipherCore.doFinal(...) causes potentially
     massive byte[] allocations during decryption
    
    Reviewed-by: ascarpino
    ---
     .../classes/com/sun/crypto/provider/CipherCore.java | 13 ++++++++-----
     1 file changed, 8 insertions(+), 5 deletions(-)
    
    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 93eede032f1..64ce01c53ab 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, 2021, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2002, 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
    @@ -812,10 +812,13 @@ final class CipherCore {
                 if (outputCapacity < estOutSize) {
                     cipher.save();
                 }
    -            // create temporary output buffer if the estimated size is larger
    -            // than the user-provided buffer.
    -            internalOutput = new byte[estOutSize];
    -            offset = 0;
    +            if (outputCapacity < estOutSize || padding != null) {
    +                // create temporary output buffer if the estimated size is larger
    +                // than the user-provided buffer or a padding needs to be removed
    +                // before copying the unpadded result to the output buffer
    +                internalOutput = new byte[estOutSize];
    +                offset = 0;
    +            }
             }
     
             byte[] outBuffer = (internalOutput != null) ? internalOutput : output;
    -- 
    GitLab
    
    
    From 95ee9bf7be40572e768cf6213c03ca183b8ad886 Mon Sep 17 00:00:00 2001
    From: Brian Burkhalter 
    Date: Fri, 28 Jan 2022 17:12:42 +0000
    Subject: [PATCH 073/400] 4774868: (fc spec) Unclear spec for FileChannel.force
    
    Reviewed-by: alanb
    ---
     .../share/classes/java/nio/channels/FileChannel.java          | 4 +++-
     1 file changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/src/java.base/share/classes/java/nio/channels/FileChannel.java b/src/java.base/share/classes/java/nio/channels/FileChannel.java
    index d8fee6ca995..fb9639a2d5d 100644
    --- a/src/java.base/share/classes/java/nio/channels/FileChannel.java
    +++ b/src/java.base/share/classes/java/nio/channels/FileChannel.java
    @@ -566,7 +566,9 @@ public abstract class FileChannel
          * actually done is system-dependent and is therefore unspecified.
          *
          * 

    This method is only guaranteed to force changes that were made to - * this channel's file via the methods defined in this class. It may or + * this channel's file via the methods defined in this class, or the methods + * defined by {@link FileOutputStream} or {@link RandomAccessFile} when the + * channel was obtained with the {@code getChannel} method. It may or * may not force changes that were made by modifying the content of a * {@link MappedByteBuffer mapped byte buffer} obtained by * invoking the {@link #map map} method. Invoking the {@link -- GitLab From ff34d624ba81698db0aacc1d5e2332c4345010ce Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Fri, 28 Jan 2022 18:09:35 +0000 Subject: [PATCH 074/400] 8280898: ProblemList compiler/regalloc/TestC2IntPressure.java on macosx-aarch64 Reviewed-by: ctornqvi --- test/hotspot/jtreg/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index e08217cd776..b5fe9a5bb83 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -73,6 +73,7 @@ compiler/whitebox/MakeMethodNotCompilableTest.java 8265360 macosx-aarch64 compiler/codecache/jmx/PoolsIndependenceTest.java 8264632 macosx-generic compiler/codecache/TestStressCodeBuffers.java 8272094 generic-aarch64 +compiler/regalloc/TestC2IntPressure.java 8280843 macosx-aarch64 ############################################################################# -- GitLab From 0740ac474cbda439684223e660827e38964e6b1f Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Fri, 28 Jan 2022 18:51:21 +0000 Subject: [PATCH 075/400] 8280555: serviceability/sa/TestObjectMonitorIterate.java is failing due to ObjectMonitor referencing a null Object Reviewed-by: sspitsyn, lmesnik --- .../serviceability/sa/TestObjectMonitorIterate.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/sa/TestObjectMonitorIterate.java b/test/hotspot/jtreg/serviceability/sa/TestObjectMonitorIterate.java index 5f1e6c48f5f..e2d79b1ce9d 100644 --- a/test/hotspot/jtreg/serviceability/sa/TestObjectMonitorIterate.java +++ b/test/hotspot/jtreg/serviceability/sa/TestObjectMonitorIterate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, NTT DATA. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -59,8 +59,12 @@ public class TestObjectMonitorIterate { while (itr.hasNext()) { ObjectMonitor mon = (ObjectMonitor)itr.next(); - Oop oop = heap.newOop(mon.object()); - System.out.println("Monitor found: " + oop.getKlass().getName().asString()); + if (mon.object() == null) { + System.out.println("Monitor found: object is null"); + } else { + Oop oop = heap.newOop(mon.object()); + System.out.println("Monitor found: " + oop.getKlass().getName().asString()); + } } } finally { agent.detach(); -- GitLab From 91391598989c70c98b9400997df4f9177d3e576f Mon Sep 17 00:00:00 2001 From: Denghui Dong Date: Fri, 28 Jan 2022 22:52:32 +0000 Subject: [PATCH 076/400] 8280843: macos-Aarch64 SEGV in frame::sender_for_compiled_frame after JDK-8277948 Reviewed-by: aph, dholmes --- src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.cpp | 6 ++++-- .../os_cpu/windows_aarch64/thread_windows_aarch64.cpp | 5 ++++- test/hotspot/jtreg/ProblemList.txt | 1 - 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.cpp b/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.cpp index d8b1a0b20ef..f07f22bc0cd 100644 --- a/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.cpp +++ b/src/hotspot/os_cpu/bsd_aarch64/thread_bsd_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -32,7 +32,9 @@ frame JavaThread::pd_last_frame() { assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); vmassert(_anchor.last_Java_pc() != NULL, "not walkable"); - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); + frame f = frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); + f.set_sp_is_trusted(); + return f; } // For Forte Analyzer AsyncGetCallTrace profiling support - thread is diff --git a/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp index 6512df3e7b9..c5267d85d37 100644 --- a/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp +++ b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * Copyright (c) 2022, Alibaba Group Holding Limited. All rights reserved. * 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 +30,9 @@ frame JavaThread::pd_last_frame() { assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); vmassert(_anchor.last_Java_pc() != NULL, "not walkable"); - return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); + frame f = frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); + f.set_sp_is_trusted(); + return f; } // For Forte Analyzer AsyncGetCallTrace profiling support - thread is diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index b5fe9a5bb83..e08217cd776 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -73,7 +73,6 @@ compiler/whitebox/MakeMethodNotCompilableTest.java 8265360 macosx-aarch64 compiler/codecache/jmx/PoolsIndependenceTest.java 8264632 macosx-generic compiler/codecache/TestStressCodeBuffers.java 8272094 generic-aarch64 -compiler/regalloc/TestC2IntPressure.java 8280843 macosx-aarch64 ############################################################################# -- GitLab From d366d15d67a08833d93a5806edef8145cb7803e5 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Fri, 28 Jan 2022 23:18:20 +0000 Subject: [PATCH 077/400] 8280903: javadoc build fails after JDK-4774868 Reviewed-by: lancea --- .../share/classes/java/nio/channels/FileChannel.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/nio/channels/FileChannel.java b/src/java.base/share/classes/java/nio/channels/FileChannel.java index fb9639a2d5d..9d9c35fbc1f 100644 --- a/src/java.base/share/classes/java/nio/channels/FileChannel.java +++ b/src/java.base/share/classes/java/nio/channels/FileChannel.java @@ -567,9 +567,10 @@ public abstract class FileChannel * *

    This method is only guaranteed to force changes that were made to * this channel's file via the methods defined in this class, or the methods - * defined by {@link FileOutputStream} or {@link RandomAccessFile} when the - * channel was obtained with the {@code getChannel} method. It may or - * may not force changes that were made by modifying the content of a + * defined by {@link java.io.FileOutputStream} or + * {@link java.io.RandomAccessFile} when the channel was obtained with the + * {@code getChannel} method. It may or may not force changes that were made + * by modifying the content of a * {@link MappedByteBuffer mapped byte buffer} obtained by * invoking the {@link #map map} method. Invoking the {@link * MappedByteBuffer#force force} method of the mapped byte buffer will -- GitLab From 268880b471eed54535927fba953347160f447fcd Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Sat, 29 Jan 2022 11:36:11 +0000 Subject: [PATCH 078/400] 8277412: Use String.isBlank to simplify code in sun.net.www.protocol.mailto.Handler Reviewed-by: dfuchs --- .../sun/net/www/protocol/mailto/Handler.java | 31 +++---------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java b/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java index e9052397483..0c420fa1400 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java +++ b/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,10 +32,6 @@ package sun.net.www.protocol.mailto; import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; -import java.io.*; -import sun.net.www.*; -//import sun.net.www.protocol.news.ArticlePoster; -import sun.net.smtp.SmtpClient; /** open an nntp input stream given a URL */ public class Handler extends URLStreamHandler { @@ -126,33 +122,16 @@ public class Handler extends URLStreamHandler { /* * Let's just make sure we DO have an Email address in the URL. */ - boolean nogood = false; - if (file == null || file.isEmpty()) - nogood = true; - else { - boolean allwhites = true; - for (int i = 0; i < file.length(); i++) - if (!Character.isWhitespace(file.charAt(i))) - allwhites = false; - if (allwhites) - nogood = true; - } - if (nogood) + if (file.isBlank()) throw new RuntimeException("No email address"); - setURLHandler(u, protocol, host, port, file, null); + setURLHandler(u, protocol, host, port, file); } /** * This method is used to suppress the deprecated warning - * - * @param u the URL to receive the result of parsing the spec - * @param spec the URL string to parse - * @param start the character position to start parsing at. This is - * just past the ':'. - * @param limit the character position to stop parsing at. */ @SuppressWarnings("deprecation") - private void setURLHandler(URL u, String protocol, String host, int port, String file, String ref) { - setURL(u,protocol,host,port,file,null); + private void setURLHandler(URL u, String protocol, String host, int port, String file) { + setURL(u, protocol, host, port, file, null); } } -- GitLab From be9f984caec32c3fe1deef30efe40fa115409ca0 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Sat, 29 Jan 2022 21:35:06 +0000 Subject: [PATCH 079/400] 8280553: resourcehogs/serviceability/sa/TestHeapDumpForLargeArray.java can fail if GC occurs Reviewed-by: alanb, amenkov --- .../serviceability/sa/LingeredAppWithLargeArray.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeArray.java b/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeArray.java index 44929f05b15..244f4187334 100644 --- a/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeArray.java +++ b/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -23,9 +23,12 @@ import jdk.test.lib.apps.LingeredApp; +import java.lang.ref.Reference; + public class LingeredAppWithLargeArray extends LingeredApp { public static void main(String args[]) { int[] hugeArray = new int[Integer.MAX_VALUE/2]; LingeredApp.main(args); + Reference.reachabilityFence(hugeArray); } } -- GitLab From 251351f49498ea39150b38860b8f73232fbaf05d Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Mon, 31 Jan 2022 08:49:02 +0000 Subject: [PATCH 080/400] 8280889: java/lang/instrument/GetObjectSizeIntrinsicsTest.java fails with -XX:-UseCompressedOops Reviewed-by: sspitsyn, dcubed --- .../instrument/GetObjectSizeIntrinsicsTest.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java b/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java index 975adb23cf5..a4fdab2ec47 100644 --- a/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java +++ b/test/jdk/java/lang/instrument/GetObjectSizeIntrinsicsTest.java @@ -280,19 +280,16 @@ * * @run main/othervm -Xmx8g * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -XX:+WhiteBoxAPI -Xbootclasspath/a:. - * -XX:ObjectAlignmentInBytes=32 * -Xint * -javaagent:basicAgent.jar GetObjectSizeIntrinsicsTest GetObjectSizeIntrinsicsTest large * * @run main/othervm -Xmx8g * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -XX:+WhiteBoxAPI -Xbootclasspath/a:. - * -XX:ObjectAlignmentInBytes=32 * -Xbatch -XX:TieredStopAtLevel=1 * -javaagent:basicAgent.jar GetObjectSizeIntrinsicsTest GetObjectSizeIntrinsicsTest large * * @run main/othervm -Xmx8g * -XX:+UnlockDiagnosticVMOptions -XX:+AbortVMOnCompilationFailure -XX:+WhiteBoxAPI -Xbootclasspath/a:. - * -XX:ObjectAlignmentInBytes=32 * -Xbatch -XX:-TieredCompilation * -javaagent:basicAgent.jar GetObjectSizeIntrinsicsTest GetObjectSizeIntrinsicsTest large */ @@ -312,8 +309,9 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase static final int SMALL_ARRAY_SIZE = 1024; - // With int[] arrays, this overflows 4G boundary - static final int LARGE_ARRAY_SIZE = 1024*1024*1024 + 1024; + // These should overflow 4G size boundary + static final int LARGE_INT_ARRAY_SIZE = 1024*1024*1024 + 1024; + static final int LARGE_OBJ_ARRAY_SIZE = (4096/(int)REF_SIZE)*1024*1024 + 1024; final String mode; @@ -446,16 +444,16 @@ public class GetObjectSizeIntrinsicsTest extends ASimpleInstrumentationTestCase } private void testSize_localLargeIntArray() { - int[] arr = new int[LARGE_ARRAY_SIZE]; - long expected = roundUp(4L*LARGE_ARRAY_SIZE + 16, OBJ_ALIGN); + int[] arr = new int[LARGE_INT_ARRAY_SIZE]; + long expected = roundUp(4L*LARGE_INT_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(arr)); } } private void testSize_localLargeObjArray() { - Object[] arr = new Object[LARGE_ARRAY_SIZE]; - long expected = roundUp(REF_SIZE*LARGE_ARRAY_SIZE + 16, OBJ_ALIGN); + Object[] arr = new Object[LARGE_OBJ_ARRAY_SIZE]; + long expected = roundUp(REF_SIZE*LARGE_OBJ_ARRAY_SIZE + 16, OBJ_ALIGN); for (int c = 0; c < ITERS; c++) { assertEquals(expected, fInst.getObjectSize(arr)); } -- GitLab From c6ed2046b4ba8eafb6b7e934b134829760d56ecd Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Mon, 31 Jan 2022 12:11:03 +0000 Subject: [PATCH 081/400] 8278263: Remove redundant synchronized from URLStreamHandler.openConnection methods Reviewed-by: dfuchs --- .../sun/net/www/protocol/mailto/Handler.java | 2 +- .../sun/net/www/protocol/file/Handler.java | 19 ++++--------------- .../sun/net/www/protocol/file/Handler.java | 19 ++++--------------- 3 files changed, 9 insertions(+), 31 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java b/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java index 0c420fa1400..cb8e490995e 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java +++ b/src/java.base/share/classes/sun/net/www/protocol/mailto/Handler.java @@ -95,7 +95,7 @@ public class Handler extends URLStreamHandler { // } */ - public synchronized URLConnection openConnection(URL u) { + public URLConnection openConnection(URL u) { return new MailToURLConnection(u); } diff --git a/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java b/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java index 5892517e938..207e95d27f8 100644 --- a/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java +++ b/src/java.base/unix/classes/sun/net/www/protocol/file/Handler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,10 @@ package sun.net.www.protocol.file; -import java.net.InetAddress; import java.net.URLConnection; import java.net.URL; import java.net.Proxy; -import java.net.MalformedURLException; import java.net.URLStreamHandler; -import java.io.InputStream; import java.io.IOException; import sun.net.www.ParseUtil; import java.io.File; @@ -42,14 +39,6 @@ import java.io.File; */ public class Handler extends URLStreamHandler { - private String getHost(URL url) { - String host = url.getHost(); - if (host == null) - host = ""; - return host; - } - - protected void parseURL(URL u, String spec, int start, int limit) { /* * Ugly backwards compatibility. Flip any file separator @@ -61,18 +50,18 @@ public class Handler extends URLStreamHandler { * rather than forcing this to be fixed in the caller of the URL * class where it belongs. Since backslash is an "unwise" * character that would normally be encoded if literally intended - * as a non-seperator character the damage of veering away from the + * as a non-separator character the damage of veering away from the * specification is presumably limited. */ super.parseURL(u, spec.replace(File.separatorChar, '/'), start, limit); } - public synchronized URLConnection openConnection(URL u) + public URLConnection openConnection(URL u) throws IOException { return openConnection(u, null); } - public synchronized URLConnection openConnection(URL u, Proxy p) + public URLConnection openConnection(URL u, Proxy p) throws IOException { String host = u.getHost(); if (host == null || host.isEmpty() || host.equals("~") || diff --git a/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java b/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java index 5475eca7c2e..18ccda6e7c1 100644 --- a/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java +++ b/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,10 @@ package sun.net.www.protocol.file; -import java.net.InetAddress; import java.net.URLConnection; import java.net.URL; import java.net.Proxy; -import java.net.MalformedURLException; import java.net.URLStreamHandler; -import java.io.InputStream; import java.io.IOException; import sun.net.www.ParseUtil; import java.io.File; @@ -42,14 +39,6 @@ import java.io.File; */ public class Handler extends URLStreamHandler { - private String getHost(URL url) { - String host = url.getHost(); - if (host == null) - host = ""; - return host; - } - - protected void parseURL(URL u, String spec, int start, int limit) { /* * Ugly backwards compatibility. Flip any file separator @@ -61,18 +50,18 @@ public class Handler extends URLStreamHandler { * rather than forcing this to be fixed in the caller of the URL * class where it belongs. Since backslash is an "unwise" * character that would normally be encoded if literally intended - * as a non-seperator character the damage of veering away from the + * as a non-separator character the damage of veering away from the * specification is presumably limited. */ super.parseURL(u, spec.replace(File.separatorChar, '/'), start, limit); } - public synchronized URLConnection openConnection(URL url) + public URLConnection openConnection(URL url) throws IOException { return openConnection(url, null); } - public synchronized URLConnection openConnection(URL url, Proxy p) + public URLConnection openConnection(URL url, Proxy p) throws IOException { String path; -- GitLab From 61794c503973a330278f0595e36be0bd686fe2b5 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Mon, 31 Jan 2022 12:30:09 +0000 Subject: [PATCH 082/400] 8280817: Clean up and unify empty VM operations Reviewed-by: shade, coleenp --- src/hotspot/share/runtime/vmOperation.hpp | 12 ++--- src/hotspot/share/runtime/vmOperations.hpp | 58 ++++++++++------------ src/hotspot/share/runtime/vmThread.cpp | 6 +-- test/hotspot/gtest/threadHelper.inline.hpp | 8 +-- 4 files changed, 35 insertions(+), 49 deletions(-) diff --git a/src/hotspot/share/runtime/vmOperation.hpp b/src/hotspot/share/runtime/vmOperation.hpp index bd453df5979..5489770f386 100644 --- a/src/hotspot/share/runtime/vmOperation.hpp +++ b/src/hotspot/share/runtime/vmOperation.hpp @@ -35,20 +35,19 @@ // Note: When new VM_XXX comes up, add 'XXX' to the template table. #define VM_OPS_DO(template) \ - template(None) \ + template(Halt) \ + template(SafepointALot) \ template(Cleanup) \ template(ThreadDump) \ template(PrintThreads) \ template(FindDeadlocks) \ template(ClearICs) \ template(ForceSafepoint) \ - template(ForceAsyncSafepoint) \ template(DeoptimizeFrame) \ template(DeoptimizeAll) \ template(ZombieAll) \ template(Verify) \ template(HeapDumper) \ - template(DeoptimizeTheWorld) \ template(CollectForMetadataAllocation) \ template(GC_HeapInspection) \ template(GenCollectFull) \ @@ -64,9 +63,7 @@ template(ZMarkEnd) \ template(ZRelocateStart) \ template(ZVerify) \ - template(HandshakeOneThread) \ template(HandshakeAllThreads) \ - template(HandshakeFallback) \ template(PopulateDumpSharedSpace) \ template(JNIFunctionTableCopier) \ template(RedefineClasses) \ @@ -89,7 +86,6 @@ template(ShenandoahDegeneratedGC) \ template(Exit) \ template(LinuxDllLoad) \ - template(RotateGCLog) \ template(WhiteBoxOperation) \ template(JVMCIResizeCounters) \ template(ClassLoaderStatsOperation) \ @@ -99,12 +95,10 @@ template(CleanClassLoaderDataMetaspaces) \ template(PrintCompileQueue) \ template(PrintClassHierarchy) \ - template(ThreadSuspend) \ - template(ThreadsSuspendJVMTI) \ template(ICBufferFull) \ - template(ScavengeMonitors) \ template(PrintMetadata) \ template(GTestExecuteAtSafepoint) \ + template(GTestStopSafepoint) \ template(JFROldObject) \ template(JvmtiPostObjectFree) diff --git a/src/hotspot/share/runtime/vmOperations.hpp b/src/hotspot/share/runtime/vmOperations.hpp index b68b6fd728b..262ac740c1c 100644 --- a/src/hotspot/share/runtime/vmOperations.hpp +++ b/src/hotspot/share/runtime/vmOperations.hpp @@ -32,58 +32,50 @@ // A hodge podge of commonly used VM Operations -class VM_None: public VM_Operation { - const char* _reason; - public: - VM_None(const char* reason) : _reason(reason) {} - const char* name() const { return _reason; } - VMOp_Type type() const { return VMOp_None; } - void doit() {}; -}; - -class VM_Cleanup: public VM_Operation { - public: - VMOp_Type type() const { return VMOp_Cleanup; } - void doit() {}; - virtual bool skip_thread_oop_barriers() const { - // None of the safepoint cleanup tasks read oops in the Java threads. +class VM_EmptyOperation : public VM_Operation { +public: + virtual void doit() final {} + virtual bool skip_thread_oop_barriers() const final { + // Neither the doit function nor the the safepoint + // cleanup tasks read oops in the Java threads. return true; } }; -class VM_ClearICs: public VM_Operation { - private: - bool _preserve_static_stubs; +class VM_Halt: public VM_EmptyOperation { public: - VM_ClearICs(bool preserve_static_stubs) { _preserve_static_stubs = preserve_static_stubs; } - void doit(); - VMOp_Type type() const { return VMOp_ClearICs; } + VMOp_Type type() const { return VMOp_Halt; } }; -// empty vm op, evaluated just to force a safepoint -class VM_ForceSafepoint: public VM_Operation { +class VM_SafepointALot: public VM_EmptyOperation { public: - void doit() {} - VMOp_Type type() const { return VMOp_ForceSafepoint; } + VMOp_Type type() const { return VMOp_SafepointALot; } }; -// empty vm op, when forcing a safepoint to suspend a thread -class VM_ThreadSuspend: public VM_ForceSafepoint { +class VM_Cleanup: public VM_EmptyOperation { public: - VMOp_Type type() const { return VMOp_ThreadSuspend; } + VMOp_Type type() const { return VMOp_Cleanup; } }; -// empty vm op, when forcing a safepoint to suspend threads from jvmti -class VM_ThreadsSuspendJVMTI: public VM_ForceSafepoint { +// empty vm op, evaluated just to force a safepoint +class VM_ForceSafepoint: public VM_EmptyOperation { public: - VMOp_Type type() const { return VMOp_ThreadsSuspendJVMTI; } + VMOp_Type type() const { return VMOp_ForceSafepoint; } }; // empty vm op, when forcing a safepoint due to inline cache buffers being full -class VM_ICBufferFull: public VM_ForceSafepoint { +class VM_ICBufferFull: public VM_EmptyOperation { public: VMOp_Type type() const { return VMOp_ICBufferFull; } - virtual bool skip_thread_oop_barriers() const { return true; } +}; + +class VM_ClearICs: public VM_Operation { + private: + bool _preserve_static_stubs; + public: + VM_ClearICs(bool preserve_static_stubs) { _preserve_static_stubs = preserve_static_stubs; } + void doit(); + VMOp_Type type() const { return VMOp_ClearICs; } }; // Base class for invoking parts of a gtest in a safepoint. diff --git a/src/hotspot/share/runtime/vmThread.cpp b/src/hotspot/share/runtime/vmThread.cpp index 2e601a11f60..e22c3398486 100644 --- a/src/hotspot/share/runtime/vmThread.cpp +++ b/src/hotspot/share/runtime/vmThread.cpp @@ -96,8 +96,8 @@ void VMOperationTimeoutTask::disarm() { //------------------------------------------------------------------------------------------------------------------ // Implementation of VMThread stuff -static VM_None safepointALot_op("SafepointALot"); -static VM_Cleanup cleanup_op; +static VM_SafepointALot safepointALot_op; +static VM_Cleanup cleanup_op; bool VMThread::_should_terminate = false; bool VMThread::_terminated = false; @@ -147,7 +147,7 @@ void VMThread::destroy() { _vm_thread = NULL; // VM thread is gone } -static VM_None halt_op("Halt"); +static VM_Halt halt_op; void VMThread::run() { assert(this == vm_thread(), "check"); diff --git a/test/hotspot/gtest/threadHelper.inline.hpp b/test/hotspot/gtest/threadHelper.inline.hpp index 52c044850e8..3c6b951df0a 100644 --- a/test/hotspot/gtest/threadHelper.inline.hpp +++ b/test/hotspot/gtest/threadHelper.inline.hpp @@ -49,13 +49,13 @@ static void startTestThread(JavaThread* thread, const char* name) { } } -class VM_StopSafepoint : public VM_Operation { +class VM_GTestStopSafepoint : public VM_Operation { public: Semaphore* _running; Semaphore* _test_complete; - VM_StopSafepoint(Semaphore* running, Semaphore* wait_for) : + VM_GTestStopSafepoint(Semaphore* running, Semaphore* wait_for) : _running(running), _test_complete(wait_for) {} - VMOp_Type type() const { return VMOp_None; } + VMOp_Type type() const { return VMOp_GTestStopSafepoint; } bool evaluate_at_safepoint() const { return false; } void doit() { _running->signal(); _test_complete->wait(); } }; @@ -67,7 +67,7 @@ class VMThreadBlocker : public JavaThread { static void blocker_thread_entry(JavaThread* thread, TRAPS) { VMThreadBlocker* t = static_cast(thread); - VM_StopSafepoint ss(&t->_ready, &t->_unblock); + VM_GTestStopSafepoint ss(&t->_ready, &t->_unblock); VMThread::execute(&ss); } -- GitLab From 091aff92e2213bfe0de79b3561a7613ab77e24b6 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Mon, 31 Jan 2022 13:43:35 +0000 Subject: [PATCH 083/400] 8278908: [macOS] Unexpected text normalization on pasting from clipboard Reviewed-by: serb, aivanov --- .../macosx/classes/sun/lwawt/macosx/CDataTransferer.java | 5 ----- .../UnicodeTransferTest/UnicodeTransferTest.java | 8 ++------ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java index 0ea70549d43..e6a16ed670f 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDataTransferer.java @@ -33,8 +33,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URL; import java.nio.charset.Charset; -import java.text.Normalizer; -import java.text.Normalizer.Form; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -165,9 +163,6 @@ public class CDataTransferer extends DataTransferer { // regular string that allows to translate data to target represantation // class by base method format = CF_STRING; - } else if (format == CF_STRING) { - String src = new String(bytes, UTF_8); - bytes = Normalizer.normalize(src, Form.NFC).getBytes(UTF_8); } return super.translateBytes(bytes, flavor, format, transferable); diff --git a/test/jdk/java/awt/datatransfer/UnicodeTransferTest/UnicodeTransferTest.java b/test/jdk/java/awt/datatransfer/UnicodeTransferTest/UnicodeTransferTest.java index 3a7ea0c5995..7dba15b5a1f 100644 --- a/test/jdk/java/awt/datatransfer/UnicodeTransferTest/UnicodeTransferTest.java +++ b/test/jdk/java/awt/datatransfer/UnicodeTransferTest/UnicodeTransferTest.java @@ -25,7 +25,7 @@ /* @test @key headful - @bug 4718897 + @bug 4718897 8278908 @summary tests that a Unicode string can be transferred between JVMs. @author das@sparc.spb.su area=datatransfer @library ../../regtesthelpers/process @@ -35,7 +35,6 @@ import java.awt.datatransfer.*; import java.awt.*; -import java.text.Normalizer; import test.java.awt.regtesthelpers.process.ProcessResults; import test.java.awt.regtesthelpers.process.ProcessCommunicator; @@ -77,10 +76,7 @@ class Util { buf.append(0x20); } } - // On OS X the unicode string is normalized but the clipboard, - // so we need to use normalized strings as well to be able to - // check the result - testString = Normalizer.normalize(buf.toString(), Normalizer.Form.NFC); + testString = buf.toString(); } public static String getTestString() { -- GitLab From bdda43e066b8da0ebf9a8ef2f843eabb230f0800 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Mon, 31 Jan 2022 16:01:18 +0000 Subject: [PATCH 084/400] 8280705: Parallel: Full gc mark stack draining should prefer to make work available to other threads Reviewed-by: ayang, mli --- .../share/gc/parallel/psCompactionManager.cpp | 18 +++++++++++++++--- .../share/gc/parallel/psCompactionManager.hpp | 1 + .../share/gc/parallel/psParallelCompact.cpp | 12 +++++------- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.cpp b/src/hotspot/share/gc/parallel/psCompactionManager.cpp index 3a7fc8ae758..c6bb7bf1e99 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.cpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.cpp @@ -113,12 +113,24 @@ ParCompactionManager::gc_thread_compaction_manager(uint index) { return _manager_array[index]; } +bool ParCompactionManager::transfer_from_overflow_stack(ObjArrayTask& task) { + while (_objarray_stack.pop_overflow(task)) { + if (!_objarray_stack.try_push_to_taskqueue(task)) { + return true; + } + } + return false; +} + void ParCompactionManager::follow_marking_stacks() { do { - // Drain the overflow stack first, to allow stealing from the marking stack. + // First, try to move tasks from the overflow stack into the shared buffer, so + // that other threads can steal. Otherwise process the overflow stack first. oop obj; while (marking_stack()->pop_overflow(obj)) { - follow_contents(obj); + if (!marking_stack()->try_push_to_taskqueue(obj)) { + follow_contents(obj); + } } while (marking_stack()->pop_local(obj)) { follow_contents(obj); @@ -126,7 +138,7 @@ void ParCompactionManager::follow_marking_stacks() { // Process ObjArrays one at a time to avoid marking stack bloat. ObjArrayTask task; - if (_objarray_stack.pop_overflow(task) || _objarray_stack.pop_local(task)) { + if (transfer_from_overflow_stack(task) || _objarray_stack.pop_local(task)) { follow_array((objArrayOop)task.obj(), task.index()); } } while (!marking_stacks_empty()); diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.hpp index 4299f7e4c02..0cb5d33e0f5 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.hpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.hpp @@ -97,6 +97,7 @@ class ParCompactionManager : public CHeapObj { static void initialize(ParMarkBitMap* mbm); + bool transfer_from_overflow_stack(ObjArrayTask& task); protected: // Array of task queues. Needed by the task terminator. static RegionTaskQueueSet* region_task_queues() { return _region_task_queues; } diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index 4657975b1bc..bc080814122 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -1984,17 +1984,15 @@ void steal_marking_work(TaskTerminator& terminator, uint worker_id) { ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id); - oop obj = NULL; - ObjArrayTask task; do { - while (ParCompactionManager::steal_objarray(worker_id, task)) { + oop obj = NULL; + ObjArrayTask task; + if (ParCompactionManager::steal_objarray(worker_id, task)) { cm->follow_array((objArrayOop)task.obj(), task.index()); - cm->follow_marking_stacks(); - } - while (ParCompactionManager::steal(worker_id, obj)) { + } else if (ParCompactionManager::steal(worker_id, obj)) { cm->follow_contents(obj); - cm->follow_marking_stacks(); } + cm->follow_marking_stacks(); } while (!terminator.offer_termination()); } -- GitLab From dcc666d53d66e87c11c0c39858b36d40299b7de6 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Mon, 31 Jan 2022 16:51:10 +0000 Subject: [PATCH 085/400] 8280139: Report more detailed statistics about task stealing in task queue stats Reviewed-by: kbarrett, iwalulya --- src/hotspot/share/gc/shared/taskqueue.cpp | 31 ++++++---- src/hotspot/share/gc/shared/taskqueue.hpp | 47 +++++++++++++--- .../share/gc/shared/taskqueue.inline.hpp | 56 ++++++++++++------- 3 files changed, 95 insertions(+), 39 deletions(-) diff --git a/src/hotspot/share/gc/shared/taskqueue.cpp b/src/hotspot/share/gc/shared/taskqueue.cpp index 2ed1c613bc8..1a11a536683 100644 --- a/src/hotspot/share/gc/shared/taskqueue.cpp +++ b/src/hotspot/share/gc/shared/taskqueue.cpp @@ -34,7 +34,9 @@ #if TASKQUEUE_STATS const char * const TaskQueueStats::_names[last_stat_id] = { - "qpush", "qpop", "qpop-s", "qattempt", "qsteal", "opush", "omax" + "push", "pop", "pop-slow", + "st-attempt", "st-empty", "st-ctdd", "st-success", "st-ctdd-max", "st-biasdrop", + "ovflw-push", "ovflw-max" }; TaskQueueStats & TaskQueueStats::operator +=(const TaskQueueStats & addend) @@ -86,20 +88,29 @@ void TaskQueueStats::print(outputStream* stream, unsigned int width) const // quiescent; they do not hold at arbitrary times. void TaskQueueStats::verify() const { - assert(get(push) == get(pop) + get(steal), - "push=" SIZE_FORMAT " pop=" SIZE_FORMAT " steal=" SIZE_FORMAT, - get(push), get(pop), get(steal)); + assert(get(push) == get(pop) + get(steal_success), + "push=%zu pop=%zu steal=%zu", + get(push), get(pop), get(steal_success)); assert(get(pop_slow) <= get(pop), - "pop_slow=" SIZE_FORMAT " pop=" SIZE_FORMAT, + "pop_slow=%zu pop=%zu", get(pop_slow), get(pop)); - assert(get(steal) <= get(steal_attempt), - "steal=" SIZE_FORMAT " steal_attempt=" SIZE_FORMAT, - get(steal), get(steal_attempt)); + assert(get(steal_empty) <= get(steal_attempt), + "steal_empty=%zu steal_attempt=%zu", + get(steal_empty), get(steal_attempt)); + assert(get(steal_contended) <= get(steal_attempt), + "steal_contended=%zu steal_attempt=%zu", + get(steal_contended), get(steal_attempt)); + assert(get(steal_success) <= get(steal_attempt), + "steal_success=%zu steal_attempt=%zu", + get(steal_success), get(steal_attempt)); + assert(get(steal_empty) + get(steal_contended) + get(steal_success) == get(steal_attempt), + "steal_empty=%zu steal_contended=%zu steal_success=%zu steal_attempt=%zu", + get(steal_empty), get(steal_contended), get(steal_success), get(steal_attempt)); assert(get(overflow) == 0 || get(push) != 0, - "overflow=" SIZE_FORMAT " push=" SIZE_FORMAT, + "overflow=%zu push=%zu", get(overflow), get(push)); assert(get(overflow_max_len) == 0 || get(overflow) != 0, - "overflow_max_len=" SIZE_FORMAT " overflow=" SIZE_FORMAT, + "overflow_max_len=%zu overflow=%zu", get(overflow_max_len), get(overflow)); } #endif // ASSERT diff --git a/src/hotspot/share/gc/shared/taskqueue.hpp b/src/hotspot/share/gc/shared/taskqueue.hpp index dd2039ddf2a..d61326bd2fd 100644 --- a/src/hotspot/share/gc/shared/taskqueue.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.hpp @@ -56,7 +56,11 @@ public: pop, // number of taskqueue pops pop_slow, // subset of taskqueue pops that were done slow-path steal_attempt, // number of taskqueue steal attempts - steal, // number of taskqueue steals + steal_empty, // number of empty taskqueues + steal_contended, // number of contended steals + steal_success, // number of successful steals + steal_max_contended_in_a_row, // maximum number of contended steals in a row + steal_bias_drop, // number of times the bias has been dropped overflow, // number of overflow pushes overflow_max_len, // max length of overflow stack last_stat_id @@ -68,8 +72,16 @@ public: inline void record_push() { ++_stats[push]; } inline void record_pop() { ++_stats[pop]; } inline void record_pop_slow() { record_pop(); ++_stats[pop_slow]; } - inline void record_steal_attempt() { ++_stats[steal_attempt]; } - inline void record_steal() { ++_stats[steal]; } + inline void record_steal_attempt(uint kind) { + ++_stats[steal_attempt]; + ++_stats[steal_empty + kind]; + } + inline void record_contended_in_a_row(uint in_a_row) { + if (_stats[steal_max_contended_in_a_row] < in_a_row) { + _stats[steal_max_contended_in_a_row] = in_a_row; + } + } + inline void record_bias_drop() { ++_stats[steal_bias_drop]; } inline void record_overflow(size_t new_length); TaskQueueStats & operator +=(const TaskQueueStats & addend); @@ -81,9 +93,9 @@ public: // Print the specified line of the header (does not include a line separator). static void print_header(unsigned int line, outputStream* const stream = tty, - unsigned int width = 10); + unsigned int width = 11); // Print the statistics (does not include a line separator). - void print(outputStream* const stream = tty, unsigned int width = 10) const; + void print(outputStream* const stream = tty, unsigned int width = 11) const; DEBUG_ONLY(void verify() const;) @@ -268,6 +280,16 @@ public: // in GenericTaskQueue. uint max_elems() const { return N - 2; } + // The result of a pop_global operation. The value order of this must correspond + // to the order in the corresponding TaskQueueStats StatId. + enum class PopResult : uint { + Empty = 0, // Queue has been empty. t is undefined. + Contended = 1, // Contention prevented successful retrieval, queue most likely contains elements. t is undefined. + Success = 2 // Successfully retrieved an element, t contains it. + }; + + TASKQUEUE_STATS_ONLY(void record_steal_attempt(PopResult kind) { stats.record_steal_attempt((uint)kind); }) + TASKQUEUE_STATS_ONLY(TaskQueueStats stats;) }; @@ -328,6 +350,8 @@ protected: using TaskQueueSuper::assert_not_underflow; public: + typedef typename TaskQueueSuper::PopResult PopResult; + using TaskQueueSuper::max_elems; using TaskQueueSuper::size; @@ -357,7 +381,7 @@ public: // Like pop_local(), but uses the "global" end of the queue (the least // recently pushed). - bool pop_global(E& t); + PopResult pop_global(E& t); // Delete any resource associated with the queue. ~GenericTaskQueue(); @@ -387,7 +411,10 @@ public: void set_last_stolen_queue_id(uint id) { _last_stolen_queue_id = id; } uint last_stolen_queue_id() const { return _last_stolen_queue_id; } bool is_last_stolen_queue_id_valid() const { return _last_stolen_queue_id != InvalidQueueId; } - void invalidate_last_stolen_queue_id() { _last_stolen_queue_id = InvalidQueueId; } + void invalidate_last_stolen_queue_id() { + TASKQUEUE_STATS_ONLY(stats.record_bias_drop();) + _last_stolen_queue_id = InvalidQueueId; + } }; // OverflowTaskQueue is a TaskQueue that also includes an overflow stack for @@ -447,12 +474,16 @@ template class GenericTaskQueueSet: public TaskQueueSetSuperImpl { public: typedef typename T::element_type E; + typedef typename T::PopResult PopResult; private: uint _n; T** _queues; - bool steal_best_of_2(uint queue_num, E& t); + // Attempts to steal an element from a foreign queue (!= queue_num), setting + // the result in t. Validity of this value and the return value is the same + // as for the last pop_global() operation. + PopResult steal_best_of_2(uint queue_num, E& t); public: GenericTaskQueueSet(uint n); diff --git a/src/hotspot/share/gc/shared/taskqueue.inline.hpp b/src/hotspot/share/gc/shared/taskqueue.inline.hpp index 1b47c4193d9..f544a24d536 100644 --- a/src/hotspot/share/gc/shared/taskqueue.inline.hpp +++ b/src/hotspot/share/gc/shared/taskqueue.inline.hpp @@ -254,7 +254,7 @@ bool OverflowTaskQueue::pop_overflow(E& t) // reads elems[oldAge.top]. The owner's bottom == the thief's oldAge.top. // (4) Thief will discard the read value, because its cmpxchg of age will fail. template -bool GenericTaskQueue::pop_global(E& t) { +typename GenericTaskQueue::PopResult GenericTaskQueue::pop_global(E& t) { Age oldAge = age_relaxed(); // Architectures with non-multi-copy-atomic memory model require a @@ -275,7 +275,7 @@ bool GenericTaskQueue::pop_global(E& t) { uint localBot = bottom_acquire(); uint n_elems = clean_size(localBot, oldAge.top()); if (n_elems == 0) { - return false; + return PopResult::Empty; } t = _elems[oldAge.top()]; @@ -289,7 +289,7 @@ bool GenericTaskQueue::pop_global(E& t) { // Note that using "bottom" here might fail, since a pop_local might // have decremented it. assert_not_underflow(localBot, newAge.top()); - return resAge == oldAge; + return resAge == oldAge ? PopResult::Success : PopResult::Contended; } inline int randomParkAndMiller(int *seed0) { @@ -316,10 +316,10 @@ int GenericTaskQueue::next_random_queue_id() { return randomParkAndMiller(&_seed); } -template bool -GenericTaskQueueSet::steal_best_of_2(uint queue_num, E& t) { +template +typename GenericTaskQueueSet::PopResult GenericTaskQueueSet::steal_best_of_2(uint queue_num, E& t) { + T* const local_queue = queue(queue_num); if (_n > 2) { - T* const local_queue = _queues[queue_num]; uint k1 = queue_num; if (local_queue->is_last_stolen_queue_id_valid()) { @@ -336,21 +336,23 @@ GenericTaskQueueSet::steal_best_of_2(uint queue_num, E& t) { k2 = local_queue->next_random_queue_id() % _n; } // Sample both and try the larger. - uint sz1 = _queues[k1]->size(); - uint sz2 = _queues[k2]->size(); + uint sz1 = queue(k1)->size(); + uint sz2 = queue(k2)->size(); uint sel_k = 0; - bool suc = false; + PopResult suc = PopResult::Empty; if (sz2 > sz1) { sel_k = k2; - suc = _queues[k2]->pop_global(t); + suc = queue(k2)->pop_global(t); + TASKQUEUE_STATS_ONLY(local_queue->record_steal_attempt(suc);) } else if (sz1 > 0) { sel_k = k1; - suc = _queues[k1]->pop_global(t); + suc = queue(k1)->pop_global(t); + TASKQUEUE_STATS_ONLY(local_queue->record_steal_attempt(suc);) } - if (suc) { + if (suc == PopResult::Success) { local_queue->set_last_stolen_queue_id(sel_k); } else { local_queue->invalidate_last_stolen_queue_id(); @@ -360,21 +362,33 @@ GenericTaskQueueSet::steal_best_of_2(uint queue_num, E& t) { } else if (_n == 2) { // Just try the other one. uint k = (queue_num + 1) % 2; - return _queues[k]->pop_global(t); + PopResult res = queue(k)->pop_global(t); + TASKQUEUE_STATS_ONLY(local_queue->record_steal_attempt(res);) + return res; } else { assert(_n == 1, "can't be zero."); - return false; + TASKQUEUE_STATS_ONLY(local_queue->record_steal_attempt(PopResult::Empty);) + return PopResult::Empty; } } -template bool -GenericTaskQueueSet::steal(uint queue_num, E& t) { - assert(queue_num < _n, "index out of range."); - for (uint i = 0; i < 2 * _n; i++) { - TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal_attempt()); - if (steal_best_of_2(queue_num, t)) { - TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal()); +template +bool GenericTaskQueueSet::steal(uint queue_num, E& t) { + uint const num_retries = 2 * _n; + + TASKQUEUE_STATS_ONLY(uint contended_in_a_row = 0;) + for (uint i = 0; i < num_retries; i++) { + PopResult sr = steal_best_of_2(queue_num, t); + if (sr == PopResult::Success) { return true; + } else if (sr == PopResult::Contended) { + TASKQUEUE_STATS_ONLY( + contended_in_a_row++; + queue(queue_num)->stats.record_contended_in_a_row(contended_in_a_row); + ) + } else { + assert(sr == PopResult::Empty, "must be"); + TASKQUEUE_STATS_ONLY(contended_in_a_row = 0;) } } return false; -- GitLab From 993a2488ef42b4c63a7e342c12bba8af8e3fab40 Mon Sep 17 00:00:00 2001 From: Thomas Schatzl Date: Mon, 31 Jan 2022 16:52:28 +0000 Subject: [PATCH 086/400] 8280450: Add task queue printing to STW Full GCs Reviewed-by: ayang, sjohanss --- src/hotspot/share/gc/g1/g1FullCollector.cpp | 4 ++++ src/hotspot/share/gc/parallel/psParallelCompact.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index dd20a099919..37c1e1476eb 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -294,6 +294,10 @@ void G1FullCollector::phase1_mark_live_objects() { } scope()->tracer()->report_object_count_after_gc(&_is_alive); +#if TASKQUEUE_STATS + oop_queue_set()->print_and_reset_taskqueue_stats("Oop Queue"); + array_queue_set()->print_and_reset_taskqueue_stats("ObjArrayOop Queue"); +#endif } void G1FullCollector::phase2_prepare_compaction() { diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index bc080814122..d415de47ca5 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -2116,6 +2116,10 @@ void PSParallelCompact::marking_phase(ParallelOldTracer *gc_tracer) { } _gc_tracer.report_object_count_after_gc(is_alive_closure()); +#if TASKQUEUE_STATS + ParCompactionManager::oop_task_queues()->print_and_reset_taskqueue_stats("Oop Queue"); + ParCompactionManager::_objarray_task_queues->print_and_reset_taskqueue_stats("ObjArrayOop Queue"); +#endif } class PSAdjustTask final : public WorkerTask { -- GitLab From 319b77492f78a08b7b9488c73876b027c3076c76 Mon Sep 17 00:00:00 2001 From: Yumin Qi Date: Mon, 31 Jan 2022 19:27:59 +0000 Subject: [PATCH 087/400] 8277101: jcmd VM.cds dynamic_dump should not regenerate holder classes Reviewed-by: iklam, ccheung --- src/hotspot/share/cds/dynamicArchive.cpp | 6 +++--- src/hotspot/share/cds/metaspaceShared.cpp | 8 +++++--- src/hotspot/share/cds/metaspaceShared.hpp | 4 ++-- .../cds/appcds/jcmd/JCmdTestDynamicDump.java | 13 ++++++++++++- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/cds/dynamicArchive.cpp b/src/hotspot/share/cds/dynamicArchive.cpp index eb99176405f..0ff6a017fed 100644 --- a/src/hotspot/share/cds/dynamicArchive.cpp +++ b/src/hotspot/share/cds/dynamicArchive.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -384,7 +384,7 @@ void DynamicArchive::check_for_dynamic_dump() { void DynamicArchive::prepare_for_dump_at_exit() { EXCEPTION_MARK; ResourceMark rm(THREAD); - MetaspaceShared::link_shared_classes(THREAD); + MetaspaceShared::link_shared_classes(false/*not from jcmd*/, THREAD); if (HAS_PENDING_EXCEPTION) { log_error(cds)("Dynamic dump has failed"); log_error(cds)("%s: %s", PENDING_EXCEPTION->klass()->external_name(), @@ -400,7 +400,7 @@ void DynamicArchive::dump_for_jcmd(const char* archive_name, TRAPS) { assert(UseSharedSpaces && RecordDynamicDumpInfo, "already checked in arguments.cpp"); assert(ArchiveClassesAtExit == nullptr, "already checked in arguments.cpp"); assert(DynamicDumpSharedSpaces, "already checked by check_for_dynamic_dump() during VM startup"); - MetaspaceShared::link_shared_classes(CHECK); + MetaspaceShared::link_shared_classes(true/*from jcmd*/, CHECK); dump(archive_name, THREAD); } diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index 5070f7bf39a..ca2e4ecacde 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -642,8 +642,10 @@ bool MetaspaceShared::link_class_for_cds(InstanceKlass* ik, TRAPS) { return res; } -void MetaspaceShared::link_shared_classes(TRAPS) { - LambdaFormInvokers::regenerate_holder_classes(CHECK); +void MetaspaceShared::link_shared_classes(bool jcmd_request, TRAPS) { + if (!jcmd_request) { + LambdaFormInvokers::regenerate_holder_classes(CHECK); + } // Collect all loaded ClassLoaderData. CollectCLDClosure collect_cld(THREAD); @@ -775,7 +777,7 @@ void MetaspaceShared::preload_and_dump_impl(TRAPS) { // were not explicitly specified in the classlist. E.g., if an interface implemented by class K // fails verification, all other interfaces that were not specified in the classlist but // are implemented by K are not verified. - link_shared_classes(CHECK); + link_shared_classes(false/*not from jcmd*/, CHECK); log_info(cds)("Rewriting and linking classes: done"); #if INCLUDE_CDS_JAVA_HEAP diff --git a/src/hotspot/share/cds/metaspaceShared.hpp b/src/hotspot/share/cds/metaspaceShared.hpp index 74077d0fff0..c7d64d7de0c 100644 --- a/src/hotspot/share/cds/metaspaceShared.hpp +++ b/src/hotspot/share/cds/metaspaceShared.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -133,7 +133,7 @@ public: } static bool try_link_class(JavaThread* current, InstanceKlass* ik); - static void link_shared_classes(TRAPS) NOT_CDS_RETURN; + static void link_shared_classes(bool jcmd_request, TRAPS) NOT_CDS_RETURN; static bool link_class_for_cds(InstanceKlass* ik, TRAPS) NOT_CDS_RETURN_(false); static bool may_be_eagerly_linked(InstanceKlass* ik) NOT_CDS_RETURN_(false); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestDynamicDump.java b/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestDynamicDump.java index 72cb5c24d9a..61ec6325854 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestDynamicDump.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jcmd/JCmdTestDynamicDump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -117,6 +117,17 @@ public class JCmdTestDynamicDump extends JCmdTestDumpBase { throw new RuntimeException("The JCmdTestLingeredApp should not start up!"); } } + // Test dynamic dump with -Xlog:cds to check lambda invoker class regeneration + print2ln(test_count++ + " Test dynamic dump with -Xlog:cds to check lambda invoker class regeneration"); + app = createLingeredApp("-cp", allJars, "-XX:+RecordDynamicDumpInfo", "-Xlog:cds", + "-XX:SharedArchiveFile=" + archiveFile); + pid = app.getPid(); + test(null, pid, noBoot, EXPECT_PASS, DYNAMIC_MESSAGES); + String stdout = app.getProcessStdout(); + if (stdout.contains("Regenerate MethodHandle Holder classes...")) { + throw new RuntimeException("jcmd VM.cds dynamic_dump should not regenerate MethodHandle Holder classes"); + } + app.stopApp(); } // Dump a static archive, not using TestCommon.dump(...), we do not take jtreg args. -- GitLab From f991891b0ba7a3767d2abd85ab9b2d284dc3d013 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Mon, 31 Jan 2022 20:25:50 +0000 Subject: [PATCH 088/400] 8280949: Correct the references for the Java Security Standard Algorithm Names specification Reviewed-by: mullan --- .../classes/javax/net/ssl/SSLEngine.java | 22 +++++++-------- .../classes/javax/net/ssl/SSLParameters.java | 28 +++++++++---------- .../javax/net/ssl/SSLServerSocket.java | 22 +++++++-------- .../javax/net/ssl/SSLServerSocketFactory.java | 14 +++++----- .../classes/javax/net/ssl/SSLSocket.java | 22 +++++++-------- .../javax/net/ssl/SSLSocketFactory.java | 14 +++++----- 6 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/java.base/share/classes/javax/net/ssl/SSLEngine.java b/src/java.base/share/classes/javax/net/ssl/SSLEngine.java index b3007b2a9a1..f60ab53f34e 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLEngine.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLEngine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -920,9 +920,9 @@ public abstract class SSLEngine { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() @@ -946,9 +946,9 @@ public abstract class SSLEngine { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suite names * @see #getSupportedCipherSuites() @@ -968,10 +968,10 @@ public abstract class SSLEngine { * Note that the standard list of cipher suite names may be found in the * - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation. Providers - * may support cipher suite names not found in this list or might not - * use the recommended name for a certain cipher suite. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification. Providers may support cipher suite + * names not found in this list or might not use the recommended name + * for a certain cipher suite. *

    * See {@link #getEnabledCipherSuites()} for more information * on why a specific cipher suite may never be used on a engine. diff --git a/src/java.base/share/classes/javax/net/ssl/SSLParameters.java b/src/java.base/share/classes/javax/net/ssl/SSLParameters.java index ae1889198bf..83b83c84270 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLParameters.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -111,9 +111,9 @@ public class SSLParameters { * {@code setCipherSuites(cipherSuites);}. Note that the * standard list of cipher suite names may be found in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation. Providers - * may support cipher suite names not found in this list. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification. Providers may support cipher suite + * names not found in this list. * * @param cipherSuites the array of ciphersuites (or null) */ @@ -131,9 +131,9 @@ public class SSLParameters { * Note that the standard list of cipher suite names may be found in the * - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation. Providers - * may support cipher suite names not found in this list. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification. Providers may support cipher suite + * names not found in this list. * * @param cipherSuites the array of ciphersuites (or null) * @param protocols the array of protocols (or null) @@ -154,9 +154,9 @@ public class SSLParameters { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher suites + * that the provider supports. * * @return a copy of the array of ciphersuites or null if none * have been set. @@ -171,10 +171,10 @@ public class SSLParameters { * @param cipherSuites the array of ciphersuites (or null). Note that the * standard list of cipher suite names may be found in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation. Providers - * may support cipher suite names not found in this list or might not - * use the recommended name for a certain cipher suite. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification. Providers may support cipher suite + * names not found in this list or might not use the recommended name + * for a certain cipher suite. */ public void setCipherSuites(String[] cipherSuites) { this.cipherSuites = clone(cipherSuites); diff --git a/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java b/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java index 00a8bed19f0..20d7e7af676 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLServerSocket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -197,9 +197,9 @@ public abstract class SSLServerSocket extends ServerSocket { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suites enabled * @see #getSupportedCipherSuites() @@ -223,10 +223,10 @@ public abstract class SSLServerSocket extends ServerSocket { * Note that the standard list of cipher suite names may be found in the * - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation. Providers - * may support cipher suite names not found in this list or might not - * use the recommended name for a certain cipher suite. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification. Providers may support cipher suite + * names not found in this list or might not use the recommended name + * for a certain cipher suite. *

    * SSLSockets returned from accept() * inherit this setting. @@ -253,9 +253,9 @@ public abstract class SSLServerSocket extends ServerSocket { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() diff --git a/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java b/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java index e66bd11239d..68c09c02a6f 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLServerSocketFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -87,9 +87,9 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @see #getSupportedCipherSuites() * @return array of the cipher suites enabled by default @@ -108,9 +108,9 @@ public abstract class SSLServerSocketFactory extends ServerSocketFactory { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suite names * @see #getDefaultCipherSuites() diff --git a/src/java.base/share/classes/javax/net/ssl/SSLSocket.java b/src/java.base/share/classes/javax/net/ssl/SSLSocket.java index 84e5be716fe..b2c912c3b65 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLSocket.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLSocket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -327,9 +327,9 @@ public abstract class SSLSocket extends Socket * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suite names * @see #getEnabledCipherSuites() @@ -353,9 +353,9 @@ public abstract class SSLSocket extends Socket * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher + * suites that the provider supports. * * @return an array of cipher suite names * @see #getSupportedCipherSuites() @@ -375,10 +375,10 @@ public abstract class SSLSocket extends Socket * Note that the standard list of cipher suite names may be found in the * - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation. Providers - * may support cipher suite names not found in this list or might not - * use the recommended name for a certain cipher suite. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification. Providers may support cipher suite + * names not found in this list or might not use the recommended name + * for a certain cipher suite. *

    * See {@link #getEnabledCipherSuites()} for more information * on why a specific ciphersuite may never be used on a connection. diff --git a/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java b/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java index 6db6d740750..dd10f422f3e 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -113,9 +113,9 @@ public abstract class SSLSocketFactory extends SocketFactory { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher suites + * that the provider supports. * * @see #getSupportedCipherSuites() * @return array of the cipher suites enabled by default @@ -132,9 +132,9 @@ public abstract class SSLSocketFactory extends SocketFactory { * The returned array includes cipher suites from the list of standard * cipher suite names in the - * JSSE Cipher Suite Names section of the Java Cryptography - * Architecture Standard Algorithm Name Documentation, and may also - * include other cipher suites that the provider supports. + * JSSE Cipher Suite Names section of the Java Security Standard + * Algorithm Names Specification, and may also include other cipher suites + * that the provider supports. * * @see #getDefaultCipherSuites() * @return an array of cipher suite names -- GitLab From 39165613aa0430861e361a33a4925b85ea24fff1 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Mon, 31 Jan 2022 21:48:32 +0000 Subject: [PATCH 089/400] 8280543: Update the "java" and "jcmd" tool specification for CDS Reviewed-by: hseigel, sspitsyn, ccheung --- src/java.base/share/man/java.1 | 599 +++++++-------------------------- src/jdk.jcmd/share/man/jcmd.1 | 20 +- 2 files changed, 145 insertions(+), 474 deletions(-) diff --git a/src/java.base/share/man/java.1 b/src/java.base/share/man/java.1 index 9ef865ec657..6a1532a8981 100644 --- a/src/java.base/share/man/java.1 +++ b/src/java.base/share/man/java.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 1994, 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 @@ -1090,8 +1090,10 @@ Require using shared class data, otherwise fail. .RS .PP \f[B]Note:\f[R] The \f[CB]\-Xshare:on\f[R] option is used for testing -purposes only and may cause intermittent failures due to the use of -address space layout randomization by the operation system. +purposes only. +It may cause the VM to unexpectedly exit during start\-up when the CDS +archive cannot be used (for example, when certain VM parameters are +changed, or when a different JDK is used). This option should not be used in production environments. .RE .TP @@ -5256,293 +5258,83 @@ who\[aq]s running the application, because administrators by default don\[aq]t have the privilege to lock pages in memory. .SH APPLICATION CLASS DATA SHARING .PP -Application Class Data Sharing (AppCDS) extends class data sharing (CDS) -to enable application classes to be placed in a shared archive. +Application Class Data Sharing (AppCDS) stores classes used by your +applications in an archive file. +Since these classes are stored in a format that can be loaded very +quickly (compared to classes stored in a JAR file), AppCDS can improve +the start\-up time of your applications. +In addition, AppCDS can reduce the runtime memory footprint by sharing +parts of these classes across multiple processes. .PP -In addition to the core library classes, AppCDS supports \f[B]Class Data -Sharing\f[R] -[https://docs.oracle.com/en/java/javase/12/vm/class\-data\-sharing.html#GUID\-7EAA3411\-8CF0\-4D19\-BD05\-DF5E1780AA91] -from the following locations: -.IP \[bu] 2 -Platform classes from the runtime image -.IP \[bu] 2 -Application classes from the runtime image -.IP \[bu] 2 -Application classes from the class path -.IP \[bu] 2 -Application classes from the module path +Classes in the CDS archive are stored in an optimized format that\[aq]s +about 2 to 5 times larger than classes stored in JAR files or the JDK +runtime image. +Therefore, it\[aq]s a good idea to archive only those classes that are +actually used by your application. +These usually are just a small portion of all available classes. +For example, your application may use only a few APIs provided by a +large library. +.SS Using CDS Archives .PP -Archiving application classes provides better start up time at runtime. -When running multiple JVM processes, AppCDS also reduces the runtime -footprint with memory sharing for read\-only metadata. +By default, in most JDK distributions, unless \f[CB]\-Xshare:off\f[R] is +specified, the JVM starts up with a default CDS archive, which is +usually located in \f[CB]JAVA_HOME/lib/server/classes.jsa\f[R] (or +\f[CB]JAVA_HOME\\bin\\server\\classes.jsa\f[R] on Windows). +This archive contains about 1300 core library classes that are used by +most applications. .PP -CDS/AppCDS supports archiving classes from JAR files only. +To use CDS for the exact set of classes used by your application, you +can use the \f[CB]\-XX:SharedArchiveFile\f[R] option, which has the +general form: +.RS .PP -Prior to JDK 11, a non\-empty directory was reported as a fatal error in -the following conditions: -.IP \[bu] 2 -For base CDS, a non\-empty directory cannot exist in the -\f[CB]\-Xbootclasspath/a\f[R] path +\f[CB]\-XX:SharedArchiveFile=:\f[R] +.RE .IP \[bu] 2 -With \f[CB]\-XX:+UseAppCDS\f[R], a non\-empty directory could not exist in -the \f[CB]\-Xbootclasspath/a\f[R] path, class path, and module path. -.PP -In JDK 11 and later, \f[CB]\-XX:+UseAppCDS\f[R] is obsolete and the -behavior for a non\-empty directory is based on the class types in the -classlist. -A non\-empty directory is reported as a fatal error in the following -conditions: +The \f[CB]\f[R] overrides the default CDS archive. .IP \[bu] 2 -If application classes or platform classes are not loaded, dump time -only reports an error if a non\-empty directory exists in -\f[CB]\-Xbootclasspath/a\f[R] path +The \f[CB]\f[R] provides additional classes that can be +loaded on top of those in the \f[CB]\f[R]. .IP \[bu] 2 -If application classes or platform classes are loaded, dump time reports -an error for a non\-empty directory that exists in -\f[CB]\-Xbootclasspath/a\f[R] path, class path, or module path -.PP -In JDK 11 and later, using -\f[CB]\-XX:DumpLoadedClassList=\f[R]\f[I]class_list_file\f[R] results a -generated classlist with all classes (both system library classes and -application classes) included. -You no longer have to specify \f[CB]\-XX:+UseAppCDS\f[R] with -\f[CB]\-XX:DumpLoadedClassList\f[R] to produce a complete class list. +On Windows, the above path delimiter \f[CB]:\f[R] should be replaced with +\f[CB];\f[R] .PP -In JDK 11 and later, because \f[CB]UseAppCDS\f[R] is obsolete, -\f[CB]SharedArchiveFile\f[R] becomes a product flag by default. -Specifying \f[CB]+UnlockDiagnosticVMOptions\f[R] for -\f[CB]SharedArchiveFile\f[R] is no longer needed in any configuration. +(The names "static" and "dyanmic" are used for historical reasons. +The only significance is that the "static" archive is loaded first and +the "dynamic" archive is loaded second). .PP -Class Data Sharing (CDS)/AppCDS does not support archiving array classes -in a class list. -When an array in the class list is encountered, CDS dump time gives the -explicit error message: +The JVM can use up to two archives. +To use only a single \f[CB]\f[R], you can omit the +\f[CB]\f[R] portion: .RS .PP -\f[CB]Preload\ Warning:\ Cannot\ find\f[R] \f[I]array_name\f[R] +\f[CB]\-XX:SharedArchiveFile=\f[R] .RE .PP -Although an array in the class list is not allowed, some array classes -can still be created at CDS/AppCDS dump time. -Those arrays are created during the execution of the Java code used by -the Java class loaders (\f[CB]PlatformClassLoader\f[R] and the system -class loader) to load classes at dump time. -The created arrays are archived with the rest of the loaded classes. -.SS Extending Class Data Sharing to Support the Module Path -.PP -In JDK 11, Class Data Sharing (CDS) has been improved to support -archiving classes from the module path. -.IP \[bu] 2 -To create a CDS archive using the \f[CB]\-\-module\-path\f[R] VM option, -use the following command line syntax: -.RS 2 -.RS -.PP -\f[CB]java\ \-Xshare:dump\ \-XX:SharedClassListFile=\f[R]\f[I]class_list_file\f[R] -\f[CB]\-XX:SharedArchiveFile=\f[R]\f[I]shared_archive_file\f[R] -\f[CB]\-\-module\-path=\f[R]\f[I]path_to_modular_jar\f[R] \f[CB]\-m\f[R] -\f[I]module_name\f[R] -.RE -.RE -.IP \[bu] 2 -To run with a CDS archive using the \f[CB]\-\-module\-path\f[R] VM option, -use the following the command line syntax: -.RS 2 +For convenience, the \f[CB]\f[R] records the location of +the \f[CB]\f[R]. +Therefore, you can omit the \f[CB]\f[R] by saying only: .RS .PP -\f[CB]java\ \-XX:SharedArchiveFile=\f[R]\f[I]shared_archive_file\f[R] -\f[CB]\-\-module\-path=\f[R]\f[I]path_to_modular_jar\f[R] \f[CB]\-m\f[R] -\f[I]module_name\f[R] -.RE +\f[CB]\-XX:SharedArchiveFile=\f[R] .RE +.SS Creating CDS Archives .PP -The following table describes how the VM options related to module paths -can be used along with the \f[CB]\-Xshare\f[R] option. -.PP -.TS -tab(@); -l l l. -T{ -Option -T}@T{ -\-Xshare:dump -T}@T{ -\-Xshare:{on,auto} -T} -_ -T{ -\f[CB]\-\-module\-path\f[R][1] \f[I]mp\f[R] -T}@T{ -Allowed -T}@T{ -Allowed[2] -T} -T{ -\f[CB]\-\-module\f[R] -T}@T{ -Allowed -T}@T{ -Allowed -T} -T{ -\f[CB]\-\-add\-module\f[R] -T}@T{ -Allowed -T}@T{ -Allowed -T} -T{ -\f[CB]\-\-upgrade\-module\-path\f[R][3] -T}@T{ -Disallowed (exits if specified) -T}@T{ -Allowed (disables CDS) -T} -T{ -\f[CB]\-\-patch\-module\f[R][4] -T}@T{ -Disallowed (exits if specified) -T}@T{ -Allowed (disables CDS) -T} -T{ -\f[CB]\-\-limit\-modules\f[R][5] -T}@T{ -Disallowed (exits if specified) -T}@T{ -Allowed (disables CDS) -T} -.TE -.PP -[1] Although there are two ways of specifying a module in a -\f[CB]\-\-module\-path\f[R], that is, modular JAR or exploded module, only -modular JARs are supported. -.PP -[2] Different \f[I]mp\f[R] can be specified during dump time versus run -time. -If an archived class K was loaded from \f[CB]mp1.jar\f[R] at dump time, -but changes in \f[I]mp\f[R] cause it to be available from a different -\f[CB]mp2.jar\f[R] at run time, then the archived version of K will be -disregarded at run time; K will be loaded dynamically. -.PP -[3] Currently, only two system modules are upgradeable -(\f[CB]java.compiler\f[R] and \f[CB]jdk.internal.vm.compiler\f[R]). -However, these modules are seldom upgraded in production software. -.PP -[4] As documented in JEP 261, using \f[CB]\-\-patch\-module\f[R] is -strongly discouraged for production use. -.PP -[5] \f[CB]\-\-limit\-modules\f[R] is intended for testing purposes. -It is seldom used in production software. -.PP -If \f[CB]\-\-upgrade\-module\-path\f[R], \f[CB]\-\-patch\-module\f[R], or -\f[CB]\-\-limit\-modules\f[R] is specified at dump time, an error will be -printed and the JVM will exit. -For example, if the \f[CB]\-\-limit\-modules\f[R] option is specified at -dump time, the user will see the following error: -.IP -.nf -\f[CB] -Error\ occurred\ during\ initialization\ of\ VM -Cannot\ use\ the\ following\ option\ when\ dumping\ the\ shared\ archive:\ \-\-limit\-modules -\f[R] -.fi -.PP -If \f[CB]\-\-upgrade\-module\-path\f[R], \f[CB]\-\-patch\-module\f[R], or -\f[CB]\-\-limit\-modules\f[R] is specified at run time, a warning message -will be printed indicating that CDS is disabled. -For example, if the \f[CB]\-\-limit\-modules\f[R] options is specified at -run time, the user will see the following warning: -.IP -.nf -\f[CB] -Java\ HotSpot(TM)\ 64\-Bit\ Server\ VM\ warning:\ CDS\ is\ disabled\ when\ the\ \-\-limit\-modules\ option\ is\ specified. -\f[R] -.fi -.PP -Several other noteworthy things include: -.IP \[bu] 2 -Any valid combinations of \f[CB]\-cp\f[R] and \f[CB]\-\-module\-path\f[R] -are supported. -.IP \[bu] 2 -A non\-empty directory in the module path causes a fatal error. -The user will see the following error messages: -.RS 2 -.IP -.nf -\f[CB] -Error:\ non\-empty\ directory\ \ Hint:\ enable\ \-Xlog:class+path=info\ to\ diagnose\ the\ failure\ Error\ occurred\ during\ initialization\ of\ VM\ Cannot\ have\ non\-empty\ directory\ in\ paths -\f[R] -.fi -.RE +CDS archives can be created with several methods: .IP \[bu] 2 -Unlike the class path, there\[aq]s no restriction that the module path -at dump time must be equal to or be a prefix of the module path at run -time. +\f[CB]\-Xshare:dump\f[R] .IP \[bu] 2 -The archive is invalidated if an existing JAR in the module path is -updated after archive generation. +\f[CB]\-XX:ArchiveClassesAtExit\f[R] .IP \[bu] 2 -Removing a JAR from the module path does not invalidate the shared -archive. -Archived classes from the removed JAR are not used at runtime. -.SS Dynamic CDS archive -.PP -Dynamic CDS archive extends AppCDS to allow archiving of classes when a -Java application exits. -It improves the usability of AppCDS by eliminating the trial run step -for creating a class list for each application. -The archived classes include all loaded application classes and library -classes that are not present in the default CDS archive which is -included in the JDK. -.PP -A base archive is required when creating a dynamic archive. -If the base archive is not specified, the default CDS archive is used as -the base archive. +\f[CB]jcmd\ VM.cds\f[R] .PP -To create a dynamic CDS archive with the default CDS archive as the base -archive, just add the -\f[CB]\-XX:ArchiveClassesAtExit=\f[R] option to the -command line for running the Java application. +One common operation in all these methods is a "trial run", where you +run the application once to determine the classes that should be stored +in the archive. +.SS Creating a Static CDS Archive File with \-Xshare:dump .PP -If the default CDS archive does not exist, the VM will exit with the -following error: -.IP -.nf -\f[CB] -ArchiveClassesAtExit\ not\ supported\ when\ base\ CDS\ archive\ is\ not\ loaded -\f[R] -.fi -.PP -To run the Java application using a dynamic CDS archive, just add the -\f[CB]\-XX:SharedArchiveFile=\f[R] option to the command -line for running the Java application. -.PP -The base archive is not required to be specified in the command line. -The base archive information, including its name and full path, will be -retrieved from the dynamic archive header. -Note that the user could also use the \f[CB]\-XX:SharedArchiveFile\f[R] -option for specifying a regular AppCDS archive. -Therefore, the specified archive in the \f[CB]\-XX:SharedArchiveFile\f[R] -option could be either a regular or dynamic archive. -During VM start up the specified archive header will be read. -If \f[CB]\-XX:SharedArchiveFile\f[R] refers to a regular archive, then the -behavior will be unchanged. -If \f[CB]\-XX:SharedArchiveFile\f[R] refers to a dynamic archive, the VM -will retrieve the base archive location from the dynamic archive. -If the dynamic archive was created with the default CDS archive, then -the current default CDS archive will be used, and will be found relative -to the current run time environment. -.PP -Please refer to \f[B]JDK\-8221706\f[R] -[https://bugs.openjdk.java.net/browse/JDK\-8221706] for details on error -checking during dynamic CDS archive dump time and run time. -.SS Creating a Shared Archive File and Using It to Run an Application -.SS AppCDS archive -.PP -The following steps create a shared archive file that contains all the -classes used by the \f[CB]test.Hello\f[R] application. -The last step runs the application with the shared archive file. +The following steps create a static CDS archive file that contains all +the classes used by the \f[CB]test.Hello\f[R] application. .IP "1." 3 Create a list of all classes used by the \f[CB]test.Hello\f[R] application. @@ -5554,23 +5346,20 @@ contains a list of all classes used by this application: \f[CB]java\ \-Xshare:off\ \-XX:DumpLoadedClassList=hello.classlist\ \-cp\ hello.jar\ test.Hello\f[R] .RE .PP -Note that the classpath specified by the \f[CB]\-cp\f[R] parameter must -contain only JAR files. +The classpath specified by the \f[CB]\-cp\f[R] parameter must contain only +JAR files. .RE .IP "2." 3 -Create a shared archive, named \f[CB]hello.jsa\f[R], that contains all the +Create a static archive, named \f[CB]hello.jsa\f[R], that contains all the classes in \f[CB]hello.classlist\f[R]: .RS 4 .RS .PP \f[CB]java\ \-Xshare:dump\ \-XX:SharedArchiveFile=hello.jsa\ \-XX:SharedClassListFile=hello.classlist\ \-cp\ hello.jar\f[R] .RE -.PP -Note that the classpath used at archive creation time must be the same -as (or a prefix of) the classpath used at run time. .RE .IP "3." 3 -Run the application \f[CB]test.Hello\f[R] with the shared archive +Run the application \f[CB]test.Hello\f[R] with the archive \f[CB]hello.jsa\f[R]: .RS 4 .RS @@ -5584,23 +5373,27 @@ using the class contained in the \f[CB]hello.jsa\f[R] shared archive: .RS 4 .RS .PP -\f[CB]java\ \-XX:SharedArchiveFile=hello.jsa\ \-cp\ hello.jar\ \-verbose:class\ test.Hello\f[R] +\f[CB]java\ \-XX:SharedArchiveFile=hello.jsa\ \-cp\ hello.jar\ \-Xlog:class+load\ test.Hello\f[R] .RE .PP The output of this command should contain the following text: -.IP -.nf -\f[CB] -Loaded\ test.Hello\ from\ shared\ objects\ file\ by\ sun/misc/Launcher$AppClassLoader -\f[R] -.fi +.RS +.PP +\f[CB][info][class,load]\ test.Hello\ source:\ shared\ objects\ file\f[R] +.RE .RE -.SS Dynamic CDS archive +.SS Creating a Dynamic CDS Archive File with \-XX:SharedArchiveFile +.PP +Advantages of dynamic CDS archives are: +.IP \[bu] 2 +They usually use less disk space, since they don\[aq]t need to store the +classes that are already in the static archive. +.IP \[bu] 2 +They are created with one fewer step than the comparable static archive. .PP The following steps create a dynamic CDS archive file that contains the -classes used by the \f[CB]test.Hello\f[R] application and are not included -in the default CDS archive. -The second step runs the application with the dynamic CDS archive. +classes that are used by the \f[CB]test.Hello\f[R] application, excluding +those that are already in the default CDS archive. .IP "1." 3 Create a dynamic CDS archive, named \f[CB]hello.jsa\f[R], that contains all the classes in \f[CB]hello.jar\f[R] loaded by the application @@ -5610,9 +5403,6 @@ all the classes in \f[CB]hello.jar\f[R] loaded by the application .PP \f[CB]java\ \-XX:ArchiveClassesAtExit=hello.jsa\ \-cp\ hello.jar\ Hello\f[R] .RE -.PP -Note that the classpath used at archive creation time must be the same -as (or a prefix of) the classpath used at run time. .RE .IP "2." 3 Run the application \f[CB]test.Hello\f[R] with the shared archive @@ -5628,218 +5418,87 @@ Run the application \f[CB]test.Hello\f[R] with the shared archive the \f[CB]test.Hello\f[R] application is using the class contained in the \f[CB]hello.jsa\f[R] shared archive. .PP -To automate the above steps 1 and 2, one can write a script such as the -following: -.IP -.nf -\f[CB] -\ \ \ \ ARCHIVE=hello.jsa -\ \ \ \ if\ test\ \-f\ $ARCHIVE;\ then -\ \ \ \ \ \ \ \ FLAG="\-XX:SharedArchiveFile=$ARCHIVE" -\ \ \ \ else -\ \ \ \ \ \ \ \ FLAG="\-XX:ArchiveClassesAtExit=$ARCHIVE" -\ \ \ \ fi -\ \ \ \ $JAVA_HOME/bin/java\ \-cp\ hello.jar\ $FLAG\ test.Hello -\f[R] -.fi -.PP -Like an AppCDS archive, the archive needs to be re\-generated if the -Java version has changed. -The above script could be adjusted to account for the Java version as -follows: -.IP -.nf -\f[CB] -\ \ \ \ ARCHIVE=hello.jsa -\ \ \ \ VERSION=foo.version -\ \ \ \ if\ test\ \-f\ $ARCHIVE\ \-a\ \-f\ $VERSION\ &&\ cmp\ \-s\ $VERSION\ $JAVA_HOME/release;\ then -\ \ \ \ \ \ \ \ FLAG="\-XX:SharedArchiveFile=$ARCHIVE" -\ \ \ \ else -\ \ \ \ \ \ \ \ FLAG="\-XX:ArchiveClassesAtExit=$ARCHIVE" -\ \ \ \ \ \ \ \ cp\ \-f\ $JAVA_HOME/release\ $VERSION -\ \ \ \ fi -\ \ \ \ $JAVA_HOME/bin/java\ \-cp\ hello.jar\ $FLAG\ test.Hello -\f[R] -.fi -.PP -Currently, we don\[aq]t support concurrent dumping operations to the -same CDS archive. -Care should be taken to avoid multiple writers to the same CDS archive. -.PP -The user could also create a dynamic CDS archive with a specific base -archive, e.g. -named as \f[CB]base.jsa\f[R] as follows: +It\[aq]s also possible to create a dynamic CDS archive with a +non\-default static CDS archive. +E.g., .RS .PP \f[CB]java\ \-XX:SharedArchiveFile=base.jsa\ \-XX:ArchiveClassesAtExit=hello.jsa\ \-cp\ hello.jar\ Hello\f[R] .RE .PP -To run the application using the dynamic CDS archive \f[CB]hello.jsa\f[R] -and a specific base CDS archive \f[CB]base.jsa\f[R]: +To run the application using this dynamic CDS archive: .RS .PP \f[CB]java\ \-XX:SharedArchiveFile=base.jsa:hello.jsa\ \-cp\ hello.jar\ Hello\f[R] .RE .PP -Note that on Windows, the above path delimiter \f[CB]:\f[R] should be -replaced with \f[CB];\f[R]. -.PP -The above command for specifying a base archive is useful if the base -archive used for creating the dynamic archive has been moved. -Normally, just specifying the dynamic archive should be sufficient since -the base archive info can be retrieved from the dynamic archive header. -.SS Sharing a Shared Archive Across Multiple Application Processes -.PP -You can share the same archive file across multiple applications -processes. -This reduces memory usage because the archive is memory\-mapped into the -address space of the processes. -The operating system automatically shares the read\-only pages across -these processes. -.PP -The following steps demonstrate how to create a common archive that can -be shared by different applications. -Classes from \f[CB]common.jar\f[R], \f[CB]hello.jar\f[R] and \f[CB]hi.jar\f[R] -are archived in the \f[CB]common.jsa\f[R] because they are all in the -classpath during the archiving step (step 3). -.PP -To include classes from \f[CB]hello.jar\f[R] and \f[CB]hi.jar\f[R], the -\f[CB]\&.jar\f[R] files must be added to the classpath specified by the -\f[CB]\-cp\f[R] parameter. -.IP "1." 3 -Create a list of all classes used by the \f[CB]Hello\f[R] application and -another list for the \f[CB]Hi\f[R] application: -.RS 4 -.RS -.PP -\f[CB]java\ \-XX:DumpLoadedClassList=hello.classlist\ \-cp\ common.jar:hello.jar\ Hello\f[R] -.RE -.RS -.PP -\f[CB]java\ \-XX:DumpLoadedClassList=hi.classlist\ \-cp\ common.jar:hi.jar\ Hi\f[R] -.RE -.RE -.IP "2." 3 -Create a single list of classes used by all the applications that will -share the shared archive file. -.RS 4 +(On Windows, the above path delimiter \f[CB]:\f[R] should be replaced with +\f[CB];\f[R]) .PP -\f[B]Linux and macOS\f[R] The following commands combine the files -\f[CB]hello.classlist\f[R] and \f[CB]hi.classlist\f[R] into one file, -\f[CB]common.classlist\f[R]: +As mention above, the name of the static archive can be skipped: .RS .PP -\f[CB]cat\ hello.classlist\ hi.classlist\ >\ common.classlist\f[R] +\f[CB]java\ \-XX:SharedArchiveFile=hello.jsa\ \-cp\ hello.jar\ Hello\f[R] .RE +.SS Creating CDS Archive Files with jcmd .PP -\f[B]Windows\f[R] The following commands combine the files -\f[CB]hello.classlist\f[R] and \f[CB]hi.classlist\f[R] into one file, -\f[CB]common.classlist\f[R]: -.RS +The previous two sections require you to modify the application\[aq]s +start\-up script in order to create a CDS archive. +Sometimes this could be difficult, for example, if the application\[aq]s +class path is set up by complex routines. .PP -\f[CB]type\ hello.classlist\ hi.classlist\ >\ common.classlist\f[R] -.RE -.RE -.IP "3." 3 -Create a shared archive named \f[CB]common.jsa\f[R] that contains all the -classes in \f[CB]common.classlist\f[R]: -.RS 4 +The \f[CB]jcmd\ VM.cds\f[R] command provides a less intrusive way for +creating a CDS archive by connecting to a running JVM process. +You can create either a static: .RS .PP -\f[CB]java\ \-Xshare:dump\ \-XX:SharedArchiveFile=common.jsa\ \-XX:SharedClassListFile=common.classlist\ \-cp\ common.jar:hello.jar:hi.jar\f[R] +\f[CB]jcmd\ \ VM.cds\ static_dump\ my_static_archive.jsa\f[R] .RE .PP -The classpath parameter used is the common class path prefix shared by -the \f[CB]Hello\f[R] and \f[CB]Hi\f[R] applications. -.RE -.IP "4." 3 -Run the \f[CB]Hello\f[R] and \f[CB]Hi\f[R] applications with the same shared -archive: -.RS 4 -.RS -.PP -\f[CB]java\ \-XX:SharedArchiveFile=common.jsa\ \-cp\ common.jar:hello.jar:hi.jar\ Hello\f[R] -.RE +or a dynamic archive: .RS .PP -\f[CB]java\ \-XX:SharedArchiveFile=common.jsa\ \-cp\ common.jar:hello.jar:hi.jar\ Hi\f[R] -.RE +\f[CB]jcmd\ \ VM.cds\ dynamic_dump\ my_dynamic_archive.jsa\f[R] .RE -.SS Specifying Additional Shared Data Added to an Archive File .PP -The \f[CB]SharedArchiveConfigFile\f[R] option is used to specify -additional shared data to add to the archive file. +To use the resulting archive file in a subsequent run of the application +without modifying the application\[aq]s start\-up script, you can use +the following technique: .RS .PP -\f[CB]\-XX:SharedArchiveConfigFile=\f[R]\f[I]shared_config_file\f[R] +\f[CB]env\ JAVA_TOOL_OPTIONS=\-XX:SharedArchiveFile=my_static_archive.jsa\ bash\ app_start.sh\f[R] .RE .PP -JDK 9 and later supports adding both symbols and string objects to an -archive for memory sharing when you have multiple JVM processes running -on the same host. -An example of this is having multiple JVM processes that use the same -set of Java EE classes. -When these common classes are loaded and used, new symbols and strings -may be created and added to the JVM\[aq]s internal "symbol" and "string" -tables. -At runtime, the symbols or string objects mapped from the archive file -can be shared across multiple JVM processes, resulting in a reduction of -overall memory usage. -In addition, archiving strings also provides added performance benefits -in both startup time and runtime execution. -.PP -In JDK 10 and later, CONSTANT_String entries in archived classes are -resolved to interned String objects at dump time, and all interned -String objects are archived. -However, even though all CONSTANT_String literals in all archived -classes are resolved, it might still beneficial to add additional -strings that are not string literals in class files, but are likely to -be used by your application at run time. -.PP -Symbol data should be generated by the \f[CB]jcmd\f[R] tool attaching to a -running JVM process. -See \f[B]jcmd\f[R]. -.PP -The following is an example of the symbol dumping command in -\f[CB]jcmd\f[R]: +Note: to use \f[CB]jcmd\ \ VM.cds\ dynamic_dump\f[R], the JVM process +identified by \f[CB]\f[R] must be started with +\f[CB]\-XX:+RecordDynamicDumpInfo\f[R], which can also be passed to the +application start\-up script with the same technique: .RS .PP -\f[CB]jcmd\f[R] \f[I]pid\f[R] \f[CB]VM.symboltable\ \-verbose\f[R] +\f[CB]env\ JAVA_TOOL_OPTIONS=\-XX:+RecordDynamicDumpInfo\ bash\ app_start.sh\f[R] .RE -.RS -.PP -\f[B]Note:\f[R] The first line (process ID) and the second line -(\f[CB]\@VERSION\ ...\f[R]) of this \f[CB]jcmd\f[R] output should be -excluded from the configuration file. -.RE -.SS Example of a Configuration File -.PP -The following is an example of a configuration file: -.IP -.nf -\f[CB] -VERSION:\ 1.0 -\@SECTION:\ Symbol -10\ \-1:\ linkMethod -\f[R] -.fi -.PP -In the configuration file example, the \f[CB]\@SECTION:\ Symbol\f[R] entry -uses the following format: -.RS -.PP -\f[I]length\f[R] \f[I]refcount\f[R]\f[CB]:\f[R] \f[I]symbol\f[R] -.RE -.PP -The \f[I]refcount\f[R] for a shared symbol is always \f[CB]\-1\f[R]. -.PP -\f[CB]\@SECTION\f[R] specifies the type of the section that follows it. -All data within the section must be the same type that\[aq]s specified -by \f[CB]\@SECTION\f[R]. -Different types of data can\[aq]t be mixed. -Multiple separated data sections for the same type specified by -different \f[CB]\@SECTION\f[R] are allowed within one -\f[CB]shared_config_file\f[R] . +.SS Restrictions on Class Path and Module Path +.IP \[bu] 2 +Neither the class path (\f[CB]\-classpath\f[R] and +\f[CB]\-Xbootclasspath/a\f[R]) nor the module path +(\f[CB]\-\-module\-path\f[R]) can contain non\-empty directories. +.IP \[bu] 2 +Only modular JAR files are supported in \f[CB]\-\-module\-path\f[R]. +Exploded modules are not supported. +.IP \[bu] 2 +The class path used at archive creation time must be the same as (or a +prefix of) the class path used at run time. +(There\[aq]s no such requirement for the module path.) +.IP \[bu] 2 +The CDS archive cannot be loaded if any JAR files in the class path or +module path are modified after the archive is generated. +.IP \[bu] 2 +If any of the VM options \f[CB]\-\-upgrade\-module\-path\f[R], +\f[CB]\-\-patch\-module\f[R] or \f[CB]\-\-limit\-modules\f[R] are specified, +CDS is disabled. +This means that the JVM will execute without loading any CDS archives. +In addition, if you try to create a CDS archive with any of these 3 +options specified, the JVM will report an error. .SH PERFORMANCE TUNING EXAMPLES .PP You can use the Java advanced runtime options to optimize the diff --git a/src/jdk.jcmd/share/man/jcmd.1 b/src/jdk.jcmd/share/man/jcmd.1 index 65adf880911..9342943ac2a 100644 --- a/src/jdk.jcmd/share/man/jcmd.1 +++ b/src/jdk.jcmd/share/man/jcmd.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2012, 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 @@ -802,7 +802,8 @@ false) .RE .TP .B \f[CB]VM.cds\f[R] [\f[I]arguments\f[R]] -Dump a static or dynamic shared archive including all shareable classes. +Dumps a static or dynamic shared archive that includes all currently +loaded classes. .RS .PP Impact: Medium \-\-\- pause time depends on number of loaded classes @@ -811,11 +812,22 @@ Permission: \f[CB]java.lang.management.ManagementPermission(monitor)\f[R] .PP \f[I]arguments\f[R]: .IP \[bu] 2 -\f[CB]subcmd\f[R]: \f[CB]static_dump\f[R] | \f[CB]dynamic_dump\f[R] (STRING, -no default value) +\f[CB]subcmd\f[R]: must be either \f[CB]static_dump\f[R] or +\f[CB]dynamic_dump\f[R] (STRING, no default value) .IP \[bu] 2 \f[CB]filename\f[R]: (Optional) Name of the shared archive to be dumped (STRING, no default value) +.PP +If \f[CB]filename\f[R] is not specified, a default file name is chosen +using the pid of the target JVM process. +For example, java_pid1234_static.jsa, java_pid5678_dynamic.jsa, etc. +.PP +If \f[CB]filename\f[R] is not specified as an absolute path, the archive +file is created in a directory relative to the current directory of the +target JVM process. +.PP +If \f[CB]dynamic_dump\f[R] is specified, the target JVM must be started +with the JVM option \f[CB]\-XX:+RecordDynamicDumpInfo\f[R]. .RE .TP .B \f[CB]VM.classloaders\f[R] [\f[I]options\f[R]] -- GitLab From 74921e8422ce31a22516b279a00935b1917c089d Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 31 Jan 2022 22:45:16 +0000 Subject: [PATCH 090/400] 8280738: Minor cleanup for HtmlStyle Reviewed-by: hannesw --- .../formats/html/markup/HtmlStyle.java | 84 ++++++++++++------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java index ad74b81eee5..8301e9b9255 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyle.java @@ -48,20 +48,14 @@ import java.util.regex.Pattern; * or {@link javax.lang.model.element.Element "language model elements"}. * The usage is made explicit when it is not clear from the surrounding context. * + * @apiNote + * The stylized use of {@code editor-fold} comments and line comments (beginning {@code //}) + * is to support extracting details of declarations with external tools. Edit with care! + * * @see WhatWG: {@code class} attribute */ public enum HtmlStyle { - /** - * The class of the {@code div} element containing a snippet element. - */ - snippetContainer, - - /** - * The class of the {@code a} element to copy snippet content to the clipboard. - */ - snippetCopy, - // // // The following constants are used for the main navigation bar that appears in the @@ -324,17 +318,6 @@ public enum HtmlStyle { */ propertyDetails, - /** - * The class for the list containing the {@code @see} tags of an element. - */ - seeList, - - /** - * The class for the list containing the {@code @see} tags of an element - * when some of the tags have longer labels. - */ - seeListLong, - /** * The class for a {@code section} element containing details of the * serialized form of an element, on the "Serialized Form" page. @@ -391,6 +374,17 @@ public enum HtmlStyle { */ previewLabel, + /** + * The class for the list containing the {@code @see} tags of an element. + */ + seeList, + + /** + * The class for the list containing the {@code @see} tags of an element + * when some of the tags have longer labels. + */ + seeListLong, + // // @@ -844,6 +838,44 @@ public enum HtmlStyle { // + // + // + // The following constants are used for the contents of snippets. + // In addition, the translation of a snippet may use the class + // {@code language-LANG} where LANG is either specified explicitly + // by the "lang" attribute in a snippet tag, or can be inferred + // from the kind of an external snippet. + + /** + * The class of the {@code pre} element presenting a snippet. + */ + snippet, + + /** + * The class of the {@code div} element containing a snippet element. + */ + snippetContainer, + + /** + * The class of the UI element to copy snippet content to the clipboard. + */ + snippetCopy, + + /** + * The class of text highlighted with the type {@code bold}. + */ + bold, + + /** + * The class of text highlighted with the type {@code italic}. + */ + italic, + + /** + * The class of text highlighted with the type {@code highlighted}. + */ + highlighted, + // // // The following constants are used in various places across a variety of pages. @@ -908,7 +940,8 @@ public enum HtmlStyle { inheritedList, /** - * The class of an element that acts as a notification for an invalid tag. + * The class of an element that acts as a notification for an invalid tag + * or other invalid items. */ invalidTag, @@ -923,7 +956,7 @@ public enum HtmlStyle { memberNameLink, /** - * The class for a {@code dl} element containing serial UID information in + * The class of a {@code dl} element containing serial UID information in * the serialized form page. */ nameValue, @@ -964,11 +997,6 @@ public enum HtmlStyle { */ sourceLineNo, - /** - * The class of the {@code pre} element presenting a snippet. - */ - snippet, - /** * The class of an {@code a} element for a link to a class or interface. */ -- GitLab From ee3be0bb567f0e28fd3e920ef3685607d0a8d656 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 31 Jan 2022 22:47:46 +0000 Subject: [PATCH 091/400] 8280488: doclint reference checks withstand warning suppression Reviewed-by: darcy --- .../jdk/javadoc/internal/doclint/Checker.java | 25 +- .../jdk/javadoc/internal/doclint/DocLint.java | 18 ++ .../jdk/javadoc/internal/doclint/Env.java | 14 + .../doclint/resources/doclint.properties | 1 + .../tool/doclint/DocLintReferencesTest.java | 255 ++++++++++++++++++ 5 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 test/langtools/jdk/javadoc/tool/doclint/DocLintReferencesTest.java diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Checker.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Checker.java index abf8c698bba..446757513a1 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Checker.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Checker.java @@ -41,6 +41,7 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; @@ -952,11 +953,31 @@ public class Checker extends DocTreePathScanner { @Override @DefinedBy(Api.COMPILER_TREE) public Void visitReference(ReferenceTree tree, Void ignore) { Element e = env.trees.getElement(getCurrentPath()); - if (e == null) - env.messages.error(REFERENCE, tree, "dc.ref.not.found"); + if (e == null) { + reportBadReference(tree); + } return super.visitReference(tree, ignore); } + private void reportBadReference(ReferenceTree tree) { + if (!env.strictReferenceChecks) { + String refSig = tree.getSignature(); + int sep = refSig.indexOf("/"); + if (sep > 0) { + String moduleName = refSig.substring(0, sep); + if (SourceVersion.isName(moduleName)) { + Element m = env.elements.getModuleElement(moduleName); + if (m == null) { + env.messages.warning(REFERENCE, tree, "dc.ref.in.missing.module", moduleName); + return; + } + } + } + } + + env.messages.error(REFERENCE, tree, "dc.ref.not.found"); + } + @Override @DefinedBy(Api.COMPILER_TREE) public Void visitReturn(ReturnTree tree, Void ignore) { if (foundReturn) { diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/DocLint.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/DocLint.java index 1c4f3a3d650..9a1d0f2e4cc 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/DocLint.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/DocLint.java @@ -274,6 +274,14 @@ public class DocLint extends com.sun.tools.doclint.DocLint { // + /** + * Initialize DocLint for use with a {@code JavacTask}. + * {@link Env#strictReferenceChecks Strict reference checks} are not enabled by default. + * + * @param task the task + * @param args arguments to configure DocLint + * @param addTaskListener whether or not to register a {@code TaskListener} to invoke DocLint + */ public void init(JavacTask task, String[] args, boolean addTaskListener) { env = new Env(); env.init(task); @@ -319,9 +327,19 @@ public class DocLint extends com.sun.tools.doclint.DocLint { } } + /** + * Initialize DocLint with the given utility objects and arguments. + * {@link Env#strictReferenceChecks Strict reference checks} are enabled by default. + * + * @param trees the {@code DocTrees} utility class + * @param elements the {@code Elements} utility class + * @param types the {@code Types} utility class + * @param args arguments to configure DocLint + */ public void init(DocTrees trees, Elements elements, Types types, String... args) { env = new Env(); env.init(trees, elements, types); + env.strictReferenceChecks = true; processArgs(env, args); checker = new Checker(env); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Env.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Env.java index 01a0a867673..be13ca43fd1 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Env.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Env.java @@ -108,6 +108,20 @@ public class Env { Set includePackages; Set excludePackages; + /** + * How to handle bad references. + * + * If {@code false}, a reference into a module that is not + * in the module graph will just be reported as a warning. + * All other bad references will be reported as errors. + * This is the desired behavior for javac. + * + * If {@code true}, all bad references will be reported as + * errors. This is the desired behavior for javadoc. + * + */ + boolean strictReferenceChecks = false; + // Utility classes DocTrees trees; Elements elements; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/resources/doclint.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/resources/doclint.properties index 091316f0e29..fbcb2c00881 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/resources/doclint.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/resources/doclint.properties @@ -61,6 +61,7 @@ dc.no.alt.attr.for.image = no "alt" attribute for image dc.no.summary.or.caption.for.table=no caption for table dc.param.name.not.found = @param name not found dc.ref.not.found = reference not found +dc.ref.in.missing.module = module for reference not found: {0} dc.return.not.first = '{@return} not at beginning of description dc.service.not.found = service-type not found dc.tag.code.within.code = '{@code} within diff --git a/test/langtools/jdk/javadoc/tool/doclint/DocLintReferencesTest.java b/test/langtools/jdk/javadoc/tool/doclint/DocLintReferencesTest.java new file mode 100644 index 00000000000..ee316135e37 --- /dev/null +++ b/test/langtools/jdk/javadoc/tool/doclint/DocLintReferencesTest.java @@ -0,0 +1,255 @@ +/* + * 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. + * + * 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 8280688 + * @summary doclint reference checks withstand warning suppression + * @library /tools/lib ../../lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * jdk.javadoc/jdk.javadoc.internal.api + * jdk.javadoc/jdk.javadoc.internal.tool + * @build toolbox.JavacTask toolbox.JavadocTask toolbox.TestRunner toolbox.ToolBox + * @run main DocLintReferencesTest + */ + +import toolbox.JavacTask; +import toolbox.JavadocTask; +import toolbox.Task; +import toolbox.TestRunner; +import toolbox.ToolBox; + +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * Combo test for how javac and javadoc handle {@code @see MODULE/TYPE} + * for different combinations of MODULE and TYPE, with and without + * {@code @SuppressWarnings("doclint") }. + * + * Generally, in javac, references to unknown elements are reported + * as suppressible warnings if the module is not resolved in the module graph. + * Otherwise, in both javac and javadoc, any issues with references + * are reported as errors. + * + * This allows references to other modules to appear in documentation comments + * without causing a hard error if the modules are not available at compile-time. + */ +public class DocLintReferencesTest extends TestRunner { + + public static void main(String... args) throws Exception { + DocLintReferencesTest t = new DocLintReferencesTest(); + t.runTests(); + } + + DocLintReferencesTest() { + super(System.err); + } + + private final ToolBox tb = new ToolBox(); + + enum SuppressKind { NO, YES } + enum ModuleKind { NONE, BAD, NOT_FOUND, GOOD } + enum TypeKind { NONE, BAD, NOT_FOUND, GOOD } + + @Test + public void comboTest () { + for (SuppressKind sk : SuppressKind.values() ) { + for (ModuleKind mk : ModuleKind.values() ) { + for (TypeKind tk: TypeKind.values() ) { + if (mk == ModuleKind.NONE && tk == TypeKind.NONE) { + continue; + } + + try { + test(sk, mk, tk); + } catch (Throwable e) { + error("Exception " + e); + } + } + } + } + } + + void test(SuppressKind sk, ModuleKind mk, TypeKind tk) throws Exception { + out.println(); + out.println("*** Test SuppressKind:" + sk + " ModuleKind: " + mk + " TypeKind: " + tk); + Path base = Path.of(sk + "-" + mk + "-" + tk); + + String sw = switch (sk) { + case NO -> ""; + case YES -> "@SuppressWarnings(\"doclint\")"; + }; + String m = switch (mk) { + case NONE -> ""; + case BAD -> "bad-name/"; + case NOT_FOUND -> "not.found/"; + case GOOD -> "java.base/"; + }; + String t = switch (tk) { + case NONE -> ""; + case BAD -> "bad-name"; + case NOT_FOUND -> "java.lang.NotFound"; + case GOOD -> "java.lang.Object"; + }; + + Path src = base.resolve("src"); + tb.writeJavaFiles(src, """ + package p; + /** + * Comment. + * @see #M##T# + */ + #SW# + public class C { + private C() { } + } + """ + .replace("#M#", m) + .replace("#T#", t) + .replace("#SW#", sw)); + + testJavac(sk, mk, tk, base, src); + testJavadoc(sk, mk, tk, base, src); + } + + void testJavac(SuppressKind sk, ModuleKind mk, TypeKind tk, Path base, Path src) throws Exception { + Files.createDirectories(base.resolve("classes")); + + out.println("javac:"); + try { + String s = predictOutput(sk, mk, tk, false); + Task.Expect e = s.isEmpty() ? Task.Expect.SUCCESS : Task.Expect.FAIL; + + String o = new JavacTask(tb) + .outdir(base.resolve("classes")) + .options("-Xdoclint:all/protected", "-Werror") + .files(tb.findJavaFiles(src)) + .run(e) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutput(s, o); + + } catch (Throwable t) { + error("Error: " + t); + } + out.println(); + } + + void testJavadoc(SuppressKind sk, ModuleKind mk, TypeKind tk, Path base, Path src) throws Exception { + Files.createDirectories(base.resolve("api")); + + out.println("javadoc:"); + try { + String s = predictOutput(sk, mk, tk, true); + Task.Expect e = s.isEmpty() ? Task.Expect.SUCCESS : Task.Expect.FAIL; + + String o = new JavadocTask(tb) + .outdir(base.resolve("api")) + .options("-Xdoclint", "-Werror", "-quiet", "-sourcepath", src.toString(), "p") + .run(e) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + checkOutput(s, o); + + } catch (Throwable t) { + error("Error: " + t); + } + out.println(); + } + + private static final String ERROR_UNEXPECTED_TEXT = "error: unexpected text"; + private static final String ERROR_REFERENCE_NOT_FOUND = "error: reference not found"; + private static final String WARNING_MODULE_FOR_REFERENCE_NOT_FOUND = "warning: module for reference not found: not.found"; + private static final String EMPTY = ""; + + /** + * Returns the expected diagnostic, if any, based on the parameters of the test case. + * + * The "interesting" cases are those for which the module name is not found, + * in which case an error for "reference not found" is reduced to warning, + * which may be suppressed. + * + * @param sk whether @SuppressWarnings is present of not + * @param mk the kind of module in the reference + * @param tk the kind of class or interface name in the reference + * @param strict whether all "not found" references are errors, + * or just warnings if the module name is not found + * @return a diagnostic string, or an empty string if no diagnostic should be generated + */ + String predictOutput(SuppressKind sk, ModuleKind mk, TypeKind tk, boolean strict) { + return switch (mk) { + case NONE -> switch(tk) { + case NONE -> throw new Error("should not happen"); // filtered out in combo loops + case BAD -> ERROR_UNEXPECTED_TEXT; + case NOT_FOUND -> ERROR_REFERENCE_NOT_FOUND; + case GOOD -> EMPTY; + }; + + case BAD -> ERROR_UNEXPECTED_TEXT; + + case NOT_FOUND -> switch(tk) { + case BAD -> ERROR_UNEXPECTED_TEXT; + case NONE, NOT_FOUND, GOOD -> strict + ? ERROR_REFERENCE_NOT_FOUND + : sk == SuppressKind.YES + ? EMPTY + : WARNING_MODULE_FOR_REFERENCE_NOT_FOUND; + }; + + case GOOD -> switch(tk) { + case BAD -> ERROR_UNEXPECTED_TEXT; + case NOT_FOUND -> ERROR_REFERENCE_NOT_FOUND; + case GOOD, NONE -> EMPTY; + }; + }; + } + + /** + * Checks the actual output against the expected string, generated by {@code predictError}. + * If the expected string is empty, the output should be empty. + * If the expected string is not empty, it should be present in the output. + * + * @param expect the expected string + * @param found the output + */ + void checkOutput(String expect, String found) { + if (expect.isEmpty()) { + if (found.isEmpty()) { + out.println("Output OK"); + } else { + error("unexpected output"); + } + } else { + if (found.contains(expect)) { + out.println("Output OK"); + } else { + error("expected output not found: " + expect); + } + } + + } +} -- GitLab From 96d0df72db277f127bd4c6b8c51bfc64d1c593e0 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 31 Jan 2022 22:54:18 +0000 Subject: [PATCH 092/400] 8272984: javadoc support for reproducible builds Reviewed-by: hannesw --- .../formats/html/HtmlConfiguration.java | 21 ++- .../formats/html/HtmlDocletWriter.java | 4 +- .../formats/html/IndexRedirectWriter.java | 4 +- .../formats/html/SourceToHTMLConverter.java | 4 +- .../doclets/formats/html/markup/Head.java | 19 ++- .../html/resources/standard.properties | 14 +- .../internal/doclets/toolkit/BaseOptions.java | 54 ++++++- .../doclet/testDateOption/TestDateOption.java | 147 ++++++++++++++++++ .../doclet/testXOption/TestXOption.java | 5 +- .../jdk/javadoc/tool/CheckManPageOptions.java | 4 +- 10 files changed, 255 insertions(+), 21 deletions(-) create mode 100644 test/langtools/jdk/javadoc/doclet/testDateOption/TestDateOption.java diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java index 100ad33940b..a11ad5db044 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -25,6 +25,7 @@ package jdk.javadoc.internal.doclets.formats.html; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Date; import java.util.EnumSet; @@ -166,6 +167,11 @@ public class HtmlConfiguration extends BaseConfiguration { */ public final Set conditionalPages; + /** + * The build date, to be recorded in generated files. + */ + private ZonedDateTime buildDate; + /** * Constructs the full configuration needed by the doclet, including * the format-specific part, defined in this class, and the format-independent @@ -215,6 +221,7 @@ public class HtmlConfiguration extends BaseConfiguration { conditionalPages = EnumSet.noneOf(ConditionalPage.class); } + protected void initConfiguration(DocletEnvironment docEnv, Function resourceKeyMapper) { super.initConfiguration(docEnv, resourceKeyMapper); @@ -223,7 +230,6 @@ public class HtmlConfiguration extends BaseConfiguration { } private final Runtime.Version docletVersion; - public final Date startTime = new Date(); @Override public Runtime.Version getDocletVersion() { @@ -259,6 +265,10 @@ public class HtmlConfiguration extends BaseConfiguration { if (!options.validateOptions()) { return false; } + + ZonedDateTime zdt = options.date(); + buildDate = zdt != null ? zdt : ZonedDateTime.now(); + if (!getSpecifiedTypeElements().isEmpty()) { Map map = new HashMap<>(); PackageElement pkg; @@ -279,6 +289,13 @@ public class HtmlConfiguration extends BaseConfiguration { return true; } + /** + * {@return the date to be recorded in generated files} + */ + public ZonedDateTime getBuildDate() { + return buildDate; + } + /** * Decide the page which will appear first in the right-hand frame. It will * be "overview-summary.html" if "-overview" option is used or no diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java index 7efa7b85992..8934d547213 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -453,7 +453,7 @@ public class HtmlDocletWriter { throws DocFileIOException { List additionalStylesheets = configuration.getAdditionalStylesheets(); additionalStylesheets.addAll(localStylesheets); - Head head = new Head(path, configuration.getDocletVersion(), configuration.startTime) + Head head = new Head(path, configuration.getDocletVersion(), configuration.getBuildDate()) .setTimestamp(!options.noTimestamp()) .setDescription(description) .setGenerator(getGenerator(getClass())) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java index 3e169dab6f0..299e565a657 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/IndexRedirectWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -74,7 +74,7 @@ public class IndexRedirectWriter extends HtmlDocletWriter { * @throws DocFileIOException if there is a problem generating the file */ private void generateIndexFile() throws DocFileIOException { - Head head = new Head(path, configuration.getDocletVersion(), configuration.startTime) + Head head = new Head(path, configuration.getDocletVersion(), configuration.getBuildDate()) .setTimestamp(!options.noTimestamp()) .setDescription("index redirect") .setGenerator(getGenerator(getClass())) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java index 7bc1f96b648..4efa6a70d22 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -232,7 +232,7 @@ public class SourceToHTMLConverter { * @param path the path for the file. */ private void writeToFile(Content body, DocPath path, TypeElement te) throws DocFileIOException { - Head head = new Head(path, configuration.getDocletVersion(), configuration.startTime) + Head head = new Head(path, configuration.getDocletVersion(), configuration.getBuildDate()) // .setTimestamp(!options.notimestamp) // temporary: compatibility! .setTitle(resources.getText("doclet.Window_Source_title")) // .setCharset(options.charset) // temporary: compatibility! diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java index 975154b7d1d..adbd5ef09fd 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/Head.java @@ -27,12 +27,14 @@ package jdk.javadoc.internal.doclets.formats.html.markup; import java.io.IOException; import java.io.Writer; -import java.text.SimpleDateFormat; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Locale; import jdk.javadoc.internal.doclets.toolkit.Content; import jdk.javadoc.internal.doclets.toolkit.util.DocPath; @@ -50,7 +52,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; */ public class Head extends Content { private final Runtime.Version docletVersion; - private final Date generatedDate; + private final ZonedDateTime generatedDate; private final DocPath pathToRoot; private String title; private String charset; @@ -78,7 +80,7 @@ public class Head extends Content { * @param path the path for the file that will include this HEAD element * @param docletVersion the doclet version */ - public Head(DocPath path, Runtime.Version docletVersion, Date generatedDate) { + public Head(DocPath path, Runtime.Version docletVersion, ZonedDateTime generatedDate) { this.docletVersion = docletVersion; this.generatedDate = generatedDate; pathToRoot = path.parent().invert(); @@ -279,8 +281,8 @@ public class Head extends Content { } if (showTimestamp) { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - tree.add(HtmlTree.META("dc.created", dateFormat.format(generatedDate))); + DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + tree.add(HtmlTree.META("dc.created", generatedDate.format(dateFormat))); } if (description != null) { @@ -309,11 +311,14 @@ public class Head extends Content { return tree; } - private Comment getGeneratedBy(boolean timestamp, Date now) { + + private Comment getGeneratedBy(boolean timestamp, ZonedDateTime buildDate) { String text = "Generated by javadoc"; // marker string, deliberately not localized text += " (" + docletVersion.feature() + ")"; if (timestamp) { - text += " on " + now; + DateTimeFormatter fmt = + DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy").withLocale(Locale.US); + text += " on " + buildDate.format(fmt); } return new Comment(text); } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties index 8a511b8ca4f..285acb051fd 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 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 @@ -169,6 +169,12 @@ doclet.systemPropertiesSummary=System Properties Summary doclet.Window_Source_title=Source code doclet.Window_Help_title=API Help +# 0: a date +doclet.Option_date_out_of_range=value for ''--date'' out of range: {0} + +# 0: a date +doclet.Option_date_not_valid=value for ''--date'' not valid: {0} + doclet.help.main_heading=\ JavaDoc Help doclet.help.navigation.head=\ @@ -420,6 +426,12 @@ doclet.usage.windowtitle.parameters=\ doclet.usage.windowtitle.description=\ Browser window title for the documentation +doclet.usage.date.parameters=\ + +doclet.usage.date.description=\ + Specifies the value to be used to timestamp the generated\n\ + pages, in ISO 8601 format + doclet.usage.doctitle.parameters=\ doclet.usage.doctitle.description=\ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseOptions.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseOptions.java index 6445f4fc6a0..42110c4aa70 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseOptions.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/BaseOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -30,8 +30,16 @@ import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalUnit; import java.util.ArrayList; import java.util.Arrays; +import java.util.Calendar; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; @@ -82,6 +90,12 @@ public abstract class BaseOptions { */ private final LinkedHashSet> customTagStrs = new LinkedHashSet<>(); + /** + * Argument for command-line option {@code --date}. + * {@code null} if option not given. + */ + private ZonedDateTime date; + /** * Argument for command-line option {@code -d}. * Destination directory name, in which doclet will generate the entire @@ -338,6 +352,33 @@ public abstract class BaseOptions { } }, + new XOption(resources, "--date", 1) { + // Valid --date range: within ten years of now + private static final ZonedDateTime now = ZonedDateTime.now(); + static final ZonedDateTime DATE_MIN = now.minusYears(10); + static final ZonedDateTime DATE_MAX = now.plusYears(10); + + @Override + public boolean process(String opt, List args) { + if (noTimestamp) { + messages.error("doclet.Option_conflict", "--date", "-notimestamp"); + return false; + } + String arg = args.get(0); + try { + date = ZonedDateTime.parse(arg, DateTimeFormatter.ISO_ZONED_DATE_TIME); + if (date.isBefore(DATE_MIN) || date.isAfter(DATE_MAX)) { + messages.error("doclet.Option_date_out_of_range", arg); + return false; + } + return true; + } catch (DateTimeParseException x) { + messages.error("doclet.Option_date_not_valid", arg); + return false; + } + } + }, + new Option(resources, "-docencoding", 1) { @Override public boolean process(String opt, List args) { @@ -471,6 +512,10 @@ public abstract class BaseOptions { @Override public boolean process(String opt, List args) { noTimestamp = true; + if (date != null) { + messages.error("doclet.Option_conflict", "--date", "-notimestamp"); + return false; + } return true; } }, @@ -739,6 +784,13 @@ public abstract class BaseOptions { return customTagStrs; } + /** + * Argument for command-line option {@code --date}. + */ + public ZonedDateTime date() { + return date; + } + /** * Argument for command-line option {@code -d}. * Destination directory name, in which doclet will generate the entire diff --git a/test/langtools/jdk/javadoc/doclet/testDateOption/TestDateOption.java b/test/langtools/jdk/javadoc/doclet/testDateOption/TestDateOption.java new file mode 100644 index 00000000000..411e37efab9 --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testDateOption/TestDateOption.java @@ -0,0 +1,147 @@ +/* + * 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. + * + * 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 8272984 + * @summary javadoc support for SOURCE_DATE_EPOCH + * @library /tools/lib ../../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build toolbox.ToolBox javadoc.tester.* + * @run main TestDateOption + */ + +import java.nio.file.Path; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.Locale; + +import javadoc.tester.JavadocTester; +import toolbox.ToolBox; + +public class TestDateOption extends JavadocTester { + + /** + * The entry point of the test. + * + * @param args the array of command line arguments + * @throws Exception if the test fails + */ + public static void main(String... args) throws Exception { + TestDateOption tester = new TestDateOption(); + tester.runTests(m -> new Object[] { Path.of(m.getName()) }); + } + + ToolBox tb = new ToolBox(); + + @Test + public void testDateOption(Path base) throws Exception { + + ZonedDateTime zdt = ZonedDateTime.now(); // uses current date, time, timezone etc + // adjust the calendar to some date before the default used by javadoc (i.e. today/now) + // set a specific time, such as 10 to 3. (Rupert Brooke, Grantchester) + ZonedDateTime testDate = zdt.minusDays(100) + .withHour(14) + .withMinute(50) + .withSecond(0); + + out.println("Test Date: '" + testDate + "'"); + + Path srcDir = base.resolve("src"); + tb.writeJavaFiles(srcDir, """ + package p; + /** Comment. */ + public interface I { } + """); + Path outDir = base.resolve("out"); + + javadoc("-d", outDir.toString(), + "-sourcepath", srcDir.toString(), + "--date", testDate.toString(), + "p"); + checkExit(Exit.OK); + + int featureVersion = Runtime.version().feature(); + + // The following format is as used by javadoc; it is the historical format used by Date.toString() + DateTimeFormatter fmt = + DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy").withLocale(Locale.US); + String generatedByStamp = testDate.format(fmt); + String generatedBy = String.format("", + featureVersion, generatedByStamp); + + DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String dcCreatedStamp = testDate.format(dateFormat); + String dcCreated = String.format(""" + """, + dcCreatedStamp); + + // check the timestamps in all generated HTML files + for (Path file : tb.findFiles(".html", outputDir)) { + checkOutput(outputDir.relativize(file).toString(), true, + generatedBy, + dcCreated); + } + } + + @Test + public void testBadDateOption(Path base) throws Exception { + Path srcDir = base.resolve("src"); + tb.writeJavaFiles(srcDir, """ + package p; + /** Comment. */ + public interface I { } + """); + Path outDir = base.resolve("out"); + + javadoc("-d", outDir.toString(), + "-sourcepath", srcDir.toString(), + "--date", "NOT A DATE", + "p"); + checkExit(Exit.CMDERR); + + checkOutput(Output.OUT, true, + "error: value for '--date' not valid: NOT A DATE"); + } + + @Test + public void testInvalidDateOption(Path base) throws Exception { + Path srcDir = base.resolve("src"); + tb.writeJavaFiles(srcDir, """ + package p; + /** Comment. */ + public interface I { } + """); + Path outDir = base.resolve("out"); + + javadoc("-d", outDir.toString(), + "-sourcepath", srcDir.toString(), + "--date", new Date(0).toInstant().toString(), + "p"); + checkExit(Exit.CMDERR); + + checkOutput(Output.OUT, true, + "error: value for '--date' out of range: 1970-01-01T00:00:00Z"); + } +} \ No newline at end of file diff --git a/test/langtools/jdk/javadoc/doclet/testXOption/TestXOption.java b/test/langtools/jdk/javadoc/doclet/testXOption/TestXOption.java index 7d00116fccc..3c65066419c 100644 --- a/test/langtools/jdk/javadoc/doclet/testXOption/TestXOption.java +++ b/test/langtools/jdk/javadoc/doclet/testXOption/TestXOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -98,6 +98,7 @@ public class TestXOption extends JavadocTester { "-Xmaxwarns ", "-Xdocrootparent ", "-Xdoclint ", - "-Xdoclint:"); + "-Xdoclint:", + "--date "); } } diff --git a/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java b/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java index a5b853c7aa4..6d49b54559e 100644 --- a/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java +++ b/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -66,7 +66,7 @@ public class CheckManPageOptions { static final PrintStream out = System.err; - List MISSING_IN_MAN_PAGE = List.of(); + List MISSING_IN_MAN_PAGE = List.of("--date"); void run(String... args) throws Exception { var file = args.length == 0 ? findDefaultFile() : Path.of(args[0]); -- GitLab From 4191b2b9b98c1137e5f27e3b64efb83857fa2c91 Mon Sep 17 00:00:00 2001 From: Igor Veresov Date: Mon, 31 Jan 2022 23:02:34 +0000 Subject: [PATCH 093/400] 8275337: C1: assert(false) failed: live_in set of first block must be empty Reviewed-by: kvn --- .../share/c1/c1_RangeCheckElimination.cpp | 7 +- .../jtreg/compiler/c1/Test8275337.java | 65 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/compiler/c1/Test8275337.java diff --git a/src/hotspot/share/c1/c1_RangeCheckElimination.cpp b/src/hotspot/share/c1/c1_RangeCheckElimination.cpp index fc5df4a4201..f5275eb9d5c 100644 --- a/src/hotspot/share/c1/c1_RangeCheckElimination.cpp +++ b/src/hotspot/share/c1/c1_RangeCheckElimination.cpp @@ -365,7 +365,12 @@ void RangeCheckEliminator::update_bound(IntegerStack &pushed, Value v, Instructi bool RangeCheckEliminator::loop_invariant(BlockBegin *loop_header, Instruction *instruction) { assert(loop_header, "Loop header must not be null!"); if (!instruction) return true; - return instruction->dominator_depth() < loop_header->dominator_depth(); + for (BlockBegin *d = loop_header->dominator(); d != NULL; d = d->dominator()) { + if (d == instruction->block()) { + return true; + } + } + return false; } // Update bound. Pushes a new bound onto the stack. Tries to do a conjunction with the current bound. diff --git a/test/hotspot/jtreg/compiler/c1/Test8275337.java b/test/hotspot/jtreg/compiler/c1/Test8275337.java new file mode 100644 index 00000000000..5e7ab912e20 --- /dev/null +++ b/test/hotspot/jtreg/compiler/c1/Test8275337.java @@ -0,0 +1,65 @@ +/* + * 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. + * + * 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 8275337 + * @run main/othervm -Xcomp -XX:TieredStopAtLevel=1 compiler.c1.Test8275337 + */ + + +package compiler.c1; + +public class Test8275337 { + public static final int N = 400; + + public static void mainTest() { + int iArr1[] = new int[N]; + float fArr1[][] = new float[N][N]; + + for (int i = 9; i < 171; i++) { + int z; + try { + z = i % i; + } catch (ArithmeticException a_e) {} + for (int j = 1; j < 155; ++j) { + fArr1[j - 1][i] -= 1; + iArr1[i - 1] = 1; + } + for (int j = 4; j < 155; j++) { + for (int k = 1; k < 2; ++k) { + iArr1[i - 1] += 1; + fArr1[k - 1][j] -= 2; + } + } + } + } + public static void main(String[] strArr) { + + try { + for (int i = 0; i < 10; i++) { + mainTest(); + } + } catch (Exception ex) { + } + } +} -- GitLab From 4dbebb62aa264adda8d96a06f608ef9d13155a26 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Mon, 31 Jan 2022 23:22:38 +0000 Subject: [PATCH 094/400] 8280534: Enable compile-time doclint reference checking Reviewed-by: serb, naoto, mchung, lancea, iris --- make/modules/java.base/Java.gmk | 2 +- make/modules/java.datatransfer/Java.gmk | 2 +- make/modules/java.logging/Java.gmk | 2 +- make/modules/java.management/Java.gmk | 2 +- src/java.base/share/classes/java/io/FilenameFilter.java | 1 + src/java.base/share/classes/java/lang/Character.java | 4 ++++ src/java.base/share/classes/java/lang/System.java | 2 ++ .../share/classes/java/lang/invoke/MethodHandleProxies.java | 3 ++- .../share/classes/java/lang/invoke/MethodHandles.java | 1 + src/java.base/share/classes/java/net/package-info.java | 1 + .../share/classes/java/text/AttributedCharacterIterator.java | 2 +- src/java.base/share/classes/java/text/Bidi.java | 1 + src/java.base/share/classes/java/util/Observable.java | 1 + src/java.base/share/classes/java/util/ServiceLoader.java | 1 + .../share/classes/java/awt/datatransfer/Clipboard.java | 1 + .../share/classes/java/util/logging/LogManager.java | 2 ++ .../share/classes/java/util/logging/LoggingMXBean.java | 1 + .../share/classes/java/lang/management/ManagementFactory.java | 3 ++- .../classes/java/lang/management/PlatformLoggingMXBean.java | 1 + .../share/classes/javax/management/remote/JMXAddressable.java | 1 + .../javax/management/remote/JMXServerErrorException.java | 1 + 21 files changed, 28 insertions(+), 7 deletions(-) diff --git a/make/modules/java.base/Java.gmk b/make/modules/java.base/Java.gmk index b5bd86ada54..25c14d2b1d2 100644 --- a/make/modules/java.base/Java.gmk +++ b/make/modules/java.base/Java.gmk @@ -23,7 +23,7 @@ # questions. # -DOCLINT += -Xdoclint:all/protected,-reference \ +DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' JAVAC_FLAGS += -XDstringConcat=inline COPY += .icu .dat .spp .nrm content-types.properties \ diff --git a/make/modules/java.datatransfer/Java.gmk b/make/modules/java.datatransfer/Java.gmk index a9f7c8f4f0a..29feb6df9f5 100644 --- a/make/modules/java.datatransfer/Java.gmk +++ b/make/modules/java.datatransfer/Java.gmk @@ -23,6 +23,6 @@ # questions. # -DOCLINT += -Xdoclint:all/protected,-reference \ +DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' COPY += flavormap.properties diff --git a/make/modules/java.logging/Java.gmk b/make/modules/java.logging/Java.gmk index a6641fc1485..f49e425718e 100644 --- a/make/modules/java.logging/Java.gmk +++ b/make/modules/java.logging/Java.gmk @@ -23,5 +23,5 @@ # questions. # -DOCLINT += -Xdoclint:all/protected,-reference \ +DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' diff --git a/make/modules/java.management/Java.gmk b/make/modules/java.management/Java.gmk index a6641fc1485..f49e425718e 100644 --- a/make/modules/java.management/Java.gmk +++ b/make/modules/java.management/Java.gmk @@ -23,5 +23,5 @@ # questions. # -DOCLINT += -Xdoclint:all/protected,-reference \ +DOCLINT += -Xdoclint:all/protected \ '-Xdoclint/package:java.*,javax.*' diff --git a/src/java.base/share/classes/java/io/FilenameFilter.java b/src/java.base/share/classes/java/io/FilenameFilter.java index 019ffb11771..43e041d546d 100644 --- a/src/java.base/share/classes/java/io/FilenameFilter.java +++ b/src/java.base/share/classes/java/io/FilenameFilter.java @@ -39,6 +39,7 @@ package java.io; * @see java.io.File#list(java.io.FilenameFilter) * @since 1.0 */ +@SuppressWarnings("doclint:reference") // cross-module links @FunctionalInterface public interface FilenameFilter { /** diff --git a/src/java.base/share/classes/java/lang/Character.java b/src/java.base/share/classes/java/lang/Character.java index 0fdd23997cc..92e9b5b43f5 100644 --- a/src/java.base/share/classes/java/lang/Character.java +++ b/src/java.base/share/classes/java/lang/Character.java @@ -10305,6 +10305,7 @@ class Character implements java.io.Serializable, Comparable, Constabl * @see java.compiler/javax.lang.model.SourceVersion#isIdentifier(CharSequence) * @since 1.1 */ + @SuppressWarnings("doclint:reference") // cross-module links public static boolean isJavaIdentifierStart(char ch) { return isJavaIdentifierStart((int)ch); } @@ -10334,6 +10335,7 @@ class Character implements java.io.Serializable, Comparable, Constabl * @see java.compiler/javax.lang.model.SourceVersion#isIdentifier(CharSequence) * @since 1.5 */ + @SuppressWarnings("doclint:reference") // cross-module links public static boolean isJavaIdentifierStart(int codePoint) { return CharacterData.of(codePoint).isJavaIdentifierStart(codePoint); } @@ -10371,6 +10373,7 @@ class Character implements java.io.Serializable, Comparable, Constabl * @see java.compiler/javax.lang.model.SourceVersion#isIdentifier(CharSequence) * @since 1.1 */ + @SuppressWarnings("doclint:reference") // cross-module links public static boolean isJavaIdentifierPart(char ch) { return isJavaIdentifierPart((int)ch); } @@ -10404,6 +10407,7 @@ class Character implements java.io.Serializable, Comparable, Constabl * @see java.compiler/javax.lang.model.SourceVersion#isIdentifier(CharSequence) * @since 1.5 */ + @SuppressWarnings("doclint:reference") // cross-module links public static boolean isJavaIdentifierPart(int codePoint) { return CharacterData.of(codePoint).isJavaIdentifierPart(codePoint); } diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index 2f9c205a327..96b32ecabb6 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -1240,6 +1240,7 @@ public final class System { * @see java.lang.System.LoggerFinder * @see java.lang.System.Logger */ + @SuppressWarnings("doclint:reference") // cross-module links public enum Level { // for convenience, we're reusing java.util.logging.Level int values @@ -1600,6 +1601,7 @@ public final class System { * * @since 9 */ + @SuppressWarnings("doclint:reference") // cross-module links public abstract static class LoggerFinder { /** * The {@code RuntimePermission("loggerFinder")} is diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java index b2e93afea12..69d975a7289 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java @@ -154,7 +154,8 @@ public class MethodHandleProxies { // entry points, must be covered by hand-written or automatically // generated adapter classes. // - @SuppressWarnings("removal") + @SuppressWarnings({"removal", + "doclint:reference"}) // cross-module links @CallerSensitive public static T asInterfaceInstance(final Class intfc, final MethodHandle target) { if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers())) diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index 908c277fa86..b7d5bde0aeb 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -2105,6 +2105,7 @@ public class MethodHandles { * @jvms 5.5 Initialization * @jls 12.7 Unloading of Classes and Interfaces */ + @SuppressWarnings("doclint:reference") // cross-module links public Lookup defineHiddenClass(byte[] bytes, boolean initialize, ClassOption... options) throws IllegalAccessException { diff --git a/src/java.base/share/classes/java/net/package-info.java b/src/java.base/share/classes/java/net/package-info.java index e0325f6a0f1..6fc9913dfed 100644 --- a/src/java.base/share/classes/java/net/package-info.java +++ b/src/java.base/share/classes/java/net/package-info.java @@ -157,4 +157,5 @@ * * @since 1.0 */ +@SuppressWarnings("doclint:reference") // cross-module links package java.net; diff --git a/src/java.base/share/classes/java/text/AttributedCharacterIterator.java b/src/java.base/share/classes/java/text/AttributedCharacterIterator.java index a77417462a7..6a2f33630e0 100644 --- a/src/java.base/share/classes/java/text/AttributedCharacterIterator.java +++ b/src/java.base/share/classes/java/text/AttributedCharacterIterator.java @@ -75,7 +75,7 @@ import java.util.Set; * @see Annotation * @since 1.2 */ - +@SuppressWarnings("doclint:reference") // cross-module links public interface AttributedCharacterIterator extends CharacterIterator { /** diff --git a/src/java.base/share/classes/java/text/Bidi.java b/src/java.base/share/classes/java/text/Bidi.java index 41269afac9b..2ec7bea6988 100644 --- a/src/java.base/share/classes/java/text/Bidi.java +++ b/src/java.base/share/classes/java/text/Bidi.java @@ -125,6 +125,7 @@ public final class Bidi { * @see java.desktop/java.awt.font.TextAttribute#NUMERIC_SHAPING * @see java.desktop/java.awt.font.TextAttribute#RUN_DIRECTION */ + @SuppressWarnings("doclint:reference") // cross-module links public Bidi(AttributedCharacterIterator paragraph) { if (paragraph == null) { throw new IllegalArgumentException("paragraph is null"); diff --git a/src/java.base/share/classes/java/util/Observable.java b/src/java.base/share/classes/java/util/Observable.java index 37a90f631ad..01956702c2d 100644 --- a/src/java.base/share/classes/java/util/Observable.java +++ b/src/java.base/share/classes/java/util/Observable.java @@ -73,6 +73,7 @@ package java.util; * {@link java.util.concurrent.Flow} API. */ @Deprecated(since="9") +@SuppressWarnings("doclint:reference") // cross-module links public class Observable { private boolean changed = false; private Vector obs; diff --git a/src/java.base/share/classes/java/util/ServiceLoader.java b/src/java.base/share/classes/java/util/ServiceLoader.java index c5d921896a0..531ffa3f09c 100644 --- a/src/java.base/share/classes/java/util/ServiceLoader.java +++ b/src/java.base/share/classes/java/util/ServiceLoader.java @@ -1647,6 +1647,7 @@ public final class ServiceLoader * @revised 9 */ @CallerSensitive + @SuppressWarnings("doclint:reference") // cross-module links public static ServiceLoader load(Class service, ClassLoader loader) { diff --git a/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java b/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java index 8aac4495547..bc3ed00a030 100644 --- a/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java +++ b/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java @@ -47,6 +47,7 @@ import sun.datatransfer.DataFlavorUtil; * @see java.desktop/java.awt.Toolkit#getSystemSelection * @since 1.1 */ +@SuppressWarnings("doclint:reference") // cross-module links public class Clipboard { String name; diff --git a/src/java.logging/share/classes/java/util/logging/LogManager.java b/src/java.logging/share/classes/java/util/logging/LogManager.java index 38e9ebafeb6..2d277602a4a 100644 --- a/src/java.logging/share/classes/java/util/logging/LogManager.java +++ b/src/java.logging/share/classes/java/util/logging/LogManager.java @@ -2563,6 +2563,7 @@ public class LogManager { * * @since 1.5 */ + @SuppressWarnings("doclint:reference") public static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging"; @@ -2581,6 +2582,7 @@ public class LogManager { * @since 1.5 */ @Deprecated(since="9") + @SuppressWarnings("doclint:reference") public static synchronized LoggingMXBean getLoggingMXBean() { return Logging.getInstance(); } diff --git a/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java b/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java index b966421f9b0..01eea1d0e1e 100644 --- a/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java +++ b/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java @@ -52,6 +52,7 @@ package java.util.logging; * @see java.management/java.lang.management.PlatformLoggingMXBean */ @Deprecated(since="9") +@SuppressWarnings("doclint:reference") public interface LoggingMXBean { /** diff --git a/src/java.management/share/classes/java/lang/management/ManagementFactory.java b/src/java.management/share/classes/java/lang/management/ManagementFactory.java index 76bc7417e68..13db85d0f09 100644 --- a/src/java.management/share/classes/java/lang/management/ManagementFactory.java +++ b/src/java.management/share/classes/java/lang/management/ManagementFactory.java @@ -246,7 +246,8 @@ import sun.management.spi.PlatformMBeanProvider.PlatformComponent; * @author Mandy Chung * @since 1.5 */ -@SuppressWarnings("removal") +@SuppressWarnings({"removal", + "doclint:reference"}) // cross-module links public class ManagementFactory { // A class with only static fields and methods. private ManagementFactory() {}; diff --git a/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java b/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java index 280d145be37..3a50dc20958 100644 --- a/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java +++ b/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java @@ -46,6 +46,7 @@ package java.lang.management; * * @since 1.7 */ +@SuppressWarnings("doclint:reference") // cross-module links public interface PlatformLoggingMXBean extends PlatformManagedObject { /** diff --git a/src/java.management/share/classes/javax/management/remote/JMXAddressable.java b/src/java.management/share/classes/javax/management/remote/JMXAddressable.java index 973626b99a1..b100004d51e 100644 --- a/src/java.management/share/classes/javax/management/remote/JMXAddressable.java +++ b/src/java.management/share/classes/javax/management/remote/JMXAddressable.java @@ -41,6 +41,7 @@ package javax.management.remote; * * @since 1.6 */ +@SuppressWarnings("doclint:reference") // cross-module links public interface JMXAddressable { /** *

    The address of this object.

    diff --git a/src/java.management/share/classes/javax/management/remote/JMXServerErrorException.java b/src/java.management/share/classes/javax/management/remote/JMXServerErrorException.java index 856234ad5dc..185912c6b66 100644 --- a/src/java.management/share/classes/javax/management/remote/JMXServerErrorException.java +++ b/src/java.management/share/classes/javax/management/remote/JMXServerErrorException.java @@ -41,6 +41,7 @@ import javax.management.MBeanServer; * @see java.rmi/java.rmi.ServerError * @since 1.5 */ +@SuppressWarnings("doclint:reference") // cross-module links public class JMXServerErrorException extends IOException { private static final long serialVersionUID = 3996732239558744666L; -- GitLab From 9c0104b9c96f012da1602f503f641824d78f4260 Mon Sep 17 00:00:00 2001 From: Mandy Chung Date: Tue, 1 Feb 2022 00:09:35 +0000 Subject: [PATCH 095/400] 8221642: AccessibleObject::setAccessible throws NPE when invoked by JNI code with no java frame on stack Reviewed-by: alanb --- .../java/lang/reflect/AccessibleObject.java | 81 +++++++++---- .../exeCallerAccessTest/CallerAccessTest.java | 9 +- .../exeCallerAccessTest/exeCallerAccessTest.c | 111 +++++++++++++++++- 3 files changed, 174 insertions(+), 27 deletions(-) diff --git a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java index 19dbce14b75..2b620967a8a 100644 --- a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java +++ b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -168,6 +168,15 @@ public class AccessibleObject implements AnnotatedElement { * open module. * * + *

    This method may be used by JNI code + * with no caller class on the stack to enable access to a {@link Member member} + * of {@link Member#getDeclaringClass() declaring class} {@code D} if and only if: + *

      + *
    • The member is {@code public} and {@code D} is {@code public} in + * a package that the module containing {@code D} {@link + * Module#isExported(String,Module) exports} unconditionally.
    • + *
    + * *

    This method cannot be used to enable access to private members, * members with default (package) access, protected instance members, or * protected constructors when the declaring class is in a different module @@ -246,6 +255,11 @@ public class AccessibleObject implements AnnotatedElement { * } * }

    * + *

    If this method is invoked by JNI code + * with no caller class on the stack, the {@code accessible} flag can + * only be set if the member and the declaring class are public, and + * the class is in a package that is exported unconditionally.

    + * *

    If there is a security manager, its {@code checkPermission} method * is first called with a {@code ReflectPermission("suppressAccessChecks")} * permission.

    @@ -304,6 +318,16 @@ public class AccessibleObject implements AnnotatedElement { throw new IllegalCallerException(); // should not happen } + if (caller == null) { + // No caller frame when a native thread attaches to the VM + // only allow access to a public accessible member + boolean canAccess = Reflection.verifyPublicMemberAccess(declaringClass, declaringClass.getModifiers()); + if (!canAccess && throwExceptionIfDenied) { + throwInaccessibleObjectException(caller, declaringClass); + } + return canAccess; + } + Module callerModule = caller.getModule(); Module declaringModule = declaringClass.getModule(); @@ -312,12 +336,7 @@ public class AccessibleObject implements AnnotatedElement { if (!declaringModule.isNamed()) return true; String pn = declaringClass.getPackageName(); - int modifiers; - if (this instanceof Executable) { - modifiers = ((Executable) this).getModifiers(); - } else { - modifiers = ((Field) this).getModifiers(); - } + int modifiers = ((Member)this).getModifiers(); // class is public and package is exported to caller boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers()); @@ -341,25 +360,37 @@ public class AccessibleObject implements AnnotatedElement { } if (throwExceptionIfDenied) { - // not accessible - String msg = "Unable to make "; - if (this instanceof Field) - msg += "field "; - msg += this + " accessible: " + declaringModule + " does not \""; - if (isClassPublic && Modifier.isPublic(modifiers)) - msg += "exports"; - else - msg += "opens"; - msg += " " + pn + "\" to " + callerModule; - InaccessibleObjectException e = new InaccessibleObjectException(msg); - if (printStackTraceWhenAccessFails()) { - e.printStackTrace(System.err); - } - throw e; + throwInaccessibleObjectException(caller, declaringClass); } return false; } + private void throwInaccessibleObjectException(Class caller, Class declaringClass) { + boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers()); + String pn = declaringClass.getPackageName(); + int modifiers = ((Member)this).getModifiers(); + + // not accessible + String msg = "Unable to make "; + if (this instanceof Field) + msg += "field "; + msg += this + " accessible"; + msg += caller == null ? " by JNI attached native thread with no caller frame: " : ": "; + msg += declaringClass.getModule() + " does not \""; + if (isClassPublic && Modifier.isPublic(modifiers)) + msg += "exports"; + else + msg += "opens"; + msg += " " + pn + "\"" ; + if (caller != null) + msg += " to " + caller.getModule(); + InaccessibleObjectException e = new InaccessibleObjectException(msg); + if (printStackTraceWhenAccessFails()) { + e.printStackTrace(System.err); + } + throw e; + } + private boolean isSubclassOf(Class queryClass, Class ofClass) { while (queryClass != null) { if (queryClass == ofClass) { @@ -409,7 +440,11 @@ public class AccessibleObject implements AnnotatedElement { * is set to {@code true}, i.e. the checks for Java language access control * are suppressed, or if the caller can access the member as * specified in The Java Language Specification, - * with the variation noted in the class description.

    + * with the variation noted in the class description. + * If this method is invoked by JNI code + * with no caller class on the stack, this method returns {@code true} + * if the member and the declaring class are public, and the class is in + * a package that is exported unconditionally.

    * * @param obj an instance object of the declaring class of this reflected * object if it is an instance method or field diff --git a/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java b/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java index 9f625a34a93..85ee270244d 100644 --- a/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java +++ b/test/jdk/java/lang/reflect/exeCallerAccessTest/CallerAccessTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -24,7 +24,7 @@ /** * @test - * @bug 8221530 + * @bug 8221530 8221642 * @summary Test uses custom launcher that starts VM using JNI that verifies * reflection API with null caller class * @library /test/lib @@ -61,7 +61,10 @@ public class CallerAccessTest { System.out.println("Launching: " + launcher + " shared library path: " + env.get(sharedLibraryPathEnvName)); - new OutputAnalyzer(pb.start()).shouldHaveExitValue(0); + new OutputAnalyzer(pb.start()) + .outputTo(System.out) + .errorTo(System.err) + .shouldHaveExitValue(0); } } diff --git a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c index c38a0cb094e..31710138aac 100644 --- a/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c +++ b/test/jdk/java/lang/reflect/exeCallerAccessTest/exeCallerAccessTest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -32,9 +32,15 @@ static jclass iaeClass; static jmethodID mid_Class_forName; static jmethodID mid_Class_getField; static jmethodID mid_Field_get; +static jmethodID mid_Field_canAccess; +static jmethodID mid_Field_trySetAccessible; +static jmethodID mid_Field_setAccessible; int getField(JNIEnv *env, char* declaringClass_name, char* field_name); int checkAndClearIllegalAccessExceptionThrown(JNIEnv *env); +int setAccessible(JNIEnv *env, char* declaringClass_name, char* field_name); +int trySetAccessible(JNIEnv *env, char* declaringClass_name, char* field_name, jboolean canAccess); +int checkAccess(JNIEnv *env, char* declaringClass_name, char* field_name, jboolean canAccess); int main(int argc, char** args) { JavaVM *jvm; @@ -65,6 +71,12 @@ int main(int argc, char** args) { jclass fieldClass = (*env)->FindClass(env, "java/lang/reflect/Field"); mid_Field_get = (*env)->GetMethodID(env, fieldClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); assert(mid_Class_getField != NULL); + mid_Field_canAccess = (*env)->GetMethodID(env, fieldClass, "canAccess", "(Ljava/lang/Object;)Z"); + assert(mid_Field_canAccess != NULL); + mid_Field_setAccessible = (*env)->GetMethodID(env, fieldClass, "setAccessible", "(Z)V"); + assert(mid_Field_setAccessible != NULL); + mid_Field_trySetAccessible = (*env)->GetMethodID(env, fieldClass, "trySetAccessible", "()Z"); + assert(mid_Field_trySetAccessible != NULL); // can access to public member of an exported type if ((rc = getField(env, "java.lang.Integer", "TYPE")) != 0) { @@ -92,6 +104,32 @@ int main(int argc, char** args) { exit(-1); } + // expect IAE to jdk.internal.misc.Unsafe class + if ((rc = setAccessible(env, "jdk.internal.misc.Unsafe", "INVALID_FIELD_OFFSET")) == 0) { + printf("ERROR: IAE not thrown\n"); + exit(-1); + } + if (checkAndClearIllegalAccessExceptionThrown(env) != JNI_TRUE) { + printf("ERROR: exception is not an instance of IAE\n"); + exit(-1); + } + + if ((rc = trySetAccessible(env, "java.lang.reflect.Modifier", "PUBLIC", JNI_TRUE)) != 0) { + printf("ERROR: unexpected result from trySetAccessible on Modifier::PUBLIC field\n"); + exit(-1); + } + if ((rc = trySetAccessible(env, "jdk.internal.misc.Unsafe", "INVALID_FIELD_OFFSET", JNI_FALSE)) != 0) { + printf("ERROR: unexpected result from trySetAccessible on Unsafe public field\n"); + exit(-1); + } + + if ((rc = checkAccess(env, "java.lang.reflect.Modifier", "PUBLIC", JNI_TRUE)) != 0) { + printf("ERROR: unexpected result from trySetAccessible on Modifier::PUBLIC field\n"); + exit(-1); + } + if ((rc = checkAccess(env, "jdk.internal.misc.Unsafe", "INVALID_FIELD_OFFSET", JNI_FALSE)) != 0) { + printf("ERROR: unexpected result from trySetAccessible on Unsafe public field\n"); + } (*jvm)->DestroyJavaVM(jvm); return 0; } @@ -127,3 +165,74 @@ int getField(JNIEnv *env, char* declaringClass_name, char* field_name) { return 0; } +int setAccessible(JNIEnv *env, char* declaringClass_name, char* field_name) { + jobject c = (*env)->CallStaticObjectMethod(env, classClass, mid_Class_forName, + (*env)->NewStringUTF(env, declaringClass_name)); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 1; + } + + jobject f = (*env)->CallObjectMethod(env, c, mid_Class_getField, (*env)->NewStringUTF(env, field_name)); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 2; + } + + (*env)->CallVoidMethod(env, f, mid_Field_setAccessible, JNI_TRUE); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 3; + } + return 0; +} + +int trySetAccessible(JNIEnv *env, char* declaringClass_name, char* field_name, jboolean canAccess) { + jobject c = (*env)->CallStaticObjectMethod(env, classClass, mid_Class_forName, + (*env)->NewStringUTF(env, declaringClass_name)); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 1; + } + + jobject f = (*env)->CallObjectMethod(env, c, mid_Class_getField, (*env)->NewStringUTF(env, field_name)); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 2; + } + + jboolean rc = (*env)->CallBooleanMethod(env, f, mid_Field_trySetAccessible); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 3; + } + if (rc != canAccess) { + return 4; + } + return 0; +} + +int checkAccess(JNIEnv *env, char* declaringClass_name, char* field_name, jboolean canAccess) { + jobject c = (*env)->CallStaticObjectMethod(env, classClass, mid_Class_forName, + (*env)->NewStringUTF(env, declaringClass_name)); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 1; + } + + jobject f = (*env)->CallObjectMethod(env, c, mid_Class_getField, (*env)->NewStringUTF(env, field_name)); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 2; + } + + jboolean rc = (*env)->CallBooleanMethod(env, f, mid_Field_canAccess, NULL); + if ((*env)->ExceptionOccurred(env) != NULL) { + (*env)->ExceptionDescribe(env); + return 3; + } + if (rc != canAccess) { + return 4; + } + return 0; +} -- GitLab From 1ea01465ab06749a3177b9b724ccea0945a2de09 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 1 Feb 2022 00:31:19 +0000 Subject: [PATCH 096/400] 8281007: Test jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java fails after JDK-8280738 Reviewed-by: darcy --- .../doclet/checkStylesheetClasses/CheckStylesheetClasses.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java b/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java index 1cc649b2c27..ca3d24aed70 100644 --- a/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java +++ b/test/langtools/jdk/javadoc/doclet/checkStylesheetClasses/CheckStylesheetClasses.java @@ -139,9 +139,6 @@ public class CheckStylesheetClasses { "search-tag-desc-result", "search-tag-holder-result", "ui-autocomplete", "ui-autocomplete-category", "expanded"); - // snippet-related - removeAll(styleSheetNames, "bold", "highlighted", "italic"); - // very JDK specific styleSheetNames.remove("module-graph"); -- GitLab From 0e70d4504c267174738485c7da82a2ac0ef09770 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 1 Feb 2022 01:27:18 +0000 Subject: [PATCH 097/400] 8280950: RandomGenerator:NextDouble() default behavior non conformant after JDK-8280550 fix Reviewed-by: bpb, jlaskey --- .../internal/util/random/RandomSupport.java | 4 +- .../util/Random/RandomNextDoubleBoundary.java | 41 ++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java b/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java index 99ca3da322d..14fe0d3906d 100644 --- a/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java +++ b/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -645,7 +645,7 @@ public class RandomSupport { if (origin < bound) { r = r * (bound - origin) + origin; if (r >= bound) // may need to correct a rounding problem - r = Math.nextAfter(r, origin); + r = Math.nextAfter(bound, origin); } return r; } diff --git a/test/jdk/java/util/Random/RandomNextDoubleBoundary.java b/test/jdk/java/util/Random/RandomNextDoubleBoundary.java index 511f251aed6..971b22d55c1 100644 --- a/test/jdk/java/util/Random/RandomNextDoubleBoundary.java +++ b/test/jdk/java/util/Random/RandomNextDoubleBoundary.java @@ -24,13 +24,19 @@ /* * @test * @summary Verify nextDouble stays within range - * @bug 8280550 + * @bug 8280550 8280950 */ import java.util.SplittableRandom; +import java.util.random.RandomGenerator; public class RandomNextDoubleBoundary { public static void main(String... args) { + negativeBounds(); + positiveBounds(); + } + + private static void negativeBounds() { // Both bounds are negative double lowerBound = -1.0000000000000002; double upperBound = -1.0; @@ -49,4 +55,37 @@ public class RandomNextDoubleBoundary { throw new RuntimeException("Less than lower bound"); } } + + private static void positiveBounds() { + double[][] originAndBounds = {{10, 100}, + {12345, 123456}, + {5432167.234, 54321678.1238}}; + for (double[] originAndBound : originAndBounds) { + nextDoublesWithRange(originAndBound[0], originAndBound[1]); + } + } + + public static void nextDoublesWithRange(double origin, double bound) { + RandomGenerator rg = new RandomGenerator() { + @Override + public double nextDouble() { + return Double.MAX_VALUE; + } + + @Override + public long nextLong() { + return 0; + } + }; + double value = rg.nextDouble(origin, bound); + + assertTrue(value >= origin); + assertTrue(value < bound); + } + + public static void assertTrue(boolean condition) { + if (!condition) { + throw new AssertionError(); + } + } } -- GitLab From de3113b998550021bb502cd6f766036fb8351e7d Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Tue, 1 Feb 2022 07:26:59 +0000 Subject: [PATCH 098/400] 8279842: HTTPS Channel Binding support for Java GSS/Kerberos Co-authored-by: Weijun Wang Reviewed-by: dfuchs, weijun, darcy --- .../java/net/doc-files/net-properties.html | 16 + .../classes/sun/net/www/http/HttpClient.java | 34 ++ .../net/www/protocol/http/HttpCallerInfo.java | 15 + .../www/protocol/http/HttpURLConnection.java | 21 +- .../AbstractDelegateHttpsURLConnection.java | 73 +++- .../util/ChannelBindingException.java | 60 ++++ .../sun/security/util}/TlsChannelBinding.java | 32 +- .../com/sun/jndi/ldap/sasl/LdapSasl.java | 41 ++- .../protocol/http/spnego/NegotiatorImpl.java | 15 +- .../sun/jndi/ldap/LdapCBPropertiesTest.java | 6 +- test/jdk/sun/security/krb5/auto/HttpsCB.java | 311 ++++++++++++++++++ 11 files changed, 587 insertions(+), 37 deletions(-) create mode 100644 src/java.base/share/classes/sun/security/util/ChannelBindingException.java rename src/{java.naming/share/classes/com/sun/jndi/ldap/sasl => java.base/share/classes/sun/security/util}/TlsChannelBinding.java (82%) create mode 100644 test/jdk/sun/security/krb5/auto/HttpsCB.java diff --git a/src/java.base/share/classes/java/net/doc-files/net-properties.html b/src/java.base/share/classes/java/net/doc-files/net-properties.html index 0c2d3e232da..2bd35580432 100644 --- a/src/java.base/share/classes/java/net/doc-files/net-properties.html +++ b/src/java.base/share/classes/java/net/doc-files/net-properties.html @@ -214,6 +214,22 @@ of proxies.

    property is defined, then its value will be used as the domain name.

    +
  • {@systemProperty jdk.https.negotiate.cbt} (default: <never>)
    + This controls the generation and sending of TLS channel binding tokens (CBT) when Kerberos + or the Negotiate authentication scheme using Kerberos are employed over HTTPS with + {@code HttpsURLConnection}. There are three possible settings:

    +
      +
    1. "never". This is also the default value if the property is not set. In this case, + CBTs are never sent.

      +
    2. "always". CBTs are sent for all Kerberos authentication attempts over HTTPS.

      +
    3. "domain:<comma separated domain list>" Each domain in the list specifies destination + host or hosts for which a CBT is sent. Domains can be single hosts like foo, or foo.com, + or literal IP addresses as specified in RFC 2732, or wildcards like *.foo.com which matches + all hosts under foo.com and its sub-domains. CBTs are not sent to any destinations + that don't match one of the list entries

      +
    +

    The channel binding tokens generated are of the type "tls-server-end-point" as defined in + RFC 5929.

    All these properties are checked only once at startup.

    diff --git a/src/java.base/share/classes/sun/net/www/http/HttpClient.java b/src/java.base/share/classes/sun/net/www/http/HttpClient.java index 4b3c40b4fc0..8993f0c2a0a 100644 --- a/src/java.base/share/classes/sun/net/www/http/HttpClient.java +++ b/src/java.base/share/classes/sun/net/www/http/HttpClient.java @@ -144,12 +144,27 @@ public class HttpClient extends NetworkClient { // Traffic capture tool, if configured. See HttpCapture class for info private HttpCapture capture = null; + /* "jdk.https.negotiate.cbt" property can be set to "always" (always sent), "never" (never sent) or + * "domain:a,c.d,*.e.f" (sent to host a, or c.d or to the domain e.f and any of its subdomains). This is + * a comma separated list of arbitrary length with no white-space allowed. + * If enabled (for a particular destination) then Negotiate/SPNEGO authentication requests will include + * a channel binding token for the destination server. The default behavior and setting for the + * property is "never" + */ + private static final String spnegoCBT; + private static final PlatformLogger logger = HttpURLConnection.getHttpLogger(); + private static void logFinest(String msg) { if (logger.isLoggable(PlatformLogger.Level.FINEST)) { logger.finest(msg); } } + private static void logError(String msg) { + if (logger.isLoggable(PlatformLogger.Level.SEVERE)) { + logger.severe(msg); + } + } protected volatile String authenticatorKey; @@ -165,6 +180,18 @@ public class HttpClient extends NetworkClient { return keepAliveTimeout; } + static String normalizeCBT(String s) { + if (s == null || s.equals("never")) { + return "never"; + } + if (s.equals("always") || s.startsWith("domain:")) { + return s; + } else { + logError("Unexpected value for \"jdk.https.negotiate.cbt\" system property"); + return "never"; + } + } + static { Properties props = GetPropertyAction.privilegedGetProperties(); String keepAlive = props.getProperty("http.keepAlive"); @@ -172,6 +199,9 @@ public class HttpClient extends NetworkClient { String cacheNTLM = props.getProperty("jdk.ntlm.cache"); String cacheSPNEGO = props.getProperty("jdk.spnego.cache"); + String s = props.getProperty("jdk.https.negotiate.cbt"); + spnegoCBT = normalizeCBT(s); + if (keepAlive != null) { keepAliveProp = Boolean.parseBoolean(keepAlive); } else { @@ -206,6 +236,10 @@ public class HttpClient extends NetworkClient { } + public String getSpnegoCBT() { + return spnegoCBT; + } + protected HttpClient() { } diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpCallerInfo.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpCallerInfo.java index 038f7adfe90..5afed084c7f 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpCallerInfo.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpCallerInfo.java @@ -29,6 +29,7 @@ import java.net.Authenticator; import java.net.Authenticator.RequestorType; import java.net.InetAddress; import java.net.URL; +import java.security.cert.X509Certificate; /** * Used in HTTP/Negotiate, to feed HTTP request info into JGSS as a HttpCaller, @@ -51,6 +52,9 @@ public final class HttpCallerInfo { public final InetAddress addr; public final RequestorType authType; public final Authenticator authenticator; + // Used to obtain server cert for SPNEGO CBT. + // May be null in which case CBT is not set + public final X509Certificate serverCert; /** * Create a schemed object based on an un-schemed one. @@ -65,13 +69,19 @@ public final class HttpCallerInfo { this.authType = old.authType; this.scheme = scheme; this.authenticator = old.authenticator; + this.serverCert = old.serverCert; } /** * Constructor an un-schemed object for site access. */ public HttpCallerInfo(URL url, Authenticator a) { + this(url, null, a); + } + + public HttpCallerInfo(URL url, X509Certificate serverCert, Authenticator a) { this.url= url; + this.serverCert= serverCert; prompt = ""; host = url.getHost(); @@ -100,9 +110,14 @@ public final class HttpCallerInfo { * Constructor an un-schemed object for proxy access. */ public HttpCallerInfo(URL url, String host, int port, Authenticator a) { + this(url, host, port, null, a); + } + + public HttpCallerInfo(URL url, String host, int port, X509Certificate serverCert, Authenticator a) { this.url= url; this.host = host; this.port = port; + this.serverCert = serverCert; prompt = ""; addr = null; protocol = url.getProtocol(); diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index c3d33014409..0ce0d29ee67 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -1739,7 +1739,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { AuthenticationHeader authhdr = new AuthenticationHeader ( "Proxy-Authenticate", responses, - new HttpCallerInfo(url, + getHttpCallerInfo(url, http.getProxyHostUsed(), http.getProxyPortUsed(), authenticator), @@ -1814,7 +1814,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { srvHdr = new AuthenticationHeader ( "WWW-Authenticate", responses, - new HttpCallerInfo(url, authenticator), + getHttpCallerInfo(url, authenticator), dontUseNegotiate ); @@ -2210,7 +2210,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { AuthenticationHeader authhdr = new AuthenticationHeader( "Proxy-Authenticate", responses, - new HttpCallerInfo(url, + getHttpCallerInfo(url, http.getProxyHostUsed(), http.getProxyPortUsed(), authenticator), @@ -2279,6 +2279,21 @@ public class HttpURLConnection extends java.net.HttpURLConnection { responses.reset(); } + /** + * Overridden in https to also include the server certificate + */ + protected HttpCallerInfo getHttpCallerInfo(URL url, String proxy, int port, + Authenticator authenticator) { + return new HttpCallerInfo(url, proxy, port, authenticator); + } + + /** + * Overridden in https to also include the server certificate + */ + protected HttpCallerInfo getHttpCallerInfo(URL url, Authenticator authenticator) { + return new HttpCallerInfo(url, authenticator); + } + static String connectRequestURI(URL url) { String host = url.getHost(); int port = url.getPort(); diff --git a/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java index 3828eb3cd29..7ed4381dda6 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/https/AbstractDelegateHttpsURLConnection.java @@ -1,4 +1,4 @@ -/* +/** * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,10 +25,13 @@ package sun.net.www.protocol.https; +import java.net.Authenticator; import java.net.URL; import java.net.Proxy; import java.net.SecureCacheResponse; import java.security.Principal; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; import java.io.IOException; import java.util.List; import java.util.Optional; @@ -36,6 +39,7 @@ import javax.net.ssl.SSLSession; import javax.net.ssl.SSLPeerUnverifiedException; import sun.net.www.http.*; import sun.net.www.protocol.http.HttpURLConnection; +import sun.net.www.protocol.http.HttpCallerInfo; /** * HTTPS URL connection support. @@ -309,4 +313,71 @@ public abstract class AbstractDelegateHttpsURLConnection extends return ((HttpsClient)http).getSSLSession(); } + + /* + * If no SSL Session available or if the system config does not allow it + * don't use the extended caller info (the server cert). + * Otherwise return true to include the server cert + */ + private boolean useExtendedCallerInfo(URL url) { + HttpsClient https = (HttpsClient)http; + if (https.getSSLSession() == null) { + return false; + } + String prop = http.getSpnegoCBT(); + if (prop.equals("never")) { + return false; + } + String target = url.getHost(); + if (prop.startsWith("domain:")) { + String[] domains = prop.substring(7).split(","); + for (String domain : domains) { + if (target.equals(domain)) { + return true; + } + if (domain.startsWith("*.") && target.endsWith(domain.substring(1))) { + return true; + } + } + return false; + } + return true; + } + + @Override + protected HttpCallerInfo getHttpCallerInfo(URL url, String proxy, int port, + Authenticator authenticator) + { + if (!useExtendedCallerInfo(url)) { + return super.getHttpCallerInfo(url, proxy, port, authenticator); + } + HttpsClient https = (HttpsClient)http; + try { + Certificate[] certs = https.getServerCertificates(); + if (certs[0] instanceof X509Certificate x509Cert) { + return new HttpCallerInfo(url, proxy, port, x509Cert, authenticator); + } + } catch (SSLPeerUnverifiedException e) { + // ignore + } + return super.getHttpCallerInfo(url, proxy, port, authenticator); + } + + @Override + protected HttpCallerInfo getHttpCallerInfo(URL url, Authenticator authenticator) + { + if (!useExtendedCallerInfo(url)) { + return super.getHttpCallerInfo(url, authenticator); + } + HttpsClient https = (HttpsClient)http; + try { + Certificate[] certs = https.getServerCertificates(); + if (certs[0] instanceof X509Certificate x509Cert) { + return new HttpCallerInfo(url, x509Cert, authenticator); + } + } catch (SSLPeerUnverifiedException e) { + // ignore + } + return super.getHttpCallerInfo(url, authenticator); + } } diff --git a/src/java.base/share/classes/sun/security/util/ChannelBindingException.java b/src/java.base/share/classes/sun/security/util/ChannelBindingException.java new file mode 100644 index 00000000000..847cd0741a0 --- /dev/null +++ b/src/java.base/share/classes/sun/security/util/ChannelBindingException.java @@ -0,0 +1,60 @@ +/* + * 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 sun.security.util; + +import java.security.GeneralSecurityException; + +/** + * Thrown by TlsChannelBinding if an error occurs + */ +public class ChannelBindingException extends GeneralSecurityException { + + @java.io.Serial + private static final long serialVersionUID = -5021387249782788460L; + + /** + * Constructs a ChannelBindingException with no detail message. A detail + * message is a String that describes this particular exception. + */ + public ChannelBindingException() { + super(); + } + + /** + * Constructs a ChannelBindingException with a detail message and + * specified cause. + */ + public ChannelBindingException(String msg, Exception e) { + super(msg, e); + } + + /** + * Constructs a ChannelBindingException with a detail message + */ + public ChannelBindingException(String msg) { + super(msg); + } +} diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/TlsChannelBinding.java b/src/java.base/share/classes/sun/security/util/TlsChannelBinding.java similarity index 82% rename from src/java.naming/share/classes/com/sun/jndi/ldap/sasl/TlsChannelBinding.java rename to src/java.base/share/classes/sun/security/util/TlsChannelBinding.java index 922fa18028c..8f7ac50bb5e 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/TlsChannelBinding.java +++ b/src/java.base/share/classes/sun/security/util/TlsChannelBinding.java @@ -22,10 +22,9 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.sun.jndi.ldap.sasl; -import javax.naming.NamingException; -import javax.security.sasl.SaslException; +package sun.security.util; + import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; @@ -47,14 +46,6 @@ import java.util.Hashtable; public class TlsChannelBinding { - // TLS channel binding type property - public static final String CHANNEL_BINDING_TYPE = - "com.sun.jndi.ldap.tls.cbtype"; - - // internal TLS channel binding property - public static final String CHANNEL_BINDING = - "jdk.internal.sasl.tlschannelbinding"; - public enum TlsChannelBindingType { /** @@ -80,19 +71,18 @@ public class TlsChannelBinding { } /** - * Parse value of "com.sun.jndi.ldap.tls.cbtype" property + * Parse given value to see if it is a recognized and supported channel binding type + * * @param cbType - * @return TLS Channel Binding type or null if - * "com.sun.jndi.ldap.tls.cbtype" property has not been set. - * @throws NamingException + * @return TLS Channel Binding type or null if given string is null + * @throws ChannelBindingException */ - public static TlsChannelBindingType parseType(String cbType) throws NamingException { + public static TlsChannelBindingType parseType(String cbType) throws ChannelBindingException { if (cbType != null) { if (cbType.equals(TlsChannelBindingType.TLS_SERVER_END_POINT.getName())) { return TlsChannelBindingType.TLS_SERVER_END_POINT; } else { - throw new NamingException("Illegal value for " + - CHANNEL_BINDING_TYPE + " property."); + throw new ChannelBindingException("Illegal value for channel binding type: " + cbType); } } return null; @@ -104,9 +94,9 @@ public class TlsChannelBinding { /** * Construct tls-server-end-point Channel Binding data * @param serverCertificate - * @throws SaslException + * @throws ChannelBindingException */ - public static TlsChannelBinding create(X509Certificate serverCertificate) throws SaslException { + public static TlsChannelBinding create(X509Certificate serverCertificate) throws ChannelBindingException { try { final byte[] prefix = TlsChannelBindingType.TLS_SERVER_END_POINT.getName().concat(":").getBytes(); @@ -127,7 +117,7 @@ public class TlsChannelBinding { System.arraycopy(hash, 0, cbData, prefix.length, hash.length); return new TlsChannelBinding(TlsChannelBindingType.TLS_SERVER_END_POINT, cbData); } catch (NoSuchAlgorithmException | CertificateEncodingException e) { - throw new SaslException("Cannot create TLS channel binding data", e); + throw new ChannelBindingException("Cannot create TLS channel binding data", e); } } diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/LdapSasl.java b/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/LdapSasl.java index bc557bfaa35..23be4706041 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/LdapSasl.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/sasl/LdapSasl.java @@ -42,7 +42,9 @@ import javax.security.sasl.*; import com.sun.jndi.ldap.Connection; import com.sun.jndi.ldap.LdapClient; import com.sun.jndi.ldap.LdapResult; -import com.sun.jndi.ldap.sasl.TlsChannelBinding.TlsChannelBindingType; +import sun.security.util.ChannelBindingException; +import sun.security.util.TlsChannelBinding; +import sun.security.util.TlsChannelBinding.TlsChannelBindingType; /** * Handles SASL support. @@ -62,6 +64,14 @@ public final class LdapSasl { private static final int LDAP_SUCCESS = 0; private static final int LDAP_SASL_BIND_IN_PROGRESS = 14; // LDAPv3 + // TLS channel binding type property + private static final String CHANNEL_BINDING_TYPE = + "com.sun.jndi.ldap.tls.cbtype"; + + // internal TLS channel binding property + private static final String CHANNEL_BINDING = + "jdk.internal.sasl.tlschannelbinding"; + private LdapSasl() { } @@ -113,8 +123,8 @@ public final class LdapSasl { String[] mechs = getSaslMechanismNames(authMech); // Internal TLS Channel Binding property cannot be set explicitly - if (env.get(TlsChannelBinding.CHANNEL_BINDING) != null) { - throw new NamingException(TlsChannelBinding.CHANNEL_BINDING + + if (env.get(CHANNEL_BINDING) != null) { + throw new NamingException(CHANNEL_BINDING + " property cannot be set explicitly"); } @@ -123,17 +133,24 @@ public final class LdapSasl { try { // Prepare TLS Channel Binding data if (conn.isTlsConnection()) { - TlsChannelBindingType cbType = - TlsChannelBinding.parseType( - (String)env.get(TlsChannelBinding.CHANNEL_BINDING_TYPE)); + TlsChannelBindingType cbType; + try { + cbType = TlsChannelBinding.parseType((String)env.get(CHANNEL_BINDING_TYPE)); + } catch (ChannelBindingException e) { + throw wrapInNamingException(e); + } if (cbType == TlsChannelBindingType.TLS_SERVER_END_POINT) { // set tls-server-end-point channel binding X509Certificate cert = conn.getTlsServerCertificate(); if (cert != null) { - TlsChannelBinding tlsCB = - TlsChannelBinding.create(cert); + TlsChannelBinding tlsCB; + try { + tlsCB = TlsChannelBinding.create(cert); + } catch (ChannelBindingException e) { + throw wrapInNamingException(e); + } envProps = (Hashtable) env.clone(); - envProps.put(TlsChannelBinding.CHANNEL_BINDING, tlsCB.getData()); + envProps.put(CHANNEL_BINDING, tlsCB.getData()); } else { throw new SaslException("No suitable certificate to generate " + "TLS Channel Binding data"); @@ -227,5 +244,11 @@ public final class LdapSasl { return mechNames; } + private static NamingException wrapInNamingException(Exception e) { + NamingException ne = new NamingException(); + ne.setRootCause(e); + return ne; + } + private static final byte[] NO_BYTES = new byte[0]; } diff --git a/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java b/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java index c17b54dd335..82f2391816b 100644 --- a/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java +++ b/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java @@ -40,6 +40,9 @@ import sun.security.jgss.GSSManagerImpl; import sun.security.jgss.GSSContextImpl; import sun.security.jgss.GSSUtil; import sun.security.jgss.HttpCaller; +import sun.security.jgss.krb5.internal.TlsChannelBindingImpl; +import sun.security.util.ChannelBindingException; +import sun.security.util.TlsChannelBinding; /** * This class encapsulates all JAAS and JGSS API calls in a separate class @@ -65,7 +68,7 @@ public class NegotiatorImpl extends Negotiator { *
  • Creating GSSContext *
  • A first call to initSecContext */ - private void init(HttpCallerInfo hci) throws GSSException { + private void init(HttpCallerInfo hci) throws GSSException, ChannelBindingException { final Oid oid; if (hci.scheme.equalsIgnoreCase("Kerberos")) { @@ -100,6 +103,14 @@ public class NegotiatorImpl extends Negotiator { if (context instanceof GSSContextImpl) { ((GSSContextImpl)context).requestDelegPolicy(true); } + if (hci.serverCert != null) { + if (DEBUG) { + System.out.println("Negotiate: Setting CBT"); + } + // set the channel binding token + TlsChannelBinding b = TlsChannelBinding.create(hci.serverCert); + context.setChannelBinding(new TlsChannelBindingImpl(b.getData())); + } oneToken = context.initSecContext(new byte[0], 0, 0); } @@ -110,7 +121,7 @@ public class NegotiatorImpl extends Negotiator { public NegotiatorImpl(HttpCallerInfo hci) throws IOException { try { init(hci); - } catch (GSSException e) { + } catch (GSSException | ChannelBindingException e) { if (DEBUG) { System.out.println("Negotiate support not initiated, will " + "fallback to other scheme if allowed. Reason:"); diff --git a/test/jdk/com/sun/jndi/ldap/LdapCBPropertiesTest.java b/test/jdk/com/sun/jndi/ldap/LdapCBPropertiesTest.java index 16b4400310a..2f2ce50e8d6 100644 --- a/test/jdk/com/sun/jndi/ldap/LdapCBPropertiesTest.java +++ b/test/jdk/com/sun/jndi/ldap/LdapCBPropertiesTest.java @@ -25,6 +25,7 @@ * @test * @bug 8245527 * @library lib/ /test/lib + * @modules java.base/sun.security.util * @run main/othervm LdapCBPropertiesTest true true com.sun.jndi.ldap.tls.cbtype tls-server-end-point * @run main/othervm LdapCBPropertiesTest false false com.sun.jndi.ldap.tls.cbtype tls-server-end-point * @run main/othervm LdapCBPropertiesTest true true com.sun.jndi.ldap.tls.cbtype tls-server-end-point com.sun.jndi.ldap.connect.timeout 2000 @@ -53,6 +54,8 @@ import javax.security.sasl.SaslException; import jdk.test.lib.net.URIBuilder; +import sun.security.util.ChannelBindingException; + public class LdapCBPropertiesTest { /* * Where do we find the keystores? @@ -187,7 +190,8 @@ public class LdapCBPropertiesTest { } } } - if (!shouldPass && ne.getRootCause() == null) { + Throwable rc = ne.getRootCause(); + if (!shouldPass && (rc == null || rc instanceof ChannelBindingException)) { // Expected exception caused by Channel Binding parameter inconsistency return true; } diff --git a/test/jdk/sun/security/krb5/auto/HttpsCB.java b/test/jdk/sun/security/krb5/auto/HttpsCB.java new file mode 100644 index 00000000000..a65aa5d0241 --- /dev/null +++ b/test/jdk/sun/security/krb5/auto/HttpsCB.java @@ -0,0 +1,311 @@ +/* + * 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. + * + * 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 8279842 + * @modules java.base/sun.security.util + * java.security.jgss/sun.security.jgss + * java.security.jgss/sun.security.jgss.krb5 + * java.security.jgss/sun.security.jgss.krb5.internal + * java.security.jgss/sun.security.krb5.internal:+open + * java.security.jgss/sun.security.krb5:+open + * java.security.jgss/sun.security.krb5.internal.ccache + * java.security.jgss/sun.security.krb5.internal.crypto + * java.security.jgss/sun.security.krb5.internal.ktab + * jdk.security.auth + * jdk.security.jgss + * jdk.httpserver + * @summary HTTPS Channel Binding support for Java GSS/Kerberos + * @library /test/lib + * @run main jdk.test.lib.FileInstaller TestHosts TestHosts + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * -Djdk.https.negotiate.cbt=always HttpsCB true true + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * -Djdk.https.negotiate.cbt=never HttpsCB false true + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * -Djdk.https.negotiate.cbt=invalid HttpsCB false true + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * HttpsCB false true + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * -Djdk.https.negotiate.cbt=domain:other.com HttpsCB false true + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * -Djdk.https.negotiate.cbt=domain:host.web.domain HttpsCB true true + * @run main/othervm -Djdk.net.hosts.file=TestHosts + * -Djdk.https.negotiate.cbt=domain:*.web.domain HttpsCB true true + */ + +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.HttpPrincipal; +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsExchange; +import com.sun.net.httpserver.HttpsServer; +import com.sun.security.auth.module.Krb5LoginModule; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.InetSocketAddress; +import java.net.PasswordAuthentication; +import java.net.Proxy; +import java.net.Socket; +import java.net.URL; +import java.security.cert.X509Certificate; +import java.util.HashMap; +import java.util.Map; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509ExtendedTrustManager; +import javax.security.auth.Subject; + +import jdk.test.lib.Asserts; +import jdk.test.lib.net.SimpleSSLContext; +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSManager; +import sun.security.jgss.GSSUtil; +import sun.security.jgss.krb5.internal.TlsChannelBindingImpl; +import sun.security.krb5.Config; +import sun.security.util.TlsChannelBinding; + +import java.util.Base64; +import java.util.concurrent.Callable; + +public class HttpsCB { + + final static String REALM_WEB = "WEB.DOMAIN"; + final static String KRB5_CONF = "web.conf"; + final static String KRB5_TAB = "web.ktab"; + + final static String WEB_USER = "web"; + final static char[] WEB_PASS = "webby".toCharArray(); + final static String WEB_HOST = "host.web.domain"; + final static String CONTENT = "Hello, World!"; + + static int webPort; + static URL cbtURL; + static URL normalURL; + + public static void main(String[] args) + throws Exception { + + boolean expectCBT = Boolean.parseBoolean(args[0]); + boolean expectNoCBT = Boolean.parseBoolean(args[1]); + + System.setProperty("sun.security.krb5.debug", "true"); + + KDC kdcw = KDC.create(REALM_WEB); + kdcw.addPrincipal(WEB_USER, WEB_PASS); + kdcw.addPrincipalRandKey("krbtgt/" + REALM_WEB); + kdcw.addPrincipalRandKey("HTTP/" + WEB_HOST); + + KDC.saveConfig(KRB5_CONF, kdcw, + "default_keytab_name = " + KRB5_TAB, + "[domain_realm]", + "", + ".web.domain="+REALM_WEB); + + System.setProperty("java.security.krb5.conf", KRB5_CONF); + Config.refresh(); + KDC.writeMultiKtab(KRB5_TAB, kdcw); + + // Write a customized JAAS conf file, so that any kinit cache + // will be ignored. + System.setProperty("java.security.auth.login.config", OneKDC.JAAS_CONF); + File f = new File(OneKDC.JAAS_CONF); + FileOutputStream fos = new FileOutputStream(f); + fos.write(( + "com.sun.security.jgss.krb5.initiate {\n" + + " com.sun.security.auth.module.Krb5LoginModule required;\n};\n" + ).getBytes()); + fos.close(); + + HttpServer h1 = httpd("Negotiate", + "HTTP/" + WEB_HOST + "@" + REALM_WEB, KRB5_TAB); + webPort = h1.getAddress().getPort(); + + cbtURL = new URL("https://" + WEB_HOST +":" + webPort + "/cbt"); + normalURL = new URL("https://" + WEB_HOST +":" + webPort + "/normal"); + + java.net.Authenticator.setDefault(new java.net.Authenticator() { + public PasswordAuthentication getPasswordAuthentication () { + return new PasswordAuthentication( + WEB_USER+"@"+REALM_WEB, WEB_PASS); + } + }); + + // Client-side SSLContext needs to ignore hostname mismatch + // and untrusted certificate. + SSLContext sc = SSLContext.getInstance("SSL"); + sc.init(null, new TrustManager[] { + new X509ExtendedTrustManager() { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted(X509Certificate[] chain, + String authType, Socket socket) { } + public void checkServerTrusted(X509Certificate[] chain, + String authType, Socket socket) { } + public void checkClientTrusted(X509Certificate[] chain, + String authType, SSLEngine engine) { } + public void checkServerTrusted(X509Certificate[] chain, + String authType, SSLEngine engine) { } + public void checkClientTrusted(X509Certificate[] certs, + String authType) { } + public void checkServerTrusted(X509Certificate[] certs, + String authType) { } + } + }, null); + + Asserts.assertEQ(visit(sc, cbtURL), expectCBT); + Asserts.assertEQ(visit(sc, normalURL), expectNoCBT); + } + + static boolean visit(SSLContext sc, URL url) { + try { + HttpsURLConnection conn = (HttpsURLConnection) + url.openConnection(Proxy.NO_PROXY); + conn.setSSLSocketFactory(sc.getSocketFactory()); + BufferedReader reader; + reader = new BufferedReader(new InputStreamReader( + conn.getInputStream())); + return reader.readLine().equals(CONTENT); + } catch (IOException e) { + return false; + } + } + + static HttpServer httpd(String scheme, String principal, String ktab) + throws Exception { + MyHttpHandler h = new MyHttpHandler(); + HttpsServer server = HttpsServer.create(new InetSocketAddress(0), 0); + server.setHttpsConfigurator( + new HttpsConfigurator(new SimpleSSLContext().get())); + server.createContext("/", h).setAuthenticator( + new MyServerAuthenticator(scheme, principal, ktab)); + server.start(); + return server; + } + + static class MyHttpHandler implements HttpHandler { + public void handle(HttpExchange t) throws IOException { + t.sendResponseHeaders(200, 0); + t.getResponseBody().write(CONTENT.getBytes()); + t.close(); + } + } + + static class MyServerAuthenticator + extends com.sun.net.httpserver.Authenticator { + Subject s = new Subject(); + GSSManager m; + GSSCredential cred; + String scheme = null; + String reqHdr = "WWW-Authenticate"; + String respHdr = "Authorization"; + int err = HttpURLConnection.HTTP_UNAUTHORIZED; + + public MyServerAuthenticator(String scheme, + String principal, String ktab) throws Exception { + + this.scheme = scheme; + Krb5LoginModule krb5 = new Krb5LoginModule(); + Map map = new HashMap<>(); + Map shared = new HashMap<>(); + + map.put("storeKey", "true"); + map.put("isInitiator", "false"); + map.put("useKeyTab", "true"); + map.put("keyTab", ktab); + map.put("principal", principal); + krb5.initialize(s, null, shared, map); + krb5.login(); + krb5.commit(); + m = GSSManager.getInstance(); + cred = Subject.callAs(s, new Callable() { + @Override + public GSSCredential call() throws Exception { + System.err.println("Creating GSSCredential"); + return m.createCredential( + null, + GSSCredential.INDEFINITE_LIFETIME, + MyServerAuthenticator.this.scheme + .equalsIgnoreCase("Negotiate") ? + GSSUtil.GSS_SPNEGO_MECH_OID : + GSSUtil.GSS_KRB5_MECH_OID, + GSSCredential.ACCEPT_ONLY); + } + }); + } + + @Override + public Result authenticate(HttpExchange exch) { + // The GSContext is stored in an HttpContext attribute named + // "GSSContext" and is created at the first request. + GSSContext c = null; + String auth = exch.getRequestHeaders().getFirst(respHdr); + try { + c = (GSSContext)exch.getHttpContext() + .getAttributes().get("GSSContext"); + if (auth == null) { // First request + Headers map = exch.getResponseHeaders(); + map.set (reqHdr, scheme); // Challenge! + c = Subject.callAs(s, () -> m.createContext(cred)); + // CBT is required for cbtURL + if (exch instanceof HttpsExchange sexch + && exch.getRequestURI().toString().equals("/cbt")) { + TlsChannelBinding b = TlsChannelBinding.create( + (X509Certificate) sexch.getSSLSession() + .getLocalCertificates()[0]); + c.setChannelBinding( + new TlsChannelBindingImpl(b.getData())); + } + exch.getHttpContext().getAttributes().put("GSSContext", c); + return new com.sun.net.httpserver.Authenticator.Retry(err); + } else { // Later requests + byte[] token = Base64.getMimeDecoder() + .decode(auth.split(" ")[1]); + token = c.acceptSecContext(token, 0, token.length); + Headers map = exch.getResponseHeaders(); + map.set (reqHdr, scheme + " " + Base64.getMimeEncoder() + .encodeToString(token).replaceAll("\\s", "")); + if (c.isEstablished()) { + return new com.sun.net.httpserver.Authenticator.Success( + new HttpPrincipal(c.getSrcName().toString(), "")); + } else { + return new com.sun.net.httpserver.Authenticator.Retry(err); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } +} -- GitLab From 16ec47d5e5bf129fc0910358464ab62bf6ce7ed8 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Tue, 1 Feb 2022 08:47:10 +0000 Subject: [PATCH 099/400] 8279856: Parallel: Use PreservedMarks to record promotion-failed objects Reviewed-by: sjohanss, tschatzl --- src/hotspot/share/gc/parallel/psPromotionManager.cpp | 5 ++++- src/hotspot/share/gc/parallel/psScavenge.cpp | 10 +--------- src/hotspot/share/gc/shared/preservedMarks.cpp | 6 ++++-- src/hotspot/share/gc/shared/preservedMarks.hpp | 1 + src/hotspot/share/gc/shared/preservedMarks.inline.hpp | 6 ++++++ 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psPromotionManager.cpp b/src/hotspot/share/gc/parallel/psPromotionManager.cpp index 0eef7667810..9c6b8acf624 100644 --- a/src/hotspot/share/gc/parallel/psPromotionManager.cpp +++ b/src/hotspot/share/gc/parallel/psPromotionManager.cpp @@ -339,7 +339,10 @@ oop PSPromotionManager::oop_promotion_failed(oop obj, markWord obj_mark) { push_contents(obj); - _preserved_marks->push_if_necessary(obj, obj_mark); + // Save the markWord of promotion-failed objs in _preserved_marks for later + // restoration. This way we don't have to walk the young-gen to locate + // these promotion-failed objs. + _preserved_marks->push_always(obj, obj_mark); } else { // We lost, someone else "owns" this object guarantee(obj->is_forwarded(), "Object must be forwarded if the cas failed."); diff --git a/src/hotspot/share/gc/parallel/psScavenge.cpp b/src/hotspot/share/gc/parallel/psScavenge.cpp index 995c5157dfc..b6ca29adefc 100644 --- a/src/hotspot/share/gc/parallel/psScavenge.cpp +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp @@ -670,19 +670,11 @@ bool PSScavenge::invoke_no_policy() { return !promotion_failure_occurred; } -// This method iterates over all objects in the young generation, -// removing all forwarding references. It then restores any preserved marks. void PSScavenge::clean_up_failed_promotion() { - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - PSYoungGen* young_gen = heap->young_gen(); - - RemoveForwardedPointerClosure remove_fwd_ptr_closure; - young_gen->object_iterate(&remove_fwd_ptr_closure); - PSPromotionManager::restore_preserved_marks(); // Reset the PromotionFailureALot counters. - NOT_PRODUCT(heap->reset_promotion_should_fail();) + NOT_PRODUCT(ParallelScavengeHeap::heap()->reset_promotion_should_fail();) } bool PSScavenge::should_attempt_scavenge() { diff --git a/src/hotspot/share/gc/shared/preservedMarks.cpp b/src/hotspot/share/gc/shared/preservedMarks.cpp index 718f97085f6..70d7f6e8934 100644 --- a/src/hotspot/share/gc/shared/preservedMarks.cpp +++ b/src/hotspot/share/gc/shared/preservedMarks.cpp @@ -125,8 +125,10 @@ public: ~RestorePreservedMarksTask() { assert(_total_size == _total_size_before, "total_size = %zu before = %zu", _total_size, _total_size_before); - - log_trace(gc)("Restored %zu marks", _total_size); + size_t mem_size = _total_size * (sizeof(oop) + sizeof(markWord)); + log_trace(gc)("Restored %zu marks, occupying %zu %s", _total_size, + byte_size_in_proper_unit(mem_size), + proper_unit_for_byte_size(mem_size)); } }; diff --git a/src/hotspot/share/gc/shared/preservedMarks.hpp b/src/hotspot/share/gc/shared/preservedMarks.hpp index b172b68e49a..1aa202cfba4 100644 --- a/src/hotspot/share/gc/shared/preservedMarks.hpp +++ b/src/hotspot/share/gc/shared/preservedMarks.hpp @@ -57,6 +57,7 @@ private: public: size_t size() const { return _stack.size(); } inline void push_if_necessary(oop obj, markWord m); + inline void push_always(oop obj, markWord m); // Iterate over the stack, restore all preserved marks, and // reclaim the memory taken up by the stack segments. void restore(); diff --git a/src/hotspot/share/gc/shared/preservedMarks.inline.hpp b/src/hotspot/share/gc/shared/preservedMarks.inline.hpp index ea3b3b9da0e..e35ba38e429 100644 --- a/src/hotspot/share/gc/shared/preservedMarks.inline.hpp +++ b/src/hotspot/share/gc/shared/preservedMarks.inline.hpp @@ -42,6 +42,12 @@ inline void PreservedMarks::push_if_necessary(oop obj, markWord m) { } } +inline void PreservedMarks::push_always(oop obj, markWord m) { + assert(!m.is_marked(), "precondition"); + OopAndMarkWord elem(obj, m); + _stack.push(elem); +} + inline void PreservedMarks::init_forwarded_mark(oop obj) { obj->init_mark(); } -- GitLab From 18a7dc8c08fa15a260b4a39b18c068d30ee45962 Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Tue, 1 Feb 2022 10:20:38 +0000 Subject: [PATCH 100/400] 8279586: [macos] custom JCheckBox and JRadioBox with custom icon set: focus is still displayed after unchecking Reviewed-by: serb, azvegint --- .../com/apple/laf/AquaButtonLabeledUI.java | 4 ++-- .../ImageCheckboxFocus/ImageCheckboxTest.java | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonLabeledUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonLabeledUI.java index 3a9ed6b12f5..3c21b325f36 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonLabeledUI.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonLabeledUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -170,7 +170,7 @@ public abstract class AquaButtonLabeledUI extends AquaButtonToggleUI implements } int offset = 0; - if (b.isFocusOwner()) { + if (b.isFocusOwner() && b.isFocusPainted()) { offset = 2; altIcon = AquaFocus.createFocusedIcon(altIcon, c, 2); } diff --git a/test/jdk/javax/swing/JCheckBox/ImageCheckboxFocus/ImageCheckboxTest.java b/test/jdk/javax/swing/JCheckBox/ImageCheckboxFocus/ImageCheckboxTest.java index b63973229a2..c93715d8087 100644 --- a/test/jdk/javax/swing/JCheckBox/ImageCheckboxFocus/ImageCheckboxTest.java +++ b/test/jdk/javax/swing/JCheckBox/ImageCheckboxFocus/ImageCheckboxTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -34,7 +34,7 @@ import javax.swing.JCheckBox; /* * @test * @key headful - * @bug 8216358 + * @bug 8216358 8279586 * @summary [macos] The focus is invisible when tab to "Image Radio Buttons" and "Image CheckBoxes" * @library ../../regtesthelpers/ * @build Util @@ -51,8 +51,12 @@ public class ImageCheckboxTest { BufferedImage.TYPE_INT_ARGB); BufferedImage imageFocus = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB); + BufferedImage imageFocusNotPainted = new BufferedImage(100, 50, + BufferedImage.TYPE_INT_ARGB); + CustomCheckBox checkbox = new CustomCheckBox("Test", new MyIcon(Color.GREEN)); + checkbox.setFocusPainted(true); checkbox.setSize(100, 50); checkbox.setFocused(false); checkbox.paint(imageNoFocus.createGraphics()); @@ -64,6 +68,17 @@ public class ImageCheckboxTest { ImageIO.write(imageNoFocus, "png", new File("imageNoFocus.png")); throw new Exception("Changing focus is not visualized"); } + + checkbox.setFocusPainted(false); + checkbox.paint(imageFocusNotPainted.createGraphics()); + + if (!Util.compareBufferedImages(imageFocusNotPainted, imageNoFocus)) { + ImageIO.write(imageFocusNotPainted, "png", + new File("imageFocusNotPainted.png")); + ImageIO.write(imageFocus, "png", new File("imageFocus.png")); + ImageIO.write(imageNoFocus, "png", new File("imageNoFocus.png")); + throw new Exception("setFocusPainted(false) is ignored"); + } } class MyIcon implements Icon { -- GitLab From d37fb1df460ec980bd8d3029b1ce7896c3249a99 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Tue, 1 Feb 2022 10:56:07 +0000 Subject: [PATCH 101/400] 8280870: Parallel: Simplify CLD roots claim in Full GC cycle Reviewed-by: stefank, sjohanss --- .../share/gc/parallel/psParallelCompact.cpp | 50 ++++--------------- 1 file changed, 11 insertions(+), 39 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index d415de47ca5..cb8dd999f5d 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -1948,36 +1948,6 @@ public: } }; -static void mark_from_roots_work(ParallelRootType::Value root_type, uint worker_id) { - assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); - - ParCompactionManager* cm = - ParCompactionManager::gc_thread_compaction_manager(worker_id); - PCMarkAndPushClosure mark_and_push_closure(cm); - - switch (root_type) { - case ParallelRootType::class_loader_data: - { - CLDToOopClosure cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_strong); - ClassLoaderDataGraph::always_strong_cld_do(&cld_closure); - } - break; - - case ParallelRootType::code_cache: - // Do not treat nmethods as strong roots for mark/sweep, since we can unload them. - //ScavengableNMethods::scavengable_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure)); - break; - - case ParallelRootType::sentinel: - DEBUG_ONLY(default:) // DEBUG_ONLY hack will create compile error on release builds (-Wswitch) and runtime check on debug builds - fatal("Bad enumeration value: %u", root_type); - break; - } - - // Do the real work - cm->follow_marking_stacks(); -} - void steal_marking_work(TaskTerminator& terminator, uint worker_id) { assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); @@ -1999,7 +1969,6 @@ void steal_marking_work(TaskTerminator& terminator, uint worker_id) { class MarkFromRootsTask : public WorkerTask { StrongRootsScope _strong_roots_scope; // needed for Threads::possibly_parallel_threads_do OopStorageSetStrongParState _oop_storage_set_par_state; - SequentialSubTasksDone _subtasks; TaskTerminator _terminator; uint _active_workers; @@ -2007,14 +1976,19 @@ public: MarkFromRootsTask(uint active_workers) : WorkerTask("MarkFromRootsTask"), _strong_roots_scope(active_workers), - _subtasks(ParallelRootType::sentinel), _terminator(active_workers, ParCompactionManager::oop_task_queues()), - _active_workers(active_workers) { - } + _active_workers(active_workers) {} virtual void work(uint worker_id) { - for (uint task = 0; _subtasks.try_claim_task(task); /*empty*/ ) { - mark_from_roots_work(static_cast(task), worker_id); + ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id); + PCMarkAndPushClosure mark_and_push_closure(cm); + + { + CLDToOopClosure cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_strong); + ClassLoaderDataGraph::always_strong_cld_do(&cld_closure); + + // Do the real work + cm->follow_marking_stacks(); } PCAddThreadRootsMarkingTaskClosure closure(worker_id); @@ -2022,9 +1996,7 @@ public: // Mark from OopStorages { - ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id); - PCMarkAndPushClosure closure(cm); - _oop_storage_set_par_state.oops_do(&closure); + _oop_storage_set_par_state.oops_do(&mark_and_push_closure); // Do the real work cm->follow_marking_stacks(); } -- GitLab From 86debf42f545a1aec0a065ebd5b016339a1ae09f Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Tue, 1 Feb 2022 11:03:31 +0000 Subject: [PATCH 102/400] 8280932: G1: Rename HeapRegionRemSet::_code_roots accessors Reviewed-by: iwalulya --- src/hotspot/share/gc/g1/g1CodeBlobClosure.cpp | 4 +- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 18 +++--- src/hotspot/share/gc/g1/g1CollectedHeap.hpp | 4 +- src/hotspot/share/gc/g1/g1ConcurrentMark.cpp | 10 ++-- src/hotspot/share/gc/g1/g1ConcurrentMark.hpp | 4 +- src/hotspot/share/gc/g1/g1EvacFailure.cpp | 2 +- src/hotspot/share/gc/g1/g1HeapVerifier.cpp | 4 +- src/hotspot/share/gc/g1/g1RemSet.cpp | 22 ++++---- src/hotspot/share/gc/g1/g1RemSetSummary.cpp | 18 +++--- src/hotspot/share/gc/g1/g1SharedClosures.hpp | 2 +- src/hotspot/share/gc/g1/g1YoungCollector.cpp | 2 +- src/hotspot/share/gc/g1/heapRegion.cpp | 56 +++++++++---------- src/hotspot/share/gc/g1/heapRegion.hpp | 14 ++--- src/hotspot/share/gc/g1/heapRegionRemSet.cpp | 16 +++--- src/hotspot/share/gc/g1/heapRegionRemSet.hpp | 35 ++++++------ 15 files changed, 105 insertions(+), 106 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CodeBlobClosure.cpp b/src/hotspot/share/gc/g1/g1CodeBlobClosure.cpp index 725e0130388..f2dc595ef53 100644 --- a/src/hotspot/share/gc/g1/g1CodeBlobClosure.cpp +++ b/src/hotspot/share/gc/g1/g1CodeBlobClosure.cpp @@ -40,8 +40,8 @@ void G1CodeBlobClosure::HeapRegionGatheringOopClosure::do_oop_work(T* p) { if (!CompressedOops::is_null(oop_or_narrowoop)) { oop o = CompressedOops::decode_not_null(oop_or_narrowoop); HeapRegion* hr = _g1h->heap_region_containing(o); - assert(!_g1h->is_in_cset(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in collection set then evacuation failed and nm must already be in the remset"); - hr->add_strong_code_root(_nm); + assert(!_g1h->is_in_cset(o) || hr->rem_set()->code_roots_list_contains(_nm), "if o still in collection set then evacuation failed and nm must already be in the remset"); + hr->add_code_root(_nm); } } diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 005ea4264ce..89c95c620ba 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1042,8 +1042,8 @@ void G1CollectedHeap::prepare_heap_for_mutators() { resize_heap_if_necessary(); uncommit_regions_if_necessary(); - // Rebuild the strong code root lists for each region - rebuild_strong_code_roots(); + // Rebuild the code root lists for each region + rebuild_code_roots(); // Purge code root memory purge_code_root_memory(); @@ -3342,8 +3342,8 @@ public: " starting at " HR_FORMAT, p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())); - // HeapRegion::add_strong_code_root_locked() avoids adding duplicate entries. - hr->add_strong_code_root_locked(_nm); + // HeapRegion::add_code_root_locked() avoids adding duplicate entries. + hr->add_code_root_locked(_nm); } } @@ -3368,7 +3368,7 @@ public: " starting at " HR_FORMAT, p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())); - hr->remove_strong_code_root(_nm); + hr->remove_code_root(_nm); } } @@ -3411,11 +3411,11 @@ void G1CollectedHeap::purge_code_root_memory() { G1CodeRootSet::purge(); } -class RebuildStrongCodeRootClosure: public CodeBlobClosure { +class RebuildCodeRootClosure: public CodeBlobClosure { G1CollectedHeap* _g1h; public: - RebuildStrongCodeRootClosure(G1CollectedHeap* g1h) : + RebuildCodeRootClosure(G1CollectedHeap* g1h) : _g1h(g1h) {} void do_code_blob(CodeBlob* cb) { @@ -3428,8 +3428,8 @@ public: } }; -void G1CollectedHeap::rebuild_strong_code_roots() { - RebuildStrongCodeRootClosure blob_cl(this); +void G1CollectedHeap::rebuild_code_roots() { + RebuildCodeRootClosure blob_cl(this); CodeCache::blobs_do(&blob_cl); } diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 8c4a8307816..83da03019af 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -1287,9 +1287,9 @@ public: // Free up superfluous code root memory. void purge_code_root_memory(); - // Rebuild the strong code root lists for each region + // Rebuild the code root lists for each region // after a full GC. - void rebuild_strong_code_roots(); + void rebuild_code_roots(); // Performs cleaning of data structures after class unloading. void complete_cleaning(BoolObjectClosure* is_alive, bool class_unloading_occurred); diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index c2800aacfbc..5d0c0dd605d 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -2954,7 +2954,7 @@ G1CMTask::G1CMTask(uint worker_id, G1PrintRegionLivenessInfoClosure::G1PrintRegionLivenessInfoClosure(const char* phase_name) : _total_used_bytes(0), _total_capacity_bytes(0), _total_prev_live_bytes(0), _total_next_live_bytes(0), - _total_remset_bytes(0), _total_strong_code_roots_bytes(0) + _total_remset_bytes(0), _total_code_roots_bytes(0) { if (!log_is_enabled(Trace, gc, liveness)) { return; @@ -3014,7 +3014,7 @@ bool G1PrintRegionLivenessInfoClosure::do_heap_region(HeapRegion* r) { size_t next_live_bytes = r->next_live_bytes(); double gc_eff = r->gc_efficiency(); size_t remset_bytes = r->rem_set()->mem_size(); - size_t strong_code_roots_bytes = r->rem_set()->strong_code_roots_mem_size(); + size_t code_roots_bytes = r->rem_set()->code_roots_mem_size(); const char* remset_type = r->rem_set()->get_short_state_str(); FormatBuffer<16> gc_efficiency(""); @@ -3023,7 +3023,7 @@ bool G1PrintRegionLivenessInfoClosure::do_heap_region(HeapRegion* r) { _total_prev_live_bytes += prev_live_bytes; _total_next_live_bytes += next_live_bytes; _total_remset_bytes += remset_bytes; - _total_strong_code_roots_bytes += strong_code_roots_bytes; + _total_code_roots_bytes += code_roots_bytes; if(gc_eff < 0) { gc_efficiency.append("-"); @@ -3044,7 +3044,7 @@ bool G1PrintRegionLivenessInfoClosure::do_heap_region(HeapRegion* r) { G1PPRL_BYTE_FORMAT, type, p2i(bottom), p2i(end), used_bytes, prev_live_bytes, next_live_bytes, gc_efficiency.buffer(), - remset_bytes, remset_type, strong_code_roots_bytes); + remset_bytes, remset_type, code_roots_bytes); return false; } @@ -3074,5 +3074,5 @@ G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() { bytes_to_mb(_total_next_live_bytes), percent_of(_total_next_live_bytes, _total_capacity_bytes), bytes_to_mb(_total_remset_bytes), - bytes_to_mb(_total_strong_code_roots_bytes)); + bytes_to_mb(_total_code_roots_bytes)); } diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp index d2e3ae624f2..cc603df18c4 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp @@ -847,8 +847,8 @@ class G1PrintRegionLivenessInfoClosure : public HeapRegionClosure { // Accumulator for the remembered set size size_t _total_remset_bytes; - // Accumulator for strong code roots memory size - size_t _total_strong_code_roots_bytes; + // Accumulator for code roots memory size + size_t _total_code_roots_bytes; static double bytes_to_mb(size_t val) { return (double) val / (double) M; diff --git a/src/hotspot/share/gc/g1/g1EvacFailure.cpp b/src/hotspot/share/gc/g1/g1EvacFailure.cpp index dbad25955ae..fd065df17c6 100644 --- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp +++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp @@ -196,7 +196,7 @@ public: size_t live_bytes = remove_self_forward_ptr_by_walking_hr(hr, during_concurrent_start); - hr->rem_set()->clean_strong_code_roots(hr); + hr->rem_set()->clean_code_roots(hr); hr->rem_set()->clear_locked(true); hr->note_self_forwarding_removal_end(live_bytes); diff --git a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp index 2c18b4a7346..1cf2c01a0e2 100644 --- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp +++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp @@ -114,9 +114,9 @@ class G1VerifyCodeRootOopClosure: public OopClosure { // Now fetch the region containing the object HeapRegion* hr = _g1h->heap_region_containing(obj); HeapRegionRemSet* hrrs = hr->rem_set(); - // Verify that the strong code root list for this region + // Verify that the code root list for this region // contains the nmethod - if (!hrrs->strong_code_roots_list_contains(_nm)) { + if (!hrrs->code_roots_list_contains(_nm)) { log_error(gc, verify)("Code root location " PTR_FORMAT " " "from nmethod " PTR_FORMAT " not in strong " "code roots for region [" PTR_FORMAT "," PTR_FORMAT ")", diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp index 13977348825..6496b6eaf64 100644 --- a/src/hotspot/share/gc/g1/g1RemSet.cpp +++ b/src/hotspot/share/gc/g1/g1RemSet.cpp @@ -946,8 +946,8 @@ class G1ScanCollectionSetRegionClosure : public HeapRegionClosure { size_t _opt_refs_scanned; size_t _opt_refs_memory_used; - Tickspan _strong_code_root_scan_time; - Tickspan _strong_code_trim_partially_time; + Tickspan _code_root_scan_time; + Tickspan _code_trim_partially_time; Tickspan _rem_set_opt_root_scan_time; Tickspan _rem_set_opt_trim_partially_time; @@ -979,8 +979,8 @@ public: _opt_roots_scanned(0), _opt_refs_scanned(0), _opt_refs_memory_used(0), - _strong_code_root_scan_time(), - _strong_code_trim_partially_time(), + _code_root_scan_time(), + _code_trim_partially_time(), _rem_set_opt_root_scan_time(), _rem_set_opt_trim_partially_time() { } @@ -997,9 +997,9 @@ public: if (_scan_state->claim_collection_set_region(region_idx)) { EventGCPhaseParallel event; - G1EvacPhaseWithTrimTimeTracker timer(_pss, _strong_code_root_scan_time, _strong_code_trim_partially_time); - // Scan the strong code root list attached to the current region - r->strong_code_roots_do(_pss->closures()->weak_codeblobs()); + G1EvacPhaseWithTrimTimeTracker timer(_pss, _code_root_scan_time, _code_trim_partially_time); + // Scan the code root list attached to the current region + r->code_roots_do(_pss->closures()->weak_codeblobs()); event.commit(GCId::current(), _worker_id, G1GCPhaseTimes::phase_name(_code_roots_phase)); } @@ -1007,8 +1007,8 @@ public: return false; } - Tickspan strong_code_root_scan_time() const { return _strong_code_root_scan_time; } - Tickspan strong_code_root_trim_partially_time() const { return _strong_code_trim_partially_time; } + Tickspan code_root_scan_time() const { return _code_root_scan_time; } + Tickspan code_root_trim_partially_time() const { return _code_trim_partially_time; } Tickspan rem_set_opt_root_scan_time() const { return _rem_set_opt_root_scan_time; } Tickspan rem_set_opt_trim_partially_time() const { return _rem_set_opt_trim_partially_time; } @@ -1031,8 +1031,8 @@ void G1RemSet::scan_collection_set_regions(G1ParScanThreadState* pss, p->record_or_add_time_secs(scan_phase, worker_id, cl.rem_set_opt_root_scan_time().seconds()); p->record_or_add_time_secs(scan_phase, worker_id, cl.rem_set_opt_trim_partially_time().seconds()); - p->record_or_add_time_secs(coderoots_phase, worker_id, cl.strong_code_root_scan_time().seconds()); - p->add_time_secs(objcopy_phase, worker_id, cl.strong_code_root_trim_partially_time().seconds()); + p->record_or_add_time_secs(coderoots_phase, worker_id, cl.code_root_scan_time().seconds()); + p->add_time_secs(objcopy_phase, worker_id, cl.code_root_trim_partially_time().seconds()); // At this time we record some metrics only for the evacuations after the initial one. if (scan_phase == G1GCPhaseTimes::OptScanHR) { diff --git a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp index cae7df6f902..faf09063bc0 100644 --- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp +++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp @@ -233,7 +233,7 @@ public: HeapRegionRemSet* hrrs = r->rem_set(); // HeapRegionRemSet::mem_size() includes the - // size of the strong code roots + // size of the code roots size_t rs_wasted_mem_sz = hrrs->wasted_mem_size(); size_t rs_mem_sz = hrrs->mem_size(); if (rs_mem_sz > _max_rs_mem_sz) { @@ -241,12 +241,12 @@ public: _max_rs_mem_sz_region = r; } size_t occupied_cards = hrrs->occupied(); - size_t code_root_mem_sz = hrrs->strong_code_roots_mem_size(); + size_t code_root_mem_sz = hrrs->code_roots_mem_size(); if (code_root_mem_sz > max_code_root_mem_sz()) { _max_code_root_mem_sz = code_root_mem_sz; _max_code_root_mem_sz_region = r; } - size_t code_root_elems = hrrs->strong_code_roots_list_length(); + size_t code_root_elems = hrrs->code_roots_list_length(); RegionTypeCounter* current = NULL; if (r->is_free()) { @@ -300,14 +300,14 @@ public: HeapRegionRemSet::print_static_mem_size(out); G1CardSetFreePool::free_list_pool()->print_on(out); - // Strong code root statistics + // Code root statistics HeapRegionRemSet* max_code_root_rem_set = max_code_root_mem_sz_region()->rem_set(); out->print_cr(" Total heap region code root sets sizes = " SIZE_FORMAT "%s." " Max = " SIZE_FORMAT "%s.", byte_size_in_proper_unit(total_code_root_mem_sz()), proper_unit_for_byte_size(total_code_root_mem_sz()), - byte_size_in_proper_unit(max_code_root_rem_set->strong_code_roots_mem_size()), - proper_unit_for_byte_size(max_code_root_rem_set->strong_code_roots_mem_size())); + byte_size_in_proper_unit(max_code_root_rem_set->code_roots_mem_size()), + proper_unit_for_byte_size(max_code_root_rem_set->code_roots_mem_size())); for (RegionTypeCounter** current = &counters[0]; *current != NULL; current++) { (*current)->print_code_root_mem_info_on(out, total_code_root_mem_sz()); } @@ -321,9 +321,9 @@ public: out->print_cr(" Region with largest amount of code roots = " HR_FORMAT ", " "size = " SIZE_FORMAT "%s, num_slots = " SIZE_FORMAT ".", HR_FORMAT_PARAMS(max_code_root_mem_sz_region()), - byte_size_in_proper_unit(max_code_root_rem_set->strong_code_roots_mem_size()), - proper_unit_for_byte_size(max_code_root_rem_set->strong_code_roots_mem_size()), - max_code_root_rem_set->strong_code_roots_list_length()); + byte_size_in_proper_unit(max_code_root_rem_set->code_roots_mem_size()), + proper_unit_for_byte_size(max_code_root_rem_set->code_roots_mem_size()), + max_code_root_rem_set->code_roots_list_length()); } }; diff --git a/src/hotspot/share/gc/g1/g1SharedClosures.hpp b/src/hotspot/share/gc/g1/g1SharedClosures.hpp index 55b9a1e62c5..4808f0ae84f 100644 --- a/src/hotspot/share/gc/g1/g1SharedClosures.hpp +++ b/src/hotspot/share/gc/g1/g1SharedClosures.hpp @@ -37,7 +37,7 @@ public: G1ParCopyClosure _oops_in_cld; // We do not need (and actually should not) collect oops from nmethods into the // optional collection set as we already automatically collect the corresponding - // nmethods in the region's strong code roots set. So set G1BarrierNoOptRoots in + // nmethods in the region's code roots set. So set G1BarrierNoOptRoots in // this closure. // If these were present there would be opportunity for multiple threads to try // to change this oop* at the same time. Since embedded oops are not necessarily diff --git a/src/hotspot/share/gc/g1/g1YoungCollector.cpp b/src/hotspot/share/gc/g1/g1YoungCollector.cpp index 1a73ed30e26..d5e1774a8bd 100644 --- a/src/hotspot/share/gc/g1/g1YoungCollector.cpp +++ b/src/hotspot/share/gc/g1/g1YoungCollector.cpp @@ -395,7 +395,7 @@ class G1PrepareEvacuationTask : public WorkerTask { cast_to_oop(hr->bottom())->size() * HeapWordSize, p2i(hr->bottom()), hr->rem_set()->occupied(), - hr->rem_set()->strong_code_roots_list_length(), + hr->rem_set()->code_roots_list_length(), _g1h->concurrent_mark()->next_mark_bitmap()->is_marked(hr->bottom()), _g1h->is_humongous_reclaim_candidate(index), cast_to_oop(hr->bottom())->is_typeArray() diff --git a/src/hotspot/share/gc/g1/heapRegion.cpp b/src/hotspot/share/gc/g1/heapRegion.cpp index 4994070eaca..a69fdea82a6 100644 --- a/src/hotspot/share/gc/g1/heapRegion.cpp +++ b/src/hotspot/share/gc/g1/heapRegion.cpp @@ -304,28 +304,28 @@ void HeapRegion::note_self_forwarding_removal_end(size_t marked_bytes) { // Code roots support -void HeapRegion::add_strong_code_root(nmethod* nm) { +void HeapRegion::add_code_root(nmethod* nm) { HeapRegionRemSet* hrrs = rem_set(); - hrrs->add_strong_code_root(nm); + hrrs->add_code_root(nm); } -void HeapRegion::add_strong_code_root_locked(nmethod* nm) { +void HeapRegion::add_code_root_locked(nmethod* nm) { assert_locked_or_safepoint(CodeCache_lock); HeapRegionRemSet* hrrs = rem_set(); - hrrs->add_strong_code_root_locked(nm); + hrrs->add_code_root_locked(nm); } -void HeapRegion::remove_strong_code_root(nmethod* nm) { +void HeapRegion::remove_code_root(nmethod* nm) { HeapRegionRemSet* hrrs = rem_set(); - hrrs->remove_strong_code_root(nm); + hrrs->remove_code_root(nm); } -void HeapRegion::strong_code_roots_do(CodeBlobClosure* blk) const { +void HeapRegion::code_roots_do(CodeBlobClosure* blk) const { HeapRegionRemSet* hrrs = rem_set(); - hrrs->strong_code_roots_do(blk); + hrrs->code_roots_do(blk); } -class VerifyStrongCodeRootOopClosure: public OopClosure { +class VerifyCodeRootOopClosure: public OopClosure { const HeapRegion* _hr; bool _failures; bool _has_oops_in_region; @@ -353,7 +353,7 @@ class VerifyStrongCodeRootOopClosure: public OopClosure { } public: - VerifyStrongCodeRootOopClosure(const HeapRegion* hr): + VerifyCodeRootOopClosure(const HeapRegion* hr): _hr(hr), _failures(false), _has_oops_in_region(false) {} void do_oop(narrowOop* p) { do_oop_work(p); } @@ -363,11 +363,11 @@ public: bool has_oops_in_region() { return _has_oops_in_region; } }; -class VerifyStrongCodeRootCodeBlobClosure: public CodeBlobClosure { +class VerifyCodeRootCodeBlobClosure: public CodeBlobClosure { const HeapRegion* _hr; bool _failures; public: - VerifyStrongCodeRootCodeBlobClosure(const HeapRegion* hr) : + VerifyCodeRootCodeBlobClosure(const HeapRegion* hr) : _hr(hr), _failures(false) {} void do_code_blob(CodeBlob* cb) { @@ -375,14 +375,14 @@ public: if (nm != NULL) { // Verify that the nemthod is live if (!nm->is_alive()) { - log_error(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has dead nmethod " PTR_FORMAT " in its strong code roots", + log_error(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has dead nmethod " PTR_FORMAT " in its code roots", p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm)); _failures = true; } else { - VerifyStrongCodeRootOopClosure oop_cl(_hr); + VerifyCodeRootOopClosure oop_cl(_hr); nm->oops_do(&oop_cl); if (!oop_cl.has_oops_in_region()) { - log_error(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has nmethod " PTR_FORMAT " in its strong code roots with no pointers into region", + log_error(gc, verify)("region [" PTR_FORMAT "," PTR_FORMAT "] has nmethod " PTR_FORMAT " in its code roots with no pointers into region", p2i(_hr->bottom()), p2i(_hr->end()), p2i(nm)); _failures = true; } else if (oop_cl.failures()) { @@ -397,47 +397,47 @@ public: bool failures() { return _failures; } }; -void HeapRegion::verify_strong_code_roots(VerifyOption vo, bool* failures) const { +void HeapRegion::verify_code_roots(VerifyOption vo, bool* failures) const { if (!G1VerifyHeapRegionCodeRoots) { // We're not verifying code roots. return; } if (vo == VerifyOption_G1UseFullMarking) { // Marking verification during a full GC is performed after class - // unloading, code cache unloading, etc so the strong code roots + // unloading, code cache unloading, etc so the code roots // attached to each heap region are in an inconsistent state. They won't - // be consistent until the strong code roots are rebuilt after the - // actual GC. Skip verifying the strong code roots in this particular + // be consistent until the code roots are rebuilt after the + // actual GC. Skip verifying the code roots in this particular // time. assert(VerifyDuringGC, "only way to get here"); return; } HeapRegionRemSet* hrrs = rem_set(); - size_t strong_code_roots_length = hrrs->strong_code_roots_list_length(); + size_t code_roots_length = hrrs->code_roots_list_length(); // if this region is empty then there should be no entries - // on its strong code root list + // on its code root list if (is_empty()) { - if (strong_code_roots_length > 0) { + if (code_roots_length > 0) { log_error(gc, verify)("region " HR_FORMAT " is empty but has " SIZE_FORMAT " code root entries", - HR_FORMAT_PARAMS(this), strong_code_roots_length); + HR_FORMAT_PARAMS(this), code_roots_length); *failures = true; } return; } if (is_continues_humongous()) { - if (strong_code_roots_length > 0) { + if (code_roots_length > 0) { log_error(gc, verify)("region " HR_FORMAT " is a continuation of a humongous region but has " SIZE_FORMAT " code root entries", - HR_FORMAT_PARAMS(this), strong_code_roots_length); + HR_FORMAT_PARAMS(this), code_roots_length); *failures = true; } return; } - VerifyStrongCodeRootCodeBlobClosure cb_cl(this); - strong_code_roots_do(&cb_cl); + VerifyCodeRootCodeBlobClosure cb_cl(this); + code_roots_do(&cb_cl); if (cb_cl.failures()) { *failures = true; @@ -730,7 +730,7 @@ void HeapRegion::verify(VerifyOption vo, return; } - verify_strong_code_roots(vo, failures); + verify_code_roots(vo, failures); } void HeapRegion::verify_rem_set(VerifyOption vo, bool* failures) const { diff --git a/src/hotspot/share/gc/g1/heapRegion.hpp b/src/hotspot/share/gc/g1/heapRegion.hpp index 782de66a1cb..e70c6481fde 100644 --- a/src/hotspot/share/gc/g1/heapRegion.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.hpp @@ -572,20 +572,20 @@ public: // Routines for managing a list of code roots (attached to the // this region's RSet) that point into this heap region. - void add_strong_code_root(nmethod* nm); - void add_strong_code_root_locked(nmethod* nm); - void remove_strong_code_root(nmethod* nm); + void add_code_root(nmethod* nm); + void add_code_root_locked(nmethod* nm); + void remove_code_root(nmethod* nm); // Applies blk->do_code_blob() to each of the entries in - // the strong code roots list for this region - void strong_code_roots_do(CodeBlobClosure* blk) const; + // the code roots list for this region + void code_roots_do(CodeBlobClosure* blk) const; uint node_index() const { return _node_index; } void set_node_index(uint node_index) { _node_index = node_index; } - // Verify that the entries on the strong code root list for this + // Verify that the entries on the code root list for this // region are live and include at least one pointer into this region. - void verify_strong_code_roots(VerifyOption vo, bool* failures) const; + void verify_code_roots(VerifyOption vo, bool* failures) const; void print() const; void print_on(outputStream* st) const; diff --git a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp index d4570173f0e..9e6c31ffdc1 100644 --- a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp +++ b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp @@ -122,19 +122,19 @@ void HeapRegionRemSet::print_static_mem_size(outputStream* out) { // When concurrent readers access the contains() function // (during the evacuation phase) no removals are allowed. -void HeapRegionRemSet::add_strong_code_root(nmethod* nm) { +void HeapRegionRemSet::add_code_root(nmethod* nm) { assert(nm != NULL, "sanity"); assert((!CodeCache_lock->owned_by_self() || SafepointSynchronize::is_at_safepoint()), - "should call add_strong_code_root_locked instead. CodeCache_lock->owned_by_self(): %s, is_at_safepoint(): %s", + "should call add_code_root_locked instead. CodeCache_lock->owned_by_self(): %s, is_at_safepoint(): %s", BOOL_TO_STR(CodeCache_lock->owned_by_self()), BOOL_TO_STR(SafepointSynchronize::is_at_safepoint())); // Optimistic unlocked contains-check if (!_code_roots.contains(nm)) { MutexLocker ml(&_m, Mutex::_no_safepoint_check_flag); - add_strong_code_root_locked(nm); + add_code_root_locked(nm); } } -void HeapRegionRemSet::add_strong_code_root_locked(nmethod* nm) { +void HeapRegionRemSet::add_code_root_locked(nmethod* nm) { assert(nm != NULL, "sanity"); assert((CodeCache_lock->owned_by_self() || (SafepointSynchronize::is_at_safepoint() && @@ -145,7 +145,7 @@ void HeapRegionRemSet::add_strong_code_root_locked(nmethod* nm) { _code_roots.add(nm); } -void HeapRegionRemSet::remove_strong_code_root(nmethod* nm) { +void HeapRegionRemSet::remove_code_root(nmethod* nm) { assert(nm != NULL, "sanity"); assert_locked_or_safepoint(CodeCache_lock); @@ -156,14 +156,14 @@ void HeapRegionRemSet::remove_strong_code_root(nmethod* nm) { guarantee(!_code_roots.contains(nm), "duplicate entry found"); } -void HeapRegionRemSet::strong_code_roots_do(CodeBlobClosure* blk) const { +void HeapRegionRemSet::code_roots_do(CodeBlobClosure* blk) const { _code_roots.nmethods_do(blk); } -void HeapRegionRemSet::clean_strong_code_roots(HeapRegion* hr) { +void HeapRegionRemSet::clean_code_roots(HeapRegion* hr) { _code_roots.clean(hr); } -size_t HeapRegionRemSet::strong_code_roots_mem_size() { +size_t HeapRegionRemSet::code_roots_mem_size() { return _code_roots.mem_size(); } diff --git a/src/hotspot/share/gc/g1/heapRegionRemSet.hpp b/src/hotspot/share/gc/g1/heapRegionRemSet.hpp index 2a1b3c5527b..04b585661f8 100644 --- a/src/hotspot/share/gc/g1/heapRegionRemSet.hpp +++ b/src/hotspot/share/gc/g1/heapRegionRemSet.hpp @@ -73,11 +73,11 @@ public: } bool is_empty() const { - return (strong_code_roots_list_length() == 0) && cardset_is_empty(); + return (code_roots_list_length() == 0) && cardset_is_empty(); } bool occupancy_less_or_equal_than(size_t occ) const { - return (strong_code_roots_list_length() == 0) && _card_set.occupancy_less_or_equal_to(occ); + return (code_roots_list_length() == 0) && _card_set.occupancy_less_or_equal_to(occ); } // Iterate the card based remembered set for merging them into the card table. @@ -128,12 +128,12 @@ public: G1SegmentedArrayMemoryStats card_set_memory_stats() const; - // The actual # of bytes this hr_remset takes up. Also includes the strong code + // The actual # of bytes this hr_remset takes up. Also includes the code // root set. size_t mem_size() { return _card_set.mem_size() - + (sizeof(HeapRegionRemSet) - sizeof(G1CardSet)) // Avoid double-counting G1CardSet. - + strong_code_roots_mem_size(); + + (sizeof(HeapRegionRemSet) - sizeof(G1CardSet)) // Avoid double-counting G1CardSet. + + code_roots_mem_size(); } size_t wasted_mem_size() { @@ -154,30 +154,29 @@ public: // Routines for managing the list of code roots that point into // the heap region that owns this RSet. - void add_strong_code_root(nmethod* nm); - void add_strong_code_root_locked(nmethod* nm); - void remove_strong_code_root(nmethod* nm); + void add_code_root(nmethod* nm); + void add_code_root_locked(nmethod* nm); + void remove_code_root(nmethod* nm); - // Applies blk->do_code_blob() to each of the entries in - // the strong code roots list - void strong_code_roots_do(CodeBlobClosure* blk) const; + // Applies blk->do_code_blob() to each of the entries in _code_roots + void code_roots_do(CodeBlobClosure* blk) const; - void clean_strong_code_roots(HeapRegion* hr); + void clean_code_roots(HeapRegion* hr); - // Returns the number of elements in the strong code roots list - size_t strong_code_roots_list_length() const { + // Returns the number of elements in _code_roots + size_t code_roots_list_length() const { return _code_roots.length(); } - // Returns true if the strong code roots contains the given + // Returns true if the code roots contains the given // nmethod. - bool strong_code_roots_list_contains(nmethod* nm) { + bool code_roots_list_contains(nmethod* nm) { return _code_roots.contains(nm); } // Returns the amount of memory, in bytes, currently - // consumed by the strong code roots. - size_t strong_code_roots_mem_size(); + // consumed by the code roots. + size_t code_roots_mem_size(); static void invalidate_from_card_cache(uint start_idx, size_t num_regions) { G1FromCardCache::invalidate(start_idx, num_regions); -- GitLab From c5a86120df7105cf612d513b5bd394501c00efed Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Tue, 1 Feb 2022 12:23:44 +0000 Subject: [PATCH 103/400] 8280458: G1: Remove G1BlockOffsetTablePart::_next_offset_threshold Reviewed-by: tschatzl, iwalulya, sjohanss --- .../share/gc/g1/g1BlockOffsetTable.cpp | 70 +++++++------------ .../share/gc/g1/g1BlockOffsetTable.hpp | 57 +++++---------- .../share/gc/g1/g1BlockOffsetTable.inline.hpp | 6 +- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 1 - src/hotspot/share/gc/g1/g1EvacFailure.cpp | 2 - .../share/gc/g1/g1FullGCCompactionPoint.cpp | 3 - .../share/gc/g1/g1ParScanThreadState.cpp | 2 +- src/hotspot/share/gc/g1/heapRegion.cpp | 8 +-- src/hotspot/share/gc/g1/heapRegion.hpp | 11 +-- src/hotspot/share/gc/g1/heapRegion.inline.hpp | 21 +----- 10 files changed, 50 insertions(+), 131 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp index 017dd232531..7bbfe60e8a8 100644 --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp @@ -74,7 +74,6 @@ void G1BlockOffsetTable::check_index(size_t index, const char* msg) const { ////////////////////////////////////////////////////////////////////// G1BlockOffsetTablePart::G1BlockOffsetTablePart(G1BlockOffsetTable* array, HeapRegion* hr) : - _next_offset_threshold(NULL), _bot(array), _hr(hr) { @@ -204,45 +203,40 @@ void G1BlockOffsetTablePart::check_all_cards(size_t start_card, size_t end_card) } // -// threshold_ +// cur_card_boundary // | _index_ // v v // +-------+-------+-------+-------+-------+ // | i-1 | i | i+1 | i+2 | i+3 | // +-------+-------+-------+-------+-------+ // ( ^ ] -// block-start +// blk_start // -void G1BlockOffsetTablePart::alloc_block_work(HeapWord** threshold_, HeapWord* blk_start, +void G1BlockOffsetTablePart::alloc_block_work(HeapWord* blk_start, HeapWord* blk_end) { - // For efficiency, do copy-in/copy-out. - HeapWord* threshold = *threshold_; - size_t index = _bot->index_for_raw(threshold); + HeapWord* const cur_card_boundary = align_up_by_card_size(blk_start); + size_t const index = _bot->index_for_raw(cur_card_boundary); assert(blk_start != NULL && blk_end > blk_start, "phantom block"); - assert(blk_end > threshold, "should be past threshold"); - assert(blk_start <= threshold, "blk_start should be at or before threshold"); - assert(pointer_delta(threshold, blk_start) < BOTConstants::card_size_in_words(), + assert(blk_end > cur_card_boundary, "should be past cur_card_boundary"); + assert(blk_start <= cur_card_boundary, "blk_start should be at or before cur_card_boundary"); + assert(pointer_delta(cur_card_boundary, blk_start) < BOTConstants::card_size_in_words(), "offset should be < BOTConstants::card_size_in_words()"); assert(G1CollectedHeap::heap()->is_in_reserved(blk_start), "reference must be into the heap"); - assert(G1CollectedHeap::heap()->is_in_reserved(blk_end-1), + assert(G1CollectedHeap::heap()->is_in_reserved(blk_end - 1), "limit must be within the heap"); - assert(threshold == _bot->_reserved.start() + index*BOTConstants::card_size_in_words(), - "index must agree with threshold"); + assert(cur_card_boundary == _bot->_reserved.start() + index*BOTConstants::card_size_in_words(), + "index must agree with cur_card_boundary"); - DEBUG_ONLY(size_t orig_index = index;) + // Mark the card that holds the offset into the block. + _bot->set_offset_array(index, cur_card_boundary, blk_start); - // Mark the card that holds the offset into the block. Note - // that _next_offset_threshold is not updated until the end - // of this method. - _bot->set_offset_array(index, threshold, blk_start); + // We need to now mark the subsequent cards that this block spans. - // We need to now mark the subsequent cards that this blk spans. - - // Index of card on which blk ends. - size_t end_index = _bot->index_for(blk_end - 1); + // Index of card on which the block ends. + size_t end_index = _bot->index_for(blk_end - 1); // Are there more cards left to be updated? if (index + 1 <= end_index) { @@ -253,27 +247,25 @@ void G1BlockOffsetTablePart::alloc_block_work(HeapWord** threshold_, HeapWord* b set_remainder_to_point_to_start(rem_st, rem_end); } - // Calculate threshold_ this way because end_index +#ifdef ASSERT + // Calculate new_card_boundary this way because end_index // may be the last valid index in the covered region. - threshold = _bot->address_for_index(end_index) + BOTConstants::card_size_in_words(); - assert(threshold >= blk_end, "Incorrect offset threshold"); + HeapWord* new_card_boundary = _bot->address_for_index(end_index) + BOTConstants::card_size_in_words(); + assert(new_card_boundary >= blk_end, "postcondition"); - *threshold_ = threshold; - -#ifdef ASSERT // The offset can be 0 if the block starts on a boundary. That // is checked by an assertion above. size_t start_index = _bot->index_for(blk_start); HeapWord* boundary = _bot->address_for_index(start_index); - assert((_bot->offset_array(orig_index) == 0 && blk_start == boundary) || - (_bot->offset_array(orig_index) > 0 && _bot->offset_array(orig_index) < BOTConstants::card_size_in_words()), + assert((_bot->offset_array(index) == 0 && blk_start == boundary) || + (_bot->offset_array(index) > 0 && _bot->offset_array(index) < BOTConstants::card_size_in_words()), "offset array should have been set - " - "orig_index offset: %u, " + "index offset: %u, " "blk_start: " PTR_FORMAT ", " "boundary: " PTR_FORMAT, - (uint)_bot->offset_array(orig_index), + (uint)_bot->offset_array(index), p2i(blk_start), p2i(boundary)); - for (size_t j = orig_index + 1; j <= end_index; j++) { + for (size_t j = index + 1; j <= end_index; j++) { assert(_bot->offset_array(j) > 0 && _bot->offset_array(j) <= (u_char) (BOTConstants::card_size_in_words()+BOTConstants::N_powers-1), @@ -289,8 +281,6 @@ void G1BlockOffsetTablePart::alloc_block_work(HeapWord** threshold_, HeapWord* b void G1BlockOffsetTablePart::verify() const { assert(_hr->bottom() < _hr->top(), "Only non-empty regions should be verified."); size_t start_card = _bot->index_for(_hr->bottom()); - // Do not verify beyond the BOT allocation threshold. - assert(_hr->top() <= _next_offset_threshold, "invariant"); size_t end_card = _bot->index_for(_hr->top() - 1); for (size_t current_card = start_card; current_card < end_card; current_card++) { @@ -341,20 +331,10 @@ void G1BlockOffsetTablePart::print_on(outputStream* out) { i, p2i(_bot->address_for_index(i)), (uint) _bot->offset_array(i)); } - out->print_cr(" next offset threshold: " PTR_FORMAT, p2i(_next_offset_threshold)); } #endif // !PRODUCT -void G1BlockOffsetTablePart::reset_bot() { - _next_offset_threshold = _hr->bottom(); -} - -bool G1BlockOffsetTablePart::is_empty() const { - return _next_offset_threshold == _hr->bottom(); -} - void G1BlockOffsetTablePart::set_for_starts_humongous(HeapWord* obj_top, size_t fill_size) { - assert(is_empty(), "first obj"); alloc_block(_hr->bottom(), obj_top); if (fill_size > 0) { alloc_block(obj_top, fill_size); diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp index 505c528da9f..04c966a29cc 100644 --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp @@ -111,9 +111,6 @@ class G1BlockOffsetTablePart { friend class HeapRegion; friend class VMStructs; private: - // allocation boundary at which offset array must be updated - HeapWord* _next_offset_threshold; - // This is the global BlockOffsetTable. G1BlockOffsetTable* _bot; @@ -140,19 +137,23 @@ private: inline HeapWord* forward_to_block_containing_addr(HeapWord* q, HeapWord* n, const void* addr) const; - // Requires that "*threshold_" be the first array entry boundary at or - // above "blk_start". If the block starts at or crosses "*threshold_", records - // "blk_start" as the appropriate block start for the array index - // starting at "*threshold_", and for any other indices crossed by the - // block. Updates "*threshold_" to correspond to the first index after - // the block end. - void alloc_block_work(HeapWord** threshold_, - HeapWord* blk_start, - HeapWord* blk_end); + // Update BOT entries corresponding to the mem range [blk_start, blk_end). + void alloc_block_work(HeapWord* blk_start, HeapWord* blk_end); void check_all_cards(size_t left_card, size_t right_card) const; public: + static HeapWord* align_up_by_card_size(HeapWord* const addr) { + return align_up(addr, BOTConstants::card_size()); + } + + static bool is_crossing_card_boundary(HeapWord* const obj_start, + HeapWord* const obj_end) { + HeapWord* cur_card_boundary = align_up_by_card_size(obj_start); + // strictly greater-than + return obj_end > cur_card_boundary; + } + // The elements of the array are initialized to zero. G1BlockOffsetTablePart(G1BlockOffsetTable* array, HeapRegion* hr); @@ -160,43 +161,21 @@ public: void verify() const; - inline HeapWord* align_up_by_card_size(HeapWord* const addr) const; - // Returns the address of the start of the block containing "addr", or // else "null" if it is covered by no block. (May have side effects, // namely updating of shared array entries that "point" too far // backwards. This can occur, for example, when lab allocation is used // in a space covered by the table.) inline HeapWord* block_start(const void* addr); - // Same as above, but does not have any of the possible side effects - // discussed above. - inline HeapWord* block_start_const(const void* addr) const; - // Reset bot to be empty. - void reset_bot(); - - bool is_empty() const; - - // Return the next threshold, the point at which the table should be - // updated. - HeapWord* threshold() const { return _next_offset_threshold; } - - // Sets the threshold explicitly to keep it consistent with what has been - // updated. This needs to be done when the threshold is not used for updating - // the bot, for example when promoting to old in young collections. - void set_threshold(HeapWord* threshold) { _next_offset_threshold = threshold; } - - // These must be guaranteed to work properly (i.e., do nothing) - // when "blk_start" ("blk" for second version) is "NULL". In this - // implementation, that's true because NULL is represented as 0, and thus - // never exceeds the "_next_offset_threshold". void alloc_block(HeapWord* blk_start, HeapWord* blk_end) { - if (blk_end > _next_offset_threshold) { - alloc_block_work(&_next_offset_threshold, blk_start, blk_end); + if (is_crossing_card_boundary(blk_start, blk_end)) { + alloc_block_work(blk_start, blk_end); } } - void alloc_block(HeapWord* blk, size_t size) { - alloc_block(blk, blk+size); + + void alloc_block(HeapWord* blk_start, size_t size) { + alloc_block(blk_start, blk_start + size); } void set_for_starts_humongous(HeapWord* obj_top, size_t fill_size); diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp index 7ae313f2f70..f70cb118627 100644 --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp @@ -30,11 +30,7 @@ #include "gc/g1/heapRegion.hpp" #include "gc/shared/memset_with_concurrent_readers.hpp" #include "runtime/atomic.hpp" - -inline HeapWord* G1BlockOffsetTablePart::align_up_by_card_size(HeapWord* const addr) const { - assert(addr >= _hr->bottom() && addr < _hr->top(), "invalid address"); - return align_up(addr, BOTConstants::card_size()); -} +#include "oops/oop.inline.hpp" inline HeapWord* G1BlockOffsetTablePart::block_start(const void* addr) { assert(addr >= _hr->bottom() && addr < _hr->top(), "invalid address"); diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index 89c95c620ba..adc3e66d316 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -3295,7 +3295,6 @@ void G1CollectedHeap::retire_gc_alloc_region(HeapRegion* alloc_region, _bytes_used_during_gc += allocated_bytes; if (dest.is_old()) { old_set_add(alloc_region); - alloc_region->update_bot_threshold(); } else { assert(dest.is_young(), "Retiring alloc region should be young (%d)", dest.type()); _survivor.add_used_bytes(allocated_bytes); diff --git a/src/hotspot/share/gc/g1/g1EvacFailure.cpp b/src/hotspot/share/gc/g1/g1EvacFailure.cpp index fd065df17c6..2a4f46ff16e 100644 --- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp +++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp @@ -187,8 +187,6 @@ public: hr->note_self_forwarding_removal_start(during_concurrent_start, during_concurrent_mark); - hr->reset_bot(); - _phase_times->record_or_add_thread_work_item(G1GCPhaseTimes::RestoreRetainedRegions, _worker_id, 1, diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp index 25ff38da77f..527397de55e 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp @@ -47,9 +47,6 @@ void G1FullGCCompactionPoint::update() { void G1FullGCCompactionPoint::initialize_values(bool init_threshold) { _compaction_top = _current_region->compaction_top(); - if (init_threshold) { - _current_region->initialize_bot_threshold(); - } } bool G1FullGCCompactionPoint::has_regions() { diff --git a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp index f2889e78779..3cc3c5c0120 100644 --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp @@ -437,7 +437,7 @@ void G1ParScanThreadState::undo_allocation(G1HeapRegionAttr dest_attr, void G1ParScanThreadState::update_bot_after_copying(oop obj, size_t word_sz) { HeapWord* obj_start = cast_from_oop(obj); HeapRegion* region = _g1h->heap_region_containing(obj_start); - region->update_bot_if_crossing_boundary(obj_start, word_sz); + region->update_bot_for_obj(obj_start, word_sz); } // Private inline function, for direct internal use and providing the diff --git a/src/hotspot/share/gc/g1/heapRegion.cpp b/src/hotspot/share/gc/g1/heapRegion.cpp index a69fdea82a6..93baa238351 100644 --- a/src/hotspot/share/gc/g1/heapRegion.cpp +++ b/src/hotspot/share/gc/g1/heapRegion.cpp @@ -260,7 +260,6 @@ void HeapRegion::initialize(bool clear_space, bool mangle_space) { set_top(bottom()); set_compaction_top(bottom()); - reset_bot(); hr_clear(false /*clear_space*/); } @@ -780,7 +779,6 @@ void HeapRegion::clear(bool mangle_space) { if (ZapUnusedHeapArea && mangle_space) { mangle_unused_area(); } - reset_bot(); } #ifndef PRODUCT @@ -789,10 +787,6 @@ void HeapRegion::mangle_unused_area() { } #endif -void HeapRegion::initialize_bot_threshold() { - _bot_part.reset_bot(); -} - void HeapRegion::alloc_block_in_bot(HeapWord* start, HeapWord* end) { _bot_part.alloc_block(start, end); } @@ -810,7 +804,7 @@ void HeapRegion::object_iterate(ObjectClosure* blk) { void HeapRegion::fill_with_dummy_object(HeapWord* address, size_t word_size, bool zap) { // Keep the BOT in sync for old generation regions. if (is_old()) { - update_bot_if_crossing_boundary(address, word_size); + update_bot_for_obj(address, word_size); } // Fill in the object. CollectedHeap::fill_with_object(address, word_size, zap); diff --git a/src/hotspot/share/gc/g1/heapRegion.hpp b/src/hotspot/share/gc/g1/heapRegion.hpp index e70c6481fde..d3af9faf9c7 100644 --- a/src/hotspot/share/gc/g1/heapRegion.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.hpp @@ -163,11 +163,10 @@ public: inline HeapWord* allocate(size_t min_word_size, size_t desired_word_size, size_t* actual_size); // Update BOT if this obj is the first entering a new card (i.e. crossing the card boundary). - inline void update_bot_if_crossing_boundary(HeapWord* obj_start, size_t obj_size); + inline void update_bot_for_obj(HeapWord* obj_start, size_t obj_size); // Full GC support methods. - void initialize_bot_threshold(); void alloc_block_in_bot(HeapWord* start, HeapWord* end); // Update heap region that has been compacted to be consistent after Full GC. @@ -192,18 +191,10 @@ public: template inline void apply_to_marked_objects(G1CMBitMap* bitmap, ApplyToMarkedClosure* closure); - void reset_bot() { - _bot_part.reset_bot(); - } - void update_bot() { _bot_part.update(); } - void update_bot_threshold() { - _bot_part.set_threshold(top()); - } - private: // The remembered set for this region. HeapRegionRemSet* _rem_set; diff --git a/src/hotspot/share/gc/g1/heapRegion.inline.hpp b/src/hotspot/share/gc/g1/heapRegion.inline.hpp index 2a47d92a475..2f78f30b419 100644 --- a/src/hotspot/share/gc/g1/heapRegion.inline.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.inline.hpp @@ -183,10 +183,6 @@ inline void HeapRegion::reset_skip_compacting_after_full_gc() { } inline void HeapRegion::reset_after_full_gc_common() { - if (is_empty()) { - reset_bot(); - } - // Clear unused heap memory in debug builds. if (ZapUnusedHeapArea) { mangle_unused_area(); @@ -231,28 +227,17 @@ inline HeapWord* HeapRegion::allocate(size_t min_word_size, return allocate_impl(min_word_size, desired_word_size, actual_word_size); } -inline void HeapRegion::update_bot_if_crossing_boundary(HeapWord* obj_start, size_t obj_size) { +inline void HeapRegion::update_bot_for_obj(HeapWord* obj_start, size_t obj_size) { assert(is_old(), "should only do BOT updates for old regions"); - HeapWord* obj_end = obj_start + obj_size; + HeapWord* obj_end = obj_start + obj_size; assert(is_in(obj_start), "obj_start must be in this region: " HR_FORMAT " obj_start " PTR_FORMAT " obj_end " PTR_FORMAT, HR_FORMAT_PARAMS(this), p2i(obj_start), p2i(obj_end)); - HeapWord* cur_card_boundary = _bot_part.align_up_by_card_size(obj_start); - - // strictly greater-than - bool cross_card_boundary = (obj_end > cur_card_boundary); - - if (cross_card_boundary) { - // Creating a dummy variable inside this `if` as the arg of `&`; this - // avoids unnecessary loads in the assembly code on the fast path (the - // bot-not-updating case). - HeapWord* dummy = cur_card_boundary; - _bot_part.alloc_block_work(&dummy, obj_start, obj_end); - } + _bot_part.alloc_block(obj_start, obj_end); } inline void HeapRegion::note_start_of_marking() { -- GitLab From 1f6fcbe2f3da4c63976b1564ec2170e4757fadcc Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 1 Feb 2022 15:44:26 +0000 Subject: [PATCH 104/400] 8278475: G1 dirty card refinement by Java threads may get unnecessarily paused Reviewed-by: tschatzl, iwalulya --- src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp index 4ef40d29f16..22e8e218057 100644 --- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp +++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp @@ -501,6 +501,14 @@ void G1DirtyCardQueueSet::handle_completed_buffer(BufferNode* new_node, return; } + // Don't try to process a buffer that will just get immediately paused. + // When going into a safepoint it's just a waste of effort. + // When coming out of a safepoint, Java threads may be running before the + // yield request (for non-Java threads) has been cleared. + if (SuspendibleThreadSet::should_yield()) { + return; + } + // Only Java threads perform mutator refinement. if (!Thread::current()->is_Java_thread()) { return; -- GitLab From 5080e815b4385751734054b5f889c4d89cfcdeb4 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Tue, 1 Feb 2022 15:59:35 +0000 Subject: [PATCH 105/400] 8280770: serviceability/sa/ClhsdbThreadContext.java sometimes fails with 'Thread "SteadyStateThread"' missing from stdout/stderr Reviewed-by: sspitsyn, dholmes --- .../sa/ClhsdbThreadContext.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbThreadContext.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbThreadContext.java index 207978ba5c6..e84ae52e920 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbThreadContext.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbThreadContext.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Map; import jdk.test.lib.apps.LingeredApp; +import jdk.test.lib.Platform; import jtreg.SkippedException; /** @@ -82,15 +83,22 @@ public class ClhsdbThreadContext { cmdStr = "threadcontext -v " + threadID; cmds = List.of(cmdStr); expStrMap = new HashMap<>(); - expStrMap.put(cmdStr, List.of( - "Thread \"SteadyStateThread\"", - "java.lang.Thread.State: BLOCKED", - "In java stack \\[0x\\p{XDigit}+,0x\\p{XDigit}+,0x\\p{XDigit}+\\] for thread")); unexpStrMap = new HashMap<>(); - unexpStrMap.put(cmdStr, List.of( - "Thread \"Common-Cleaner\"", - "Thread \"Service Thread\"", - "Thread \"Finalizer\"")); + if (Platform.isWindows()) { + // On windows thread IDs are not guaranteed to be the same each time you attach, + // so the ID we gleaned above for SteadyStateThread may not actually be for + // SteadyStateThread when we attach for the next threadcontext command, so we + // choose not to check the result on Windows. + } else { + expStrMap.put(cmdStr, List.of( + "Thread \"SteadyStateThread\"", + "java.lang.Thread.State: BLOCKED", + "In java stack \\[0x\\p{XDigit}+,0x\\p{XDigit}+,0x\\p{XDigit}+\\] for thread")); + unexpStrMap.put(cmdStr, List.of( + "Thread \"Common-Cleaner\"", + "Thread \"Service Thread\"", + "Thread \"Finalizer\"")); + } test.run(theApp.getPid(), cmds, expStrMap, unexpStrMap); // Run threadcontext on all threads in verbose mode -- GitLab From 4532c3a1639af0b4ff8c4f42c3796fa73ca5be83 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Tue, 1 Feb 2022 16:02:10 +0000 Subject: [PATCH 106/400] 8280554: resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java can fail if GC is triggered Reviewed-by: alanb, amenkov, lmesnik --- .../serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java | 3 +-- .../serviceability/sa/LingeredAppWithLargeStringArray.java | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java b/test/hotspot/jtreg/resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java index 9e04c9ac89a..5694d0fb528 100644 --- a/test/hotspot/jtreg/resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java +++ b/test/hotspot/jtreg/resourcehogs/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -63,7 +63,6 @@ public class ClhsdbRegionDetailsScanOopsForG1 { expStrMap.put("g1regiondetails", List.of( "Region", "Eden", - "Survivor", "StartsHumongous", "ContinuesHumongous", "Free")); diff --git a/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeStringArray.java b/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeStringArray.java index bc7aec91f99..adc81b1f46d 100644 --- a/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeStringArray.java +++ b/test/hotspot/jtreg/resourcehogs/serviceability/sa/LingeredAppWithLargeStringArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -23,6 +23,8 @@ import jdk.test.lib.apps.LingeredApp; +import java.lang.ref.Reference; + public class LingeredAppWithLargeStringArray extends LingeredApp { public static void main(String args[]) { String[] hugeArray = new String[Integer.MAX_VALUE/8]; @@ -31,5 +33,6 @@ public class LingeredAppWithLargeStringArray extends LingeredApp { hugeArray[i] = new String(smallArray[i%3]); } LingeredApp.main(args); + Reference.reachabilityFence(hugeArray); } } -- GitLab From d1cc5fda8f9fe3480d661985f15c71a8a9a4a7f8 Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Tue, 1 Feb 2022 17:19:26 +0000 Subject: [PATCH 107/400] 8280941: os::print_memory_mappings() prints segment preceeding the inclusion range Reviewed-by: stefank, minqi --- src/hotspot/os/linux/os_linux.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 31b110efcbc..28477ba8bcb 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -5380,21 +5380,20 @@ bool os::supports_map_sync() { } void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) { + // Note: all ranges are "[..)" unsigned long long start = (unsigned long long)addr; unsigned long long end = start + bytes; FILE* f = os::fopen("/proc/self/maps", "r"); int num_found = 0; if (f != NULL) { - st->print("Range [%llx-%llx) contains: ", start, end); + st->print_cr("Range [%llx-%llx) contains: ", start, end); char line[512]; while(fgets(line, sizeof(line), f) == line) { - unsigned long long a1 = 0; - unsigned long long a2 = 0; - if (::sscanf(line, "%llx-%llx", &a1, &a2) == 2) { + unsigned long long segment_start = 0; + unsigned long long segment_end = 0; + if (::sscanf(line, "%llx-%llx", &segment_start, &segment_end) == 2) { // Lets print out every range which touches ours. - if ((a1 >= start && a1 < end) || // left leg in - (a2 >= start && a2 < end) || // right leg in - (a1 < start && a2 >= end)) { // superimposition + if (segment_start < end && segment_end > start) { num_found ++; st->print("%s", line); // line includes \n } @@ -5402,7 +5401,7 @@ void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) { } ::fclose(f); if (num_found == 0) { - st->print("nothing."); + st->print_cr("nothing."); } st->cr(); } -- GitLab From 2531c332f89c5faedf71ce1737373581c9abf905 Mon Sep 17 00:00:00 2001 From: Tobias Hartmann Date: Tue, 1 Feb 2022 17:41:15 +0000 Subject: [PATCH 108/400] 8278871: [JVMCI] assert((uint)reason < 2* _trap_hist_limit) failed: oob Backport-of: 6f0e8da6d3bef340299e48977d5e17d05eabe682 --- src/hotspot/share/jvmci/vmStructs_jvmci.cpp | 4 ++-- src/hotspot/share/oops/methodData.hpp | 8 +++++--- src/hotspot/share/runtime/deoptimization.cpp | 3 ++- src/hotspot/share/runtime/deoptimization.hpp | 12 +++++++----- .../src/jdk/vm/ci/hotspot/HotSpotVMConfig.java | 2 +- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index 43493e65000..928b59a834f 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -558,8 +558,8 @@ declare_constant(Deoptimization::Reason_not_compiled_exception_handler) \ declare_constant(Deoptimization::Reason_unresolved) \ declare_constant(Deoptimization::Reason_jsr_mismatch) \ - declare_constant(Deoptimization::Reason_LIMIT) \ - declare_constant(Deoptimization::_support_large_access_byte_array_virtualization) \ + declare_constant(Deoptimization::Reason_TRAP_HISTORY_LENGTH) \ + declare_constant(Deoptimization::_support_large_access_byte_array_virtualization) \ \ declare_constant(FieldInfo::access_flags_offset) \ declare_constant(FieldInfo::name_index_offset) \ diff --git a/src/hotspot/share/oops/methodData.hpp b/src/hotspot/share/oops/methodData.hpp index a33b118334e..55967e9ee19 100644 --- a/src/hotspot/share/oops/methodData.hpp +++ b/src/hotspot/share/oops/methodData.hpp @@ -30,6 +30,7 @@ #include "oops/method.hpp" #include "oops/oop.hpp" #include "runtime/atomic.hpp" +#include "runtime/deoptimization.hpp" #include "runtime/mutex.hpp" #include "utilities/align.hpp" #include "utilities/copy.hpp" @@ -1965,7 +1966,7 @@ public: // Whole-method sticky bits and flags enum { - _trap_hist_limit = 25 JVMCI_ONLY(+5), // decoupled from Deoptimization::Reason_LIMIT + _trap_hist_limit = Deoptimization::Reason_TRAP_HISTORY_LENGTH, _trap_hist_mask = max_jubyte, _extra_data_count = 4 // extra DataLayout headers, for trap history }; // Public flag values @@ -1980,6 +1981,7 @@ public: uint _nof_overflow_traps; // trap count, excluding _trap_hist union { intptr_t _align; + // JVMCI separates trap history for OSR compilations from normal compilations u1 _array[JVMCI_ONLY(2 *) MethodData::_trap_hist_limit]; } _trap_hist; @@ -1996,14 +1998,14 @@ public: // Return (uint)-1 for overflow. uint trap_count(int reason) const { - assert((uint)reason < JVMCI_ONLY(2*) _trap_hist_limit, "oob"); + assert((uint)reason < ARRAY_SIZE(_trap_hist._array), "oob"); return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1; } uint inc_trap_count(int reason) { // Count another trap, anywhere in this method. assert(reason >= 0, "must be single trap"); - assert((uint)reason < JVMCI_ONLY(2*) _trap_hist_limit, "oob"); + assert((uint)reason < ARRAY_SIZE(_trap_hist._array), "oob"); uint cnt1 = 1 + _trap_hist._array[reason]; if ((cnt1 & _trap_hist_mask) != 0) { // if no counter overflow... _trap_hist._array[reason] = cnt1; diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index ad733dcfc5a..7a89069a025 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -2279,7 +2279,8 @@ Deoptimization::query_update_method_data(MethodData* trap_mdo, uint idx = reason; #if INCLUDE_JVMCI if (is_osr) { - idx += Reason_LIMIT; + // Upper half of history array used for traps in OSR compilations + idx += Reason_TRAP_HISTORY_LENGTH; } #endif uint prior_trap_count = trap_mdo->trap_count(idx); diff --git a/src/hotspot/share/runtime/deoptimization.hpp b/src/hotspot/share/runtime/deoptimization.hpp index 74b78a853b4..35904ab3c0f 100644 --- a/src/hotspot/share/runtime/deoptimization.hpp +++ b/src/hotspot/share/runtime/deoptimization.hpp @@ -46,6 +46,7 @@ class Deoptimization : AllStatic { public: // What condition caused the deoptimization? + // Note: Keep this enum in sync. with Deoptimization::_trap_reason_name. enum DeoptReason { Reason_many = -1, // indicates presence of several reasons Reason_none = 0, // indicates absence of a relevant deopt. @@ -98,20 +99,22 @@ class Deoptimization : AllStatic { Reason_jsr_mismatch, #endif + // Used to define MethodData::_trap_hist_limit where Reason_tenured isn't included + Reason_TRAP_HISTORY_LENGTH, + // Reason_tenured is counted separately, add normal counted Reasons above. - // Related to MethodData::_trap_hist_limit where Reason_tenured isn't included - Reason_tenured, // age of the code has reached the limit + Reason_tenured = Reason_TRAP_HISTORY_LENGTH, // age of the code has reached the limit Reason_LIMIT, - // Note: Keep this enum in sync. with _trap_reason_name. - Reason_RECORDED_LIMIT = Reason_profile_predicate // some are not recorded per bc // Note: Reason_RECORDED_LIMIT should fit into 31 bits of // DataLayout::trap_bits. This dependency is enforced indirectly // via asserts, to avoid excessive direct header-to-header dependencies. // See Deoptimization::trap_state_reason and class DataLayout. + Reason_RECORDED_LIMIT = Reason_profile_predicate, // some are not recorded per bc }; // What action must be taken by the runtime? + // Note: Keep this enum in sync. with Deoptimization::_trap_action_name. enum DeoptAction { Action_none, // just interpret, do not invalidate nmethod Action_maybe_recompile, // recompile the nmethod; need not invalidate @@ -119,7 +122,6 @@ class Deoptimization : AllStatic { Action_make_not_entrant, // invalidate the nmethod, recompile (probably) Action_make_not_compilable, // invalidate the nmethod and do not compile Action_LIMIT - // Note: Keep this enum in sync. with _trap_action_name. }; enum { diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java index 1a477cf02b0..927dbed4297 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java @@ -336,7 +336,7 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess { final int deoptReasonLoopLimitCheck = getConstant("Deoptimization::Reason_loop_limit_check", Integer.class); final int deoptReasonAliasing = getConstant("Deoptimization::Reason_aliasing", Integer.class); final int deoptReasonTransferToInterpreter = getConstant("Deoptimization::Reason_transfer_to_interpreter", Integer.class); - final int deoptReasonOSROffset = getConstant("Deoptimization::Reason_LIMIT", Integer.class); + final int deoptReasonOSROffset = getConstant("Deoptimization::Reason_TRAP_HISTORY_LENGTH", Integer.class); final int deoptActionNone = getConstant("Deoptimization::Action_none", Integer.class); final int deoptActionMaybeRecompile = getConstant("Deoptimization::Action_maybe_recompile", Integer.class); -- GitLab From bde2b3783e0e9787cf2f270fcb3a54c2d4f1e5ab Mon Sep 17 00:00:00 2001 From: Jim Laskey Date: Tue, 1 Feb 2022 18:45:31 +0000 Subject: [PATCH 109/400] 8279954: java/lang/StringBuffer(StringBuilder)/HugeCapacity.java intermittently fails Reviewed-by: shade, dholmes --- test/jdk/java/lang/StringBuffer/HugeCapacity.java | 4 ++-- test/jdk/java/lang/StringBuilder/HugeCapacity.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/jdk/java/lang/StringBuffer/HugeCapacity.java b/test/jdk/java/lang/StringBuffer/HugeCapacity.java index d30d2d945b5..e3c98496c50 100644 --- a/test/jdk/java/lang/StringBuffer/HugeCapacity.java +++ b/test/jdk/java/lang/StringBuffer/HugeCapacity.java @@ -26,8 +26,8 @@ * @bug 8218227 * @summary StringBuilder/StringBuffer constructor throws confusing * NegativeArraySizeException - * @requires (sun.arch.data.model == "64" & os.maxMemory >= 6G) - * @run main/othervm -Xms5G -Xmx5G HugeCapacity + * @requires (sun.arch.data.model == "64" & os.maxMemory >= 8G) + * @run main/othervm -Xms6G -Xmx6G HugeCapacity */ public class HugeCapacity { diff --git a/test/jdk/java/lang/StringBuilder/HugeCapacity.java b/test/jdk/java/lang/StringBuilder/HugeCapacity.java index 9f1617a9dd2..a584ce1f07a 100644 --- a/test/jdk/java/lang/StringBuilder/HugeCapacity.java +++ b/test/jdk/java/lang/StringBuilder/HugeCapacity.java @@ -26,9 +26,9 @@ * @bug 8149330 8218227 * @summary Capacity should not get close to Integer.MAX_VALUE unless * necessary - * @requires (sun.arch.data.model == "64" & os.maxMemory >= 6G) - * @run main/othervm -Xms5G -Xmx5G -XX:+CompactStrings HugeCapacity true - * @run main/othervm -Xms5G -Xmx5G -XX:-CompactStrings HugeCapacity false + * @requires (sun.arch.data.model == "64" & os.maxMemory >= 8G) + * @run main/othervm -Xms6G -Xmx6G -XX:+CompactStrings HugeCapacity true + * @run main/othervm -Xms6G -Xmx6G -XX:-CompactStrings HugeCapacity false */ public class HugeCapacity { -- GitLab From d95de5c7fea4b224d6cd073a6d6921d7108bb7e1 Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Tue, 1 Feb 2022 19:33:36 +0000 Subject: [PATCH 110/400] 8255495: Support CDS Archived Heap for uncompressed oops Reviewed-by: iklam, tschatzl --- src/hotspot/share/cds/archiveUtils.cpp | 24 +++- src/hotspot/share/cds/filemap.cpp | 104 +++++++++++---- src/hotspot/share/cds/filemap.hpp | 5 +- src/hotspot/share/cds/heapShared.cpp | 61 +++++++-- src/hotspot/share/cds/heapShared.hpp | 21 ++- src/hotspot/share/cds/metaspaceShared.cpp | 34 ++++- src/hotspot/share/cds/metaspaceShared.hpp | 3 + src/hotspot/share/classfile/stringTable.cpp | 36 +++++- src/hotspot/share/gc/epsilon/epsilonHeap.hpp | 2 +- src/hotspot/share/gc/serial/serialHeap.hpp | 2 +- src/hotspot/share/memory/universe.cpp | 4 + test/hotspot/jtreg/TEST.groups | 7 + .../cds/appcds/DumpingWithNoCoops.java | 120 ++++++++++++++++++ .../cacheObject/DifferentHeapSizes.java | 6 +- 14 files changed, 367 insertions(+), 62 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/DumpingWithNoCoops.java diff --git a/src/hotspot/share/cds/archiveUtils.cpp b/src/hotspot/share/cds/archiveUtils.cpp index 27c94290c23..073c5f829d2 100644 --- a/src/hotspot/share/cds/archiveUtils.cpp +++ b/src/hotspot/share/cds/archiveUtils.cpp @@ -266,7 +266,7 @@ void WriteClosure::do_oop(oop* o) { } else { assert(HeapShared::can_write(), "sanity"); _dump_region->append_intptr_t( - (intptr_t)CompressedOops::encode_not_null(*o)); + UseCompressedOops ? (intptr_t)CompressedOops::encode_not_null(*o) : (intptr_t)((void*)(*o))); } } @@ -308,13 +308,23 @@ void ReadClosure::do_tag(int tag) { } void ReadClosure::do_oop(oop *p) { - narrowOop o = CompressedOops::narrow_oop_cast(nextPtr()); - if (CompressedOops::is_null(o) || !HeapShared::is_fully_available()) { - *p = NULL; + if (UseCompressedOops) { + narrowOop o = CompressedOops::narrow_oop_cast(nextPtr()); + if (CompressedOops::is_null(o) || !HeapShared::is_fully_available()) { + *p = NULL; + } else { + assert(HeapShared::can_use(), "sanity"); + assert(HeapShared::is_fully_available(), "must be"); + *p = HeapShared::decode_from_archive(o); + } } else { - assert(HeapShared::can_use(), "sanity"); - assert(HeapShared::is_fully_available(), "must be"); - *p = HeapShared::decode_from_archive(o); + intptr_t dumptime_oop = nextPtr(); + if (dumptime_oop == 0 || !HeapShared::is_fully_available()) { + *p = NULL; + } else { + intptr_t runtime_oop = dumptime_oop + HeapShared::runtime_delta(); + *p = cast_to_oop(runtime_oop); + } } } diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 5bf1887cfce..5128565803b 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -245,8 +245,13 @@ void FileMapHeader::populate(FileMapInfo *info, size_t core_region_alignment, _narrow_oop_mode = CompressedOops::mode(); _narrow_oop_base = CompressedOops::base(); _narrow_oop_shift = CompressedOops::shift(); - _heap_begin = CompressedOops::begin(); - _heap_end = CompressedOops::end(); + if (UseCompressedOops) { + _heap_begin = CompressedOops::begin(); + _heap_end = CompressedOops::end(); + } else { + _heap_begin = (address)G1CollectedHeap::heap()->reserved().start(); + _heap_end = (address)G1CollectedHeap::heap()->reserved().end(); + } } _compressed_oops = UseCompressedOops; _compressed_class_ptrs = UseCompressedClassPointers; @@ -316,6 +321,7 @@ void FileMapHeader::print(outputStream* st) { st->print_cr("- compressed_class_ptrs: %d", _compressed_class_ptrs); st->print_cr("- cloned_vtables_offset: " SIZE_FORMAT_HEX, _cloned_vtables_offset); st->print_cr("- serialized_data_offset: " SIZE_FORMAT_HEX, _serialized_data_offset); + st->print_cr("- heap_begin: " INTPTR_FORMAT, p2i(_heap_begin)); st->print_cr("- heap_end: " INTPTR_FORMAT, p2i(_heap_end)); st->print_cr("- jvm_ident: %s", _jvm_ident); st->print_cr("- shared_path_table_offset: " SIZE_FORMAT_HEX, _shared_path_table_offset); @@ -1491,7 +1497,11 @@ void FileMapInfo::write_region(int region, char* base, size_t size, } else if (HeapShared::is_heap_region(region)) { assert(!DynamicDumpSharedSpaces, "must be"); requested_base = base; - mapping_offset = (size_t)CompressedOops::encode_not_null(cast_to_oop(base)); + if (UseCompressedOops) { + mapping_offset = (size_t)CompressedOops::encode_not_null(cast_to_oop(base)); + } else { + mapping_offset = requested_base - (char*)G1CollectedHeap::heap()->reserved().start(); + } assert(mapping_offset == (size_t)(uint32_t)mapping_offset, "must be 32-bit only"); } else { char* requested_SharedBaseAddress = (char*)MetaspaceShared::requested_base_address(); @@ -2013,7 +2023,10 @@ bool FileMapInfo::can_use_heap_regions() { log_info(cds)(" narrow_oop_mode = %d, narrow_oop_base = " PTR_FORMAT ", narrow_oop_shift = %d", CompressedOops::mode(), p2i(CompressedOops::base()), CompressedOops::shift()); log_info(cds)(" heap range = [" PTR_FORMAT " - " PTR_FORMAT "]", - p2i(CompressedOops::begin()), p2i(CompressedOops::end())); + UseCompressedOops ? p2i(CompressedOops::begin()) : + UseG1GC ? p2i((address)G1CollectedHeap::heap()->reserved().start()) : 0L, + UseCompressedOops ? p2i(CompressedOops::end()) : + UseG1GC ? p2i((address)G1CollectedHeap::heap()->reserved().end()) : 0L); if (narrow_klass_base() != CompressedKlassPointers::base() || narrow_klass_shift() != CompressedKlassPointers::shift()) { @@ -2023,6 +2036,26 @@ bool FileMapInfo::can_use_heap_regions() { return true; } +// The address where the bottom of this shared heap region should be mapped +// at runtime +address FileMapInfo::heap_region_runtime_start_address(FileMapRegion* spc) { + assert(UseSharedSpaces, "runtime only"); + spc->assert_is_heap_region(); + if (UseCompressedOops) { + return start_address_as_decoded_from_archive(spc); + } else { + assert(is_aligned(spc->mapping_offset(), sizeof(HeapWord)), "must be"); + return header()->heap_begin() + spc->mapping_offset() + HeapShared::runtime_delta(); + } +} + +void FileMapInfo::set_shared_heap_runtime_delta(ptrdiff_t delta) { + if (UseCompressedOops) { + HeapShared::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift()); + } else { + HeapShared::set_runtime_delta(delta); + } +} // // Map the closed and open archive heap objects to the runtime java heap. @@ -2045,39 +2078,66 @@ void FileMapInfo::map_heap_regions_impl() { log_info(cds)("CDS heap data needs to be relocated because the archive was created with an incompatible oop encoding mode."); _heap_pointers_need_patching = true; } else { - MemRegion range = get_heap_regions_range_with_current_oop_encoding_mode(); - if (!CompressedOops::is_in(range)) { - log_info(cds)("CDS heap data needs to be relocated because"); - log_info(cds)("the desired range " PTR_FORMAT " - " PTR_FORMAT, p2i(range.start()), p2i(range.end())); - log_info(cds)("is outside of the heap " PTR_FORMAT " - " PTR_FORMAT, p2i(CompressedOops::begin()), p2i(CompressedOops::end())); - _heap_pointers_need_patching = true; - } else if (header()->heap_end() != CompressedOops::end()) { - log_info(cds)("CDS heap data needs to be relocated to the end of the runtime heap to reduce fragmentation"); - _heap_pointers_need_patching = true; + if (UseCompressedOops) { + MemRegion range = get_heap_regions_range_with_current_oop_encoding_mode(); + if (!CompressedOops::is_in(range)) { + log_info(cds)("CDS heap data needs to be relocated because"); + log_info(cds)("the desired range " PTR_FORMAT " - " PTR_FORMAT, p2i(range.start()), p2i(range.end())); + log_info(cds)("is outside of the heap " PTR_FORMAT " - " PTR_FORMAT, p2i(CompressedOops::begin()), p2i(CompressedOops::end())); + _heap_pointers_need_patching = true; + } else if (header()->heap_end() != CompressedOops::end()) { + log_info(cds)("CDS heap data needs to be relocated to the end of the runtime heap to reduce fragmentation"); + _heap_pointers_need_patching = true; + } + } else { + MemRegion range((HeapWord*)header()->heap_begin(), (HeapWord*)header()->heap_end()); + if (!G1CollectedHeap::heap()->reserved().contains(range)) { + log_info(cds)("CDS heap data needs to be relocated because"); + log_info(cds)("the desired range " PTR_FORMAT " - " PTR_FORMAT, p2i(range.start()), p2i(range.end())); + log_info(cds)("is outside of the heap " PTR_FORMAT " - " PTR_FORMAT, + p2i((address)G1CollectedHeap::heap()->reserved().start()), p2i((address)G1CollectedHeap::heap()->reserved().end())); + _heap_pointers_need_patching = true; + } else if (header()->heap_end() != (address)G1CollectedHeap::heap()->reserved().end()) { + log_info(cds)("CDS heap data needs to be relocated to the end of the runtime heap to reduce fragmentation"); + _heap_pointers_need_patching = true; + } } } ptrdiff_t delta = 0; if (_heap_pointers_need_patching) { // dumptime heap end ------------v - // [ |archived heap regions| ] runtime heap end ------v + // [ |archived heap regions| ] run time heap end -----v // [ |archived heap regions| ] + // ^ + // D ^ + // R // |<-----delta-------------------->| // // At dump time, the archived heap regions were near the top of the heap. - // At run time, they may not be inside the heap, so we move them so - // that they are now near the top of the runtime time. This can be done by + // At run time, if the heap ends at a different address, we need to + // move them near to top of the run time heap. This can be done by // the simple math of adding the delta as shown above. + // + // Also: D = bottom of a heap region at dump time + // R = bottom of a heap region at run time + // + // FileMapRegion* spc = ...; + // address D = header()->heap_begin() + spc->mapping_offset(); + // address R = D + delta; address dumptime_heap_end = header()->heap_end(); - address runtime_heap_end = CompressedOops::end(); + address runtime_heap_end = UseCompressedOops ? CompressedOops::end() : + (address)G1CollectedHeap::heap()->reserved().end(); delta = runtime_heap_end - dumptime_heap_end; } log_info(cds)("CDS heap data relocation delta = " INTX_FORMAT " bytes", delta); - HeapShared::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift()); + + set_shared_heap_runtime_delta(delta); FileMapRegion* si = space_at(MetaspaceShared::first_closed_heap_region); - address relocated_closed_heap_region_bottom = start_address_as_decoded_from_archive(si); + address relocated_closed_heap_region_bottom = heap_region_runtime_start_address(si); + if (!is_aligned(relocated_closed_heap_region_bottom, HeapRegion::GrainBytes)) { // Align the bottom of the closed archive heap regions at G1 region boundary. // This will avoid the situation where the highest open region and the lowest @@ -2088,9 +2148,9 @@ void FileMapInfo::map_heap_regions_impl() { log_info(cds)("CDS heap data needs to be relocated lower by a further " SIZE_FORMAT " bytes to " INTX_FORMAT " to be aligned with HeapRegion::GrainBytes", align, delta); - HeapShared::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift()); + set_shared_heap_runtime_delta(delta); + relocated_closed_heap_region_bottom = heap_region_runtime_start_address(si); _heap_pointers_need_patching = true; - relocated_closed_heap_region_bottom = start_address_as_decoded_from_archive(si); } assert(is_aligned(relocated_closed_heap_region_bottom, HeapRegion::GrainBytes), "must be"); @@ -2148,7 +2208,7 @@ bool FileMapInfo::map_heap_regions(int first, int max, bool is_open_archive, si = space_at(i); size_t size = si->used(); if (size > 0) { - HeapWord* start = (HeapWord*)start_address_as_decoded_from_archive(si); + HeapWord* start = (HeapWord*)heap_region_runtime_start_address(si); regions[num_regions] = MemRegion(start, size / HeapWordSize); num_regions ++; log_info(cds)("Trying to map heap data: region[%d] at " INTPTR_FORMAT ", size = " SIZE_FORMAT_W(8) " bytes", diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp index ac2ad867f79..e6655858187 100644 --- a/src/hotspot/share/cds/filemap.hpp +++ b/src/hotspot/share/cds/filemap.hpp @@ -351,9 +351,8 @@ private: static bool _memory_mapping_failed; static GrowableArray* _non_existent_class_paths; - FileMapHeader *header() const { return _header; } - public: + FileMapHeader *header() const { return _header; } static bool get_base_archive_name_from_header(const char* archive_name, char** base_archive_name); static SharedPathTable shared_path_table() { @@ -568,6 +567,8 @@ public: bool can_use_heap_regions(); bool load_heap_regions() NOT_CDS_JAVA_HEAP_RETURN_(false); bool map_heap_regions() NOT_CDS_JAVA_HEAP_RETURN_(false); + address heap_region_runtime_start_address(FileMapRegion* spc) NOT_CDS_JAVA_HEAP_RETURN_(NULL); + void set_shared_heap_runtime_delta(ptrdiff_t delta) NOT_CDS_JAVA_HEAP_RETURN; void map_heap_regions_impl() NOT_CDS_JAVA_HEAP_RETURN; MapArchiveResult map_region(int i, intx addr_delta, char* mapped_base_address, ReservedSpace rs); bool relocate_pointers_in_core_regions(intx addr_delta); diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index a224db848bb..f519daabbe5 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -76,6 +76,7 @@ address HeapShared::_narrow_oop_base; int HeapShared::_narrow_oop_shift; DumpedInternedStrings *HeapShared::_dumped_interned_strings = NULL; +// Support for loaded heap. uintptr_t HeapShared::_loaded_heap_bottom = 0; uintptr_t HeapShared::_loaded_heap_top = 0; uintptr_t HeapShared::_dumptime_base_0 = UINTPTR_MAX; @@ -88,6 +89,10 @@ intx HeapShared::_runtime_offset_1 = 0; intx HeapShared::_runtime_offset_2 = 0; intx HeapShared::_runtime_offset_3 = 0; bool HeapShared::_loading_failed = false; + +// Suport for mapped heap (!UseCompressedOops only) +ptrdiff_t HeapShared::_runtime_delta = 0; + // // If you add new entries to the following tables, you should know what you're doing! // @@ -362,7 +367,10 @@ void HeapShared::archive_objects(GrowableArray* closed_regions, create_archived_object_cache(); log_info(cds)("Heap range = [" PTR_FORMAT " - " PTR_FORMAT "]", - p2i(CompressedOops::begin()), p2i(CompressedOops::end())); + UseCompressedOops ? p2i(CompressedOops::begin()) : + p2i((address)G1CollectedHeap::heap()->reserved().start()), + UseCompressedOops ? p2i(CompressedOops::end()) : + p2i((address)G1CollectedHeap::heap()->reserved().end())); log_info(cds)("Dumping objects to closed archive heap region ..."); copy_closed_objects(closed_regions); @@ -658,7 +666,6 @@ void HeapShared::write_subgraph_info_table() { CompactHashtableWriter writer(d_table->_count, &stats); CopyKlassSubGraphInfoToArchive copy(&writer); d_table->iterate(©); - writer.dump(&_run_time_subgraph_info_table, "subgraphs"); } @@ -1400,39 +1407,44 @@ void HeapShared::add_to_dumped_interned_strings(oop string) { // region. This way we can quickly relocate all the pointers without using // BasicOopIterateClosure at runtime. class FindEmbeddedNonNullPointers: public BasicOopIterateClosure { - narrowOop* _start; + void* _start; BitMap *_oopmap; int _num_total_oops; int _num_null_oops; public: - FindEmbeddedNonNullPointers(narrowOop* start, BitMap* oopmap) + FindEmbeddedNonNullPointers(void* start, BitMap* oopmap) : _start(start), _oopmap(oopmap), _num_total_oops(0), _num_null_oops(0) {} virtual void do_oop(narrowOop* p) { _num_total_oops ++; narrowOop v = *p; if (!CompressedOops::is_null(v)) { - size_t idx = p - _start; + size_t idx = p - (narrowOop*)_start; _oopmap->set_bit(idx); } else { _num_null_oops ++; } } - virtual void do_oop(oop *p) { - ShouldNotReachHere(); + virtual void do_oop(oop* p) { + _num_total_oops ++; + if ((*p) != NULL) { + size_t idx = p - (oop*)_start; + _oopmap->set_bit(idx); + } else { + _num_null_oops ++; + } } int num_total_oops() const { return _num_total_oops; } int num_null_oops() const { return _num_null_oops; } }; ResourceBitMap HeapShared::calculate_oopmap(MemRegion region) { - assert(UseCompressedOops, "must be"); - size_t num_bits = region.byte_size() / sizeof(narrowOop); + size_t num_bits = region.byte_size() / (UseCompressedOops ? sizeof(narrowOop) : sizeof(oop)); ResourceBitMap oopmap(num_bits); HeapWord* p = region.start(); HeapWord* end = region.end(); - FindEmbeddedNonNullPointers finder((narrowOop*)p, &oopmap); + FindEmbeddedNonNullPointers finder((void*)p, &oopmap); ArchiveBuilder* builder = DumpSharedSpaces ? ArchiveBuilder::current() : NULL; int num_objs = 0; @@ -1453,11 +1465,11 @@ ResourceBitMap HeapShared::calculate_oopmap(MemRegion region) { // Patch all the embedded oop pointers inside an archived heap region, // to be consistent with the runtime oop encoding. -class PatchEmbeddedPointers: public BitMapClosure { +class PatchCompressedEmbeddedPointers: public BitMapClosure { narrowOop* _start; public: - PatchEmbeddedPointers(narrowOop* start) : _start(start) {} + PatchCompressedEmbeddedPointers(narrowOop* start) : _start(start) {} bool do_bit(size_t offset) { narrowOop* p = _start + offset; @@ -1469,6 +1481,22 @@ class PatchEmbeddedPointers: public BitMapClosure { } }; +class PatchUncompressedEmbeddedPointers: public BitMapClosure { + oop* _start; + + public: + PatchUncompressedEmbeddedPointers(oop* start) : _start(start) {} + + bool do_bit(size_t offset) { + oop* p = _start + offset; + intptr_t dumptime_oop = (intptr_t)((void*)*p); + assert(dumptime_oop != 0, "null oops should have been filtered out at dump time"); + intptr_t runtime_oop = dumptime_oop + HeapShared::runtime_delta(); + RawAccess::oop_store(p, cast_to_oop(runtime_oop)); + return true; + } +}; + // Patch all the non-null pointers that are embedded in the archived heap objects // in this region void HeapShared::patch_embedded_pointers(MemRegion region, address oopmap, @@ -1481,8 +1509,13 @@ void HeapShared::patch_embedded_pointers(MemRegion region, address oopmap, assert(bm.is_same(checkBm), "sanity"); #endif - PatchEmbeddedPointers patcher((narrowOop*)region.start()); - bm.iterate(&patcher); + if (UseCompressedOops) { + PatchCompressedEmbeddedPointers patcher((narrowOop*)region.start()); + bm.iterate(&patcher); + } else { + PatchUncompressedEmbeddedPointers patcher((oop*)region.start()); + bm.iterate(&patcher); + } } // The CDS archive remembers each heap object by its address at dump time, but diff --git a/src/hotspot/share/cds/heapShared.hpp b/src/hotspot/share/cds/heapShared.hpp index 6447b124d2f..fc7a0bcb57a 100644 --- a/src/hotspot/share/cds/heapShared.hpp +++ b/src/hotspot/share/cds/heapShared.hpp @@ -159,7 +159,7 @@ public: if (_disable_writing) { return false; } - return (UseG1GC && UseCompressedOops && UseCompressedClassPointers); + return (UseG1GC && UseCompressedClassPointers); ) NOT_CDS_JAVA_HEAP(return false;) } @@ -169,7 +169,7 @@ public: } // Can this VM map archived heap regions? Currently only G1+compressed{oops,cp} static bool can_map() { - CDS_JAVA_HEAP_ONLY(return (UseG1GC && UseCompressedOops && UseCompressedClassPointers);) + CDS_JAVA_HEAP_ONLY(return (UseG1GC && UseCompressedClassPointers);) NOT_CDS_JAVA_HEAP(return false;) } static bool is_mapped() { @@ -297,10 +297,13 @@ private: static void init_subgraph_entry_fields(ArchivableStaticFieldInfo fields[], int num, TRAPS); - // Used by decode_from_archive + // UseCompressedOops only: Used by decode_from_archive static address _narrow_oop_base; static int _narrow_oop_shift; + // !UseCompressedOops only: used to relocate pointers to the archived objects + static ptrdiff_t _runtime_delta; + typedef ResourceHashtable max_heap_size) { + log_debug(cds)("Setting MinHeapSize to 4G for CDS dumping, original size = " SIZE_FORMAT "M", MinHeapSize/M); + FLAG_SET_ERGO(MinHeapSize, max_heap_size); + } + if (InitialHeapSize > max_heap_size) { + log_debug(cds)("Setting InitialHeapSize to 4G for CDS dumping, original size = " SIZE_FORMAT "M", InitialHeapSize/M); + FLAG_SET_ERGO(InitialHeapSize, max_heap_size); + } + if (MaxHeapSize > max_heap_size) { + log_debug(cds)("Setting MaxHeapSize to 4G for CDS dumping, original size = " SIZE_FORMAT "M", MaxHeapSize/M); + FLAG_SET_ERGO(MaxHeapSize, max_heap_size); + } +} +#endif // INCLUDE_CDS_JAVA_HEAP && _LP64 + void MetaspaceShared::preload_classes(TRAPS) { char default_classlist[JVM_MAXPATHLEN]; const char* classlist_path; @@ -834,11 +859,10 @@ bool MetaspaceShared::try_link_class(JavaThread* current, InstanceKlass* ik) { void VM_PopulateDumpSharedSpace::dump_java_heap_objects(GrowableArray* klasses) { if(!HeapShared::can_write()) { log_info(cds)( - "Archived java heap is not supported as UseG1GC, " - "UseCompressedOops and UseCompressedClassPointers are required." - "Current settings: UseG1GC=%s, UseCompressedOops=%s, UseCompressedClassPointers=%s.", - BOOL_TO_STR(UseG1GC), BOOL_TO_STR(UseCompressedOops), - BOOL_TO_STR(UseCompressedClassPointers)); + "Archived java heap is not supported as UseG1GC " + "and UseCompressedClassPointers are required." + "Current settings: UseG1GC=%s, UseCompressedClassPointers=%s.", + BOOL_TO_STR(UseG1GC), BOOL_TO_STR(UseCompressedClassPointers)); return; } // Find all the interned strings that should be dumped. diff --git a/src/hotspot/share/cds/metaspaceShared.hpp b/src/hotspot/share/cds/metaspaceShared.hpp index c7d64d7de0c..63c1089bd27 100644 --- a/src/hotspot/share/cds/metaspaceShared.hpp +++ b/src/hotspot/share/cds/metaspaceShared.hpp @@ -82,6 +82,9 @@ class MetaspaceShared : AllStatic { static void prepare_for_dumping() NOT_CDS_RETURN; static void preload_and_dump() NOT_CDS_RETURN; +#ifdef _LP64 + static void adjust_heap_sizes_for_dumping() NOT_CDS_JAVA_HEAP_RETURN; +#endif private: static void preload_and_dump_impl(TRAPS) NOT_CDS_RETURN; diff --git a/src/hotspot/share/classfile/stringTable.cpp b/src/hotspot/share/classfile/stringTable.cpp index c43f940b790..e3015a02eb5 100644 --- a/src/hotspot/share/classfile/stringTable.cpp +++ b/src/hotspot/share/classfile/stringTable.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "cds/archiveBuilder.hpp" +#include "cds/filemap.hpp" #include "cds/heapShared.inline.hpp" #include "classfile/altHashing.hpp" #include "classfile/compactHashtable.hpp" @@ -55,6 +56,9 @@ #include "utilities/macros.hpp" #include "utilities/resizeableResourceHash.hpp" #include "utilities/utf8.hpp" +#if INCLUDE_G1GC +#include "gc/g1/g1CollectedHeap.hpp" +#endif // We prefer short chains of avg 2 const double PREF_AVG_LIST_LEN = 2.0; @@ -67,9 +71,18 @@ const double CLEAN_DEAD_HIGH_WATER_MARK = 0.5; #if INCLUDE_CDS_JAVA_HEAP inline oop read_string_from_compact_hashtable(address base_address, u4 offset) { - assert(sizeof(narrowOop) == sizeof(offset), "must be"); - narrowOop v = CompressedOops::narrow_oop_cast(offset); - return HeapShared::decode_from_archive(v); + if (UseCompressedOops) { + assert(sizeof(narrowOop) == sizeof(offset), "must be"); + narrowOop v = CompressedOops::narrow_oop_cast(offset); + return HeapShared::decode_from_archive(v); + } else { + intptr_t dumptime_oop = (uintptr_t)offset; + assert(dumptime_oop != 0, "null strings cannot be interned"); + intptr_t runtime_oop = dumptime_oop + + (intptr_t)FileMapInfo::current_info()->header()->heap_begin() + + (intptr_t)HeapShared::runtime_delta(); + return (oop)cast_to_oop(runtime_oop); + } } typedef CompactHashtable< @@ -746,6 +759,16 @@ oop StringTable::create_archived_string(oop s) { class CopyToArchive : StackObj { CompactHashtableWriter* _writer; +private: + u4 compute_delta(oop s) { + HeapWord* start = G1CollectedHeap::heap()->reserved().start(); + intx offset = ((address)(void*)s) - ((address)(void*)start); + assert(offset >= 0, "must be"); + if (offset > 0xffffffff) { + fatal("too large"); + } + return (u4)offset; + } public: CopyToArchive(CompactHashtableWriter* writer) : _writer(writer) {} bool do_entry(oop s, bool value_ignored) { @@ -757,7 +780,11 @@ public: } // add to the compact table - _writer->add(hash, CompressedOops::narrow_oop_value(new_s)); + if (UseCompressedOops) { + _writer->add(hash, CompressedOops::narrow_oop_value(new_s)); + } else { + _writer->add(hash, compute_delta(new_s)); + } return true; } }; @@ -771,7 +798,6 @@ void StringTable::write_to_archive(const DumpedInternedStrings* dumped_interned_ // Copy the interned strings into the "string space" within the java heap CopyToArchive copier(&writer); dumped_interned_strings->iterate(&copier); - writer.dump(&_shared_table, "string"); } diff --git a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp index 0f929b64bd9..036593c72ae 100644 --- a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp +++ b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp @@ -132,7 +132,7 @@ public: bool is_in_reserved(const void* addr) const { return _reserved.contains(addr); } // Support for loading objects from CDS archive into the heap - virtual bool can_load_archived_objects() const { return true; } + virtual bool can_load_archived_objects() const { return UseCompressedOops; } virtual HeapWord* allocate_loaded_archive_space(size_t size); virtual void print_on(outputStream* st) const; diff --git a/src/hotspot/share/gc/serial/serialHeap.hpp b/src/hotspot/share/gc/serial/serialHeap.hpp index 0451a9679a4..f71b4a6740c 100644 --- a/src/hotspot/share/gc/serial/serialHeap.hpp +++ b/src/hotspot/share/gc/serial/serialHeap.hpp @@ -105,7 +105,7 @@ public: virtual void safepoint_synchronize_end(); // Support for loading objects from CDS archive into the heap - bool can_load_archived_objects() const { return true; } + bool can_load_archived_objects() const { return UseCompressedOops; } HeapWord* allocate_loaded_archive_space(size_t size); void complete_loaded_archive_space(MemRegion archive_space); }; diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp index 5ec4f4860ab..998ff620f08 100644 --- a/src/hotspot/share/memory/universe.cpp +++ b/src/hotspot/share/memory/universe.cpp @@ -748,6 +748,10 @@ jint universe_init() { GCLogPrecious::initialize(); +#ifdef _LP64 + MetaspaceShared::adjust_heap_sizes_for_dumping(); +#endif // _LP64 + GCConfig::arguments()->initialize_heap_sizes(); jint status = Universe::initialize_heap(); diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index 63759898530..dece67b5474 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -46,6 +46,10 @@ hotspot_gc = \ hotspot_runtime = \ runtime +hotspot_runtime_no_cds = \ + runtime \ + -runtime/cds + hotspot_handshake = \ runtime/handshake @@ -384,6 +388,8 @@ hotspot_cds = \ runtime/cds/ \ runtime/CompressedOops/ +hotspot_cds_only = \ + runtime/cds/ hotspot_appcds_dynamic = \ runtime/cds/appcds/ \ @@ -405,6 +411,7 @@ hotspot_appcds_dynamic = \ -runtime/cds/appcds/BadBSM.java \ -runtime/cds/appcds/DumpClassList.java \ -runtime/cds/appcds/DumpClassListWithLF.java \ + -runtime/cds/appcds/DumpingWithNoCoops.java \ -runtime/cds/appcds/ExtraSymbols.java \ -runtime/cds/appcds/LambdaContainsOldInf.java \ -runtime/cds/appcds/LambdaEagerInit.java \ diff --git a/test/hotspot/jtreg/runtime/cds/appcds/DumpingWithNoCoops.java b/test/hotspot/jtreg/runtime/cds/appcds/DumpingWithNoCoops.java new file mode 100644 index 00000000000..00fed755b7e --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/DumpingWithNoCoops.java @@ -0,0 +1,120 @@ +/* + * 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. + * + * 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 8255495 + * @summary Test CDS with UseCompressedOops disable with various heap sizes. + * @requires vm.cds.write.archived.java.heap + * @requires vm.gc.G1 + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds + * @compile test-classes/Hello.java + * @run driver DumpingWithNoCoops + */ + +import java.util.ArrayList; +import java.util.List; + +import jdk.test.lib.process.OutputAnalyzer; + +public class DumpingWithNoCoops { + static class HeapArgs { + int initialSize, minSize, maxSize; + HeapArgs(int initial, int min, int max) { + initialSize = initial; + minSize = min; + maxSize = max; + } + String heapArgsString(HeapArgs ha) { + String heapArgs = ""; + if (ha.initialSize > 0) { + heapArgs += "-XX:InitialHeapSize=" + ha.initialSize + "g"; + } + if (ha.minSize > 0) { + if (heapArgs.length() > 0) { + heapArgs += " "; + } + heapArgs += "-XX:MinHeapSize=" + ha.minSize + "g"; + } + if (ha.maxSize > 0) { + if (heapArgs.length() > 0) { + heapArgs += " "; + } + heapArgs += "-XX:MaxHeapSize=" + ha.maxSize + "g"; + } + return heapArgs; + } + } + + static HeapArgs[] heapArgsCases = { + // InitialHeapSize, MinHeapSize, MaxHeapSize + // all sizes are in the unit of GB + // size of 0 means don't set the heap size + new HeapArgs( 0, 0, 0), + new HeapArgs( 8, 0, 0), + new HeapArgs( 0, 8, 0), + new HeapArgs( 0, 0, 8), + new HeapArgs( 8, 8, 0), + new HeapArgs( 0, 8, 8), + new HeapArgs( 8, 0, 8), + new HeapArgs( 8, 8, 8), + new HeapArgs( 2, 1, 33), + }; + + public static void main(String[] args) throws Exception { + final String noCoops = "-XX:-UseCompressedOops"; + final String logArg = "-Xlog:gc+heap=trace,cds=debug"; + JarBuilder.getOrCreateHelloJar(); + String appJar = TestCommon.getTestJar("hello.jar"); + String appClasses[] = TestCommon.list("Hello"); + + for (HeapArgs ha : heapArgsCases) { + String heapArg = ha.heapArgsString(ha); + List dumptimeArgs = new ArrayList(); + // UseCompressedOops is ergonomically disabled for MaxHeapSize > 32g. + if (ha.maxSize < 32) { + dumptimeArgs.add(noCoops); + } + dumptimeArgs.add(logArg); + OutputAnalyzer output; + if (heapArg.length() == 0) { + System.out.println("\n Test without heap args\n"); + output = TestCommon.dump(appJar, appClasses, dumptimeArgs.toArray(new String[0])); + } else { + System.out.println("\n Test with heap args: " + heapArg + "\n"); + String[] heapSizes = heapArg.split(" "); + for (String heapSize : heapSizes) { + dumptimeArgs.add(heapSize); + } + output = TestCommon.dump(appJar, appClasses, dumptimeArgs.toArray(new String[0])); + output.shouldContain("Setting MaxHeapSize to 4G for CDS dumping"); + } + TestCommon.checkDump(output); + + TestCommon.run("-cp", appJar, + logArg, "-Xlog:class+load", noCoops, "Hello") + .assertNormalExit("Hello source: shared objects file"); + } + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/DifferentHeapSizes.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/DifferentHeapSizes.java index 4afbb705c88..fa9482abebd 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/DifferentHeapSizes.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/DifferentHeapSizes.java @@ -62,6 +62,8 @@ public class DifferentHeapSizes { JarBuilder.getOrCreateHelloJar(); String appJar = TestCommon.getTestJar("hello.jar"); String appClasses[] = TestCommon.list("Hello"); + WhiteBox wb = WhiteBox.getWhiteBox(); + boolean useCompressedOops = wb.getBooleanVMFlag("UseCompressedOops"); for (Scenario s : scenarios) { String dumpXmx = "-Xmx" + s.dumpSize + "m"; @@ -71,7 +73,7 @@ public class DifferentHeapSizes { String runXmx = "-Xmx" + runSize + "m"; CDSTestUtils.Result result = TestCommon.run("-cp", appJar, "-showversion", "-Xlog:cds", runXmx, DEDUP, "Hello"); - if (runSize < 32768) { + if (runSize < 32768 || !useCompressedOops) { result .assertNormalExit("Hello World") .assertNormalExit(out -> { @@ -88,7 +90,7 @@ public class DifferentHeapSizes { // Test various settings of -XX:HeapBaseMinAddress that would trigger // "CDS heap data need to be relocated because the desired range ... is outside of the heap" - long default_base = WhiteBox.getWhiteBox().getSizeTVMFlag("HeapBaseMinAddress").longValue(); + long default_base = wb.getSizeTVMFlag("HeapBaseMinAddress").longValue(); long M = 1024 * 1024; long bases[] = new long[] { /* dump xmx */ /* run xmx */ /* dump base */ /* run base */ -- GitLab From fdd9ca74bd6ca87c30be2bcdcfd22e19b7687a5a Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Tue, 1 Feb 2022 20:13:14 +0000 Subject: [PATCH 111/400] 8280642: ObjectInputStream.readObject should throw InvalidClassException instead of IllegalAccessError Reviewed-by: naoto, mchung --- .../classes/java/io/ObjectInputStream.java | 4 ++++ .../loadProxyClasses/LoadProxyClasses.java | 17 +++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java index dec50deb9c9..714785cd117 100644 --- a/src/java.base/share/classes/java/io/ObjectInputStream.java +++ b/src/java.base/share/classes/java/io/ObjectInputStream.java @@ -1995,6 +1995,10 @@ public class ObjectInputStream } } catch (ClassNotFoundException ex) { resolveEx = ex; + } catch (IllegalAccessError aie) { + IOException ice = new InvalidClassException(aie.getMessage()); + ice.initCause(aie); + throw ice; } catch (OutOfMemoryError memerr) { IOException ex = new InvalidObjectException("Proxy interface limit exceeded: " + Arrays.toString(ifaces)); diff --git a/test/jdk/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java b/test/jdk/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java index 9b8ed213160..568eeb1e6be 100644 --- a/test/jdk/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java +++ b/test/jdk/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -22,7 +22,7 @@ */ /* @test - * + * @bug 8280642 * @summary functional test for RMIClassLoader.loadProxyClass; test * ensures that the default RMI class loader provider implements * RMIClassLoader.loadProxyClass correctly. @@ -48,6 +48,7 @@ import java.rmi.MarshalledObject; import java.net.URL; import java.net.URLClassLoader; import java.io.Serializable; +import java.io.InvalidClassException; import java.io.IOException; import java.util.Arrays; @@ -205,20 +206,20 @@ public class LoadProxyClasses { currentThread.getContextClassLoader(); currentThread.setContextClassLoader(nonpublicLoaderB); - IllegalAccessError illegal = null; + InvalidClassException invalid = null; try { unmarshalProxyClass(proxy4, fnnLoader2, nonpublicLoaderB, 4, null); - } catch (IllegalAccessError e) { - illegal = e; + } catch (InvalidClassException e) { + invalid = e; } - if (illegal == null) { - TestLibrary.bomb("case4: IllegalAccessError not thrown " + + if (invalid == null) { + TestLibrary.bomb("case4: InvalidClassException not thrown " + "when multiple nonpublic interfaces have \n" + "different class loaders"); } else { - System.err.println("\ncase4: IllegalAccessError correctly " + + System.err.println("\ncase4: InvalidClassException correctly " + "thrown \n when trying to load proxy " + "with multiple nonpublic interfaces in \n" + " different class loaders"); -- GitLab From a18beb4797a1ca6fc6b31e997be48b2bd91c6ac0 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 1 Feb 2022 20:55:39 +0000 Subject: [PATCH 112/400] 8280867: Cpuid1Ecx feature parsing is incorrect for AMD CPUs Reviewed-by: kvn, dlong --- src/hotspot/cpu/x86/vm_version_x86.hpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/hotspot/cpu/x86/vm_version_x86.hpp b/src/hotspot/cpu/x86/vm_version_x86.hpp index 27342dbdc96..2fd1bbc9617 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.hpp +++ b/src/hotspot/cpu/x86/vm_version_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -148,12 +148,11 @@ class VM_Version : public Abstract_VM_Version { uint32_t LahfSahf : 1, CmpLegacy : 1, : 3, - lzcnt_intel : 1, lzcnt : 1, sse4a : 1, misalignsse : 1, prefetchw : 1, - : 22; + : 23; } bits; }; @@ -640,10 +639,10 @@ protected: // Intel features. if (is_intel()) { - if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0) + if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0) { result |= CPU_LZCNT; - // for Intel, ecx.bits.misalignsse bit (bit 8) indicates support for prefetchw - if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) { + } + if (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0) { result |= CPU_3DNOW_PREFETCH; } if (_cpuid_info.sef_cpuid7_ebx.bits.clwb != 0) { @@ -655,10 +654,10 @@ protected: // ZX features. if (is_zx()) { - if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt_intel != 0) + if (_cpuid_info.ext_cpuid1_ecx.bits.lzcnt != 0) { result |= CPU_LZCNT; - // for ZX, ecx.bits.misalignsse bit (bit 8) indicates support for prefetchw - if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) { + } + if (_cpuid_info.ext_cpuid1_ecx.bits.prefetchw != 0) { result |= CPU_3DNOW_PREFETCH; } } -- GitLab From c74b8f48fad8380dbd811e4a42c361006e13021d Mon Sep 17 00:00:00 2001 From: Boris Ulasevich Date: Tue, 1 Feb 2022 20:56:57 +0000 Subject: [PATCH 113/400] 8275914: SHA3: changing java implementation to help C2 create high-performance code Reviewed-by: ascarpino, phh --- .../classes/sun/security/provider/SHA3.java | 211 ++++++++++-------- 1 file changed, 116 insertions(+), 95 deletions(-) diff --git a/src/java.base/share/classes/sun/security/provider/SHA3.java b/src/java.base/share/classes/sun/security/provider/SHA3.java index fb21e3ceb6e..f8fdf8790a8 100644 --- a/src/java.base/share/classes/sun/security/provider/SHA3.java +++ b/src/java.base/share/classes/sun/security/provider/SHA3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -158,99 +158,6 @@ abstract class SHA3 extends DigestBase { } } - /** - * Step mapping Theta as defined in section 3.2.1 . - */ - private static long[] smTheta(long[] a) { - long c0 = a[0]^a[5]^a[10]^a[15]^a[20]; - long c1 = a[1]^a[6]^a[11]^a[16]^a[21]; - long c2 = a[2]^a[7]^a[12]^a[17]^a[22]; - long c3 = a[3]^a[8]^a[13]^a[18]^a[23]; - long c4 = a[4]^a[9]^a[14]^a[19]^a[24]; - long d0 = c4 ^ Long.rotateLeft(c1, 1); - long d1 = c0 ^ Long.rotateLeft(c2, 1); - long d2 = c1 ^ Long.rotateLeft(c3, 1); - long d3 = c2 ^ Long.rotateLeft(c4, 1); - long d4 = c3 ^ Long.rotateLeft(c0, 1); - for (int y = 0; y < a.length; y += DM) { - a[y] ^= d0; - a[y+1] ^= d1; - a[y+2] ^= d2; - a[y+3] ^= d3; - a[y+4] ^= d4; - } - return a; - } - - /** - * Merged Step mapping Rho (section 3.2.2) and Pi (section 3.2.3). - * for performance. Optimization is achieved by precalculating - * shift constants for the following loop - * int xNext, yNext; - * for (int t = 0, x = 1, y = 0; t <= 23; t++, x = xNext, y = yNext) { - * int numberOfShift = ((t + 1)*(t + 2)/2) % 64; - * a[y][x] = Long.rotateLeft(a[y][x], numberOfShift); - * xNext = y; - * yNext = (2 * x + 3 * y) % DM; - * } - * and with inplace permutation. - */ - private static long[] smPiRho(long[] a) { - long tmp = Long.rotateLeft(a[10], 3); - a[10] = Long.rotateLeft(a[1], 1); - a[1] = Long.rotateLeft(a[6], 44); - a[6] = Long.rotateLeft(a[9], 20); - a[9] = Long.rotateLeft(a[22], 61); - a[22] = Long.rotateLeft(a[14], 39); - a[14] = Long.rotateLeft(a[20], 18); - a[20] = Long.rotateLeft(a[2], 62); - a[2] = Long.rotateLeft(a[12], 43); - a[12] = Long.rotateLeft(a[13], 25); - a[13] = Long.rotateLeft(a[19], 8); - a[19] = Long.rotateLeft(a[23], 56); - a[23] = Long.rotateLeft(a[15], 41); - a[15] = Long.rotateLeft(a[4], 27); - a[4] = Long.rotateLeft(a[24], 14); - a[24] = Long.rotateLeft(a[21], 2); - a[21] = Long.rotateLeft(a[8], 55); - a[8] = Long.rotateLeft(a[16], 45); - a[16] = Long.rotateLeft(a[5], 36); - a[5] = Long.rotateLeft(a[3], 28); - a[3] = Long.rotateLeft(a[18], 21); - a[18] = Long.rotateLeft(a[17], 15); - a[17] = Long.rotateLeft(a[11], 10); - a[11] = Long.rotateLeft(a[7], 6); - a[7] = tmp; - return a; - } - - /** - * Step mapping Chi as defined in section 3.2.4. - */ - private static long[] smChi(long[] a) { - for (int y = 0; y < a.length; y+=DM) { - long ay0 = a[y]; - long ay1 = a[y+1]; - long ay2 = a[y+2]; - long ay3 = a[y+3]; - long ay4 = a[y+4]; - a[y] = ay0 ^ ((~ay1) & ay2); - a[y+1] = ay1 ^ ((~ay2) & ay3); - a[y+2] = ay2 ^ ((~ay3) & ay4); - a[y+3] = ay3 ^ ((~ay4) & ay0); - a[y+4] = ay4 ^ ((~ay0) & ay1); - } - return a; - } - - /** - * Step mapping Iota as defined in section 3.2.5. - */ - private static long[] smIota(long[] a, int rndIndex) { - a[0] ^= RC_CONSTANTS[rndIndex]; - return a; - } - /** * The function Keccak as defined in section 5.2 with * rate r = 1600 and capacity c = (digest length x 2). @@ -258,10 +165,124 @@ abstract class SHA3 extends DigestBase { private void keccak() { // convert the 200-byte state into 25 lanes bytes2Lanes(state, lanes); + + long a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12; + long a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24; + // move data into local variables + a0 = lanes[0]; a1 = lanes[1]; a2 = lanes[2]; a3 = lanes[3]; a4 = lanes[4]; + a5 = lanes[5]; a6 = lanes[6]; a7 = lanes[7]; a8 = lanes[8]; a9 = lanes[9]; + a10 = lanes[10]; a11 = lanes[11]; a12 = lanes[12]; a13 = lanes[13]; a14 = lanes[14]; + a15 = lanes[15]; a16 = lanes[16]; a17 = lanes[17]; a18 = lanes[18]; a19 = lanes[19]; + a20 = lanes[20]; a21 = lanes[21]; a22 = lanes[22]; a23 = lanes[23]; a24 = lanes[24]; + // process the lanes through step mappings for (int ir = 0; ir < NR; ir++) { - smIota(smChi(smPiRho(smTheta(lanes))), ir); + // Step mapping Theta as defined in section 3.2.1. + long c0 = a0^a5^a10^a15^a20; + long c1 = a1^a6^a11^a16^a21; + long c2 = a2^a7^a12^a17^a22; + long c3 = a3^a8^a13^a18^a23; + long c4 = a4^a9^a14^a19^a24; + long d0 = c4 ^ Long.rotateLeft(c1, 1); + long d1 = c0 ^ Long.rotateLeft(c2, 1); + long d2 = c1 ^ Long.rotateLeft(c3, 1); + long d3 = c2 ^ Long.rotateLeft(c4, 1); + long d4 = c3 ^ Long.rotateLeft(c0, 1); + a0 ^= d0; a1 ^= d1; a2 ^= d2; a3 ^= d3; a4 ^= d4; + a5 ^= d0; a6 ^= d1; a7 ^= d2; a8 ^= d3; a9 ^= d4; + a10 ^= d0; a11 ^= d1; a12 ^= d2; a13 ^= d3; a14 ^= d4; + a15 ^= d0; a16 ^= d1; a17 ^= d2; a18 ^= d3; a19 ^= d4; + a20 ^= d0; a21 ^= d1; a22 ^= d2; a23 ^= d3; a24 ^= d4; + + /** + * Merged Step mapping Rho (section 3.2.2) and Pi (section 3.2.3). + * for performance. Optimization is achieved by precalculating + * shift constants for the following loop + * int xNext, yNext; + * for (int t = 0, x = 1, y = 0; t <= 23; t++, x = xNext, y = yNext) { + * int numberOfShift = ((t + 1)*(t + 2)/2) % 64; + * a[y][x] = Long.rotateLeft(a[y][x], numberOfShift); + * xNext = y; + * yNext = (2 * x + 3 * y) % DM; + * } + * and with inplace permutation. + */ + long ay = Long.rotateLeft(a10, 3); + a10 = Long.rotateLeft(a1, 1); + a1 = Long.rotateLeft(a6, 44); + a6 = Long.rotateLeft(a9, 20); + a9 = Long.rotateLeft(a22, 61); + a22 = Long.rotateLeft(a14, 39); + a14 = Long.rotateLeft(a20, 18); + a20 = Long.rotateLeft(a2, 62); + a2 = Long.rotateLeft(a12, 43); + a12 = Long.rotateLeft(a13, 25); + a13 = Long.rotateLeft(a19, 8); + a19 = Long.rotateLeft(a23, 56); + a23 = Long.rotateLeft(a15, 41); + a15 = Long.rotateLeft(a4, 27); + a4 = Long.rotateLeft(a24, 14); + a24 = Long.rotateLeft(a21, 2); + a21 = Long.rotateLeft(a8, 55); + a8 = Long.rotateLeft(a16, 45); + a16 = Long.rotateLeft(a5, 36); + a5 = Long.rotateLeft(a3, 28); + a3 = Long.rotateLeft(a18, 21); + a18 = Long.rotateLeft(a17, 15); + a17 = Long.rotateLeft(a11, 10); + a11 = Long.rotateLeft(a7, 6); + a7 = ay; + + // Step mapping Chi as defined in section 3.2.4. + long tmp0 = a0; + long tmp1 = a1; + long tmp2 = a2; + long tmp3 = a3; + long tmp4 = a4; + a0 = tmp0 ^ ((~tmp1) & tmp2); + a1 = tmp1 ^ ((~tmp2) & tmp3); + a2 = tmp2 ^ ((~tmp3) & tmp4); + a3 = tmp3 ^ ((~tmp4) & tmp0); + a4 = tmp4 ^ ((~tmp0) & tmp1); + + tmp0 = a5; tmp1 = a6; tmp2 = a7; tmp3 = a8; tmp4 = a9; + a5 = tmp0 ^ ((~tmp1) & tmp2); + a6 = tmp1 ^ ((~tmp2) & tmp3); + a7 = tmp2 ^ ((~tmp3) & tmp4); + a8 = tmp3 ^ ((~tmp4) & tmp0); + a9 = tmp4 ^ ((~tmp0) & tmp1); + + tmp0 = a10; tmp1 = a11; tmp2 = a12; tmp3 = a13; tmp4 = a14; + a10 = tmp0 ^ ((~tmp1) & tmp2); + a11 = tmp1 ^ ((~tmp2) & tmp3); + a12 = tmp2 ^ ((~tmp3) & tmp4); + a13 = tmp3 ^ ((~tmp4) & tmp0); + a14 = tmp4 ^ ((~tmp0) & tmp1); + + tmp0 = a15; tmp1 = a16; tmp2 = a17; tmp3 = a18; tmp4 = a19; + a15 = tmp0 ^ ((~tmp1) & tmp2); + a16 = tmp1 ^ ((~tmp2) & tmp3); + a17 = tmp2 ^ ((~tmp3) & tmp4); + a18 = tmp3 ^ ((~tmp4) & tmp0); + a19 = tmp4 ^ ((~tmp0) & tmp1); + + tmp0 = a20; tmp1 = a21; tmp2 = a22; tmp3 = a23; tmp4 = a24; + a20 = tmp0 ^ ((~tmp1) & tmp2); + a21 = tmp1 ^ ((~tmp2) & tmp3); + a22 = tmp2 ^ ((~tmp3) & tmp4); + a23 = tmp3 ^ ((~tmp4) & tmp0); + a24 = tmp4 ^ ((~tmp0) & tmp1); + + // Step mapping Iota as defined in section 3.2.5. + a0 ^= RC_CONSTANTS[ir]; } + + lanes[0] = a0; lanes[1] = a1; lanes[2] = a2; lanes[3] = a3; lanes[4] = a4; + lanes[5] = a5; lanes[6] = a6; lanes[7] = a7; lanes[8] = a8; lanes[9] = a9; + lanes[10] = a10; lanes[11] = a11; lanes[12] = a12; lanes[13] = a13; lanes[14] = a14; + lanes[15] = a15; lanes[16] = a16; lanes[17] = a17; lanes[18] = a18; lanes[19] = a19; + lanes[20] = a20; lanes[21] = a21; lanes[22] = a22; lanes[23] = a23; lanes[24] = a24; + // convert the resulting 25 lanes back into 200-byte state lanes2Bytes(lanes, state); } -- GitLab From 9ca7ff3e4f0a944bacf38da7e5426082d64c52bd Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 1 Feb 2022 22:30:08 +0000 Subject: [PATCH 114/400] 8281082: Improve javadoc references to JOSS Reviewed-by: iris, rriggs, naoto, lancea --- .../share/classes/java/io/ObjectOutputStream.java | 7 ++++--- src/java.base/share/classes/java/io/Serial.java | 5 +++-- src/java.base/share/classes/java/lang/Enum.java | 7 ++++--- src/java.base/share/classes/java/lang/String.java | 2 +- src/java.base/share/classes/java/security/Key.java | 4 ++-- src/java.base/share/classes/java/security/KeyRep.java | 4 ++-- 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/java.base/share/classes/java/io/ObjectOutputStream.java b/src/java.base/share/classes/java/io/ObjectOutputStream.java index 811ef3bcc20..1ac6f60614f 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, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -656,10 +656,11 @@ public class ObjectOutputStream * stream. Subclasses of ObjectOutputStream may override this method to * customize the way in which class descriptors are written to the * serialization stream. The corresponding method in ObjectInputStream, - * {@code readClassDescriptor}, should then be overridden to + * {@link ObjectInputStream#readClassDescriptor readClassDescriptor}, should then be overridden to * reconstitute the class descriptor from its custom stream representation. * By default, this method writes class descriptors according to the format - * defined in the Object Serialization specification. + * defined in the + * Java Object Serialization Specification. * *

    Note that this method will only be called if the ObjectOutputStream * is not using the old serialization stream format (set by calling diff --git a/src/java.base/share/classes/java/io/Serial.java b/src/java.base/share/classes/java/io/Serial.java index 60ba804d3a2..d648f046159 100644 --- a/src/java.base/share/classes/java/io/Serial.java +++ b/src/java.base/share/classes/java/io/Serial.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -30,7 +30,8 @@ import java.lang.annotation.*; /** * Indicates that an annotated field or method is part of the {@linkplain * Serializable serialization mechanism} defined by the - * Java Object Serialization Specification. This + * + * Java Object Serialization Specification. This * annotation type is intended to allow compile-time checking of * serialization-related declarations, analogous to the checking * enabled by the {@link java.lang.Override} annotation type to diff --git a/src/java.base/share/classes/java/lang/Enum.java b/src/java.base/share/classes/java/lang/Enum.java index 886461c3a91..55926fc3a40 100644 --- a/src/java.base/share/classes/java/lang/Enum.java +++ b/src/java.base/share/classes/java/lang/Enum.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -51,8 +51,9 @@ import static java.util.Objects.requireNonNull; * by the serialization mechanism. The serialized representation used * for enum constants cannot be customized. Declarations of methods * and fields that would otherwise interact with serialization are - * ignored, including {@code serialVersionUID}; see the Java - * Object Serialization Specification for details. + * ignored, including {@code serialVersionUID}; see the + * Java + * Object Serialization Specification for details. * *

    Note that when using an enumeration type as the type of a set * or as the type of the keys in a map, specialized and efficient diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index 43c76d5eb3e..e79884bd4cc 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -230,7 +230,7 @@ public final class String * * A String instance is written into an ObjectOutputStream according to * - * Object Serialization Specification, Section 6.2, "Stream Elements" + * Java Object Serialization Specification, Section 6.2, "Stream Elements" */ @java.io.Serial private static final ObjectStreamField[] serialPersistentFields = diff --git a/src/java.base/share/classes/java/security/Key.java b/src/java.base/share/classes/java/security/Key.java index b0159f0b33e..4ea5ae0887b 100644 --- a/src/java.base/share/classes/java/security/Key.java +++ b/src/java.base/share/classes/java/security/Key.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -84,7 +84,7 @@ package java.security; * which should not be exposed in untrusted environments. See the * * Security Appendix - * of the Serialization Specification for more information. + * of the Java Object Serialization Specification for more information. * * @see PublicKey * @see PrivateKey diff --git a/src/java.base/share/classes/java/security/KeyRep.java b/src/java.base/share/classes/java/security/KeyRep.java index 341c3d99af1..779f5a7181a 100644 --- a/src/java.base/share/classes/java/security/KeyRep.java +++ b/src/java.base/share/classes/java/security/KeyRep.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -44,7 +44,7 @@ import javax.crypto.spec.SecretKeySpec; * which should not be exposed in untrusted environments. See the * * Security Appendix - * of the Serialization Specification for more information. + * of the Java Object Serialization Specification for more information. * * @see Key * @see KeyFactory -- GitLab From 85d839fb4f3f820d130ea95f9a54ae137a95c20a Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Tue, 1 Feb 2022 23:02:06 +0000 Subject: [PATCH 115/400] 8280601: ClhsdbThreadContext.java test is triggering codecache related asserts Reviewed-by: kevinw, sspitsyn --- .../jvm/hotspot/utilities/PointerFinder.java | 16 ++++++++--- .../hotspot/utilities/PointerLocation.java | 27 ++++++++++++------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java index 90572eefb79..cd9e8264f28 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -135,9 +135,17 @@ public class PointerFinder { CodeCache c = VM.getVM().getCodeCache(); if (c.contains(a)) { loc.inCodeCache = true; - loc.blob = c.findBlobUnsafe(a); - if (Assert.ASSERTS_ENABLED) { - Assert.that(loc.blob != null, "Should have found CodeBlob"); + try { + loc.blob = c.findBlobUnsafe(a); + } catch (Exception e) { + // Since we potentially have a random address in the codecache and therefore could + // be dealing with a freed or partialy intialized blob, exceptions are possible. + } + if (loc.blob == null) { + // It's possible that there is no CodeBlob for this address. Let + // PointerLocation deal with it. + loc.inBlobUnknownLocation = true; + return loc; } loc.inBlobCode = loc.blob.codeContains(a); loc.inBlobData = loc.blob.dataContains(a); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java index aa2da619b46..a7cfa5de983 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -301,18 +301,25 @@ public class PointerLocation { } else if (isInBlobOops()) { tty.print("oops"); } else { - if (Assert.ASSERTS_ENABLED) { - Assert.that(isInBlobUnknownLocation(), "Should have known location in CodeBlob"); - } - tty.print("unknown location"); + tty.print("unknown CodeCache location"); } - tty.print(" in "); - if (verbose) { - b.printOn(tty); // includes "\n" + if (b == null) { + tty.println(); } else { - tty.println(b.toString()); + tty.print(" in "); + // Since we potentially have a random address in the codecache and therefore could + // be dealing with a freed or partialy intialized blob, exceptions are possible. + // One known case is an NMethod where the method is still null, resulting in an NPE. + try { + if (verbose) { + b.printOn(tty); // includes "\n" + } else { + tty.println(b.toString()); + } + } catch (Exception e) { + tty.println(""); + } } - // FIXME: add more detail } else if (isInStrongGlobalJNIHandles()) { tty.println("In JNI strong global"); -- GitLab From d32f99ee65679601d6e160e7975fc1e367bfa6f4 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Wed, 2 Feb 2022 07:34:22 +0000 Subject: [PATCH 116/400] 8279219: [REDO] C2 crash when allocating array of size too large Reviewed-by: thartmann, neliasso --- src/hotspot/share/opto/callnode.cpp | 49 +----------- src/hotspot/share/opto/callnode.hpp | 10 +-- src/hotspot/share/opto/cfgnode.cpp | 11 +++ src/hotspot/share/opto/compile.cpp | 29 ++++--- src/hotspot/share/opto/graphKit.cpp | 16 +++- src/hotspot/share/opto/macro.cpp | 14 +++- src/hotspot/share/opto/macro.hpp | 4 +- src/hotspot/share/opto/split_if.cpp | 13 +-- .../TestAllocArrayAfterAllocNoUse.java | 52 ++++++++++++ .../allocation/TestCCPAllocateArray.java | 53 +++++++++++++ .../TestFailedAllocationBadGraph.java | 79 +++++++++++++++++++ 11 files changed, 254 insertions(+), 76 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/allocation/TestAllocArrayAfterAllocNoUse.java create mode 100644 test/hotspot/jtreg/compiler/allocation/TestCCPAllocateArray.java create mode 100644 test/hotspot/jtreg/compiler/allocation/TestFailedAllocationBadGraph.java diff --git a/src/hotspot/share/opto/callnode.cpp b/src/hotspot/share/opto/callnode.cpp index 7345f49cbf1..b4cf07cfbbb 100644 --- a/src/hotspot/share/opto/callnode.cpp +++ b/src/hotspot/share/opto/callnode.cpp @@ -1656,6 +1656,7 @@ AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype, init_req( KlassNode , klass_node); init_req( InitialTest , initial_test); init_req( ALength , topnode); + init_req( ValidLengthTest , topnode); C->add_macro_node(this); } @@ -1682,54 +1683,6 @@ Node *AllocateNode::make_ideal_mark(PhaseGVN *phase, Node* obj, Node* control, N return mark_node; } -//============================================================================= -Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) { - if (remove_dead_region(phase, can_reshape)) return this; - // Don't bother trying to transform a dead node - if (in(0) && in(0)->is_top()) return NULL; - - const Type* type = phase->type(Ideal_length()); - if (type->isa_int() && type->is_int()->_hi < 0) { - if (can_reshape) { - PhaseIterGVN *igvn = phase->is_IterGVN(); - // Unreachable fall through path (negative array length), - // the allocation can only throw so disconnect it. - Node* proj = proj_out_or_null(TypeFunc::Control); - Node* catchproj = NULL; - if (proj != NULL) { - for (DUIterator_Fast imax, i = proj->fast_outs(imax); i < imax; i++) { - Node *cn = proj->fast_out(i); - if (cn->is_Catch()) { - catchproj = cn->as_Multi()->proj_out_or_null(CatchProjNode::fall_through_index); - break; - } - } - } - if (catchproj != NULL && catchproj->outcnt() > 0 && - (catchproj->outcnt() > 1 || - catchproj->unique_out()->Opcode() != Op_Halt)) { - assert(catchproj->is_CatchProj(), "must be a CatchProjNode"); - Node* nproj = catchproj->clone(); - igvn->register_new_node_with_optimizer(nproj); - - Node *frame = new ParmNode( phase->C->start(), TypeFunc::FramePtr ); - frame = phase->transform(frame); - // Halt & Catch Fire - Node* halt = new HaltNode(nproj, frame, "unexpected negative array length"); - phase->C->root()->add_req(halt); - phase->transform(halt); - - igvn->replace_node(catchproj, phase->C->top()); - return this; - } - } else { - // Can't correct it during regular GVN so register for IGVN - phase->C->record_for_igvn(this); - } - } - return NULL; -} - // Retrieve the length from the AllocateArrayNode. Narrow the type with a // CastII, if appropriate. If we are not allowed to create new nodes, and // a CastII is appropriate, return NULL. diff --git a/src/hotspot/share/opto/callnode.hpp b/src/hotspot/share/opto/callnode.hpp index 7c8baefbca9..1017a76a25e 100644 --- a/src/hotspot/share/opto/callnode.hpp +++ b/src/hotspot/share/opto/callnode.hpp @@ -913,6 +913,7 @@ public: KlassNode, // type (maybe dynamic) of the obj. InitialTest, // slow-path test (may be constant) ALength, // array length (or TOP if none) + ValidLengthTest, ParmLimit }; @@ -922,6 +923,7 @@ public: fields[KlassNode] = TypeInstPtr::NOTNULL; fields[InitialTest] = TypeInt::BOOL; fields[ALength] = t; // length (can be a bad length) + fields[ValidLengthTest] = TypeInt::BOOL; const TypeTuple *domain = TypeTuple::make(ParmLimit, fields); @@ -1016,18 +1018,16 @@ public: // class AllocateArrayNode : public AllocateNode { public: - AllocateArrayNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio, - Node* size, Node* klass_node, Node* initial_test, - Node* count_val - ) + AllocateArrayNode(Compile* C, const TypeFunc* atype, Node* ctrl, Node* mem, Node* abio, Node* size, Node* klass_node, + Node* initial_test, Node* count_val, Node* valid_length_test) : AllocateNode(C, atype, ctrl, mem, abio, size, klass_node, initial_test) { init_class_id(Class_AllocateArray); set_req(AllocateNode::ALength, count_val); + set_req(AllocateNode::ValidLengthTest, valid_length_test); } virtual int Opcode() const; - virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); // Dig the length operand out of a array allocation site. Node* Ideal_length() { diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp index e583dd9deec..14357ec8e46 100644 --- a/src/hotspot/share/opto/cfgnode.cpp +++ b/src/hotspot/share/opto/cfgnode.cpp @@ -2687,6 +2687,17 @@ const Type* CatchNode::Value(PhaseGVN* phase) const { // Rethrows always throw exceptions, never return if (call->entry_point() == OptoRuntime::rethrow_stub()) { f[CatchProjNode::fall_through_index] = Type::TOP; + } else if (call->is_AllocateArray()) { + Node* klass_node = call->in(AllocateNode::KlassNode); + Node* length = call->in(AllocateNode::ALength); + const Type* length_type = phase->type(length); + const Type* klass_type = phase->type(klass_node); + Node* valid_length_test = call->in(AllocateNode::ValidLengthTest); + const Type* valid_length_test_t = phase->type(valid_length_test); + if (length_type == Type::TOP || klass_type == Type::TOP || valid_length_test_t == Type::TOP || + valid_length_test_t->is_int()->is_con(0)) { + f[CatchProjNode::fall_through_index] = Type::TOP; + } } else if( call->req() > TypeFunc::Parms ) { const Type *arg0 = phase->type( call->in(TypeFunc::Parms) ); // Check for null receiver to virtual or interface calls diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 9adda4961e5..1296a3ff8b8 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -3812,7 +3812,7 @@ bool Compile::final_graph_reshaping() { // 'fall-thru' path, so expected kids is 1 less. if (n->is_PCTable() && n->in(0) && n->in(0)->in(0)) { if (n->in(0)->in(0)->is_Call()) { - CallNode *call = n->in(0)->in(0)->as_Call(); + CallNode* call = n->in(0)->in(0)->as_Call(); if (call->entry_point() == OptoRuntime::rethrow_stub()) { required_outcnt--; // Rethrow always has 1 less kid } else if (call->req() > TypeFunc::Parms && @@ -3821,22 +3821,25 @@ bool Compile::final_graph_reshaping() { // detected that the virtual call will always result in a null // pointer exception. The fall-through projection of this CatchNode // will not be populated. - Node *arg0 = call->in(TypeFunc::Parms); + Node* arg0 = call->in(TypeFunc::Parms); if (arg0->is_Type() && arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) { required_outcnt--; } - } else if (call->entry_point() == OptoRuntime::new_array_Java() && - call->req() > TypeFunc::Parms+1 && - call->is_CallStaticJava()) { - // Check for negative array length. In such case, the optimizer has + } else if (call->entry_point() == OptoRuntime::new_array_Java() || + call->entry_point() == OptoRuntime::new_array_nozero_Java()) { + // Check for illegal array length. In such case, the optimizer has // detected that the allocation attempt will always result in an // exception. There is no fall-through projection of this CatchNode . - Node *arg1 = call->in(TypeFunc::Parms+1); - if (arg1->is_Type() && - arg1->as_Type()->type()->join(TypeInt::POS)->empty()) { + assert(call->is_CallStaticJava(), "static call expected"); + assert(call->req() == call->jvms()->endoff() + 1, "missing extra input"); + Node* valid_length_test = call->in(call->req()-1); + call->del_req(call->req()-1); + if (valid_length_test->find_int_con(1) == 0) { required_outcnt--; } + assert(n->outcnt() == required_outcnt, "malformed control flow"); + continue; } } } @@ -3845,6 +3848,14 @@ bool Compile::final_graph_reshaping() { record_method_not_compilable("malformed control flow"); return true; // Not all targets reachable! } + } else if (n->is_PCTable() && n->in(0) && n->in(0)->in(0) && n->in(0)->in(0)->is_Call()) { + CallNode* call = n->in(0)->in(0)->as_Call(); + if (call->entry_point() == OptoRuntime::new_array_Java() || + call->entry_point() == OptoRuntime::new_array_nozero_Java()) { + assert(call->is_CallStaticJava(), "static call expected"); + assert(call->req() == call->jvms()->endoff() + 1, "missing extra input"); + call->del_req(call->req()-1); // valid length test useless now + } } // Check that I actually visited all kids. Unreached kids // must be infinite loops. diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index da96ebd9169..ecee3147787 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -2728,7 +2728,9 @@ void GraphKit::make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool sep // Make a catch node with just two handlers: fall-through and catch-all Node* i_o = _gvn.transform( new ProjNode(call, TypeFunc::I_O, separate_io_proj) ); Node* catc = _gvn.transform( new CatchNode(control(), i_o, 2) ); - Node* norm = _gvn.transform( new CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci) ); + Node* norm = new CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci); + _gvn.set_type_bottom(norm); + C->record_for_igvn(norm); Node* excp = _gvn.transform( new CatchProjNode(catc, CatchProjNode::catch_all_index, CatchProjNode::no_handler_bci) ); { PreserveJVMState pjvms(this); @@ -3969,20 +3971,28 @@ Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable) initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn); } + const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type(); + Node* valid_length_test = _gvn.intcon(1); + if (ary_type->klass()->is_array_klass()) { + BasicType bt = ary_type->klass()->as_array_klass()->element_type()->basic_type(); + jint max = TypeAryPtr::max_array_length(bt); + Node* valid_length_cmp = _gvn.transform(new CmpUNode(length, intcon(max))); + valid_length_test = _gvn.transform(new BoolNode(valid_length_cmp, BoolTest::le)); + } + // Create the AllocateArrayNode and its result projections AllocateArrayNode* alloc = new AllocateArrayNode(C, AllocateArrayNode::alloc_type(TypeInt::INT), control(), mem, i_o(), size, klass_node, initial_slow_test, - length); + length, valid_length_test); // Cast to correct type. Note that the klass_node may be constant or not, // and in the latter case the actual array type will be inexact also. // (This happens via a non-constant argument to inline_native_newArray.) // In any case, the value of klass_node provides the desired array type. const TypeInt* length_type = _gvn.find_int_type(length); - const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type(); if (ary_type->isa_aryptr() && length_type != NULL) { // Try to get a better type than POS for the size ary_type = ary_type->is_aryptr()->cast_to_size(length_type); diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp index a4bdcecb12a..5f45ffc09c3 100644 --- a/src/hotspot/share/opto/macro.cpp +++ b/src/hotspot/share/opto/macro.cpp @@ -1208,7 +1208,8 @@ void PhaseMacroExpand::expand_allocate_common( AllocateNode* alloc, // allocation node to be expanded Node* length, // array length for an array allocation const TypeFunc* slow_call_type, // Type of slow call - address slow_call_address // Address of slow call + address slow_call_address, // Address of slow call + Node* valid_length_test // whether length is valid or not ) { Node* ctrl = alloc->in(TypeFunc::Control); @@ -1393,6 +1394,12 @@ void PhaseMacroExpand::expand_allocate_common( // Copy debug information and adjust JVMState information, then replace // allocate node with the call call->copy_call_debug_info(&_igvn, alloc); + // For array allocations, copy the valid length check to the call node so Compile::final_graph_reshaping() can verify + // that the call has the expected number of CatchProj nodes (in case the allocation always fails and the fallthrough + // path dies). + if (valid_length_test != NULL) { + call->add_req(valid_length_test); + } if (expand_fast_path) { call->set_cnt(PROB_UNLIKELY_MAG(4)); // Same effect as RC_UNCOMMON. } else { @@ -1875,11 +1882,12 @@ Node* PhaseMacroExpand::prefetch_allocation(Node* i_o, Node*& needgc_false, void PhaseMacroExpand::expand_allocate(AllocateNode *alloc) { expand_allocate_common(alloc, NULL, OptoRuntime::new_instance_Type(), - OptoRuntime::new_instance_Java()); + OptoRuntime::new_instance_Java(), NULL); } void PhaseMacroExpand::expand_allocate_array(AllocateArrayNode *alloc) { Node* length = alloc->in(AllocateNode::ALength); + Node* valid_length_test = alloc->in(AllocateNode::ValidLengthTest); InitializeNode* init = alloc->initialization(); Node* klass_node = alloc->in(AllocateNode::KlassNode); ciKlass* k = _igvn.type(klass_node)->is_klassptr()->klass(); @@ -1894,7 +1902,7 @@ void PhaseMacroExpand::expand_allocate_array(AllocateArrayNode *alloc) { } expand_allocate_common(alloc, length, OptoRuntime::new_array_Type(), - slow_call_address); + slow_call_address, valid_length_test); } //-------------------mark_eliminated_box---------------------------------- diff --git a/src/hotspot/share/opto/macro.hpp b/src/hotspot/share/opto/macro.hpp index b65b97fec87..c028120a0fc 100644 --- a/src/hotspot/share/opto/macro.hpp +++ b/src/hotspot/share/opto/macro.hpp @@ -92,8 +92,8 @@ private: void expand_allocate_common(AllocateNode* alloc, Node* length, const TypeFunc* slow_call_type, - address slow_call_address); - void yank_initalize_node(InitializeNode* node); + address slow_call_address, + Node* valid_length_test); void yank_alloc_node(AllocateNode* alloc); Node *value_from_mem(Node *mem, Node *ctl, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, AllocateNode *alloc); Node *value_from_mem_phi(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, AllocateNode *alloc, Node_Stack *value_phis, int level); diff --git a/src/hotspot/share/opto/split_if.cpp b/src/hotspot/share/opto/split_if.cpp index 060d3464514..05babc625c6 100644 --- a/src/hotspot/share/opto/split_if.cpp +++ b/src/hotspot/share/opto/split_if.cpp @@ -128,8 +128,8 @@ bool PhaseIdealLoop::split_up( Node *n, Node *blk1, Node *blk2 ) { } } else { // We might see an Opaque1 from a loop limit check here - assert(use->is_If() || use->is_CMove() || use->Opcode() == Op_Opaque1, "unexpected node type"); - Node *use_c = use->is_If() ? use->in(0) : get_ctrl(use); + assert(use->is_If() || use->is_CMove() || use->Opcode() == Op_Opaque1 || use->is_AllocateArray(), "unexpected node type"); + Node *use_c = (use->is_If() || use->is_AllocateArray()) ? use->in(0) : get_ctrl(use); if (use_c == blk1 || use_c == blk2) { assert(use->is_CMove(), "unexpected node type"); continue; @@ -166,14 +166,15 @@ bool PhaseIdealLoop::split_up( Node *n, Node *blk1, Node *blk2 ) { --j; } else { // We might see an Opaque1 from a loop limit check here - assert(u->is_If() || u->is_CMove() || u->Opcode() == Op_Opaque1, "unexpected node type"); - assert(u->in(1) == bol, ""); + assert(u->is_If() || u->is_CMove() || u->Opcode() == Op_Opaque1 || u->is_AllocateArray(), "unexpected node type"); + assert(u->is_AllocateArray() || u->in(1) == bol, ""); + assert(!u->is_AllocateArray() || u->in(AllocateNode::ValidLengthTest) == bol, "wrong input to AllocateArray"); // Get control block of either the CMove or the If input - Node *u_ctrl = u->is_If() ? u->in(0) : get_ctrl(u); + Node *u_ctrl = (u->is_If() || u->is_AllocateArray()) ? u->in(0) : get_ctrl(u); assert((u_ctrl != blk1 && u_ctrl != blk2) || u->is_CMove(), "won't converge"); Node *x = bol->clone(); register_new_node(x, u_ctrl); - _igvn.replace_input_of(u, 1, x); + _igvn.replace_input_of(u, u->is_AllocateArray() ? AllocateNode::ValidLengthTest : 1, x); --j; } } diff --git a/test/hotspot/jtreg/compiler/allocation/TestAllocArrayAfterAllocNoUse.java b/test/hotspot/jtreg/compiler/allocation/TestAllocArrayAfterAllocNoUse.java new file mode 100644 index 00000000000..e2bc9bfdd16 --- /dev/null +++ b/test/hotspot/jtreg/compiler/allocation/TestAllocArrayAfterAllocNoUse.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8279125 + * @summary fatal error: no reachable node should have no use + * @requires vm.flavor == "server" + * + * @run main/othervm -XX:-BackgroundCompilation -XX:-DoEscapeAnalysis TestAllocArrayAfterAllocNoUse + * + */ + +public class TestAllocArrayAfterAllocNoUse { + private static Object field; + + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(); + } + } + + private static void test() { + try { + final TestAllocArrayAfterAllocNoUse o = new TestAllocArrayAfterAllocNoUse(); + } catch (Exception e) { + final int[] array = new int[100]; + field = array; + } + + } +} diff --git a/test/hotspot/jtreg/compiler/allocation/TestCCPAllocateArray.java b/test/hotspot/jtreg/compiler/allocation/TestCCPAllocateArray.java new file mode 100644 index 00000000000..9e312a79530 --- /dev/null +++ b/test/hotspot/jtreg/compiler/allocation/TestCCPAllocateArray.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8279062 + * @summary C2: assert(t->meet(t0) == t) failed: Not monotonic after JDK-8278413 + * + * @run main/othervm -XX:-BackgroundCompilation TestCCPAllocateArray + * + */ + +public class TestCCPAllocateArray { + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + try { + test(); + } catch (OutOfMemoryError e) { + } + length(42); + } + } + + private static int[] test() { + int i = 2; + for (; i < 4; i *= 2); + return new int[length(i)]; + } + + private static int length(int i) { + return i == 4 ? Integer.MAX_VALUE : 0; + } +} diff --git a/test/hotspot/jtreg/compiler/allocation/TestFailedAllocationBadGraph.java b/test/hotspot/jtreg/compiler/allocation/TestFailedAllocationBadGraph.java new file mode 100644 index 00000000000..bd720a9b4f1 --- /dev/null +++ b/test/hotspot/jtreg/compiler/allocation/TestFailedAllocationBadGraph.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * bug 8279219 + * @summary C2 crash when allocating array of size too large + * @library /test/lib / + * @build sun.hotspot.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -ea -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation TestFailedAllocationBadGraph + */ + +import sun.hotspot.WhiteBox; +import java.lang.reflect.Method; +import compiler.whitebox.CompilerWhiteBoxTest; + +public class TestFailedAllocationBadGraph { + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + + private static long[] array; + private static int field; + private static volatile int barrier; + + public static void main(String[] args) throws Exception { + run("test1"); + run("test2"); + } + + private static void run(String method) throws Exception { + Method m = TestFailedAllocationBadGraph.class.getDeclaredMethod(method); + WHITE_BOX.enqueueMethodForCompilation(m, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); + if (!WHITE_BOX.isMethodCompiled(m) || WHITE_BOX.getMethodCompilationLevel(m) != CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) { + throw new RuntimeException("should still be compiled"); + } + } + + private static int test1() { + int length = Integer.MAX_VALUE; + try { + array = new long[length]; + } catch (OutOfMemoryError outOfMemoryError) { + barrier = 0x42; + length = field; + } + return length; + } + + private static int test2() { + int length = -1; + try { + array = new long[length]; + } catch (OutOfMemoryError outOfMemoryError) { + barrier = 0x42; + length = field; + } + return length; + } +} -- GitLab From 97af32304101397bb33cbbd1e35fd9124f9e2311 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Wed, 2 Feb 2022 07:35:34 +0000 Subject: [PATCH 117/400] 8280842: Access violation in ciTypeFlow::profiled_count Reviewed-by: neliasso, vlivanov, kvn --- src/hotspot/share/ci/ciTypeFlow.cpp | 3 +- .../TestSharedHeadExceptionBackedges.java | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/profiling/TestSharedHeadExceptionBackedges.java diff --git a/src/hotspot/share/ci/ciTypeFlow.cpp b/src/hotspot/share/ci/ciTypeFlow.cpp index 240cb654380..fc8553aac48 100644 --- a/src/hotspot/share/ci/ciTypeFlow.cpp +++ b/src/hotspot/share/ci/ciTypeFlow.cpp @@ -2462,9 +2462,8 @@ int ciTypeFlow::profiled_count(ciTypeFlow::Loop* loop) { } ciProfileData* data = methodData->bci_to_data(tail->control()); - assert(data != NULL, "some profile data expected at branch"); - if (!data->is_JumpData()) { + if (data == NULL || !data->is_JumpData()) { return 0; } diff --git a/test/hotspot/jtreg/compiler/profiling/TestSharedHeadExceptionBackedges.java b/test/hotspot/jtreg/compiler/profiling/TestSharedHeadExceptionBackedges.java new file mode 100644 index 00000000000..e02df36fa1c --- /dev/null +++ b/test/hotspot/jtreg/compiler/profiling/TestSharedHeadExceptionBackedges.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * bug 8280842 + * @summary Access violation in ciTypeFlow::profiled_count + * @run main/othervm -XX:-BackgroundCompilation TestSharedHeadExceptionBackedges + */ + +public class TestSharedHeadExceptionBackedges { + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(); + } + } + + static class MyException extends Exception { + } + + private static void test() { + int i = 0; + while (i < 10) { + try { + int j = 0; + i++; + if (i % 2 == 0) { + throw new MyException(); + } + do { + j++; + } while (j < 100); + + throw new MyException(); + + } catch (MyException me) { + } + } + } +} -- GitLab From 48a32b5f3aa1b238bc9857002325579a5b041685 Mon Sep 17 00:00:00 2001 From: Jatin Bhateja Date: Wed, 2 Feb 2022 07:36:47 +0000 Subject: [PATCH 118/400] 8280976: Incorrect encoding of avx512 vpsraq instruction with mask and constant shift. Reviewed-by: neliasso, thartmann --- src/hotspot/cpu/x86/assembler_x86.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp index 3b1e42f3f95..c645e5461de 100644 --- a/src/hotspot/cpu/x86/assembler_x86.cpp +++ b/src/hotspot/cpu/x86/assembler_x86.cpp @@ -9301,7 +9301,7 @@ void Assembler::evpsraq(XMMRegister dst, KRegister mask, XMMRegister src, int sh attributes.reset_is_clear_context(); } int encode = vex_prefix_and_encode(xmm4->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes); - emit_int24(0x73, (0xC0 | encode), shift & 0xFF); + emit_int24(0x72, (0xC0 | encode), shift & 0xFF); } void Assembler::evpsllw(XMMRegister dst, KRegister mask, XMMRegister nds, XMMRegister src, bool merge, int vector_len) { -- GitLab From ab638341de164965e06bb1d59808670260916b82 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Wed, 2 Feb 2022 07:37:44 +0000 Subject: [PATCH 119/400] 8280885: Shenandoah: Some tests failed with "EA: missing allocation reference path" Reviewed-by: rkennke --- .../shenandoah/c2/shenandoahBarrierSetC2.cpp | 2 +- .../compiler/TestUnexpectedIUBarrierEA.java | 74 +++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/gc/shenandoah/compiler/TestUnexpectedIUBarrierEA.java diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp index 8bd18c1aa66..a9974783c79 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp @@ -718,7 +718,7 @@ Node* ShenandoahBarrierSetC2::atomic_xchg_at_resolved(C2AtomicParseAccess& acces // Support for GC barriers emitted during parsing bool ShenandoahBarrierSetC2::is_gc_barrier_node(Node* node) const { - if (node->Opcode() == Op_ShenandoahLoadReferenceBarrier) return true; + if (node->Opcode() == Op_ShenandoahLoadReferenceBarrier || node->Opcode() == Op_ShenandoahIUBarrier) return true; if (node->Opcode() != Op_CallLeaf && node->Opcode() != Op_CallLeafNoFP) { return false; } diff --git a/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnexpectedIUBarrierEA.java b/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnexpectedIUBarrierEA.java new file mode 100644 index 00000000000..8662130c378 --- /dev/null +++ b/test/hotspot/jtreg/gc/shenandoah/compiler/TestUnexpectedIUBarrierEA.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * bug 8280885 + * @summary Shenandoah: Some tests failed with "EA: missing allocation reference path" + * @requires vm.gc.Shenandoah + * + * @run main/othervm -XX:-BackgroundCompilation -XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=iu + * -XX:CompileCommand=dontinline,TestUnexpectedIUBarrierEA::notInlined TestUnexpectedIUBarrierEA + */ + +public class TestUnexpectedIUBarrierEA { + + private static Object field; + + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(false); + } + } + + private static void test(boolean flag) { + A a = new A(); + B b = new B(); + b.field = a; + notInlined(); + Object o = b.field; + if (!(o instanceof A)) { + + } + C c = new C(); + c.field = o; + if (flag) { + field = c.field; + } + } + + private static void notInlined() { + + } + + private static class A { + } + + private static class B { + public Object field; + } + + private static class C { + public Object field; + } +} -- GitLab From 4304a7728ec60f7937e0198c4f85384064fe560e Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Wed, 2 Feb 2022 07:38:36 +0000 Subject: [PATCH 120/400] 8279535: C2: Dead code in PhaseIdealLoop::create_loop_nest after JDK-8276116 Reviewed-by: thartmann --- src/hotspot/share/opto/loopnode.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp index d7ec4d6ee64..e2b01f61d49 100644 --- a/src/hotspot/share/opto/loopnode.cpp +++ b/src/hotspot/share/opto/loopnode.cpp @@ -830,10 +830,7 @@ bool PhaseIdealLoop::create_loop_nest(IdealLoopTree* loop, Node_List &old_new) { return false; } - IfNode* exit_test = head->loopexit(); - BoolTest::mask mask = exit_test->as_BaseCountedLoopEnd()->test_trip(); - Node* cmp = exit_test->as_BaseCountedLoopEnd()->cmp_node(); assert(back_control->Opcode() == Op_IfTrue, "wrong projection for back edge"); -- GitLab From de826ba18a5e98586029581c2d4bcd27334fbdd1 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Wed, 2 Feb 2022 08:01:00 +0000 Subject: [PATCH 121/400] 8280600: C2: assert(!had_error) failed: bad dominance Reviewed-by: kvn, thartmann --- src/hotspot/share/opto/loopTransform.cpp | 2 +- .../TestCastIIMakesMainLoopPhiDead.java | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/compiler/loopopts/TestCastIIMakesMainLoopPhiDead.java diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp index 033ab5d47ab..21dab9335c0 100644 --- a/src/hotspot/share/opto/loopTransform.cpp +++ b/src/hotspot/share/opto/loopTransform.cpp @@ -1234,7 +1234,7 @@ Node *PhaseIdealLoop::clone_up_backedge_goo(Node *back_ctrl, Node *preheader_ctr } Node* PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) { - Node* castii = new CastIINode(incr, TypeInt::INT, ConstraintCastNode::StrongDependency); + Node* castii = new CastIINode(incr, TypeInt::INT, ConstraintCastNode::UnconditionalDependency); castii->set_req(0, ctrl); register_new_node(castii, ctrl); for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) { diff --git a/test/hotspot/jtreg/compiler/loopopts/TestCastIIMakesMainLoopPhiDead.java b/test/hotspot/jtreg/compiler/loopopts/TestCastIIMakesMainLoopPhiDead.java new file mode 100644 index 00000000000..3c40761a77d --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestCastIIMakesMainLoopPhiDead.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * bug 8280600 + * @summary C2: assert(!had_error) failed: bad dominance + * @run main/othervm -Xcomp -XX:CompileOnly=TestCastIIMakesMainLoopPhiDead TestCastIIMakesMainLoopPhiDead + */ + +public class TestCastIIMakesMainLoopPhiDead { + int iArr[] = new int[0]; + + void test() { + int x = 8; + try { + for (int i = 0; i < 8; i++) { + iArr[1] = 9; + for (int j = -400; 1 > j; j++) { + iArr[j] = 4; + x -= 2; + } + } + } catch (ArrayIndexOutOfBoundsException e) { + } + } + public static void main(String[] k) { + TestCastIIMakesMainLoopPhiDead t = new TestCastIIMakesMainLoopPhiDead(); + for (int i = 0; i < 3; i++) { + t.test(); + } + } +} -- GitLab From ae2504b4692a5298b5835727b04a44e1edc8a4d6 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Wed, 2 Feb 2022 10:04:50 +0000 Subject: [PATCH 122/400] 8278254: Cleanup doclint warnings in java.desktop module Reviewed-by: aivanov, serb --- .../classes/java/awt/BufferCapabilities.java | 27 ++- .../share/classes/java/awt/Component.java | 10 +- .../classes/java/awt/event/KeyEvent.java | 183 +++++++++++++++--- .../BeanContextServicesSupport.java | 9 +- .../beans/beancontext/BeanContextSupport.java | 15 +- .../swing/DefaultListSelectionModel.java | 8 +- .../share/classes/javax/swing/JApplet.java | 6 +- .../share/classes/javax/swing/JDialog.java | 6 +- .../share/classes/javax/swing/JScrollBar.java | 11 +- .../swing/filechooser/FileSystemView.java | 10 +- .../swing/plaf/basic/BasicMenuItemUI.java | 2 +- .../javax/swing/plaf/basic/BasicMenuUI.java | 1 - .../javax/swing/plaf/metal/MetalBorders.java | 5 +- .../javax/swing/text/LayeredHighlighter.java | 5 +- .../classes/javax/swing/text/html/HTML.java | 7 +- .../javax/swing/text/html/HTMLEditorKit.java | 7 +- .../swing/text/html/parser/AttributeList.java | 15 +- .../javax/swing/text/html/parser/Parser.java | 3 +- .../javax/swing/undo/UndoableEditSupport.java | 3 +- 19 files changed, 251 insertions(+), 82 deletions(-) diff --git a/src/java.desktop/share/classes/java/awt/BufferCapabilities.java b/src/java.desktop/share/classes/java/awt/BufferCapabilities.java index 8d2288023b5..22df13cfb50 100644 --- a/src/java.desktop/share/classes/java/awt/BufferCapabilities.java +++ b/src/java.desktop/share/classes/java/awt/BufferCapabilities.java @@ -33,7 +33,6 @@ package java.awt; * @author Michael Martak * @since 1.4 */ -@SuppressWarnings("doclint:missing") public class BufferCapabilities implements Cloneable { private ImageCapabilities frontCaps; @@ -63,6 +62,8 @@ public class BufferCapabilities implements Cloneable { } /** + * Returns the image capabilities of the front (displayed) buffer. + * * @return the image capabilities of the front (displayed) buffer */ public ImageCapabilities getFrontBufferCapabilities() { @@ -70,6 +71,9 @@ public class BufferCapabilities implements Cloneable { } /** + * Returns the image capabilities of all back buffers (intermediate buffers + * are considered back buffers). + * * @return the image capabilities of all back buffers (intermediate buffers * are considered back buffers) */ @@ -78,27 +82,31 @@ public class BufferCapabilities implements Cloneable { } /** - * @return whether or not the buffer strategy uses page flipping; a set of - * buffers that uses page flipping + * Returns whether or not the buffer strategy uses page flipping. + * A set of buffers that uses page flipping * can swap the contents internally between the front buffer and one or * more back buffers by switching the video pointer (or by copying memory * internally). A non-flipping set of * buffers uses blitting to copy the contents from one buffer to * another; when this is the case, {@code getFlipContents} returns - * {@code null} + * {@code null}. + * + * @return whether or not the buffer strategy uses page flipping */ public boolean isPageFlipping() { return (getFlipContents() != null); } /** - * @return the resulting contents of the back buffer after page-flipping. + * Returns the resulting contents of the back buffer after page-flipping. * This value is {@code null} when the {@code isPageFlipping} * returns {@code false}, implying blitting. It can be one of * {@code FlipContents.UNDEFINED} * (the assumed default), {@code FlipContents.BACKGROUND}, * {@code FlipContents.PRIOR}, or * {@code FlipContents.COPIED}. + * + * @return the resulting contents of the back buffer after page-flipping * @see #isPageFlipping * @see FlipContents#UNDEFINED * @see FlipContents#BACKGROUND @@ -110,9 +118,11 @@ public class BufferCapabilities implements Cloneable { } /** - * @return whether page flipping is only available in full-screen mode. If this + * Returns whether page flipping is only available in full-screen mode. If this * is {@code true}, full-screen exclusive mode is required for * page-flipping. + * + * @return whether page flipping is only available in full-screen mode * @see #isPageFlipping * @see GraphicsDevice#setFullScreenWindow */ @@ -121,9 +131,12 @@ public class BufferCapabilities implements Cloneable { } /** - * @return whether or not + * Returns whether or not * page flipping can be performed using more than two buffers (one or more * intermediate buffers as well as the front and back buffer). + * + * @return whether or not + * page flipping can be performed using more than two buffers * @see #isPageFlipping */ public boolean isMultiBufferAvailable() { diff --git a/src/java.desktop/share/classes/java/awt/Component.java b/src/java.desktop/share/classes/java/awt/Component.java index 2378588b033..813f9bd0c79 100644 --- a/src/java.desktop/share/classes/java/awt/Component.java +++ b/src/java.desktop/share/classes/java/awt/Component.java @@ -214,7 +214,6 @@ import static sun.java2d.pipe.hw.ExtendedBufferCapabilities.VSyncType.VSYNC_ON; * @author Arthur van Hoff * @author Sami Shaio */ -@SuppressWarnings("doclint:missing") public abstract class Component implements ImageObserver, MenuContainer, Serializable { @@ -4133,7 +4132,9 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * @return direct access to the back buffer, as an image. + * Provides direct access to the back buffer as an image. + * + * @return the back buffer as an image * @exception IllegalStateException if the buffers have not yet * been created */ @@ -4693,9 +4694,12 @@ public abstract class Component implements ImageObserver, MenuContainer, } /** - * @return whether or not paint messages received from the operating system + * Returns whether or not paint messages received from the operating system * should be ignored. * + * @return whether or not paint messages received from the operating system + * should be ignored + * * @since 1.4 * @see #setIgnoreRepaint */ diff --git a/src/java.desktop/share/classes/java/awt/event/KeyEvent.java b/src/java.desktop/share/classes/java/awt/event/KeyEvent.java index f416719fd2e..21bf7ec1716 100644 --- a/src/java.desktop/share/classes/java/awt/event/KeyEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/KeyEvent.java @@ -151,7 +151,6 @@ import sun.awt.AWTAccessor; * * @since 1.1 */ -@SuppressWarnings("doclint:missing") public class KeyEvent extends InputEvent { /** @@ -650,53 +649,142 @@ public class KeyEvent extends InputEvent { public static final int VK_KP_RIGHT = 0xE3; /* For European keyboards */ - /** @since 1.2 */ + /** + * Constant for the Dead Grave key. + * @since 1.2 + */ public static final int VK_DEAD_GRAVE = 0x80; - /** @since 1.2 */ + + /** + * Constant for the Dead Acute key. + * @since 1.2 + */ public static final int VK_DEAD_ACUTE = 0x81; - /** @since 1.2 */ + + /** + * Constant for the Dead Circumflex key. + * @since 1.2 + */ public static final int VK_DEAD_CIRCUMFLEX = 0x82; - /** @since 1.2 */ + + /** + * Constant for the Dead Tilde key. + * @since 1.2 + */ public static final int VK_DEAD_TILDE = 0x83; - /** @since 1.2 */ + + /** + * Constant for the Dead Macron key. + * @since 1.2 + */ public static final int VK_DEAD_MACRON = 0x84; - /** @since 1.2 */ + + /** + * Constant for the Dead Breve key. + * @since 1.2 + */ public static final int VK_DEAD_BREVE = 0x85; - /** @since 1.2 */ + + /** + * Constant for the Dead Above Dot key. + * @since 1.2 + */ public static final int VK_DEAD_ABOVEDOT = 0x86; - /** @since 1.2 */ + + /** + * Constant for the Dead Diaeresis key. + * @since 1.2 + */ public static final int VK_DEAD_DIAERESIS = 0x87; - /** @since 1.2 */ + + /** + * Constant for the Dead Above Ring key. + * @since 1.2 + */ public static final int VK_DEAD_ABOVERING = 0x88; - /** @since 1.2 */ + + /** + * Constant for the Dead Double Acute key. + * @since 1.2 + */ public static final int VK_DEAD_DOUBLEACUTE = 0x89; - /** @since 1.2 */ + + /** + * Constant for the Dead Caron key. + * @since 1.2 + */ public static final int VK_DEAD_CARON = 0x8a; - /** @since 1.2 */ + + /** + * Constant for the Dead Cedilla key. + * @since 1.2 + */ public static final int VK_DEAD_CEDILLA = 0x8b; - /** @since 1.2 */ + + /** + * Constant for the Dead Ogonek key. + * @since 1.2 + */ public static final int VK_DEAD_OGONEK = 0x8c; - /** @since 1.2 */ + + /** + * Constant for the Dead Iota key. + * @since 1.2 + */ public static final int VK_DEAD_IOTA = 0x8d; - /** @since 1.2 */ + + /** + * Constant for the Dead Voiced Sound key. + * @since 1.2 + */ public static final int VK_DEAD_VOICED_SOUND = 0x8e; - /** @since 1.2 */ + + /** + * Constant for the Dead Semivoiced Sound key. + * @since 1.2 + */ public static final int VK_DEAD_SEMIVOICED_SOUND = 0x8f; - /** @since 1.2 */ + /** + * Constant for the "&" key. + * @since 1.2 + */ public static final int VK_AMPERSAND = 0x96; - /** @since 1.2 */ + + /** + * Constant for the "*" key. + * @since 1.2 + */ public static final int VK_ASTERISK = 0x97; - /** @since 1.2 */ + + /** + * Constant for the """" key. + * @since 1.2 + */ public static final int VK_QUOTEDBL = 0x98; - /** @since 1.2 */ + + /** + * Constant for the "<" key. + * @since 1.2 + */ public static final int VK_LESS = 0x99; - /** @since 1.2 */ + /** + * Constant for the ">" key. + * @since 1.2 + */ public static final int VK_GREATER = 0xa0; - /** @since 1.2 */ + + /** + * Constant for the "{" key. + * @since 1.2 + */ public static final int VK_BRACELEFT = 0xa1; - /** @since 1.2 */ + + /** + * Constant for the "}" key. + * @since 1.2 + */ public static final int VK_BRACERIGHT = 0xa2; /** @@ -926,21 +1014,52 @@ public class KeyEvent extends InputEvent { public static final int VK_INPUT_METHOD_ON_OFF = 0x0107; /* for Sun keyboards */ - /** @since 1.2 */ + /** + * Constant for the Cut key. + * @since 1.2 + */ public static final int VK_CUT = 0xFFD1; - /** @since 1.2 */ + + /** + * Constant for the Copy key. + * @since 1.2 + */ public static final int VK_COPY = 0xFFCD; - /** @since 1.2 */ + + /** + * Constant for the Paste key. + * @since 1.2 + */ public static final int VK_PASTE = 0xFFCF; - /** @since 1.2 */ + + /** + * Constant for the Undo key. + * @since 1.2 + */ public static final int VK_UNDO = 0xFFCB; - /** @since 1.2 */ + + /** + * Constant for the Again key. + * @since 1.2 + */ public static final int VK_AGAIN = 0xFFC9; - /** @since 1.2 */ + + /** + * Constant for the Find key. + * @since 1.2 + */ public static final int VK_FIND = 0xFFD0; - /** @since 1.2 */ + + /** + * Constant for the Props key. + * @since 1.2 + */ public static final int VK_PROPS = 0xFFCA; - /** @since 1.2 */ + + /** + * Constant for the Stop key. + * @since 1.2 + */ public static final int VK_STOP = 0xFFC8; /** diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java index d3e6c6ea87a..21e136ba9e5 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java @@ -54,7 +54,6 @@ import java.util.TooManyListenersException; * @author Laurence P. G. Cable * @since 1.2 */ -@SuppressWarnings("doclint:missing") public class BeanContextServicesSupport extends BeanContextSupport implements BeanContextServices { @@ -157,6 +156,10 @@ public class BeanContextServicesSupport extends BeanContextSupport * when the BeanContextSupport is serialized. */ + /** + * A protected nested class containing per-child information + * in the {@code children} hashtable. + */ protected class BCSSChild extends BeanContextSupport.BCSChild { /** @@ -787,6 +790,10 @@ public class BeanContextServicesSupport extends BeanContextSupport * to an enclosing BeanContext. */ + /** + * Subclasses may subclass this nested class to represent a proxy for + * each BeanContextServiceProvider. + */ protected class BCSSProxyServiceProvider implements BeanContextServiceProvider, BeanContextServiceRevokedListener { BCSSProxyServiceProvider(BeanContextServices bcs) { diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java index e5e53db3dfe..66b0995bf02 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java @@ -59,7 +59,6 @@ import java.util.Map; * @author Laurence P. G. Cable * @since 1.2 */ -@SuppressWarnings("doclint:missing") public class BeanContextSupport extends BeanContextChildSupport implements BeanContext, Serializable, @@ -305,13 +304,17 @@ public class BeanContextSupport extends BeanContextChildSupport * when the BeanContextSupport is serialized. */ - protected class BCSChild implements Serializable { - /** - * Use serialVersionUID from JDK 1.7 for interoperability. + * A protected nested class containing per-child information + * in the {@code children} hashtable. */ - @Serial - private static final long serialVersionUID = -5815286101609939109L; + protected class BCSChild implements Serializable { + + /** + * Use serialVersionUID from JDK 1.7 for interoperability. + */ + @Serial + private static final long serialVersionUID = -5815286101609939109L; BCSChild(Object bcc, Object peer) { super(); diff --git a/src/java.desktop/share/classes/javax/swing/DefaultListSelectionModel.java b/src/java.desktop/share/classes/javax/swing/DefaultListSelectionModel.java index 1924df3123e..55b8fbba66c 100644 --- a/src/java.desktop/share/classes/javax/swing/DefaultListSelectionModel.java +++ b/src/java.desktop/share/classes/javax/swing/DefaultListSelectionModel.java @@ -50,8 +50,7 @@ import javax.swing.event.*; * @see ListSelectionModel * @since 1.2 */ -@SuppressWarnings({"serial", // Same-version serialization only - "doclint:missing"}) +@SuppressWarnings({"serial"}) // Same-version serialization only public class DefaultListSelectionModel implements ListSelectionModel, Cloneable, Serializable { private static final int MIN = -1; @@ -206,6 +205,11 @@ public class DefaultListSelectionModel implements ListSelectionModel, Cloneable, } /** + * Notifies ListSelectionListeners that the value + * of the selection, in the closed interval firstIndex, + * lastIndex, has changed and if this is the final change + * in the series of adjustments. + * * @param firstIndex the first index in the interval * @param lastIndex the last index in the interval * @param isAdjusting true if this is the final change in a series of diff --git a/src/java.desktop/share/classes/javax/swing/JApplet.java b/src/java.desktop/share/classes/javax/swing/JApplet.java index a1ba64dcf0d..a1d51bf0069 100644 --- a/src/java.desktop/share/classes/javax/swing/JApplet.java +++ b/src/java.desktop/share/classes/javax/swing/JApplet.java @@ -99,13 +99,15 @@ import javax.accessibility.AccessibleContext; @Deprecated(since = "9", forRemoval = true) @JavaBean(defaultProperty = "JMenuBar", description = "Swing's Applet subclass.") @SwingContainer(delegate = "getContentPane") -@SuppressWarnings({"serial", "removal", // Same-version serialization only - "doclint:missing"}) +@SuppressWarnings({"serial", "removal"}) // Same-version serialization only public class JApplet extends Applet implements Accessible, RootPaneContainer, TransferHandler.HasGetTransferHandler { /** + * The JRootPane instance that manages the + * contentPane. + * * @see #getRootPane * @see #setRootPane */ diff --git a/src/java.desktop/share/classes/javax/swing/JDialog.java b/src/java.desktop/share/classes/javax/swing/JDialog.java index 97013e59a6b..ace7d15adad 100644 --- a/src/java.desktop/share/classes/javax/swing/JDialog.java +++ b/src/java.desktop/share/classes/javax/swing/JDialog.java @@ -95,8 +95,7 @@ import javax.accessibility.*; */ @JavaBean(defaultProperty = "JMenuBar", description = "A toplevel window for creating dialog boxes.") @SwingContainer(delegate = "getContentPane") -@SuppressWarnings({"serial", // Same-version serialization only - "doclint:missing"}) +@SuppressWarnings({"serial"}) // Same-version serialization only public class JDialog extends Dialog implements WindowConstants, Accessible, RootPaneContainer, @@ -112,6 +111,9 @@ public class JDialog extends Dialog implements WindowConstants, private int defaultCloseOperation = HIDE_ON_CLOSE; /** + * The JRootPane instance that manages the + * contentPane. + * * @see #getRootPane * @see #setRootPane */ diff --git a/src/java.desktop/share/classes/javax/swing/JScrollBar.java b/src/java.desktop/share/classes/javax/swing/JScrollBar.java index 25cdb0886a9..6bb997a6150 100644 --- a/src/java.desktop/share/classes/javax/swing/JScrollBar.java +++ b/src/java.desktop/share/classes/javax/swing/JScrollBar.java @@ -83,8 +83,7 @@ import javax.swing.plaf.ScrollBarUI; */ @JavaBean(defaultProperty = "UI", description = "A component that helps determine the visible content range of an area.") @SwingContainer(false) -@SuppressWarnings({"serial", // Same-version serialization only - "doclint:missing"}) +@SuppressWarnings({"serial"}) // Same-version serialization only public class JScrollBar extends JComponent implements Adjustable, Accessible { /** @@ -109,18 +108,26 @@ public class JScrollBar extends JComponent implements Adjustable, Accessible /** + * Orientation of this scrollBar. + * * @see #setOrientation */ protected int orientation; /** + * Stores the amount by which the value of the scrollbar is changed + * upon a unit up/down request. + * * @see #setUnitIncrement */ protected int unitIncrement; /** + * Stores the amount by which the value of the scrollbar is changed + * upon a block (usually "page") up/down request. + * * @see #setBlockIncrement */ protected int blockIncrement; diff --git a/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java b/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java index 0f30ef14d88..8b0b1190aef 100644 --- a/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java +++ b/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java @@ -65,7 +65,6 @@ import sun.awt.shell.ShellFolder; // PENDING(jeff) - need to provide a specification for // how Mac/OS2/BeOS/etc file systems can modify FileSystemView // to handle their particular type of file system. -@SuppressWarnings("doclint:missing") public abstract class FileSystemView { static FileSystemView windowsFileSystemView = null; @@ -348,13 +347,14 @@ public abstract class FileSystemView { } /** + * Returns a File object which is normally constructed with new + * File(parent, fileName) except when the parent and child are both + * special folders, in which case the File is a wrapper containing + * a ShellFolder object. * * @param parent a File object representing a directory or special folder * @param fileName a name of a file or folder which exists in parent - * @return a File object. This is normally constructed with new - * File(parent, fileName) except when parent and child are both - * special folders, in which case the File is a wrapper containing - * a ShellFolder object. + * @return a File object. * @since 1.4 */ public File getChild(File parent, String fileName) { diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java index fa6a5312767..db9eee52f1f 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java @@ -45,7 +45,6 @@ import sun.swing.*; * @author Arnaud Weber * @author Fredrik Lagerblad */ -@SuppressWarnings("doclint:missing") public class BasicMenuItemUI extends MenuItemUI { /** @@ -257,6 +256,7 @@ public class BasicMenuItemUI extends MenuItemUI } /** + * Registers the subcomponents of the menu. * * @param menuItem a menu item * @since 1.3 diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuUI.java index 78727a729c4..0d2b0fde15e 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuUI.java @@ -46,7 +46,6 @@ import java.util.ArrayList; * @author David Karlton * @author Arnaud Weber */ -@SuppressWarnings("doclint:missing") public class BasicMenuUI extends BasicMenuItemUI { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java index 9513b723490..d43dd59544a 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalBorders.java @@ -47,7 +47,6 @@ import sun.swing.SwingUtilities2; * Factory object that can vend Borders appropriate for the metal L & F. * @author Steve Wilson */ -@SuppressWarnings("doclint:missing") public class MetalBorders { /** @@ -926,7 +925,7 @@ public class MetalBorders { } /** - * The class represents the border of a {@code JTestField}. + * Border for a {@code JTextField}. */ @SuppressWarnings("serial") // Superclass is not serializable across versions public static class TextFieldBorder extends Flush3DBorder { @@ -1027,6 +1026,8 @@ public class MetalBorders { } /** + * Border for a {@code JToggleButton}. + * * @since 1.3 */ @SuppressWarnings("serial") // Superclass is not serializable across versions diff --git a/src/java.desktop/share/classes/javax/swing/text/LayeredHighlighter.java b/src/java.desktop/share/classes/javax/swing/text/LayeredHighlighter.java index c50710233fc..e484a0d9af2 100644 --- a/src/java.desktop/share/classes/javax/swing/text/LayeredHighlighter.java +++ b/src/java.desktop/share/classes/javax/swing/text/LayeredHighlighter.java @@ -28,12 +28,13 @@ import java.awt.Graphics; import java.awt.Shape; /** + * Implementation of {@code Highlighter} interface to mark up the + * background of leaf views with colored areas. * * @author Scott Violet * @author Timothy Prinzing * @see Highlighter */ -@SuppressWarnings("doclint:missing") public abstract class LayeredHighlighter implements Highlighter { /** * Constructor for subclasses to call. @@ -68,6 +69,8 @@ public abstract class LayeredHighlighter implements Highlighter { protected LayerPainter() {} /** + * Paints a portion of a highlight. + * * @return a shape * @param g Graphics used to draw * @param p0 starting offset of view diff --git a/src/java.desktop/share/classes/javax/swing/text/html/HTML.java b/src/java.desktop/share/classes/javax/swing/text/html/HTML.java index a27893d9fcc..23e3f089b73 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/HTML.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/HTML.java @@ -43,7 +43,6 @@ import javax.swing.text.StyleContext; * @author Sunita Mani * */ -@SuppressWarnings("doclint:missing") public class HTML { /** @@ -60,7 +59,11 @@ public class HTML { */ public static class Tag { - /** @since 1.3 */ + /** + * Constructs a {@code Tag}. + * + * @since 1.3 + */ public Tag() {} /** diff --git a/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java b/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java index fb507ed0aea..8d78819b0e8 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/HTMLEditorKit.java @@ -216,8 +216,7 @@ import static java.nio.charset.StandardCharsets.ISO_8859_1; * * @author Timothy Prinzing */ -@SuppressWarnings({"serial", // Same-version serialization only - "doclint:missing"}) +@SuppressWarnings({"serial"}) // Same-version serialization only public class HTMLEditorKit extends StyledEditorKit implements Accessible { private JEditorPane theEditor; @@ -1684,6 +1683,8 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { } /** + * Returns HTMLDocument of the given JEditorPane. + * * @param e the JEditorPane * @return HTMLDocument of e. */ @@ -1696,6 +1697,8 @@ public class HTMLEditorKit extends StyledEditorKit implements Accessible { } /** + * Returns HTMLEditorKit of the given JEditorPane. + * * @param e the JEditorPane * @return HTMLEditorKit for e. */ diff --git a/src/java.desktop/share/classes/javax/swing/text/html/parser/AttributeList.java b/src/java.desktop/share/classes/javax/swing/text/html/parser/AttributeList.java index f57a7f2a917..36d1d0087c5 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/parser/AttributeList.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/AttributeList.java @@ -44,8 +44,7 @@ import java.io.*; * @author Arthur Van Hoff * */ -@SuppressWarnings({"serial", // Same-version serialization only - "doclint:missing"}) +@SuppressWarnings({"serial"}) // Same-version serialization only public final class AttributeList implements DTDConstants, Serializable { @@ -111,14 +110,14 @@ class AttributeList implements DTDConstants, Serializable { } /** - * @return attribute name + * {@return the attribute name} */ public String getName() { return name; } /** - * @return attribute type + * {@return the attribute type} * @see DTDConstants */ public int getType() { @@ -126,7 +125,7 @@ class AttributeList implements DTDConstants, Serializable { } /** - * @return attribute modifier + * {@return the attribute modifier} * @see DTDConstants */ public int getModifier() { @@ -134,21 +133,21 @@ class AttributeList implements DTDConstants, Serializable { } /** - * @return possible attribute values + * {@return possible attribute values} */ public Enumeration getValues() { return (values != null) ? values.elements() : null; } /** - * @return default attribute value + * {@return default attribute value} */ public String getValue() { return value; } /** - * @return the next attribute in the list + * {@return the next attribute in the list} */ public AttributeList getNext() { return next; diff --git a/src/java.desktop/share/classes/javax/swing/text/html/parser/Parser.java b/src/java.desktop/share/classes/javax/swing/text/html/parser/Parser.java index fc7cac3cdc1..f8a78440fba 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/parser/Parser.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/Parser.java @@ -75,7 +75,6 @@ import java.net.URL; * @author Arthur van Hoff * @author Sunita Mani */ -@SuppressWarnings("doclint:missing") public class Parser implements DTDConstants { @@ -211,6 +210,8 @@ class Parser implements DTDConstants { /** + * Returns the line number of the line currently being parsed. + * * @return the line number of the line currently being parsed */ protected int getCurrentLine() { diff --git a/src/java.desktop/share/classes/javax/swing/undo/UndoableEditSupport.java b/src/java.desktop/share/classes/javax/swing/undo/UndoableEditSupport.java index 5646222ecb1..f7228d4dc42 100644 --- a/src/java.desktop/share/classes/javax/swing/undo/UndoableEditSupport.java +++ b/src/java.desktop/share/classes/javax/swing/undo/UndoableEditSupport.java @@ -33,7 +33,6 @@ import java.util.*; * * @author Ray Ryan */ -@SuppressWarnings("doclint:missing") public class UndoableEditSupport { /** * The update level. @@ -148,7 +147,7 @@ public class UndoableEditSupport { } /** - * + * Starts a compound edit update. */ public synchronized void beginUpdate() { if (updateLevel == 0) { -- GitLab From 4ea6037ea57ce7bbad00ef172dfc3c122b2317fc Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Wed, 2 Feb 2022 10:43:02 +0000 Subject: [PATCH 123/400] 8281035: Serial: Move RemoveForwardedPointerClosure to local scope Reviewed-by: kbarrett, tschatzl --- .../share/gc/serial/defNewGeneration.cpp | 18 +++++++++++++++--- src/hotspot/share/gc/shared/preservedMarks.cpp | 6 ------ src/hotspot/share/gc/shared/preservedMarks.hpp | 5 ----- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp index 4b64494d242..dac84ffb78a 100644 --- a/src/hotspot/share/gc/serial/defNewGeneration.cpp +++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp @@ -669,9 +669,21 @@ void DefNewGeneration::init_assuming_no_promotion_failure() { } void DefNewGeneration::remove_forwarding_pointers() { - RemoveForwardedPointerClosure rspc; - eden()->object_iterate(&rspc); - from()->object_iterate(&rspc); + assert(_promotion_failed, "precondition"); + + // Will enter Full GC soon due to failed promotion. Must reset the mark word + // of objs in young-gen so that no objs are marked (forwarded) when Full GC + // starts. (The mark word is overloaded: `is_marked()` == `is_forwarded()`.) + struct ResetForwardedMarkWord : ObjectClosure { + void do_object(oop obj) override { + if (obj->is_forwarded()) { + obj->init_mark(); + } + } + } cl; + eden()->object_iterate(&cl); + from()->object_iterate(&cl); + restore_preserved_marks(); } diff --git a/src/hotspot/share/gc/shared/preservedMarks.cpp b/src/hotspot/share/gc/shared/preservedMarks.cpp index 70d7f6e8934..9003ccb1697 100644 --- a/src/hotspot/share/gc/shared/preservedMarks.cpp +++ b/src/hotspot/share/gc/shared/preservedMarks.cpp @@ -71,12 +71,6 @@ void PreservedMarks::assert_empty() { } #endif // ndef PRODUCT -void RemoveForwardedPointerClosure::do_object(oop obj) { - if (obj->is_forwarded()) { - PreservedMarks::init_forwarded_mark(obj); - } -} - void PreservedMarksSet::init(uint num) { assert(_stacks == nullptr && _num == 0, "do not re-initialize"); assert(num > 0, "pre-condition"); diff --git a/src/hotspot/share/gc/shared/preservedMarks.hpp b/src/hotspot/share/gc/shared/preservedMarks.hpp index 1aa202cfba4..9a09e78bd46 100644 --- a/src/hotspot/share/gc/shared/preservedMarks.hpp +++ b/src/hotspot/share/gc/shared/preservedMarks.hpp @@ -75,11 +75,6 @@ public: ~PreservedMarks() { assert_empty(); } }; -class RemoveForwardedPointerClosure: public ObjectClosure { -public: - virtual void do_object(oop obj); -}; - class PreservedMarksSet : public CHeapObj { private: // true -> _stacks will be allocated in the C heap -- GitLab From ce71e8b281176d39cc879ae4ecf95f3d643ebd29 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Wed, 2 Feb 2022 14:56:52 +0000 Subject: [PATCH 124/400] 8279917: Refactor subclassAudits in Thread to use ClassValue Reviewed-by: alanb, rriggs --- .../share/classes/java/lang/Thread.java | 93 ++----------------- 1 file changed, 8 insertions(+), 85 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Thread.java b/src/java.base/share/classes/java/lang/Thread.java index 77e0bbc6129..0d41973b99e 100644 --- a/src/java.base/share/classes/java/lang/Thread.java +++ b/src/java.base/share/classes/java/lang/Thread.java @@ -25,16 +25,11 @@ package java.lang; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; import java.security.AccessController; import java.security.AccessControlContext; import java.security.PrivilegedAction; import java.util.Map; import java.util.HashMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.LockSupport; @@ -1672,16 +1667,15 @@ public class Thread implements Runnable { } /** cache of subclass security audit results */ - /* Replace with ConcurrentReferenceHashMap when/if it appears in a future - * release */ private static class Caches { /** cache of subclass security audit results */ - static final ConcurrentMap subclassAudits = - new ConcurrentHashMap<>(); - - /** queue for WeakReferences to audited subclasses */ - static final ReferenceQueue> subclassAuditsQueue = - new ReferenceQueue<>(); + static final ClassValue subclassAudits = + new ClassValue<>() { + @Override + protected Boolean computeValue(Class type) { + return auditSubclass(type); + } + }; } /** @@ -1694,15 +1688,7 @@ public class Thread implements Runnable { if (cl == Thread.class) return false; - processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits); - WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); - Boolean result = Caches.subclassAudits.get(key); - if (result == null) { - result = Boolean.valueOf(auditSubclass(cl)); - Caches.subclassAudits.putIfAbsent(key, result); - } - - return result.booleanValue(); + return Caches.subclassAudits.get(cl); } /** @@ -2008,69 +1994,6 @@ public class Thread implements Runnable { getUncaughtExceptionHandler().uncaughtException(this, e); } - /** - * Removes from the specified map any keys that have been enqueued - * on the specified reference queue. - */ - static void processQueue(ReferenceQueue> queue, - ConcurrentMap>, ?> map) - { - Reference> ref; - while((ref = queue.poll()) != null) { - map.remove(ref); - } - } - - /** - * Weak key for Class objects. - **/ - static class WeakClassKey extends WeakReference> { - /** - * saved value of the referent's identity hash code, to maintain - * a consistent hash code after the referent has been cleared - */ - private final int hash; - - /** - * Create a new WeakClassKey to the given object, registered - * with a queue. - */ - WeakClassKey(Class cl, ReferenceQueue> refQueue) { - super(cl, refQueue); - hash = System.identityHashCode(cl); - } - - /** - * Returns the identity hash code of the original referent. - */ - @Override - public int hashCode() { - return hash; - } - - /** - * Returns true if the given object is this identical - * WeakClassKey instance, or, if this object's referent has not - * been cleared, if the given object is another WeakClassKey - * instance with the identical non-null referent as this one. - */ - @Override - public boolean equals(Object obj) { - if (obj == this) - return true; - - if (obj instanceof WeakClassKey) { - Class referent = get(); - return (referent != null) && - (((WeakClassKey) obj).refersTo(referent)); - } else { - return false; - } - } - } - - // The following three initially uninitialized fields are exclusively // managed by class java.util.concurrent.ThreadLocalRandom. These // fields are used to build the high-performance PRNGs in the -- GitLab From 87ab0994ded3b535a160bb87b6540bd072042c44 Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Wed, 2 Feb 2022 15:04:59 +0000 Subject: [PATCH 125/400] 8280944: Enable Unix domain sockets in Windows Selector notification mechanism Reviewed-by: dfuchs, alanb --- .../windows/classes/sun/nio/ch/PipeImpl.java | 43 ++++++++++++++----- .../sun/nio/ch/WEPollSelectorImpl.java | 2 +- .../sun/nio/ch/WindowsSelectorImpl.java | 2 +- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java b/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java index b78ac0e3a20..005a0a93339 100644 --- a/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java @@ -33,6 +33,7 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.StandardSocketOptions; +import java.net.UnixDomainSocketAddress; import java.nio.*; import java.nio.channels.*; import java.nio.file.Files; @@ -44,6 +45,7 @@ import java.security.PrivilegedActionException; import java.security.SecureRandom; import java.util.Random; +import static java.net.StandardProtocolFamily.UNIX; /** * A simple Pipe implementation based on a socket connection. @@ -67,12 +69,14 @@ class PipeImpl { private final SelectorProvider sp; + private final boolean preferUnixDomain; private IOException ioe; SourceChannelImpl source; SinkChannelImpl sink; - private Initializer(SelectorProvider sp) { + private Initializer(SelectorProvider sp, boolean preferUnixDomain) { this.sp = sp; + this.preferUnixDomain = preferUnixDomain; } @Override @@ -120,7 +124,7 @@ class PipeImpl // Bind ServerSocketChannel to a port on the loopback // address if (ssc == null || !ssc.isOpen()) { - ssc = createListener(); + ssc = createListener(preferUnixDomain); sa = ssc.getLocalAddress(); } @@ -162,6 +166,9 @@ class PipeImpl try { if (ssc != null) ssc.close(); + if (sa instanceof UnixDomainSocketAddress uaddr) { + Files.deleteIfExists(uaddr.getPath()); + } } catch (IOException e2) {} } } @@ -169,21 +176,24 @@ class PipeImpl } /** - * Creates a Pipe implementation that supports buffering. + * Creates a (TCP) Pipe implementation that supports buffering. */ PipeImpl(SelectorProvider sp) throws IOException { - this(sp, true); + this(sp, true, false); } /** - * Creates Pipe implementation that supports optionally buffering. + * Creates Pipe implementation that supports optionally buffering + * and is TCP by default, but if Unix domain is supported and + * preferAfUnix is true, then Unix domain sockets are used. + * + * @param preferAfUnix use Unix domain sockets if supported * - * @implNote Uses a loopback connection. When buffering is - * disabled then it sets TCP_NODELAY on the sink channel. + * @param buffering if false set TCP_NODELAY on TCP sockets */ @SuppressWarnings("removal") - PipeImpl(SelectorProvider sp, boolean buffering) throws IOException { - Initializer initializer = new Initializer(sp); + PipeImpl(SelectorProvider sp, boolean preferAfUnix, boolean buffering) throws IOException { + Initializer initializer = new Initializer(sp, preferAfUnix); try { AccessController.doPrivileged(initializer); SinkChannelImpl sink = initializer.sink; @@ -205,8 +215,19 @@ class PipeImpl return sink; } - private static ServerSocketChannel createListener() throws IOException { - ServerSocketChannel listener = ServerSocketChannel.open(); + private static ServerSocketChannel createListener(boolean preferUnixDomain) throws IOException { + ServerSocketChannel listener = null; + if (preferUnixDomain && UnixDomainSockets.isSupported()) { + try { + listener = ServerSocketChannel.open(UNIX); + listener.bind(null); + return listener; + } catch (IOException | UnsupportedOperationException e) { + if (listener != null) + listener.close(); + } + } + listener = ServerSocketChannel.open(); InetAddress lb = InetAddress.getLoopbackAddress(); listener.bind(new InetSocketAddress(lb, 0)); return listener; diff --git a/src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java b/src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java index 89331e1211d..8a2f26ef2b7 100644 --- a/src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/WEPollSelectorImpl.java @@ -75,7 +75,7 @@ class WEPollSelectorImpl extends SelectorImpl { // wakeup support try { - this.pipe = new PipeImpl(sp, /*buffering*/ false); + this.pipe = new PipeImpl(sp, /* AF_UNIX */ true, /*buffering*/ false); } catch (IOException ioe) { WEPoll.freePollArray(pollArrayAddress); WEPoll.close(eph); diff --git a/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java b/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java index 1df7cb76b32..4aa565674a4 100644 --- a/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/WindowsSelectorImpl.java @@ -139,7 +139,7 @@ class WindowsSelectorImpl extends SelectorImpl { WindowsSelectorImpl(SelectorProvider sp) throws IOException { super(sp); pollWrapper = new PollArrayWrapper(INIT_CAP); - wakeupPipe = new PipeImpl(sp, false); + wakeupPipe = new PipeImpl(sp, /* AF_UNIX */ true, /*buffering*/ false); wakeupSourceFd = ((SelChImpl)wakeupPipe.source()).getFDVal(); wakeupSinkFd = ((SelChImpl)wakeupPipe.sink()).getFDVal(); pollWrapper.addWakeupSocket(wakeupSourceFd, 0); -- GitLab From 9d578537ced356eb0526a70f717b5669e30eadc6 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Wed, 2 Feb 2022 15:17:50 +0000 Subject: [PATCH 126/400] 8281042: G1: Remove unused init_threshold in G1FullGCCompactionPoint Reviewed-by: tschatzl, kbarrett --- src/hotspot/share/gc/g1/g1FullCollector.cpp | 2 +- src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp | 8 ++++---- src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp | 4 ++-- src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index 37c1e1476eb..e6e7dd25c0a 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -353,7 +353,7 @@ void G1FullCollector::phase2c_prepare_serial_compaction() { if (!cp->is_initialized()) { // Initialize the compaction point. Nothing more is needed for the first heap region // since it is already prepared for compaction. - cp->initialize(current, false); + cp->initialize(current); } else { assert(!current->is_humongous(), "Should be no humongous regions in compaction queue"); G1SerialRePrepareClosure re_prepare(cp, current); diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp index 527397de55e..0e7543ec63d 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp @@ -45,7 +45,7 @@ void G1FullGCCompactionPoint::update() { } } -void G1FullGCCompactionPoint::initialize_values(bool init_threshold) { +void G1FullGCCompactionPoint::initialize_values() { _compaction_top = _current_region->compaction_top(); } @@ -57,9 +57,9 @@ bool G1FullGCCompactionPoint::is_initialized() { return _current_region != NULL; } -void G1FullGCCompactionPoint::initialize(HeapRegion* hr, bool init_threshold) { +void G1FullGCCompactionPoint::initialize(HeapRegion* hr) { _current_region = hr; - initialize_values(init_threshold); + initialize_values(); } HeapRegion* G1FullGCCompactionPoint::current_region() { @@ -86,7 +86,7 @@ void G1FullGCCompactionPoint::switch_region() { _current_region->set_compaction_top(_compaction_top); // Get the next region and re-initialize the values. _current_region = next_region(); - initialize_values(true); + initialize_values(); } void G1FullGCCompactionPoint::forward(oop object, size_t size) { diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp index 21bb75ee2e9..41a9783a07c 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.hpp @@ -38,7 +38,7 @@ class G1FullGCCompactionPoint : public CHeapObj { GrowableArrayIterator _compaction_region_iterator; bool object_will_fit(size_t size); - void initialize_values(bool init_threshold); + void initialize_values(); void switch_region(); HeapRegion* next_region(); @@ -48,7 +48,7 @@ public: bool has_regions(); bool is_initialized(); - void initialize(HeapRegion* hr, bool init_threshold); + void initialize(HeapRegion* hr); void update(); void forward(oop object, size_t size); void add(HeapRegion* hr); diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp index 75493b7de4f..a5807c33c37 100644 --- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp +++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.inline.hpp @@ -70,7 +70,7 @@ inline void G1DetermineCompactionQueueClosure::add_to_compaction_queue(HeapRegio hr->set_compaction_top(hr->bottom()); G1FullGCCompactionPoint* cp = next_compaction_point(); if (!cp->is_initialized()) { - cp->initialize(hr, true); + cp->initialize(hr); } // Add region to the compaction queue. cp->add(hr); -- GitLab From 47800bf3da181ae0ee612b14d95773fd1dc90350 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 2 Feb 2022 17:11:22 +0000 Subject: [PATCH 127/400] 8280868: LineBodyHandlerTest.java creates and discards too many clients Reviewed-by: michaelm --- .../net/httpclient/LineBodyHandlerTest.java | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/test/jdk/java/net/httpclient/LineBodyHandlerTest.java b/test/jdk/java/net/httpclient/LineBodyHandlerTest.java index 601f1ad4080..10717a848bd 100644 --- a/test/jdk/java/net/httpclient/LineBodyHandlerTest.java +++ b/test/jdk/java/net/httpclient/LineBodyHandlerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -84,7 +84,7 @@ import static org.testng.Assert.assertTrue; * java.logging * jdk.httpserver * @library /test/lib http2/server - * @build Http2TestServer LineBodyHandlerTest HttpServerAdapters + * @build Http2TestServer LineBodyHandlerTest HttpServerAdapters ReferenceTracker * @build jdk.test.lib.net.SimpleSSLContext * @run testng/othervm -XX:+UnlockDiagnosticVMOptions -XX:DiagnoseSyncOnValueBasedClasses=1 LineBodyHandlerTest */ @@ -101,6 +101,10 @@ public class LineBodyHandlerTest implements HttpServerAdapters { String http2URI; String https2URI; + final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE; + final AtomicInteger clientCount = new AtomicInteger(); + HttpClient sharedClient; + @DataProvider(name = "uris") public Object[][] variants() { return new Object[][]{ @@ -189,10 +193,14 @@ public class LineBodyHandlerTest implements HttpServerAdapters { } HttpClient newClient() { - return HttpClient.newBuilder() + if (sharedClient != null) { + return sharedClient; + } + clientCount.incrementAndGet(); + return sharedClient = TRACKER.track(HttpClient.newBuilder() .sslContext(sslContext) .proxy(Builder.NO_PROXY) - .build(); + .build()); } @Test(dataProvider = "uris") @@ -695,10 +703,21 @@ public class LineBodyHandlerTest implements HttpServerAdapters { @AfterTest public void teardown() throws Exception { + sharedClient = null; + try { + System.gc(); + Thread.sleep(200); + } catch (InterruptedException io) { + // don't care; + } + AssertionError fail = TRACKER.check(500); + System.out.printf("Tear down: %s client created.%n", clientCount.get()); + System.err.printf("Tear down: %s client created.%n", clientCount.get()); httpTestServer.stop(); httpsTestServer.stop(); http2TestServer.stop(); https2TestServer.stop(); + if (fail != null) throw fail; } static void printBytes(PrintStream out, String prefix, byte[] bytes) { -- GitLab From e3d5c9e7c4ab210ae7a4417a47632603910744a1 Mon Sep 17 00:00:00 2001 From: Masanori Yano Date: Wed, 2 Feb 2022 21:02:19 +0000 Subject: [PATCH 128/400] 8266974: duplicate property key in java.sql.rowset resource bundle Reviewed-by: lancea --- .../classes/com/sun/rowset/RowSetResourceBundle.properties | 3 +-- .../classes/com/sun/rowset/RowSetResourceBundle_de.properties | 3 +-- .../classes/com/sun/rowset/RowSetResourceBundle_es.properties | 3 +-- .../classes/com/sun/rowset/RowSetResourceBundle_fr.properties | 3 +-- .../classes/com/sun/rowset/RowSetResourceBundle_it.properties | 3 +-- .../classes/com/sun/rowset/RowSetResourceBundle_ja.properties | 3 +-- .../classes/com/sun/rowset/RowSetResourceBundle_ko.properties | 3 +-- .../com/sun/rowset/RowSetResourceBundle_pt_BR.properties | 3 +-- .../classes/com/sun/rowset/RowSetResourceBundle_sv.properties | 3 +-- .../com/sun/rowset/RowSetResourceBundle_zh_CN.properties | 3 +-- .../com/sun/rowset/RowSetResourceBundle_zh_TW.properties | 3 +-- 11 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle.properties index 47ad98d28ae..f84ede5eb41 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow : no meta data cachedrowsetimpl.movetoins2 = moveToInsertRow : invalid number of columns cachedrowsetimpl.tablename = Table name cannot be null cachedrowsetimpl.keycols = Invalid key columns -cachedrowsetimpl.invalidcol = Invalid column index cachedrowsetimpl.opnotsupp = Operation not supported by Database cachedrowsetimpl.matchcols = Match columns are not the same as those set cachedrowsetimpl.setmatchcols = Set Match columns before getting them diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_de.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_de.properties index fe9d17299e7..e1e43a16010 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_de.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_de.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: keine Metadaten cachedrowsetimpl.movetoins2 = moveToInsertRow: ung\u00FCltige Spaltenanzahl cachedrowsetimpl.tablename = Tabellenname darf nicht null sein cachedrowsetimpl.keycols = Ung\u00FCltige Schl\u00FCsselspalten -cachedrowsetimpl.invalidcol = Ung\u00FCltiger Spaltenindex cachedrowsetimpl.opnotsupp = Vorgang nicht von Datenbank unterst\u00FCtzt cachedrowsetimpl.matchcols = \u00DCbereinstimmungsspalten entsprechen nicht den festgelegten Spalten cachedrowsetimpl.setmatchcols = \u00DCbereinstimmungsspalten m\u00FCssen vor dem Abrufen festgelegt werden diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_es.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_es.properties index 8f9cb1f2392..a07408974a3 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_es.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_es.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: no hay metadatos cachedrowsetimpl.movetoins2 = moveToInsertRow: n\u00FAmero de columnas no v\u00E1lido cachedrowsetimpl.tablename = El nombre de la tabla no puede ser nulo cachedrowsetimpl.keycols = Columnas clave no v\u00E1lidas -cachedrowsetimpl.invalidcol = \u00CDndice de columnas no v\u00E1lido cachedrowsetimpl.opnotsupp = La base de datos no admite esta operaci\u00F3n cachedrowsetimpl.matchcols = Las columnas coincidentes no concuerdan con las definidas cachedrowsetimpl.setmatchcols = Defina las columnas coincidentes antes de obtenerlas diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_fr.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_fr.properties index 4beab2bf8f1..585ed33b035 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_fr.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_fr.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow : aucune m\u00E9tadonn\u00E9e cachedrowsetimpl.movetoins2 = moveToInsertRow : nombre de colonnes non valide cachedrowsetimpl.tablename = Le nom de la table ne peut pas \u00EAtre NULL cachedrowsetimpl.keycols = Colonnes de cl\u00E9 non valides -cachedrowsetimpl.invalidcol = Index de colonne non valide cachedrowsetimpl.opnotsupp = Op\u00E9ration non prise en charge par la base de donn\u00E9es cachedrowsetimpl.matchcols = Les colonnes correspondantes ne sont pas les m\u00EAmes que les colonnes d\u00E9finies cachedrowsetimpl.setmatchcols = D\u00E9finir les colonnes correspondantes avant de les prendre diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_it.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_it.properties index 4261aedea70..f971660d290 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_it.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_it.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: nessun metadato cachedrowsetimpl.movetoins2 = moveToInsertRow: numero di colonne non valido cachedrowsetimpl.tablename = Il nome di tabella non pu\u00F2 essere nullo cachedrowsetimpl.keycols = Colonne chiave non valide -cachedrowsetimpl.invalidcol = Indice di colonna non valido cachedrowsetimpl.opnotsupp = Operazione non supportata dal database cachedrowsetimpl.matchcols = Le colonne di corrispondenza non coincidono con le colonne impostate cachedrowsetimpl.setmatchcols = Impostare le colonne di corrispondenza prima di recuperarle diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ja.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ja.properties index 3192a22063e..cd40ad2ef42 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ja.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ja.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: \u30E1\u30BF\u30C7\u30FC\u30BF\u3 cachedrowsetimpl.movetoins2 = moveToInsertRow: \u7121\u52B9\u306A\u5217\u6570 cachedrowsetimpl.tablename = \u8868\u540D\u306Bnull\u306F\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093 cachedrowsetimpl.keycols = \u7121\u52B9\u306A\u30AD\u30FC\u5217 -cachedrowsetimpl.invalidcol = \u7121\u52B9\u306A\u5217\u7D22\u5F15 cachedrowsetimpl.opnotsupp = \u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3067\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u306A\u3044\u64CD\u4F5C cachedrowsetimpl.matchcols = \u4E00\u81F4\u5217\u304C\u5217\u306E\u30BB\u30C3\u30C8\u3068\u540C\u3058\u3067\u306F\u3042\u308A\u307E\u305B\u3093 cachedrowsetimpl.setmatchcols = \u4E00\u81F4\u5217\u3092\u53D6\u5F97\u3059\u308B\u524D\u306B\u8A2D\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties index 81e468eeb1d..9041d671483 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_ko.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: \uBA54\uD0C0\uB370\uC774\uD130\uA cachedrowsetimpl.movetoins2 = moveToInsertRow: \uC5F4 \uC218\uAC00 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. cachedrowsetimpl.tablename = \uD14C\uC774\uBE14 \uC774\uB984\uC740 \uB110\uC77C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. cachedrowsetimpl.keycols = \uD0A4 \uC5F4\uC774 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. -cachedrowsetimpl.invalidcol = \uC5F4 \uC778\uB371\uC2A4\uAC00 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4. cachedrowsetimpl.opnotsupp = \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC5D0\uC11C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC791\uC5C5\uC785\uB2C8\uB2E4. cachedrowsetimpl.matchcols = \uC77C\uCE58 \uC5F4\uC774 \uC124\uC815\uB41C \uC5F4\uACFC \uB3D9\uC77C\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. cachedrowsetimpl.setmatchcols = \uC77C\uCE58 \uC5F4\uC744 \uC124\uC815\uD55C \uD6C4 \uAC00\uC838\uC624\uC2ED\uC2DC\uC624. diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_pt_BR.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_pt_BR.properties index 6a2ebe4fa31..05a783ee8fc 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_pt_BR.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_pt_BR.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow : sem metadados cachedrowsetimpl.movetoins2 = moveToInsertRow : n\u00FAmero de colunas inv\u00E1lido cachedrowsetimpl.tablename = O nome da tabela n\u00E3o pode ser nulo cachedrowsetimpl.keycols = Colunas de chaves inv\u00E1lidas -cachedrowsetimpl.invalidcol = \u00CDndice de coluna inv\u00E1lido cachedrowsetimpl.opnotsupp = Opera\u00E7\u00E3o n\u00E3o suportada pelo Banco de Dados cachedrowsetimpl.matchcols = As colunas correspondentes n\u00E3o s\u00E3o iguais \u00E0s colunas definidas cachedrowsetimpl.setmatchcols = Definir Colunas correspondentes antes de obt\u00EA-las diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_sv.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_sv.properties index 912dc257219..5cac0f3c502 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_sv.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_sv.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: inga metadata cachedrowsetimpl.movetoins2 = moveToInsertRow: ogiltigt antal kolumner cachedrowsetimpl.tablename = Tabellnamnet kan inte vara null cachedrowsetimpl.keycols = Ogiltiga nyckelkolumner -cachedrowsetimpl.invalidcol = Ogiltigt kolumnindex cachedrowsetimpl.opnotsupp = Databasen har inte st\u00F6d f\u00F6r denna \u00E5tg\u00E4rd cachedrowsetimpl.matchcols = Matchningskolumnerna \u00E4r inte samma som de som st\u00E4llts in cachedrowsetimpl.setmatchcols = St\u00E4ll in matchningskolumnerna innan du h\u00E4mtar dem diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_CN.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_CN.properties index adb91c4e8d8..a9f1203518c 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_CN.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_CN.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: \u65E0\u5143\u6570\u636E cachedrowsetimpl.movetoins2 = moveToInsertRow: \u5217\u6570\u65E0\u6548 cachedrowsetimpl.tablename = \u8868\u540D\u4E0D\u80FD\u4E3A\u7A7A\u503C cachedrowsetimpl.keycols = \u5173\u952E\u5B57\u5217\u65E0\u6548 -cachedrowsetimpl.invalidcol = \u5217\u7D22\u5F15\u65E0\u6548 cachedrowsetimpl.opnotsupp = \u64CD\u4F5C\u4E0D\u53D7\u6570\u636E\u5E93\u652F\u6301 cachedrowsetimpl.matchcols = \u5339\u914D\u5217\u4E0E\u8BBE\u7F6E\u7684\u90A3\u4E9B\u5339\u914D\u5217\u4E0D\u540C cachedrowsetimpl.setmatchcols = \u5728\u83B7\u53D6\u5339\u914D\u5217\u4E4B\u524D\u5148\u8BBE\u7F6E\u5339\u914D\u5217 diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_TW.properties b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_TW.properties index dba19053aee..d42340d39e4 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_TW.properties +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/RowSetResourceBundle_zh_TW.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 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 @@ -60,7 +60,6 @@ cachedrowsetimpl.movetoins1 = moveToInsertRow: \u6C92\u6709\u63CF\u8FF0\u8CC7\u6 cachedrowsetimpl.movetoins2 = moveToInsertRow: \u6B04\u6578\u7121\u6548 cachedrowsetimpl.tablename = \u8868\u683C\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A\u503C cachedrowsetimpl.keycols = \u95DC\u9375\u6B04\u7121\u6548 -cachedrowsetimpl.invalidcol = \u6B04\u7D22\u5F15\u7121\u6548 cachedrowsetimpl.opnotsupp = \u8CC7\u6599\u5EAB\u4E0D\u652F\u63F4\u4F5C\u696D cachedrowsetimpl.matchcols = \u5339\u914D\u6B04\u548C\u8A2D\u5B9A\u7684\u6B04\u4E0D\u540C cachedrowsetimpl.setmatchcols = \u5728\u53D6\u5F97\u5339\u914D\u6B04\u4E4B\u524D\u8A2D\u5B9A\u5B83\u5011 -- GitLab From fe0118f8040ce7e5e3d605942443e3a5d442fa92 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Wed, 2 Feb 2022 21:51:39 +0000 Subject: [PATCH 129/400] 8279662: serviceability/sa/ClhsdbScanOops.java can fail do to unexpected GC Reviewed-by: sspitsyn, kevinw --- .../serviceability/sa/ClhsdbScanOops.java | 56 +++++++++++++------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java index c390fc61dca..c032b71a000 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -47,6 +47,7 @@ import java.util.Map; import java.util.ArrayList; import jdk.test.lib.Utils; import jdk.test.lib.apps.LingeredApp; +import jdk.test.lib.process.OutputAnalyzer; import jtreg.SkippedException; public class ClhsdbScanOops { @@ -71,35 +72,54 @@ public class ClhsdbScanOops { Map> expStrMap = new HashMap<>(); Map> unExpStrMap = new HashMap<>(); - String startAddress = null; - String endAddress = null; - String[] snippets = null; + String startAddress; + String endAddress; + String[] snippets; + String[] words; + String cmd; + // Run scanoops on the old gen + if (gc.contains("UseParallelGC")) { + snippets = universeOutput.split("PSOldGen \\[ "); + } else { + snippets = universeOutput.split("old \\["); + } + words = snippets[1].split(","); + // Get the addresses for Old gen + startAddress = words[0].replace("[", ""); + endAddress = words[1]; + cmd = "scanoops " + startAddress + " " + endAddress; + String output1 = test.run(theApp.getPid(), List.of(cmd), null, null); + + // Run scanoops on the eden gen if (gc.contains("UseParallelGC")) { snippets = universeOutput.split("eden = "); } else { snippets = universeOutput.split("eden \\["); } - String[] words = snippets[1].split(","); - // Get the addresses from Eden + words = snippets[1].split(","); + // Get the addresses for Eden gen startAddress = words[0].replace("[", ""); endAddress = words[1]; - String cmd = "scanoops " + startAddress + " " + endAddress; - cmds.add(cmd); - - expStrMap.put(cmd, List.of - ("java/lang/Object", "java/lang/Class", "java/lang/Thread", - "java/lang/String", "\\[B", "\\[I")); + cmd = "scanoops " + startAddress + " " + endAddress; + String output2 = test.run(theApp.getPid(), List.of(cmd), null, null); + + // Look for expected types in the combined eden and old gens + OutputAnalyzer out = new OutputAnalyzer(output1 + output2); + List expectStrs = List.of( + "java/lang/Object", "java/lang/Class", "java/lang/Thread", + "java/lang/String", "\\[B", "\\[I"); + for (String expectStr : expectStrs) { + out.shouldMatch(expectStr); + } - // Test the 'type' option also - // scanoops java/lang/String + // Test the 'type' option also: + // scanoops java/lang/String // Ensure that only the java/lang/String oops are printed. cmd = cmd + " java/lang/String"; - cmds.add(cmd); expStrMap.put(cmd, List.of("java/lang/String")); - unExpStrMap.put(cmd, List.of("java/lang/Thread")); - - test.run(theApp.getPid(), cmds, expStrMap, unExpStrMap); + unExpStrMap.put(cmd, List.of("java/lang/Thread", "java/lang/Class", "java/lang/Object")); + test.run(theApp.getPid(), List.of(cmd), expStrMap, unExpStrMap); } catch (SkippedException e) { throw e; } catch (Exception ex) { -- GitLab From a95ee5ada230a0177517efd3a417f319066169dd Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Thu, 3 Feb 2022 06:28:19 +0000 Subject: [PATCH 130/400] 8065422: Trailing dot in hostname causes TLS handshake to fail with SNI disabled Reviewed-by: weijun --- .../classes/sun/security/ssl/Utilities.java | 11 +- .../security/ssl/X509TrustManagerImpl.java | 6 + .../net/ssl/ServerName/EndingDotHostname.java | 251 +++++++++++++ .../net/ssl/templates/SSLExampleCert.java | 351 ++++++++++++++++++ 4 files changed, 616 insertions(+), 3 deletions(-) create mode 100644 test/jdk/javax/net/ssl/ServerName/EndingDotHostname.java create mode 100644 test/jdk/javax/net/ssl/templates/SSLExampleCert.java diff --git a/src/java.base/share/classes/sun/security/ssl/Utilities.java b/src/java.base/share/classes/sun/security/ssl/Utilities.java index 19fe784e0ca..8317d9ae3cb 100644 --- a/src/java.base/share/classes/sun/security/ssl/Utilities.java +++ b/src/java.base/share/classes/sun/security/ssl/Utilities.java @@ -101,14 +101,19 @@ final class Utilities { * not look like a FQDN */ private static SNIHostName rawToSNIHostName(String hostname) { - SNIHostName sniHostName = null; + // Is it a Fully-Qualified Domain Names (FQDN) ending with a dot? + if (hostname != null && hostname.endsWith(".")) { + // Remove the ending dot, which is not allowed in SNIHostName. + hostname = hostname.substring(0, hostname.length() - 1); + } + if (hostname != null && hostname.indexOf('.') > 0 && !hostname.endsWith(".") && !IPAddressUtil.isIPv4LiteralAddress(hostname) && !IPAddressUtil.isIPv6LiteralAddress(hostname)) { try { - sniHostName = new SNIHostName(hostname); + return new SNIHostName(hostname); } catch (IllegalArgumentException iae) { // don't bother to handle illegal host_name if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { @@ -118,7 +123,7 @@ final class Utilities { } } - return sniHostName; + return null; } /** diff --git a/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java b/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java index 63651db53c3..5b18641b3ad 100644 --- a/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java @@ -404,6 +404,12 @@ final class X509TrustManagerImpl extends X509ExtendedTrustManager boolean identifiable = false; String peerHost = session.getPeerHost(); + // Is it a Fully-Qualified Domain Names (FQDN) ending with a dot? + if (peerHost != null && peerHost.endsWith(".")) { + // Remove the ending dot, which is not allowed in SNIHostName. + peerHost = peerHost.substring(0, peerHost.length() - 1); + } + if (!checkClientTrusted) { List sniNames = getRequestedServerNames(session); String sniHostName = getHostNameInSNI(sniNames); diff --git a/test/jdk/javax/net/ssl/ServerName/EndingDotHostname.java b/test/jdk/javax/net/ssl/ServerName/EndingDotHostname.java new file mode 100644 index 00000000000..20ebc144088 --- /dev/null +++ b/test/jdk/javax/net/ssl/ServerName/EndingDotHostname.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. + * 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 8806542 + * @summary Trailing dot in hostname causes TLS handshake to fail + * @library /javax/net/ssl/templates + * @run main/othervm -Djdk.net.hosts.file=hostsForExample EndingDotHostname + */ + +import javax.net.ssl.*; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class EndingDotHostname { + public static void main(String[] args) throws Exception { + System.setProperty("jdk.net.hosts.file", "hostsForExample"); + (new EndingDotHostname()).run(); + } + + public void run() throws Exception { + bootUp(); + } + + // ================================================= + // Stuffs to boot up the client-server mode testing. + private Thread serverThread = null; + private volatile Exception serverException = null; + private volatile Exception clientException = null; + + // Is the server ready to serve? + protected final CountDownLatch serverCondition = new CountDownLatch(1); + + // Is the client ready to handshake? + protected final CountDownLatch clientCondition = new CountDownLatch(1); + + // What's the server port? Use any free port by default + protected volatile int serverPort = 0; + + // Boot up the testing, used to drive remainder of the test. + private void bootUp() throws Exception { + Exception startException = null; + try { + startServer(); + startClient(); + } catch (Exception e) { + startException = e; + } + + // Wait for other side to close down. + if (serverThread != null) { + serverThread.join(); + } + + // The test is pretty much over. Which side threw an exception? + Exception local = clientException; + Exception remote = serverException; + + Exception exception = null; + + // Check various exception conditions. + if ((local != null) && (remote != null)) { + // If both failed, return the curthread's exception. + local.initCause(remote); + exception = local; + } else if (local != null) { + exception = local; + } else if (remote != null) { + exception = remote; + } else if (startException != null) { + exception = startException; + } + + // If there was an exception *AND* a startException, output it. + if (exception != null) { + if (exception != startException && startException != null) { + exception.addSuppressed(startException); + } + throw exception; + } + + // Fall-through: no exception to throw! + } + + private void startServer() { + serverThread = new Thread(() -> { + try { + doServerSide(); + } catch (Exception e) { + // Our server thread just died. Release the client, + // if not active already... + serverException = e; + } + }); + + serverThread.start(); + } + + private void startClient() { + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } + } + + protected void doServerSide() throws Exception { + // kick off the server side service + SSLContext context = SSLExampleCert.createServerSSLContext(); + SSLServerSocketFactory sslssf = context.getServerSocketFactory(); + + SSLServerSocket sslServerSocket = + (SSLServerSocket)sslssf.createServerSocket(); + sslServerSocket.bind(new InetSocketAddress( + InetAddress.getLoopbackAddress(), 0)); + serverPort = sslServerSocket.getLocalPort(); + + // Signal the client, the server is ready to accept connection. + serverCondition.countDown(); + + // Try to accept a connection in 30 seconds. + SSLSocket sslSocket; + try { + sslServerSocket.setSoTimeout(30000); + sslSocket = (SSLSocket)sslServerSocket.accept(); + } catch (SocketTimeoutException ste) { + // Ignore the test case if no connection within 30 seconds. + System.out.println( + "No incoming client connection in 30 seconds. " + + "Ignore in server side."); + return; + } finally { + sslServerSocket.close(); + } + + // handle the connection + try { + // Is it the expected client connection? + // + // Naughty test cases or third party routines may try to + // connection to this server port unintentionally. In + // order to mitigate the impact of unexpected client + // connections and avoid intermittent failure, it should + // be checked that the accepted connection is really linked + // to the expected client. + boolean clientIsReady = + clientCondition.await(30L, TimeUnit.SECONDS); + + if (clientIsReady) { + // Run the application in server side. + runServerApplication(sslSocket); + } else { // Otherwise, ignore + // We don't actually care about plain socket connections + // for TLS communication testing generally. Just ignore + // the test if the accepted connection is not linked to + // the expected client or the client connection timeout + // in 30 seconds. + System.out.println( + "The client is not the expected one or timeout. " + + "Ignore in server side."); + } + } finally { + sslSocket.close(); + } + } + + // Define the server side application of the test for the specified socket. + protected void runServerApplication(SSLSocket socket) throws Exception { + // here comes the test logic + InputStream sslIS = socket.getInputStream(); + OutputStream sslOS = socket.getOutputStream(); + + sslIS.read(); + sslOS.write(85); + sslOS.flush(); + } + + protected void doClientSide() throws Exception { + // Wait for server to get started. + // + // The server side takes care of the issue if the server cannot + // get started in 90 seconds. The client side would just ignore + // the test case if the serer is not ready. + boolean serverIsReady = + serverCondition.await(90L, TimeUnit.SECONDS); + if (!serverIsReady) { + System.out.println( + "The server is not ready yet in 90 seconds. " + + "Ignore in client side."); + return; + } + + SSLContext context = SSLExampleCert.createClientSSLContext(); + SSLSocketFactory sslsf = context.getSocketFactory(); + + try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket( + "www.example.com.", serverPort)) { + // OK, here the client and server get connected. + SSLParameters sslParameters = sslSocket.getSSLParameters(); + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); + sslSocket.setSSLParameters(sslParameters); + + // Signal the server, the client is ready to communicate. + clientCondition.countDown(); + + // There is still a chance in theory that the server thread may + // wait client-ready timeout and then quit. The chance should + // be really rare so we don't consider it until it becomes a + // real problem. + + // Run the application in client side. + runClientApplication(sslSocket); + } + } + + // Define the client side application of the test for the specified socket. + protected void runClientApplication(SSLSocket socket) throws Exception { + InputStream sslIS = socket.getInputStream(); + OutputStream sslOS = socket.getOutputStream(); + + sslOS.write(280); + sslOS.flush(); + sslIS.read(); + } +} + diff --git a/test/jdk/javax/net/ssl/templates/SSLExampleCert.java b/test/jdk/javax/net/ssl/templates/SSLExampleCert.java new file mode 100644 index 00000000000..bc8a1fdb2e9 --- /dev/null +++ b/test/jdk/javax/net/ssl/templates/SSLExampleCert.java @@ -0,0 +1,351 @@ +/* + * Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. + * 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 javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; +import java.io.*; +import java.net.InetAddress; +import java.security.KeyFactory; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Base64; + +// A template to use "www.example.com" as the server name. The caller should +// set a virtual hosts file with System Property, "jdk.net.hosts.file". This +// class will map the loopback address to "www.example.com", and write to +// the specified hosts file. +public enum SSLExampleCert { + // Version: 3 (0x2) + // Serial Number: 15223159159760931473 (0xd34386999cc8ca91) + // Signature Algorithm: sha256WithRSAEncryption + // Issuer: C=US, ST=California, O=Example, OU=Test + // Validity + // Not Before: Jan 26 04:50:29 2022 GMT + // Not After : Feb 25 04:50:29 2022 GMT + // Subject: C=US, ST=California, O=Example, OU=Test + // Public Key Algorithm: rsaEncryption + CA_RSA("RSA", + """ + -----BEGIN CERTIFICATE----- + MIIDXDCCAkSgAwIBAgIJANNDhpmcyMqRMA0GCSqGSIb3DQEBCwUAMEMxCzAJBgNV + BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRAwDgYDVQQKDAdFeGFtcGxlMQ0w + CwYDVQQLDARUZXN0MB4XDTIyMDEyNjA0NTAyOVoXDTIyMDIyNTA0NTAyOVowQzEL + MAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEDAOBgNVBAoMB0V4YW1w + bGUxDTALBgNVBAsMBFRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB + AQDnOL2hB/GYyYziXo/ppxi7V1LfMMLeHt0lZbYlrmNxUlln4naI4B4Lkg75eb1Y + DgC7MZQd5nKijK9Dkq52Z2zLxaqBYnLxKJ36qKPqbtTL3I8mfUvVEeNIDN/8YTAt + suIEQi54dNtQVrB4YReMdnUq+xCKLAfEio4QLEQr7KtyCBXHZpM7RYRT0giQFvDU + 2kls9lFLeqKXgocnA7VpoL0V12hpxDeJoRm1szf0M5YXGJumQLaE5qM/+P2OOhw/ + T+xkupy2GF02s6FBXkH7NrFIjtuBSaVhSvCG/N7njWSn339thr3kiPEaCS4KSH5E + E6FEazxZQrTCbkQQ+v3y1pS1AgMBAAGjUzBRMA8GA1UdEwEB/wQFMAMBAf8wHQYD + VR0OBBYEFMFw2FWUvwZx3FJjm1G9TujCjAJSMB8GA1UdIwQYMBaAFMFw2FWUvwZx + 3FJjm1G9TujCjAJSMA0GCSqGSIb3DQEBCwUAA4IBAQCJsJjeYcT/GtKp64C+9KCi + Vgw/WnBZwbosSFZmqyID8aAnAxaGMkZ2B2pUZHTtCkBf6d9c0tuWb5yF8npV77sE + bZqeNg2GU7EvH3WPgPbQVT7+Qb+WbY3EEPgJHLytch61Rm/TRQ3OqD0B+Gs7YjAU + fEspmk1JJ6DWuXX13SHoGWgVnO7rXBnCJaGnGpONtggG4oO5hrwnMzQZKh5eZDhC + 7tkNPqVDoLv+QqnFk8q6k8hhxnVf+aw56IdsebN+9Bi+Lv6OQ+stKUo/u/RTW2z1 + odCOwc8DPF3jbacJsOmLhl3ciuWGOckx9KCvaBeTTgkPdLQH1gpNha2tnqgxUXmC + -----END CERTIFICATE-----""", + + """ + MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDnOL2hB/GYyYzi + Xo/ppxi7V1LfMMLeHt0lZbYlrmNxUlln4naI4B4Lkg75eb1YDgC7MZQd5nKijK9D + kq52Z2zLxaqBYnLxKJ36qKPqbtTL3I8mfUvVEeNIDN/8YTAtsuIEQi54dNtQVrB4 + YReMdnUq+xCKLAfEio4QLEQr7KtyCBXHZpM7RYRT0giQFvDU2kls9lFLeqKXgocn + A7VpoL0V12hpxDeJoRm1szf0M5YXGJumQLaE5qM/+P2OOhw/T+xkupy2GF02s6FB + XkH7NrFIjtuBSaVhSvCG/N7njWSn339thr3kiPEaCS4KSH5EE6FEazxZQrTCbkQQ + +v3y1pS1AgMBAAECggEBAJQAKLkTWZx/njMjbiCT+Wuo6H2+O21r+ge/BAk4h6R4 + nou1VEQmmHS1h+o992mOhP9NK867vDK5tFGfaRaW+vevzYTF3GbqpbxVB56+VG0s + /2AWoVx/96gdvZ1RJEKMFsm9BvvJaLwS0SAsnaMmC7d4Ps0Cg/JU8bv+aaBn/BGf + TWiofYWeUk6llco4kO9H2APxUVzlaUUU/cPAJqX7XktnhDCI9/esuVg7nVR0XxOF + GDrV/jdqSYmSbp4aTRXgI9nwxOmlKiGgevTrCUXl3/KaJxZekllVjushY1VVzgbY + K5R4bcN5MXMmFdgF9DTEW72RqEfg9iXqyhYbZp3Q/UECgYEA/yiaJd0w2HS22HSg + o4dJ072WbyR3qUqQmPbSUn9hBQTJAz1eX3cci8u4oawo/S+jN38b/DfpSg3eIMLB + vnXW3wZtodpJnFaweKd3yUaSF2r9vZRHJgfPfe67VbruEOF6BsCjTq/deGeNnGeH + /IDVn9WtSeRX/bv/s5YHvGaHGGUCgYEA5/vugmilOBq979EqksCG/7EQHSOoEukO + J/aunDyEwz+BMEHOEW7tDMUefdiSfnGXSW+ZTmpmvc+aLk37Xuo34jpugK5ayUFY + iYVgiqdnygGiBevBM2o0O/parQkAGEB8GPButrYItUzubUgXnuw+EdMiXGnpjJaK + S3dPYJEHvhECgYEAjqIIwV/LPUTJLWjMn30yBN43KLvu9ECNYiSfX6R6/I43O8tj + ZOQ1nePsutt9MkMd7xjr8OrkSxRDdnbITQqcaaGzSUW33mALV/btnCMJ6XNSklZA + C39UOuZn7D2JdQBF8V5gK81ddUAVxjeNqdXvFOEidGrj0R/1iVM10dhSbo0CgYBk + P8GtR02Gtj+4P/qW2m48VqbxALSkH2SHrpl8WMbCnVHVqcpETFxSNWjc11dPHwVS + rdBhS6fEhM9LDVYAiVTHBZs1LqN67ys0mpfCs18ts5Dx4BRohI+4D5NZzVbmJA+8 + s0IU4QtYVbt/LDVQ7yRPjZ7+sqJDp9ZxkEiUIXhoEQKBgQCPG2f8BhsCYNAOV60F + hJVjhDdf59Mia3B2J9SSnrg6Tl2rWB7GPP19TiSPFS6Sn95mWrMjZ2ZuOXtCYV4H + +hmu87AV2CXFhW5c588cajXMT92GFVMSXdE1OHRzDjhpH+/ll8SnmQa7sXmEV36+ + sawd7mwcB9IEi562wglADxBUCA== + """), + + // Version: 3 (0x2) + // Serial Number: 14845986384898254166 (0xce0789f5ac256556) + // Signature Algorithm: sha1WithRSAEncryption + // Issuer: C=US, ST=California, O=Example, OU=Test + // Validity + // Not Before: Jan 26 04:50:29 2022 GMT + // Not After : Feb 25 04:50:29 2022 GMT + // Subject: C=US, ST=California, O=Example, OU=Test, CN=www.example.com + // Public Key Algorithm: rsaEncryption + SERVER_EXAMPLE_RSA("RSA", + """ + -----BEGIN CERTIFICATE----- + MIIDjDCCAnSgAwIBAgIJAM4HifWsJWVWMA0GCSqGSIb3DQEBBQUAMEMxCzAJBgNV + BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRAwDgYDVQQKDAdFeGFtcGxlMQ0w + CwYDVQQLDARUZXN0MB4XDTIyMDEyNjA0NTAyOVoXDTIyMDIyNTA0NTAyOVowXTEL + MAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEDAOBgNVBAoMB0V4YW1w + bGUxDTALBgNVBAsMBFRlc3QxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIw + DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK/i4bVSAF6/aFHyzrFAON8Uwn2a + Q9jFoAMowUkH6+PCexlt4wCOEMVH9IQPa1yzeVlkYRqHggz3i6aVYvd27Q+c6vOF + FuRegWdJusyEuoXd5nwxSGiZZMLmFQswODSPmucroCG+Tq9RKY5oEKiRP8tUDqyn + eE52PaeSR2Q6mng7BM5Llj7amVgimO3jlH2AWLLpHNTkc3j/M1QrLFV2PqN4dpxT + OeFuVWzpfTWJSH+9Kq4u/zBMbYl8ON7DSgJAzc2BOw8VPIYIK6JIw6IDbLn4dIQf + GikdgHKB2K6EDOc9LuX6UqQQODDFU88muAyPgpGfUQjxKZeUoTqoAFyisI0CAwEA + AaNpMGcwCQYDVR0TBAIwADAdBgNVHQ4EFgQUQqf/4nqluVMZ8huD3I5FNqLXTqAw + HwYDVR0jBBgwFoAUwXDYVZS/BnHcUmObUb1O6MKMAlIwGgYDVR0RBBMwEYIPd3d3 + LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQBl8FJD98fJh/0KY+3LtZDW + CQZDeBSfnpq4milrvHH+gcOCaKYlB9702tAQ6rL1c1dLz/Lpw1x7EYvO8XIwXMRc + DZghf8EJ6wMpZbLVLAQLCTggiB65XPwmhUoMvgVRVLYoXT3ozmNPt7P+ZURisqem + 0/xVVfxqmHw9Hb4DNlc7oZDgOK7IrqriaBK6Amsu3m2eThsvkwTdJfeFG3ZdV6x5 + mbaGZDMt/wgWIqyq5CZNpXPaFRH7KM4zhcoqXvFAoq9jxWOuBkJUUx5EHaxGhhPw + SMgE1yl4O+N7GJmF/WMR5zp2LGKMqJ3vwLPv6QNkUmLwB5ZLYJ8E2dpj6DjQWa7X + -----END CERTIFICATE-----""", + + """ + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCv4uG1UgBev2hR + 8s6xQDjfFMJ9mkPYxaADKMFJB+vjwnsZbeMAjhDFR/SED2tcs3lZZGEah4IM94um + lWL3du0PnOrzhRbkXoFnSbrMhLqF3eZ8MUhomWTC5hULMDg0j5rnK6Ahvk6vUSmO + aBCokT/LVA6sp3hOdj2nkkdkOpp4OwTOS5Y+2plYIpjt45R9gFiy6RzU5HN4/zNU + KyxVdj6jeHacUznhblVs6X01iUh/vSquLv8wTG2JfDjew0oCQM3NgTsPFTyGCCui + SMOiA2y5+HSEHxopHYBygdiuhAznPS7l+lKkEDgwxVPPJrgMj4KRn1EI8SmXlKE6 + qABcorCNAgMBAAECggEBAJb2SvfP7BVmf+lmV9V249lE/jHECFu0M8TCZDOEowiX + 0gRfdqjxRp+tRMdcXK/yM0Nwjo+wowTyK2DNc2YnIw11h4uAPcfA/ZxjgfssKNPh + Q4Rw4E826W8HACTcPEGQyEmF/ik4KFz9coeR9kpYcMLZ4MZ77xyZDA4Z1UDHs/Fg + egrd4k35fxIFOavsjNuekMIjZlyQ2xU1a11QDBrZAu/pjITXXulg4jCxLbeNOOPs + hH+Sx+jnsVV7qIBNwulzxEdpb3+NkWIMmOQK4HOSeHgjRVvSXXBPgYadMaP/Bzvx + AwJ9WeLZg7KWHE03aOc7CSMoyHfmhXx3gD8icGpSq8ECgYEA3TWGBSgny/wket+V + 65ldWjp4NOKHbLPtBdL9ygIO+1bGfLl5srCxUWHBYdcWCXKuB5ALCBu0hMY+TlwF + s/BzZmvVW7RLAEZZ3Q5HpawDlr9j8Kenm4X2Mqh0MSkmwIDRDHF8jRXAvWIzcBiS + +rPZm2CMZpznUSE4X+GrvTSCBbkCgYEAy4yJ58wNUavj/tR8KySn5ygPABFZ1Uoy + pIyabm18Oe3gCl5UulBskoN0WreTKnA4r9jGlnrgeuu5WfMK53AZKbC+YduZixW4 + QFuJBSMbFCBDt4nkhkMMR7VcV4jIqaOK7qNrs7ubGTZhsG8wj6/WWdCp3Avnx1rS + WCCoYNhAK3UCgYADaLnCBpZmbGJbimqTEPABXflQR1Vy9WrnthK3NETq1rGEZo9b + k6GH8Yu7aEcsqhnIgA3LeDHWAgAf0Qc9eK0unObS3Ppy7KKh54BvKzF690QhB1Rr + 7yqWKUZxI4M3YETYfj8/JWCtCoBkb9yEBJWL8Xb4dd6Sv4JQ5/dvmQmP8QKBgBX+ + 5+Aeksnik060U36uBV7bW1OcjGKaFALoFsAcILJ53B4Ct5Eyo6jpf6dV8xdA7T9D + Y6JbQOrHkk4AD4uW94Ej0k7s1hjLjg+WVKYzdvejzO2GfyVrFWaiWIo1A8ohHCBR + lI/llAsTb1cLjOnaDIXEILbgqnlGfTh8vvVIKRcJAoGALF6Q1Ca2GIx4kJZ2/Az5 + qx89q95wQoWVHcJCA91g/GKg/bD0ZJMWEhhVH3QcnDOU7afRGKOPGdSSBdPQnspQ + 1OPpPjA3U5Mffy5PJ2bHTpPBeeHOzDO4Jt073zK3N81QovJzS8COoOwuGdcocURH + mFMnEtK7d+EK1C1NTWDyNzU= + """), + + + // Version: 3 (0x2) + // Serial Number: 14845986384898254167 (0xce0789f5ac256557) + // Signature Algorithm: sha1WithRSAEncryption + // Issuer: C=US, ST=California, O=Example, OU=Test + // Validity + // Not Before: Jan 26 04:50:29 2022 GMT + // Not After : Feb 25 04:50:29 2022 GMT + // Subject: C=US, ST=California, O=Example, OU=Test, CN=Do-Not-Reply + // Public Key Algorithm: rsaEncryption + CLIENT_EXAMPLE_RSA("RSA", + """ + -----BEGIN CERTIFICATE----- + MIIDkjCCAnqgAwIBAgIJAM4HifWsJWVXMA0GCSqGSIb3DQEBBQUAMEMxCzAJBgNV + BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRAwDgYDVQQKDAdFeGFtcGxlMQ0w + CwYDVQQLDARUZXN0MB4XDTIyMDEyNjA0NTAyOVoXDTIyMDIyNTA0NTAyOVowWjEL + MAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEDAOBgNVBAoMB0V4YW1w + bGUxDTALBgNVBAsMBFRlc3QxFTATBgNVBAMMDERvLU5vdC1SZXBseTCCASIwDQYJ + KoZIhvcNAQEBBQADggEPADCCAQoCggEBAODbsCteHcAg3dktUO5fiPTytIahKZMg + U2h6h0+BT803tYcdN6WDHnLNlU/3iFnBMpyTwzWhYIftC9c/TIkXBAGfWl4HHQgc + x08NHPms0E+GF6CDthvHERSvRCBrIyVna0KIZPemBzUfeBeNdiqwsLvg+C5dqWu5 + YcILvL6GzTMvdMwJeEX+c2ZYHibqd8aZydWsT+IPVZnueDX6KTOnYvexLFIoid2a + 62FavnMWiPKnICertDDg+gHlN2XceW3tlYQwO+HMig4DH3u2x0SApOoM3y8k29Ew + Fn6wquSRomcbDiI8SEOeaBFenu6W0g24iaxIZfqEM52kPbQFdzqg+O0CAwEAAaNy + MHAwCQYDVR0TBAIwADAdBgNVHQ4EFgQU0t+I5iAfPq6C/I2CSvTKHGK6+2kwHwYD + VR0jBBgwFoAUwXDYVZS/BnHcUmObUb1O6MKMAlIwIwYDVR0RBBwwGoEYZG8tbm90 + LXJlcGx5QGV4YW1wbGUuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQBqWk35XXpb3L+N + 7kPlNmSlhfamenVOVYxPBq/tSFpl728CV0OrGAy79awEFDvzhpbBg9Mz7HS/a7ax + f+lBbsAt1maWlsVSsaaJrmy3znl9CZiIg+ykZ5ZzLS5FkIbQ6LkzvxYZJ1JYCzXm + P/5+rbQyIvQaDGL23PmE7AB2Q0q+imt4b9HKs+SnI4XERyj8OF/kseRtILtP2ltV + r+3XgcBxwyU17CLwsHrjnQ8/1eGovBKzGAfUXeHBdzOuD3ZemjnqwlzQTf2TAkBP + OuMc8gr2Umc5tMtdiRUFPODO7DG7vB7LKEsJGKWLUtGbR+3S55lIcCF5NFZ//TNZ + 4x2GPOJ+ + -----END CERTIFICATE-----""", + + """ + MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDg27ArXh3AIN3Z + LVDuX4j08rSGoSmTIFNoeodPgU/NN7WHHTelgx5yzZVP94hZwTKck8M1oWCH7QvX + P0yJFwQBn1peBx0IHMdPDRz5rNBPhhegg7YbxxEUr0QgayMlZ2tCiGT3pgc1H3gX + jXYqsLC74PguXalruWHCC7y+hs0zL3TMCXhF/nNmWB4m6nfGmcnVrE/iD1WZ7ng1 + +ikzp2L3sSxSKIndmuthWr5zFojypyAnq7Qw4PoB5Tdl3Hlt7ZWEMDvhzIoOAx97 + tsdEgKTqDN8vJNvRMBZ+sKrkkaJnGw4iPEhDnmgRXp7ultINuImsSGX6hDOdpD20 + BXc6oPjtAgMBAAECggEAKjqX900RoUeK4oKUNHBUtEvwg2g4+pyTjYeVaeULK6tO + uDVQghEB4uWhKQd/3/tcmfNWMfhAvMZT9vS4Vvavle5rdkU3upJNDBeWXX2LEaRJ + Q6f4x3a3Sn8v+DamvxuRFUmwTKItsFhcoW+7xYCxcFdrxKlqbATAy0SRCecfGoFw + 9pAsFIgIqLGQtV9V9fZWKdXIfLkH3venNImHt0n5pYadl4kZu0gNCmOGRO1MqB51 + bdAck3dBg22TE5+sZBIZmCjBAEbrc2RUQu5mAoDs8eeenxBlFYszWZxqM8BkJL5e + SqQkbc18E8Gzdx52xEx6BCLTq0MITKliKX4B2tsQsQKBgQD1DIvt13yg9LlyoiAb + Fc1zzKZQBPRgDUJCGzCPeC6AqbPUjoxvFAHxGNgmJXqAXwsqcs88qlSGAjk6ANAx + fHWUQ3UmkZjGvV0ru3rIPcXvS7isjzm/cbq1YZua6+ohFl4+hojc/iyUrOaCd9uY + V2zwrr+A0JJrlev72niEuAtEmwKBgQDq6CaLP79dHqAOIV43+SyX7KdwNkMMWIR7 + El6E/74V0IWOYWFXLmV4sX6BKi0ZBTFZ3wKwMTDqQBYD2/a7gq43HjzuWu+2dFhA + pCQumMOKNqcNS9NldqoxAiGLxC+JMhGGyf3RO0Ey9gdPnQuje3133Wce8WWaHHv2 + lD5BcmzdFwKBgQCCeca7wiPy07s2ZUqxAT/eq5XWP30a85RW/IEzsusXyMQepjPy + JPYPuInGbeg3F+QrGuxrQco1fFOaJbq0zq8QXYawHY/6KfPFCFMM8Y9FpczT3IME + A3tFfo5Kw9hq+6z8n8eZ26BDHXiy+Tysdchksrb20JdVv4LiG+ZVzGT7hwKBgG+b + Bp0IF4JFh6PPBLWxRBeWT2MH1Mkr0R2r945W91fj72BbMeU63Oj/42u4vx5xEiZx + xxQw+t2AvzTsMAicqOr1CdvxBoz4L+neUnZ1DApBtxKhIPnG7EtGiOuftToIuL0C + gP4EmhB9RbH0mk/83vqxDUptRGl4+QiJHB76H3DXAoGASGT6tfs1/92rGqe0COm3 + aHpelvW7Wwr9AuBumE7/ur/JWAAiM4pm6w7m5H5duYZtG3eWz1s+jvjy8jIPBIkN + RA2DoneC2J/tsRRNFBqZrOWon5Jv4dc9R79qR13B/Oqu8H6FYSB2oDyh67Csud3q + PRrz4o7UKM+HQ/obr1rUYqM= + """); + + final String keyAlgo; + final String certStr; + final String privateKeyStr; + + // Trusted certificate + private final static SSLExampleCert[] TRUSTED_CERTS = { + SSLExampleCert.CA_RSA + }; + + // Server certificate. + private final static SSLExampleCert[] SERVER_CERTS = { + SSLExampleCert.SERVER_EXAMPLE_RSA + }; + + // Client certificate. + private final static SSLExampleCert[] CLIENT_CERTS = { + SSLExampleCert.CLIENT_EXAMPLE_RSA + }; + + // Set "www.example.com" to loopback address. + static { + String hostsFileName = System.getProperty("jdk.net.hosts.file"); + String loopbackHostname = + InetAddress.getLoopbackAddress().getHostAddress() + + " " + "www.example.com www.example.com.\n"; + try (FileWriter writer= new FileWriter(hostsFileName, false)) { + writer.write(loopbackHostname); + } catch (IOException ioe) { + // ignore + } + } + + SSLExampleCert(String keyAlgo, String certStr, String privateKeyStr) { + this.keyAlgo = keyAlgo; + this.certStr = certStr; + this.privateKeyStr = privateKeyStr; + } + + public static SSLContext createClientSSLContext() throws Exception { + return createSSLContext(TRUSTED_CERTS, CLIENT_CERTS); + } + + public static SSLContext createServerSSLContext() throws Exception { + return createSSLContext(TRUSTED_CERTS, SERVER_CERTS); + } + + private static SSLContext createSSLContext( + SSLExampleCert[] trustedCerts, + SSLExampleCert[] endEntityCerts) throws Exception { + char[] passphrase = "passphrase".toCharArray(); + + // Generate certificate from cert string. + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + // Import the trusted certs. + KeyStore ts = null; // trust store + if (trustedCerts != null && trustedCerts.length != 0) { + ts = KeyStore.getInstance("PKCS12"); + ts.load(null, null); + + Certificate[] trustedCert = new Certificate[trustedCerts.length]; + for (int i = 0; i < trustedCerts.length; i++) { + try (ByteArrayInputStream is = new ByteArrayInputStream( + trustedCerts[i].certStr.getBytes())) { + trustedCert[i] = cf.generateCertificate(is); + } + + ts.setCertificateEntry("trusted-cert-" + + trustedCerts[i].name(), trustedCert[i]); + } + } + + // Import the key materials. + KeyStore ks = null; // trust store + if (endEntityCerts != null && endEntityCerts.length != 0) { + ks = KeyStore.getInstance("PKCS12"); + ks.load(null, null); + + for (SSLExampleCert endEntityCert : endEntityCerts) { + // generate the private key. + PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( + Base64.getMimeDecoder() + .decode(endEntityCert.privateKeyStr)); + KeyFactory kf = + KeyFactory.getInstance( + endEntityCert.keyAlgo); + PrivateKey priKey = kf.generatePrivate(priKeySpec); + + // generate certificate chain + Certificate keyCert; + try (ByteArrayInputStream is = new ByteArrayInputStream( + endEntityCert.certStr.getBytes())) { + keyCert = cf.generateCertificate(is); + } + + Certificate[] chain = new Certificate[]{keyCert}; + + // import the key entry. + ks.setKeyEntry("end-entity-cert-" + + endEntityCert.name(), + priKey, passphrase, chain); + } + } + + // Create an SSLContext object. + TrustManagerFactory tmf = + TrustManagerFactory.getInstance("PKIX"); + tmf.init(ts); + + SSLContext context = SSLContext.getInstance("TLS"); + if (endEntityCerts != null && endEntityCerts.length != 0) { + KeyManagerFactory kmf = + KeyManagerFactory.getInstance("NewSunX509"); + kmf.init(ks, passphrase); + + context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + } else { + context.init(null, tmf.getTrustManagers(), null); + } + + return context; + } +} -- GitLab From fe547eacd71b4eb8119ecc7ca2d0bbe8e757f854 Mon Sep 17 00:00:00 2001 From: Artem Semenov Date: Thu, 3 Feb 2022 07:22:30 +0000 Subject: [PATCH 131/400] 8280956: Re-examine copyright headers on files in src/java.desktop/macosx/native/libawt_lwawt/awt/a11y Reviewed-by: kizune, prr --- .../macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.h | 4 +++- .../macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.m | 4 +++- .../macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.h | 4 +++- .../macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.m | 4 +++- .../native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.h | 4 +++- .../native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.m | 4 +++- .../libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.h | 4 +++- .../libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.m | 4 +++- .../macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.h | 4 +++- .../macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.m | 4 +++- .../native/libawt_lwawt/awt/a11y/ListRowAccessibility.h | 4 +++- .../native/libawt_lwawt/awt/a11y/ListRowAccessibility.m | 4 +++- .../native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.h | 4 +++- .../native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.m | 4 +++- .../native/libawt_lwawt/awt/a11y/OutlineAccessibility.h | 4 +++- .../native/libawt_lwawt/awt/a11y/OutlineAccessibility.m | 4 +++- .../native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.h | 4 +++- .../native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.m | 4 +++- .../native/libawt_lwawt/awt/a11y/TabButtonAccessibility.h | 4 +++- .../native/libawt_lwawt/awt/a11y/TabButtonAccessibility.m | 4 +++- .../native/libawt_lwawt/awt/a11y/TabGroupAccessibility.h | 4 +++- .../native/libawt_lwawt/awt/a11y/TabGroupAccessibility.m | 4 +++- .../macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.h | 4 +++- .../macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.m | 4 +++- .../native/libawt_lwawt/awt/a11y/TableRowAccessibility.h | 4 +++- .../native/libawt_lwawt/awt/a11y/TableRowAccessibility.m | 4 +++- 26 files changed, 78 insertions(+), 26 deletions(-) diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.h index ef67c92a06d..103f2c31912 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.m index c44309a1e3c..ba91dbb8b6f 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/CellAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.h index a78afaa924b..80f633f4a91 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.m index 238b82f609e..fb41511275b 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ColumnAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.h index 4a39938a826..cfdd1faee61 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.m index 0fd70eb8151..0029436579f 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComboBoxAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.h index fd1e774c274..269ea2d5ff8 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.m index 2101d7042fe..c2ce3260871 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ComponentWrapperAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.h index ddfcd2217f8..88f55f99c34 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.m index 4dc958886bb..fc75efc6029 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.h index 130d12721e6..2b3b4412beb 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.m index 8b30080c85b..dc9e617d43c 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/ListRowAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.h index 33a05318b5a..ebf314c7394 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.m index 84d8785e205..138d502f10f 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/NavigableTextAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h index 48074b209e0..2992d82cbe4 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m index acc5727cd6b..cdf6dbbd4ab 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.h index 8cc8e1760c6..4185c0a27b9 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.m index e4d7e66027d..4653821283d 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/OutlineRowAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.h index 0b497d4afc2..892225cf2ac 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.m index 538240028b8..2b22db80aa8 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabButtonAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.h index c99b18c904e..c660ff0e780 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.m index 76fafc0faaf..06375fc2934 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TabGroupAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.h index 5fe04aa257f..6fa9fd0b636 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.m index d6382822e1e..d9d18b24fce 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.h b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.h index afa9eb44e3f..d9c19ccbc42 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.h +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.h @@ -5,7 +5,9 @@ * * 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. + * 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 diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.m index 31636dd99bb..890ac973311 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/a11y/TableRowAccessibility.m @@ -5,7 +5,9 @@ * * 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. + * 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 -- GitLab From 5ab22e88da8d79f9e19e8afffdd06206f42bab94 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Thu, 3 Feb 2022 07:24:59 +0000 Subject: [PATCH 132/400] 8276990: Memory leak in invoker.c fillInvokeRequest() during JDI operations Reviewed-by: sspitsyn, cjplummer --- src/jdk.jdwp.agent/share/native/libjdwp/invoker.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c b/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c index 42e6741d467..2f6eb5f40a1 100644 --- a/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c +++ b/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c @@ -232,6 +232,7 @@ fillInvokeRequest(JNIEnv *env, InvokeRequest *request, /* * Squirrel away the method signature */ + JDI_ASSERT_MSG(request->methodSignature == NULL, "Request methodSignature not null"); error = methodSignature(method, NULL, &request->methodSignature, NULL); if (error != JVMTI_ERROR_NONE) { return error; @@ -775,6 +776,10 @@ invoker_completeInvokeRequest(jthread thread) */ deleteGlobalArgumentRefs(env, request); + JDI_ASSERT_MSG(request->methodSignature != NULL, "methodSignature is NULL"); + jvmtiDeallocate(request->methodSignature); + request->methodSignature = NULL; + /* From now on, do not access the request structure anymore * for this request id, because once we give up the invokerLock it may * be immediately reused by a new invoke request. -- GitLab From 63a00a0df24b154ef459936dbd69bcd2f0626235 Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Thu, 3 Feb 2022 10:10:45 +0000 Subject: [PATCH 133/400] 8272777: Clean up remaining AccessController warnings in test library Reviewed-by: rriggs, sspitsyn --- test/lib/jdk/test/lib/SA/SATestUtils.java | 1 + test/lib/jdk/test/lib/net/IPSupport.java | 3 ++- test/lib/jdk/test/lib/net/SimpleSSLContext.java | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/test/lib/jdk/test/lib/SA/SATestUtils.java b/test/lib/jdk/test/lib/SA/SATestUtils.java index d4daf5ef145..2f98cf99357 100644 --- a/test/lib/jdk/test/lib/SA/SATestUtils.java +++ b/test/lib/jdk/test/lib/SA/SATestUtils.java @@ -159,6 +159,7 @@ public class SATestUtils { * if we are root, so return true. Then return false for an expected denial * if "ptrace_scope" is 1, and true otherwise. */ + @SuppressWarnings("removal") private static boolean canPtraceAttachLinux() throws IOException { // SELinux deny_ptrace: var deny_ptrace = Paths.get("/sys/fs/selinux/booleans/deny_ptrace"); diff --git a/test/lib/jdk/test/lib/net/IPSupport.java b/test/lib/jdk/test/lib/net/IPSupport.java index b86354a2503..78efba3a172 100644 --- a/test/lib/jdk/test/lib/net/IPSupport.java +++ b/test/lib/jdk/test/lib/net/IPSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -71,6 +71,7 @@ public class IPSupport { } } + @SuppressWarnings("removal") private static T runPrivilegedAction(Callable callable) { try { PrivilegedExceptionAction pa = () -> callable.call(); diff --git a/test/lib/jdk/test/lib/net/SimpleSSLContext.java b/test/lib/jdk/test/lib/net/SimpleSSLContext.java index 5660ed048aa..e8611fb007f 100644 --- a/test/lib/jdk/test/lib/net/SimpleSSLContext.java +++ b/test/lib/jdk/test/lib/net/SimpleSSLContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -54,6 +54,7 @@ public class SimpleSSLContext { this(() -> "TLS"); } + @SuppressWarnings("removal") private SimpleSSLContext(Supplier protocols) throws IOException { try { final String proto = protocols.get(); -- GitLab From 010965c86ab39260b882df807c4f5d6420b20ca9 Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Thu, 3 Feb 2022 14:12:29 +0000 Subject: [PATCH 134/400] 8281023: NMT integration into pp debug command does not work Reviewed-by: zgu, iklam --- src/hotspot/share/services/mallocTracker.cpp | 30 ++++++++++++++ src/hotspot/share/services/mallocTracker.hpp | 10 +++++ .../share/services/virtualMemoryTracker.cpp | 30 ++++++++------ .../share/services/virtualMemoryTracker.hpp | 4 +- src/hotspot/share/utilities/debug.cpp | 41 ++++++------------- 5 files changed, 72 insertions(+), 43 deletions(-) diff --git a/src/hotspot/share/services/mallocTracker.cpp b/src/hotspot/share/services/mallocTracker.cpp index e27d312ad81..04cf12be94f 100644 --- a/src/hotspot/share/services/mallocTracker.cpp +++ b/src/hotspot/share/services/mallocTracker.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "runtime/os.hpp" +#include "runtime/safefetch.inline.hpp" #include "services/mallocSiteTable.hpp" #include "services/mallocTracker.hpp" #include "services/mallocTracker.inline.hpp" @@ -289,3 +290,32 @@ void* MallocTracker::record_free(void* memblock) { header->release(); return (void*)header; } + +// Given a pointer, if it seems to point to the start of a valid malloced block, +// print the block. Note that since there is very low risk of memory looking +// accidentally like a valid malloc block header (canaries and all) this is not +// totally failproof. Only use this during debugging or when you can afford +// signals popping up, e.g. when writing an hs_err file. +bool MallocTracker::print_pointer_information(const void* p, outputStream* st) { + assert(MemTracker::enabled(), "NMT must be enabled"); + if (CanUseSafeFetch32() && os::is_readable_pointer(p)) { + const NMT_TrackingLevel tracking_level = MemTracker::tracking_level(); + const MallocHeader* mhdr = (const MallocHeader*)MallocTracker::get_base(const_cast(p), tracking_level); + char msg[256]; + address p_corrupted; + if (os::is_readable_pointer(mhdr) && + mhdr->check_block_integrity(msg, sizeof(msg), &p_corrupted)) { + st->print_cr(PTR_FORMAT " malloc'd " SIZE_FORMAT " bytes by %s", + p2i(p), mhdr->size(), NMTUtil::flag_to_name(mhdr->flags())); + if (tracking_level == NMT_detail) { + NativeCallStack ncs; + if (mhdr->get_stack(ncs)) { + ncs.print_on(st); + st->cr(); + } + } + return true; + } + } + return false; +} diff --git a/src/hotspot/share/services/mallocTracker.hpp b/src/hotspot/share/services/mallocTracker.hpp index ac8eaf17c5c..78e20c30f15 100644 --- a/src/hotspot/share/services/mallocTracker.hpp +++ b/src/hotspot/share/services/mallocTracker.hpp @@ -31,6 +31,8 @@ #include "services/nmtCommon.hpp" #include "utilities/nativeCallStack.hpp" +class outputStream; + /* * This counter class counts memory allocation and deallocation, * records total memory allocation size and number of allocations. @@ -438,6 +440,14 @@ class MallocTracker : AllStatic { static inline void record_arena_size_change(ssize_t size, MEMFLAGS flags) { MallocMemorySummary::record_arena_size_change(size, flags); } + + // Given a pointer, if it seems to point to the start of a valid malloced block, + // print the block. Note that since there is very low risk of memory looking + // accidentally like a valid malloc block header (canaries and all) this is not + // totally failproof. Only use this during debugging or when you can afford + // signals popping up, e.g. when writing an hs_err file. + static bool print_pointer_information(const void* p, outputStream* st); + private: static inline MallocHeader* malloc_header(void *memblock) { assert(memblock != NULL, "NULL pointer"); diff --git a/src/hotspot/share/services/virtualMemoryTracker.cpp b/src/hotspot/share/services/virtualMemoryTracker.cpp index 53a2cf10642..d259966e611 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.cpp +++ b/src/hotspot/share/services/virtualMemoryTracker.cpp @@ -672,28 +672,32 @@ bool VirtualMemoryTracker::walk_virtual_memory(VirtualMemoryWalker* walker) { return true; } -class FindAndSnapshotRegionWalker : public VirtualMemoryWalker { +class PrintRegionWalker : public VirtualMemoryWalker { private: - ReservedMemoryRegion& _region; - const address _p; - bool _found_region; + const address _p; + outputStream* _st; public: - FindAndSnapshotRegionWalker(void* p, ReservedMemoryRegion& region) : - _region(region), _p((address)p), _found_region(false) { } + PrintRegionWalker(const void* p, outputStream* st) : + _p((address)p), _st(st) { } bool do_allocation_site(const ReservedMemoryRegion* rgn) { if (rgn->contain_address(_p)) { - _region = *rgn; - _found_region = true; + _st->print_cr(PTR_FORMAT " in mmap'd memory region [" PTR_FORMAT " - " PTR_FORMAT "] by %s", + p2i(_p), p2i(rgn->base()), p2i(rgn->base() + rgn->size()), rgn->flag_name()); + if (MemTracker::tracking_level() == NMT_detail) { + rgn->call_stack()->print_on(_st); + _st->cr(); + } return false; } return true; } - bool found_region() const { return _found_region; } }; -const bool VirtualMemoryTracker::snapshot_region_contains(void* p, ReservedMemoryRegion& region) { - FindAndSnapshotRegionWalker walker(p, region); - walk_virtual_memory(&walker); - return walker.found_region(); +// If p is contained within a known memory region, print information about it to the +// given stream and return true; false otherwise. +bool VirtualMemoryTracker::print_containing_region(const void* p, outputStream* st) { + PrintRegionWalker walker(p, st); + return !walk_virtual_memory(&walker); + } diff --git a/src/hotspot/share/services/virtualMemoryTracker.hpp b/src/hotspot/share/services/virtualMemoryTracker.hpp index 15627470f78..9ae61a605fb 100644 --- a/src/hotspot/share/services/virtualMemoryTracker.hpp +++ b/src/hotspot/share/services/virtualMemoryTracker.hpp @@ -385,7 +385,9 @@ class VirtualMemoryTracker : AllStatic { // Walk virtual memory data structure for creating baseline, etc. static bool walk_virtual_memory(VirtualMemoryWalker* walker); - static const bool snapshot_region_contains(void* p, ReservedMemoryRegion& region); + // If p is contained within a known memory region, print information about it to the + // given stream and return true; false otherwise. + static bool print_containing_region(const void* p, outputStream* st); // Snapshot current thread stacks static void snapshot_thread_stacks(); diff --git a/src/hotspot/share/utilities/debug.cpp b/src/hotspot/share/utilities/debug.cpp index bb2a0446aee..e8d95ebec1c 100644 --- a/src/hotspot/share/utilities/debug.cpp +++ b/src/hotspot/share/utilities/debug.cpp @@ -44,7 +44,6 @@ #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" -#include "runtime/safefetch.inline.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubCodeGenerator.hpp" #include "runtime/stubRoutines.hpp" @@ -483,39 +482,23 @@ extern "C" JNIEXPORT void pp(void* p) { oop obj = cast_to_oop(p); obj->print(); } else { + // Ask NMT about this pointer. + // GDB note: We will be using SafeFetch to access the supposed malloc header. If the address is + // not readable, this will generate a signal. That signal will trip up the debugger: gdb will + // catch the signal and disable the pp() command for further use. + // In order to avoid that, switch off SIGSEGV handling with "handle SIGSEGV nostop" before + // invoking pp() if (MemTracker::enabled()) { - const NMT_TrackingLevel tracking_level = MemTracker::tracking_level(); - ReservedMemoryRegion region(0, 0); - // Check and snapshot a mmap'd region that contains the pointer - if (VirtualMemoryTracker::snapshot_region_contains(p, region)) { - tty->print_cr(PTR_FORMAT " in mmap'd memory region [" PTR_FORMAT " - " PTR_FORMAT "] by %s", - p2i(p), p2i(region.base()), p2i(region.base() + region.size()), region.flag_name()); - if (tracking_level == NMT_detail) { - region.call_stack()->print_on(tty); - tty->cr(); - } + // Does it point into a known mmaped region? + if (VirtualMemoryTracker::print_containing_region(p, tty)) { return; } - // Check if it is a malloc'd memory block - if (CanUseSafeFetchN() && SafeFetchN((intptr_t*)p, 0) != 0) { - const MallocHeader* mhdr = (const MallocHeader*)MallocTracker::get_base(p, tracking_level); - char msg[256]; - address p_corrupted; - if (SafeFetchN((intptr_t*)mhdr, 0) != 0 && mhdr->check_block_integrity(msg, sizeof(msg), &p_corrupted)) { - tty->print_cr(PTR_FORMAT " malloc'd " SIZE_FORMAT " bytes by %s", - p2i(p), mhdr->size(), NMTUtil::flag_to_name(mhdr->flags())); - if (tracking_level == NMT_detail) { - NativeCallStack ncs; - if (mhdr->get_stack(ncs)) { - ncs.print_on(tty); - tty->cr(); - } - } - return; - } + // Does it look like the start of a malloced block? + if (MallocTracker::print_pointer_information(p, tty)) { + return; } } - tty->print(PTR_FORMAT, p2i(p)); + tty->print_cr(PTR_FORMAT, p2i(p)); } } -- GitLab From 1f926609372c9b80dde831a014310a3729768c92 Mon Sep 17 00:00:00 2001 From: Pavel Rappo Date: Thu, 3 Feb 2022 14:55:08 +0000 Subject: [PATCH 135/400] 8281057: Fix doc references to overriding in JLS Reviewed-by: darcy, iris, dholmes, cjplummer --- src/hotspot/share/oops/klassVtable.cpp | 4 ++-- .../share/classes/com/sun/tools/javac/code/Symbol.java | 10 +++++----- .../share/classes/com/sun/tools/javac/comp/Attr.java | 4 ++-- .../share/classes/com/sun/tools/javac/comp/Check.java | 8 ++++---- .../share/classes/com/sun/jdi/ReferenceType.java | 10 +++++----- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/hotspot/share/oops/klassVtable.cpp b/src/hotspot/share/oops/klassVtable.cpp index b107f5d70b2..f96db693de3 100644 --- a/src/hotspot/share/oops/klassVtable.cpp +++ b/src/hotspot/share/oops/klassVtable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -274,7 +274,7 @@ void klassVtable::initialize_vtable(GrowableArray* supers) { } // Returns true iff super_method can be overridden by a method in targetclassname -// See JLS 3rd edition 8.4.6.1 +// See JLS 8.4.8.1 // Assumes name-signature match // Note that the InstanceKlass of the method in the targetclassname has not always been created yet static bool can_be_overridden(Method* super_method, Handle targetclassloader, Symbol* targetclassname) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java index f72a943a2a2..558d2b3107c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -667,7 +667,7 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem * It is assumed that both symbols have the same name. The static * modifier is ignored for this test. * - * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 + * See JLS 8.4.8.1 (without transitivity) and 8.4.8.4 */ public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { return false; @@ -2060,7 +2060,7 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem * origin) don't get rejected as summarily and are put to test against the * suitable criteria. * - * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 + * See JLS 8.4.8.1 (without transitivity) and 8.4.8.4 */ public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) { return overrides(_other, origin, types, checkResult, true); @@ -2077,7 +2077,7 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem * It is assumed that both symbols have the same name. The static * modifier is ignored for this test. * - * See JLS 8.4.6.1 (without transitivity) and 8.4.6.4 + * See JLS 8.4.8.1 (without transitivity) and 8.4.8.4 */ public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult, boolean requireConcreteIfInherited) { @@ -2115,7 +2115,7 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem } private boolean isOverridableIn(TypeSymbol origin) { - // JLS 8.4.6.1 + // JLS 8.4.8.1 switch ((int)(flags_field & Flags.AccessFlags)) { case Flags.PRIVATE: return false; 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 230539f6e0e..b7fd5a76c09 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -5470,7 +5470,7 @@ public class Attr extends JCTree.Visitor { } else { // Check that all extended classes and interfaces // are compatible (i.e. no two define methods with same arguments - // yet different return types). (JLS 8.4.6.3) + // yet different return types). (JLS 8.4.8.3) chk.checkCompatibleSupertypes(tree.pos(), c.type); if (allowDefaultMethods) { chk.checkDefaultMethodClashes(tree.pos(), c.type); diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java index 55f71a2b871..96d91f22c21 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -1790,7 +1790,7 @@ public class Check { return; } - // Error if static method overrides instance method (JLS 8.4.6.2). + // Error if static method overrides instance method (JLS 8.4.8.2). if ((m.flags() & STATIC) != 0 && (other.flags() & STATIC) == 0) { log.error(TreeInfo.diagnosticPositionFor(m, tree), @@ -1800,7 +1800,7 @@ public class Check { } // Error if instance method overrides static or final - // method (JLS 8.4.6.1). + // method (JLS 8.4.8.1). if ((other.flags() & FINAL) != 0 || (m.flags() & STATIC) == 0 && (other.flags() & STATIC) != 0) { @@ -1816,7 +1816,7 @@ public class Check { return; } - // Error if overriding method has weaker access (JLS 8.4.6.3). + // Error if overriding method has weaker access (JLS 8.4.8.3). if (protection(m.flags()) > protection(other.flags())) { log.error(TreeInfo.diagnosticPositionFor(m, tree), (other.flags() & AccessFlags) == 0 ? diff --git a/src/jdk.jdi/share/classes/com/sun/jdi/ReferenceType.java b/src/jdk.jdi/share/classes/com/sun/jdi/ReferenceType.java index 2e84651fbd0..043acc839f7 100644 --- a/src/jdk.jdi/share/classes/com/sun/jdi/ReferenceType.java +++ b/src/jdk.jdi/share/classes/com/sun/jdi/ReferenceType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -413,13 +413,13 @@ public interface ReferenceType /** * Returns a list containing each {@link Method} * declared or inherited by this type. Methods from superclasses - * or superinterfaces that that have been hidden or overridden + * or superinterfaces that have been hidden or overridden * are not included. *

    * Note that despite this exclusion, multiple inherited methods * with the same signature can be present in the returned list, but * at most one can be a member of a {@link ClassType}. - * See JLS section 8.4.6 for details. + * See JLS section 8.4.8 for details. *

    * For arrays ({@link ArrayType}) and primitive classes, the returned * list is always empty. @@ -454,7 +454,7 @@ public interface ReferenceType * find overloaded methods. *

    * Overridden and hidden methods are not included. - * See JLS (8.4.6) for details. + * See JLS (8.4.8) for details. *

    * For arrays ({@link ArrayType}) and primitive classes, the returned * list is always empty. @@ -478,7 +478,7 @@ public interface ReferenceType *

  • (IIII)Z * * This method follows the inheritance rules specified - * in the JLS (8.4.6) to determine visibility. + * in the JLS (8.4.8) to determine visibility. *

    * At most one method in the list is a concrete method and a * component of {@link ClassType}; any other methods in the list -- GitLab From 86c24b319ed5e2f0097cfb4b1afe2eb358eb5f75 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Thu, 3 Feb 2022 15:51:16 +0000 Subject: [PATCH 136/400] 8240908: RetransformClass does not know about MethodParameters attribute Reviewed-by: cjplummer, sspitsyn --- .../prims/jvmtiClassFileReconstituter.cpp | 33 ++- .../prims/jvmtiClassFileReconstituter.hpp | 3 +- .../share/prims/jvmtiRedefineClasses.cpp | 30 +-- .../RetransformWithMethodParametersTest.java | 255 ++++++++++++++++++ .../jdk/test/lib/util/ClassTransformer.java | 163 +++++++++++ 5 files changed, 466 insertions(+), 18 deletions(-) create mode 100644 test/jdk/java/lang/instrument/RetransformWithMethodParametersTest.java create mode 100644 test/lib/jdk/test/lib/util/ClassTransformer.java diff --git a/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp b/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp index f530ae37caf..4fb97970036 100644 --- a/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp +++ b/src/hotspot/share/prims/jvmtiClassFileReconstituter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -287,6 +287,31 @@ void JvmtiClassFileReconstituter::write_exceptions_attribute(ConstMethod* const_ } } +// Write MethodParameters attribute +// JVMSpec| MethodParameters_attribute { +// JVMSpec| u2 attribute_name_index; +// JVMSpec| u4 attribute_length; +// JVMSpec| u1 parameters_count; +// JVMSpec| { u2 name_index; +// JVMSpec| u2 access_flags; +// JVMSpec| } parameters[parameters_count]; +// JVMSpec| } +void JvmtiClassFileReconstituter::write_method_parameter_attribute(const ConstMethod* const_method) { + const MethodParametersElement *parameters = const_method->method_parameters_start(); + int length = const_method->method_parameters_length(); + assert(length <= max_jubyte, "must fit u1"); + int size = 1 // parameters_count + + (2 + 2) * length; // parameters + + write_attribute_name_index("MethodParameters"); + write_u4(size); + write_u1(length); + for (int index = 0; index < length; index++) { + write_u2(parameters[index].name_cp_index); + write_u2(parameters[index].flags); + } +} + // Write SourceFile attribute // JVMSpec| SourceFile_attribute { // JVMSpec| u2 attribute_name_index; @@ -689,6 +714,9 @@ void JvmtiClassFileReconstituter::write_method_info(const methodHandle& method) if (default_anno != NULL) { ++attr_count; // has AnnotationDefault attribute } + if (const_method->has_method_parameters()) { + ++attr_count; // has MethodParameters attribute + } // Deprecated attribute would go here if (access_flags.is_synthetic()) { // FIXME // ++attr_count; @@ -716,6 +744,9 @@ void JvmtiClassFileReconstituter::write_method_info(const methodHandle& method) if (default_anno != NULL) { write_annotations_attribute("AnnotationDefault", default_anno); } + if (const_method->has_method_parameters()) { + write_method_parameter_attribute(const_method); + } // Deprecated attribute would go here if (access_flags.is_synthetic()) { // write_synthetic_attribute(); diff --git a/src/hotspot/share/prims/jvmtiClassFileReconstituter.hpp b/src/hotspot/share/prims/jvmtiClassFileReconstituter.hpp index 86d15b4c34a..3948e7af9b3 100644 --- a/src/hotspot/share/prims/jvmtiClassFileReconstituter.hpp +++ b/src/hotspot/share/prims/jvmtiClassFileReconstituter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -101,6 +101,7 @@ class JvmtiClassFileReconstituter : public JvmtiConstantPoolReconstituter { void write_method_info(const methodHandle& method); void write_code_attribute(const methodHandle& method); void write_exceptions_attribute(ConstMethod* const_method); + void write_method_parameter_attribute(const ConstMethod* const_method); void write_synthetic_attribute(); void write_class_attributes(); void write_source_file_attribute(); diff --git a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp index 89e41730ed9..586c0679177 100644 --- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp +++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -2266,21 +2266,6 @@ void VM_RedefineClasses::rewrite_cp_refs_in_method(methodHandle method, break; } } // end for each bytecode - - // We also need to rewrite the parameter name indexes, if there is - // method parameter data present - if(method->has_method_parameters()) { - const int len = method->method_parameters_length(); - MethodParametersElement* elem = method->method_parameters_start(); - - for (int i = 0; i < len; i++) { - const u2 cp_index = elem[i].name_cp_index; - const u2 new_cp_index = find_new_index(cp_index); - if (new_cp_index != 0) { - elem[i].name_cp_index = new_cp_index; - } - } - } } // end rewrite_cp_refs_in_method() @@ -3694,6 +3679,19 @@ void VM_RedefineClasses::set_new_constant_pool( } // end for each local variable table entry } // end if there are local variable table entries + // Update constant pool indices in the method's method_parameters. + int mp_length = method->method_parameters_length(); + if (mp_length > 0) { + MethodParametersElement* elem = method->method_parameters_start(); + for (int j = 0; j < mp_length; j++) { + const int cp_index = elem[j].name_cp_index; + const int new_cp_index = find_new_index(cp_index); + if (new_cp_index != 0) { + elem[j].name_cp_index = (u2)new_cp_index; + } + } + } + rewrite_cp_refs_in_stack_map_table(method); } // end for each method } // end set_new_constant_pool() diff --git a/test/jdk/java/lang/instrument/RetransformWithMethodParametersTest.java b/test/jdk/java/lang/instrument/RetransformWithMethodParametersTest.java new file mode 100644 index 00000000000..ef7e3818eb0 --- /dev/null +++ b/test/jdk/java/lang/instrument/RetransformWithMethodParametersTest.java @@ -0,0 +1,255 @@ +/* + * 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. + * + * 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 8240908 + * + * @library /test/lib + * @run compile -g -parameters RetransformWithMethodParametersTest.java + * @run shell MakeJAR.sh retransformAgent + * + * @run main/othervm -javaagent:retransformAgent.jar RetransformWithMethodParametersTest + */ + +import java.io.File; +import java.io.FileOutputStream; +import java.lang.instrument.ClassFileTransformer; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.ProtectionDomain; +import java.util.Arrays; + +import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.util.ClassTransformer; + +/* + * The test verifies Instrumentation.retransformClasses() (and JVMTI function RetransformClasses) + * correctly handles MethodParameter attribute: + * 1) classfile bytes passed to transformers (and JVMTI ClassFileLoadHook event callback) contain the attribute; + * 2) the attribute is updated if new version has the attribute with different values; + * 3) the attribute is removed if new version doesn't contain the attribute. + */ + +// See ClassTransformer.transform(int) comment for @1 tag explanations. +class MethodParametersTarget { + // The class contains the only method, so we don't have issue with method sorting + // and ClassFileReconstituter should restore the same bytes as original classbytes. + public void method1( + int intParam1, String stringParam1 // @1 commentout + // @1 uncomment int intParam2, String stringParam2 + ) + { + // @1 uncomment System.out.println(stringParam2); // change CP + } +} + +public class RetransformWithMethodParametersTest extends ATransformerManagementTestCase { + + public static void main (String[] args) throws Throwable { + ATestCaseScaffold test = new RetransformWithMethodParametersTest(); + test.runTest(); + } + + private String targetClassName = "MethodParametersTarget"; + private String classFileName = targetClassName + ".class"; + private String sourceFileName = "RetransformWithMethodParametersTest.java"; + private Class targetClass; + private byte[] originalClassBytes; + + private byte[] seenClassBytes; + private byte[] newClassBytes; + + public RetransformWithMethodParametersTest() throws Throwable { + super("RetransformWithMethodParametersTest"); + + File origClassFile = new File(System.getProperty("test.classes", "."), classFileName); + log("Reading test class from " + origClassFile); + originalClassBytes = Files.readAllBytes(origClassFile.toPath()); + log("Read " + originalClassBytes.length + " bytes."); + } + + private void log(Object o) { + System.out.println(String.valueOf(o)); + } + + private Parameter[] getTargetMethodParameters() throws ClassNotFoundException { + Class cls = Class.forName(targetClassName); + // the class contains 1 method (method1) + Method method = cls.getDeclaredMethods()[0]; + Parameter[] params = method.getParameters(); + log("Params of " + method.getName() + " method (" + params.length + "):"); + for (int i = 0; i < params.length; i++) { + log(" " + i + ": " + params[i].getName() + + " (" + (params[i].isNamePresent() ? "present" : "absent") + ")"); + } + return params; + } + + // Verifies MethodParameters attribute is present and contains the expected values. + private void verifyPresentMethodParams(String... expectedNames) throws Throwable { + Parameter[] params = getTargetMethodParameters(); + assertEquals(expectedNames.length, params.length); + for (int i = 0; i < params.length; i++) { + assertTrue(params[i].isNamePresent()); + assertEquals(expectedNames[i], params[i].getName()); + } + } + + // Verifies MethodParameters attribute is absent. + private void verifyAbsentMethodParams() throws Throwable { + Parameter[] params = getTargetMethodParameters(); + for (int i = 0; i < params.length; i++) { + assertTrue(!params[i].isNamePresent()); + } + } + + // Retransforms target class using provided class bytes; + // Returns class bytes passed to the transformer. + private byte[] retransform(byte[] classBytes) throws Throwable { + seenClassBytes = null; + newClassBytes = classBytes; + fInst.retransformClasses(targetClass); + assertTrue(targetClassName + " was not seen by transform()", seenClassBytes != null); + return seenClassBytes; + } + + // Prints dissassembled class bytes. + private void printDisassembled(String description, byte[] bytes) throws Exception { + log(description + " -------------------"); + + File f = new File(classFileName); + try (FileOutputStream fos = new FileOutputStream(f)) { + fos.write(bytes); + } + JDKToolLauncher javap = JDKToolLauncher.create("javap") + .addToolArg("-verbose") + .addToolArg("-p") // Shows all classes and members. + //.addToolArg("-c") // Prints out disassembled code + //.addToolArg("-s") // Prints internal type signatures. + .addToolArg(f.toString()); + ProcessBuilder pb = new ProcessBuilder(javap.getCommand()); + OutputAnalyzer out = ProcessTools.executeProcess(pb); + out.shouldHaveExitValue(0); + try { + Files.delete(f.toPath()); + } catch (Exception ex) { + // ignore + } + out.asLines().forEach(s -> log(s)); + log("=========================================="); + } + + // Verifies class bytes are equal. + private void compareClassBytes(byte[] expected, byte[] actual) throws Exception { + + int pos = Arrays.mismatch(expected, actual); + if (pos < 0) { + log("Class bytes are identical."); + return; + } + log("Class bytes are different."); + printDisassembled("expected", expected); + printDisassembled("expected", actual); + fail(targetClassName + " did not match .class file"); + } + + protected final void doRunTest() throws Throwable { + beVerbose(); + + ClassLoader loader = getClass().getClassLoader(); + targetClass = loader.loadClass(targetClassName); + // sanity check + assertEquals(targetClassName, targetClass.getName()); + // sanity check + verifyPresentMethodParams("intParam1", "stringParam1"); + + addTransformerToManager(fInst, new Transformer(), true); + + { + log("Testcase 1: ensure ClassFileReconstituter restores MethodParameters attribute"); + + byte[] classBytes = retransform(null); + compareClassBytes(originalClassBytes, classBytes); + + log(""); + } + + { + log("Testcase 2: redefine class with changed parameter names"); + + byte[] classBytes = Files.readAllBytes(Paths.get( + ClassTransformer.fromTestSource(sourceFileName) + .transform(1, targetClassName, "-g", "-parameters"))); + retransform(classBytes); + // MethodParameters attribute should be updated. + verifyPresentMethodParams("intParam2", "stringParam2"); + + log(""); + } + + { + log("Testcase 3: redefine class with no parameter names"); + // compile without "-parameters" + byte[] classBytes = Files.readAllBytes(Paths.get( + ClassTransformer.fromTestSource(sourceFileName) + .transform(1, targetClassName, "-g"))); + retransform(classBytes); + // MethodParameters attribute should be dropped. + verifyAbsentMethodParams(); + + log(""); + } + } + + + public class Transformer implements ClassFileTransformer { + public Transformer() { + } + + public String toString() { + return Transformer.this.getClass().getName(); + } + + public byte[] transform(ClassLoader loader, String className, + Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { + + if (className.equals(targetClassName)) { + log(this + ".transform() sees '" + className + + "' of " + classfileBuffer.length + " bytes."); + seenClassBytes = classfileBuffer; + if (newClassBytes != null) { + log(this + ".transform() sets new classbytes for '" + className + + "' of " + newClassBytes.length + " bytes."); + } + return newClassBytes; + } + + return null; + } + } +} diff --git a/test/lib/jdk/test/lib/util/ClassTransformer.java b/test/lib/jdk/test/lib/util/ClassTransformer.java new file mode 100644 index 00000000000..7ace81df87b --- /dev/null +++ b/test/lib/jdk/test/lib/util/ClassTransformer.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2018, 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. + * + * 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.test.lib.util; + +import jdk.test.lib.compiler.CompilerUtils; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +// ClassTransformer provides functionality to transform java source and compile it. +// We cannot use InMemoryJavaCompiler as test files usually contain 2 classes (the test itself and debuggee) +// and InMemoryJavaCompiler cannot compile them. +public class ClassTransformer { + + private final List lines; + private String fileName; + private String workDir = "ver{0}"; + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + private ClassTransformer(List lines) { + this.lines = lines; + } + + public ClassTransformer setFileName(String fileName) { + this.fileName = fileName; + return this; + } + + // workDir is a MessageFormat pattern, id (int) is an {0} arg of the pattern. + // can be relative (relatively "scratch" dir) or absolute. + public ClassTransformer setWorkDir(String dir) { + workDir = dir; + return this; + } + + public static ClassTransformer fromString(String content) { + return new ClassTransformer(Arrays.asList(content.split("\\R"))); + } + + public static ClassTransformer fromFile(Path filePath) { + try { + return new ClassTransformer(Files.readAllLines(filePath)) + .setFileName(filePath.getFileName().toString()); + } catch (IOException e) { + throw new RuntimeException("failed to read " + filePath, e); + } + } + public static ClassTransformer fromFile(String filePath) { + return fromFile(Paths.get(filePath)); + } + + public static ClassTransformer fromTestSource(String fileName) { + return fromFile(Paths.get(System.getProperty("test.src")).resolve(fileName)); + } + + // returns path to the .class file of the transformed class + public String transform(int id, String className, String... compilerOptions) { + Path subdir = Paths.get(".").resolve(MessageFormat.format(workDir, id)); + Path transformedSrc = subdir.resolve(fileName); + try { + Files.createDirectories(subdir); + Files.write(transformedSrc, transform(id).getBytes()); + } catch (IOException e) { + throw new RuntimeException("failed to write transformed " + transformedSrc, e); + } + try { + // need to add extra classpath args + List args = new LinkedList<>(Arrays.asList(compilerOptions)); + args.add("-cp"); + args.add(System.getProperty("java.class.path")); + CompilerUtils.compile(subdir, subdir, false, args.toArray(new String[args.size()])); + } catch (IOException e) { + throw new RuntimeException("failed to compile " + transformedSrc, e); + } + return subdir.resolve(className + ".class").toString(); + } + + /* + * To do RedefineClasses operations, embed @1 tags in the .java + * file to tell this script how to modify it to produce the 2nd + * version of the .class file to be used in the redefine operation. + * Here are examples of each editing tag and what change + * it causes in the new file. Note that blanks are not preserved + * in these editing operations. + * + * @1 uncomment + * orig: // @1 uncomment gus = 89; + * new: gus = 89; + * + * @1 commentout + * orig: gus = 89 // @1 commentout + * new: // gus = 89 // @1 commentout + * + * @1 delete + * orig: gus = 89 // @1 delete + * new: entire line deleted + * + * @1 newline + * orig: gus = 89; // @1 newline gus++; + * new: gus = 89; // + * gus++; + * + * @1 replace + * orig: gus = 89; // @1 replace gus = 90; + * new: gus = 90; + */ + public String transform(int id) { + Pattern delete = Pattern.compile("@" + id + " *delete"); + Pattern uncomment = Pattern.compile("// *@" + id + " *uncomment (.*)"); + Pattern commentout = Pattern.compile(".* @" + id + " *commentout"); + Pattern newline = Pattern.compile("(.*) @" + id + " *newline (.*)"); + Pattern replace = Pattern.compile("@" + id + " *replace (.*)"); + return lines.stream() + .filter(s -> !delete.matcher(s).find()) // @1 delete + .map(s -> { + Matcher m = uncomment.matcher(s); // @1 uncomment + return m.find() ? m.group(1) : s; + }) + .map(s-> { + Matcher m = commentout.matcher(s); // @1 commentout + return m.find() ? "//" + s : s; + }) + .map(s -> { + Matcher m = newline.matcher(s); // @1 newline + return m.find() ? m.group(1) + LINE_SEPARATOR + m.group(2) : s; + }) + .map(s -> { + Matcher m = replace.matcher(s); // @1 replace + return m.find() ? m.group(1) : s; + }) + .collect(Collectors.joining(LINE_SEPARATOR)); + } + +} -- GitLab From cda9c3011beeec8df68e78e096132e712255ce1b Mon Sep 17 00:00:00 2001 From: Yumin Qi Date: Thu, 3 Feb 2022 18:02:40 +0000 Subject: [PATCH 137/400] 8278753: Runtime crashes with access violation during JNI_CreateJavaVM call Reviewed-by: dholmes, stuefe --- make/data/hotspot-symbols/symbols-unix | 3 ++- src/hotspot/share/classfile/classLoader.cpp | 20 ++++++++-------- src/hotspot/share/classfile/classLoader.hpp | 8 +++++-- src/hotspot/share/include/jvm.h | 5 +++- src/hotspot/share/prims/jvm.cpp | 7 +++++- .../native/libjimage/imageDecompressor.cpp | 23 ++++++------------- 6 files changed, 35 insertions(+), 31 deletions(-) diff --git a/make/data/hotspot-symbols/symbols-unix b/make/data/hotspot-symbols/symbols-unix index 9ec0c1ec7c7..d51fcb3727d 100644 --- a/make/data/hotspot-symbols/symbols-unix +++ b/make/data/hotspot-symbols/symbols-unix @@ -1,5 +1,5 @@ # -# Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 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 @@ -158,6 +158,7 @@ JVM_IsSupportedJNIVersion JVM_IsThreadAlive JVM_IsVMGeneratedMethodIx JVM_LatestUserDefinedLoader +JVM_LoadZipLibrary JVM_LoadLibrary JVM_LookupDefineClass JVM_LookupLambdaProxyClassFromArchive diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp index 7fb8f71cbc8..bf450cbf407 100644 --- a/src/hotspot/share/classfile/classLoader.cpp +++ b/src/hotspot/share/classfile/classLoader.cpp @@ -99,7 +99,8 @@ static FindEntry_t FindEntry = NULL; static ReadEntry_t ReadEntry = NULL; static GetNextEntry_t GetNextEntry = NULL; static Crc32_t Crc32 = NULL; -int ClassLoader::_libzip_loaded = 0; +int ClassLoader::_libzip_loaded = 0; +void* ClassLoader::_zip_handle = NULL; // Entry points for jimage.dll for loading jimage file entries @@ -942,20 +943,19 @@ void ClassLoader::load_zip_library() { assert(ZipOpen == NULL, "should not load zip library twice"); char path[JVM_MAXPATHLEN]; char ebuf[1024]; - void* handle = NULL; if (os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), "zip")) { - handle = os::dll_load(path, ebuf, sizeof ebuf); + _zip_handle = os::dll_load(path, ebuf, sizeof ebuf); } - if (handle == NULL) { + if (_zip_handle == NULL) { vm_exit_during_initialization("Unable to load zip library", path); } - ZipOpen = CAST_TO_FN_PTR(ZipOpen_t, dll_lookup(handle, "ZIP_Open", path)); - ZipClose = CAST_TO_FN_PTR(ZipClose_t, dll_lookup(handle, "ZIP_Close", path)); - FindEntry = CAST_TO_FN_PTR(FindEntry_t, dll_lookup(handle, "ZIP_FindEntry", path)); - ReadEntry = CAST_TO_FN_PTR(ReadEntry_t, dll_lookup(handle, "ZIP_ReadEntry", path)); - GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, dll_lookup(handle, "ZIP_GetNextEntry", path)); - Crc32 = CAST_TO_FN_PTR(Crc32_t, dll_lookup(handle, "ZIP_CRC32", path)); + ZipOpen = CAST_TO_FN_PTR(ZipOpen_t, dll_lookup(_zip_handle, "ZIP_Open", path)); + ZipClose = CAST_TO_FN_PTR(ZipClose_t, dll_lookup(_zip_handle, "ZIP_Close", path)); + FindEntry = CAST_TO_FN_PTR(FindEntry_t, dll_lookup(_zip_handle, "ZIP_FindEntry", path)); + ReadEntry = CAST_TO_FN_PTR(ReadEntry_t, dll_lookup(_zip_handle, "ZIP_ReadEntry", path)); + GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, dll_lookup(_zip_handle, "ZIP_GetNextEntry", path)); + Crc32 = CAST_TO_FN_PTR(Crc32_t, dll_lookup(_zip_handle, "ZIP_CRC32", path)); } void ClassLoader::load_jimage_library() { diff --git a/src/hotspot/share/classfile/classLoader.hpp b/src/hotspot/share/classfile/classLoader.hpp index c454a503a2e..d2f2c6ccef1 100644 --- a/src/hotspot/share/classfile/classLoader.hpp +++ b/src/hotspot/share/classfile/classLoader.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -229,6 +229,9 @@ class ClassLoader: AllStatic { bool check_for_duplicates); CDS_ONLY(static void add_to_module_path_entries(const char* path, ClassPathEntry* entry);) + + // cache the zip library handle + static void* _zip_handle; public: CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;}) CDS_ONLY(static ClassPathEntry* module_path_entries() {return _module_path_entries;}) @@ -253,9 +256,10 @@ class ClassLoader: AllStatic { private: static int _libzip_loaded; // used to sync loading zip. static void release_load_zip_library(); - static inline void load_zip_library_if_needed(); public: + static inline void load_zip_library_if_needed(); + static void* zip_library_handle() { return _zip_handle; } static jzfile* open_zip_file(const char* canonical_path, char** error_msg, JavaThread* thread); static ClassPathEntry* create_class_path_entry(JavaThread* current, const char *path, const struct stat* st, diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index e4f56c552b7..dfdd2219869 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -150,6 +150,9 @@ JVM_ActiveProcessorCount(void); JNIEXPORT jboolean JNICALL JVM_IsUseContainerSupport(void); +JNIEXPORT void * JNICALL +JVM_LoadZipLibrary(); + JNIEXPORT void * JNICALL JVM_LoadLibrary(const char *name, jboolean throwException); diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 776e1d10011..4f54235cd4d 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -30,7 +30,7 @@ #include "cds/heapShared.hpp" #include "cds/lambdaFormInvokers.hpp" #include "classfile/classFileStream.hpp" -#include "classfile/classLoader.hpp" +#include "classfile/classLoader.inline.hpp" #include "classfile/classLoaderData.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoadInfo.hpp" @@ -3373,6 +3373,11 @@ JVM_END // Library support /////////////////////////////////////////////////////////////////////////// +JVM_LEAF(void*, JVM_LoadZipLibrary()) + ClassLoader::load_zip_library_if_needed(); + return ClassLoader::zip_library_handle(); +JVM_END + JVM_ENTRY_NO_ENV(void*, JVM_LoadLibrary(const char* name, jboolean throwException)) //%note jvm_ct char ebuf[1024]; diff --git a/src/java.base/share/native/libjimage/imageDecompressor.cpp b/src/java.base/share/native/libjimage/imageDecompressor.cpp index 5deebe350f7..65bda0957b8 100644 --- a/src/java.base/share/native/libjimage/imageDecompressor.cpp +++ b/src/java.base/share/native/libjimage/imageDecompressor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,6 +30,7 @@ */ #include "jni.h" +#include "jvm.h" #include "imageDecompressor.hpp" #include "endian.hpp" #ifdef WIN32 @@ -57,24 +58,14 @@ static ZipInflateFully_t ZipInflateFully = NULL; * @return the address of the entry point or NULL */ static void* findEntry(const char* name) { - void *addr = NULL; -#ifdef WIN32 - HMODULE handle = GetModuleHandle("zip.dll"); - if (handle == NULL) { - handle = LoadLibrary("zip.dll"); - } - if (handle == NULL) { - return NULL; - } - addr = (void*) GetProcAddress(handle, name); - return addr; -#else - addr = dlopen(JNI_LIB_PREFIX "zip" JNI_LIB_SUFFIX, RTLD_GLOBAL|RTLD_LAZY); + void *addr = JVM_LoadZipLibrary(); if (addr == NULL) { return NULL; } - addr = dlsym(addr, name); - return addr; +#ifdef WIN32 + return (void*) GetProcAddress(static_cast(addr), name); +#else + return dlsym(addr, name); #endif } -- GitLab From 130cf46dcb7b089fcf4a4e950cdc701513f7b53f Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 3 Feb 2022 19:12:27 +0000 Subject: [PATCH 138/400] 4750574: (se spec) Selector spec should clarify calculation of select return value Reviewed-by: alanb --- .../share/classes/java/nio/channels/Selector.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/java.base/share/classes/java/nio/channels/Selector.java b/src/java.base/share/classes/java/nio/channels/Selector.java index 4fb98f3a8ce..d8c0dc261bd 100644 --- a/src/java.base/share/classes/java/nio/channels/Selector.java +++ b/src/java.base/share/classes/java/nio/channels/Selector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -355,7 +355,8 @@ public abstract class Selector implements Closeable { * of the {@link #wakeup wakeup} method.

    * * @return The number of keys, possibly zero, whose ready-operation sets - * were updated by the selection operation + * now indicate readiness for at least one category of operations + * for which the channel was not previously detected to be ready * * @throws IOException * If an I/O error occurs @@ -383,8 +384,9 @@ public abstract class Selector implements Closeable { * channel to become ready; if zero, block indefinitely; * must not be negative * - * @return The number of keys, possibly zero, - * whose ready-operation sets were updated + * @return The number of keys, possibly zero, whose ready-operation sets + * now indicate readiness for at least one category of operations + * for which the channel was not previously detected to be ready * * @throws IOException * If an I/O error occurs @@ -406,8 +408,9 @@ public abstract class Selector implements Closeable { * this selector's {@link #wakeup wakeup} method is invoked, or the current * thread is interrupted, whichever comes first.

    * - * @return The number of keys, possibly zero, - * whose ready-operation sets were updated + * @return The number of keys, possibly zero, whose ready-operation sets + * now indicate readiness for at least one category of operations + * for which the channel was not previously detected to be ready * * @throws IOException * If an I/O error occurs -- GitLab From b6935dfb86a1c011355d2dfb2140be26ec536351 Mon Sep 17 00:00:00 2001 From: Yi-Fan Tsai Date: Thu, 3 Feb 2022 19:34:28 +0000 Subject: [PATCH 139/400] 8251505: Use of types in compiler shared code should be consistent. Reviewed-by: phh --- src/hotspot/share/code/nmethod.hpp | 6 ++--- src/hotspot/share/compiler/compileBroker.cpp | 2 +- src/hotspot/share/compiler/compileBroker.hpp | 6 ++--- src/hotspot/share/jvmci/jvmciEnv.cpp | 2 +- src/hotspot/share/jvmci/jvmciEnv.hpp | 2 +- .../share/runtime/interfaceSupport.cpp | 2 +- .../share/runtime/interfaceSupport.inline.hpp | 2 +- src/hotspot/share/runtime/sweeper.cpp | 27 ++++++++++--------- src/hotspot/share/runtime/sweeper.hpp | 12 ++++----- src/hotspot/share/runtime/vmStructs.cpp | 3 ++- 10 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/hotspot/share/code/nmethod.hpp b/src/hotspot/share/code/nmethod.hpp index d0154bc85a3..d31e62f404a 100644 --- a/src/hotspot/share/code/nmethod.hpp +++ b/src/hotspot/share/code/nmethod.hpp @@ -256,7 +256,7 @@ class nmethod : public CompiledMethod { // stack. An not_entrant method can be removed when there are no // more activations, i.e., when the _stack_traversal_mark is less than // current sweep traversal index. - volatile long _stack_traversal_mark; + volatile int64_t _stack_traversal_mark; // The _hotness_counter indicates the hotness of a method. The higher // the value the hotter the method. The hotness counter of a nmethod is @@ -538,8 +538,8 @@ public: void fix_oop_relocations() { fix_oop_relocations(NULL, NULL, false); } // Sweeper support - long stack_traversal_mark() { return _stack_traversal_mark; } - void set_stack_traversal_mark(long l) { _stack_traversal_mark = l; } + int64_t stack_traversal_mark() { return _stack_traversal_mark; } + void set_stack_traversal_mark(int64_t l) { _stack_traversal_mark = l; } // On-stack replacement support int osr_entry_bci() const { assert(is_osr_method(), "wrong kind of nmethod"); return _entry_bci; } diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index 1e2b5e395ba..4ae7bc21ce6 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -186,7 +186,7 @@ int CompileBroker::_sum_standard_bytes_compiled = 0; int CompileBroker::_sum_nmethod_size = 0; int CompileBroker::_sum_nmethod_code_size = 0; -long CompileBroker::_peak_compilation_time = 0; +jlong CompileBroker::_peak_compilation_time = 0; CompilerStatistics CompileBroker::_stats_per_level[CompLevel_full_optimization]; diff --git a/src/hotspot/share/compiler/compileBroker.hpp b/src/hotspot/share/compiler/compileBroker.hpp index 33fde0dace6..be770aac9c2 100644 --- a/src/hotspot/share/compiler/compileBroker.hpp +++ b/src/hotspot/share/compiler/compileBroker.hpp @@ -222,7 +222,7 @@ class CompileBroker: AllStatic { static int _sum_standard_bytes_compiled; static int _sum_nmethod_size; static int _sum_nmethod_code_size; - static long _peak_compilation_time; + static jlong _peak_compilation_time; static CompilerStatistics _stats_per_level[]; @@ -411,8 +411,8 @@ public: static int get_sum_standard_bytes_compiled() { return _sum_standard_bytes_compiled; } static int get_sum_nmethod_size() { return _sum_nmethod_size;} static int get_sum_nmethod_code_size() { return _sum_nmethod_code_size; } - static long get_peak_compilation_time() { return _peak_compilation_time; } - static long get_total_compilation_time() { return _t_total_compilation.milliseconds(); } + static jlong get_peak_compilation_time() { return _peak_compilation_time; } + static jlong get_total_compilation_time() { return _t_total_compilation.milliseconds(); } // Log that compilation profiling is skipped because metaspace is full. static void log_metaspace_failure(); diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index aa4989acf28..f789cd6ac0b 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -553,7 +553,7 @@ void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) { } } -long JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) { +jlong JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) { if (is_hotspot()) { return HotSpotJVMCI::resolve(array)->long_at(index); } else { diff --git a/src/hotspot/share/jvmci/jvmciEnv.hpp b/src/hotspot/share/jvmci/jvmciEnv.hpp index 18a80accd8b..61b7cd4e331 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.hpp +++ b/src/hotspot/share/jvmci/jvmciEnv.hpp @@ -251,7 +251,7 @@ public: jint get_int_at(JVMCIPrimitiveArray array, int index); void put_int_at(JVMCIPrimitiveArray array, int index, jint value); - long get_long_at(JVMCIPrimitiveArray array, int index); + jlong get_long_at(JVMCIPrimitiveArray array, int index); void put_long_at(JVMCIPrimitiveArray array, int index, jlong value); void copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length); diff --git a/src/hotspot/share/runtime/interfaceSupport.cpp b/src/hotspot/share/runtime/interfaceSupport.cpp index 2037b732e50..ffacf150e58 100644 --- a/src/hotspot/share/runtime/interfaceSupport.cpp +++ b/src/hotspot/share/runtime/interfaceSupport.cpp @@ -78,7 +78,7 @@ VMNativeEntryWrapper::~VMNativeEntryWrapper() { unsigned int InterfaceSupport::_scavenge_alot_counter = 1; unsigned int InterfaceSupport::_fullgc_alot_counter = 1; -int InterfaceSupport::_fullgc_alot_invocation = 0; +intx InterfaceSupport::_fullgc_alot_invocation = 0; void InterfaceSupport::gc_alot() { Thread *thread = Thread::current(); diff --git a/src/hotspot/share/runtime/interfaceSupport.inline.hpp b/src/hotspot/share/runtime/interfaceSupport.inline.hpp index 13ecf2d80ce..7cbdb00995c 100644 --- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp +++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp @@ -54,7 +54,7 @@ class InterfaceSupport: AllStatic { public: static unsigned int _scavenge_alot_counter; static unsigned int _fullgc_alot_counter; - static int _fullgc_alot_invocation; + static intx _fullgc_alot_invocation; // Helper methods used to implement +ScavengeALot and +FullGCALot static void check_gc_alot() { if (ScavengeALot || FullGCALot) gc_alot(); } diff --git a/src/hotspot/share/runtime/sweeper.cpp b/src/hotspot/share/runtime/sweeper.cpp index 31c9220ea78..ec394559247 100644 --- a/src/hotspot/share/runtime/sweeper.cpp +++ b/src/hotspot/share/runtime/sweeper.cpp @@ -55,9 +55,9 @@ // Sweeper logging code class SweeperRecord { public: - int traversal; + int64_t traversal; int compile_id; - long traversal_mark; + int64_t traversal_mark; int state; const char* kind; address vep; @@ -65,8 +65,8 @@ class SweeperRecord { int line; void print() { - tty->print_cr("traversal = %d compile_id = %d %s uep = " PTR_FORMAT " vep = " - PTR_FORMAT " state = %d traversal_mark %ld line = %d", + tty->print_cr("traversal = " INT64_FORMAT " compile_id = %d %s uep = " PTR_FORMAT " vep = " + PTR_FORMAT " state = %d traversal_mark " INT64_FORMAT " line = %d", traversal, compile_id, kind == NULL ? "" : kind, @@ -107,8 +107,8 @@ void NMethodSweeper::init_sweeper_log() { #endif CompiledMethodIterator NMethodSweeper::_current(CompiledMethodIterator::all_blobs); // Current compiled method -long NMethodSweeper::_traversals = 0; // Stack scan count, also sweep ID. -long NMethodSweeper::_total_nof_code_cache_sweeps = 0; // Total number of full sweeps of the code cache +int64_t NMethodSweeper::_traversals = 0; // Stack scan count, also sweep ID. +int64_t NMethodSweeper::_total_nof_code_cache_sweeps = 0; // Total number of full sweeps of the code cache int NMethodSweeper::_seen = 0; // Nof. nmethod we have currently processed in current pass of CodeCache size_t NMethodSweeper::_sweep_threshold_bytes = 0; // Threshold for when to sweep. Updated after ergonomics @@ -119,8 +119,8 @@ volatile size_t NMethodSweeper::_bytes_changed = 0; // Counts the tot // 2) not_entrant -> zombie int NMethodSweeper::_hotness_counter_reset_val = 0; -long NMethodSweeper::_total_nof_methods_reclaimed = 0; // Accumulated nof methods flushed -long NMethodSweeper::_total_nof_c2_methods_reclaimed = 0; // Accumulated nof methods flushed +int64_t NMethodSweeper::_total_nof_methods_reclaimed = 0; // Accumulated nof methods flushed +int64_t NMethodSweeper::_total_nof_c2_methods_reclaimed = 0; // Accumulated nof methods flushed size_t NMethodSweeper::_total_flushed_size = 0; // Total number of bytes flushed from the code cache Tickspan NMethodSweeper::_total_time_sweeping; // Accumulated time sweeping Tickspan NMethodSweeper::_total_time_this_sweep; // Total time this sweep @@ -187,7 +187,7 @@ CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() { _total_time_this_sweep = Tickspan(); if (PrintMethodFlushing) { - tty->print_cr("### Sweep: stack traversal %ld", _traversals); + tty->print_cr("### Sweep: stack traversal " INT64_FORMAT, _traversals); } return &mark_activation_closure; } @@ -217,7 +217,7 @@ void NMethodSweeper::sweeper_loop() { { ThreadBlockInVM tbivm(JavaThread::current()); MonitorLocker waiter(CodeSweeper_lock, Mutex::_no_safepoint_check_flag); - const long wait_time = 60*60*24 * 1000; + const int64_t wait_time = 60*60*24 * 1000; timeout = waiter.wait(wait_time); } if (!timeout && (_should_sweep || _force_sweep)) { @@ -646,7 +646,7 @@ void NMethodSweeper::log_sweep(const char* msg, const char* format, ...) { CodeCache::log_state(&s); ttyLocker ttyl; - xtty->begin_elem("sweeper state='%s' traversals='" INTX_FORMAT "' ", msg, (intx)traversal_count()); + xtty->begin_elem("sweeper state='%s' traversals='" INT64_FORMAT "' ", msg, traversal_count()); if (format != NULL) { va_list ap; va_start(ap, format); @@ -664,8 +664,9 @@ void NMethodSweeper::print(outputStream* out) { out = (out == NULL) ? tty : out; out->print_cr("Code cache sweeper statistics:"); out->print_cr(" Total sweep time: %1.0lf ms", (double)_total_time_sweeping.value()/1000000); - out->print_cr(" Total number of full sweeps: %ld", _total_nof_code_cache_sweeps); - out->print_cr(" Total number of flushed methods: %ld (thereof %ld C2 methods)", _total_nof_methods_reclaimed, + out->print_cr(" Total number of full sweeps: " INT64_FORMAT, _total_nof_code_cache_sweeps); + out->print_cr(" Total number of flushed methods: " INT64_FORMAT " (thereof " INT64_FORMAT " C2 methods)", + _total_nof_methods_reclaimed, _total_nof_c2_methods_reclaimed); out->print_cr(" Total size of flushed methods: " SIZE_FORMAT " kB", _total_flushed_size/K); } diff --git a/src/hotspot/share/runtime/sweeper.hpp b/src/hotspot/share/runtime/sweeper.hpp index 9ba2298e9ef..ecf5a353cfd 100644 --- a/src/hotspot/share/runtime/sweeper.hpp +++ b/src/hotspot/share/runtime/sweeper.hpp @@ -66,8 +66,8 @@ class NMethodSweeper : public AllStatic { MadeZombie, Flushed }; - static long _traversals; // Stack scan count, also sweep ID. - static long _total_nof_code_cache_sweeps; // Total number of full sweeps of the code cache + static int64_t _traversals; // Stack scan count, also sweep ID. + static int64_t _total_nof_code_cache_sweeps; // Total number of full sweeps of the code cache static CompiledMethodIterator _current; // Current compiled method static int _seen; // Nof. nmethod we have currently processed in current pass of CodeCache static size_t _sweep_threshold_bytes; // The threshold for when to invoke sweeps @@ -78,8 +78,8 @@ class NMethodSweeper : public AllStatic { // 1) alive -> not_entrant // 2) not_entrant -> zombie // Stat counters - static long _total_nof_methods_reclaimed; // Accumulated nof methods flushed - static long _total_nof_c2_methods_reclaimed; // Accumulated nof C2-compiled methods flushed + static int64_t _total_nof_methods_reclaimed; // Accumulated nof methods flushed + static int64_t _total_nof_c2_methods_reclaimed; // Accumulated nof C2-compiled methods flushed static size_t _total_flushed_size; // Total size of flushed methods static int _hotness_counter_reset_val; @@ -97,10 +97,10 @@ class NMethodSweeper : public AllStatic { static void do_stack_scanning(); static void sweep(); public: - static long traversal_count() { return _traversals; } + static int64_t traversal_count() { return _traversals; } static size_t sweep_threshold_bytes() { return _sweep_threshold_bytes; } static void set_sweep_threshold_bytes(size_t threshold) { _sweep_threshold_bytes = threshold; } - static int total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } + static int64_t total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } static const Tickspan total_time_sweeping() { return _total_time_sweeping; } static const Tickspan peak_sweep_time() { return _peak_sweep_time; } static const Tickspan peak_sweep_fraction_time() { return _peak_sweep_fraction_time; } diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index 3ec853d38f0..7fc64c94385 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -660,7 +660,7 @@ nonstatic_field(nmethod, _verified_entry_point, address) \ nonstatic_field(nmethod, _osr_entry_point, address) \ volatile_nonstatic_field(nmethod, _lock_count, jint) \ - volatile_nonstatic_field(nmethod, _stack_traversal_mark, long) \ + volatile_nonstatic_field(nmethod, _stack_traversal_mark, int64_t) \ nonstatic_field(nmethod, _compile_id, int) \ nonstatic_field(nmethod, _comp_level, int) \ \ @@ -1199,6 +1199,7 @@ declare_integer_type(ssize_t) \ declare_integer_type(intx) \ declare_integer_type(intptr_t) \ + declare_integer_type(int64_t) \ declare_unsigned_integer_type(uintx) \ declare_unsigned_integer_type(uintptr_t) \ declare_unsigned_integer_type(uint8_t) \ -- GitLab From e44dc638b8936b1b76ca9ddf9ece0c5c4705a19c Mon Sep 17 00:00:00 2001 From: Dean Long Date: Thu, 3 Feb 2022 22:10:44 +0000 Subject: [PATCH 140/400] 8271055: Crash during deoptimization with "assert(bb->is_reachable()) failed: getting result from unreachable basicblock" with -XX:+VerifyStack Co-authored-by: Yi Yang Co-authored-by: Yi Yang Reviewed-by: vlivanov, thartmann --- src/hotspot/share/runtime/deoptimization.cpp | 17 ++++- .../jtreg/compiler/interpreter/Custom.jasm | 63 +++++++++++++++++++ .../VerifyStackWithUnreachableBlock.java | 42 +++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/compiler/interpreter/Custom.jasm create mode 100644 test/hotspot/jtreg/compiler/interpreter/VerifyStackWithUnreachableBlock.java diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index 206e5951304..fee21540809 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -704,6 +704,21 @@ void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_arr assert(f->is_interpreted_frame(), "must be interpreted"); } +#ifndef PRODUCT +static bool falls_through(Bytecodes::Code bc) { + switch (bc) { + // List may be incomplete. Here we really only care about bytecodes where compiled code + // can deoptimize. + case Bytecodes::_goto: + case Bytecodes::_goto_w: + case Bytecodes::_athrow: + return false; + default: + return true; + } +} +#endif + // Return BasicType of value being returned JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_mode)) @@ -801,7 +816,7 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m // calls. It seems to be hard to tell whether the compiler // has emitted debug information matching the "state before" // a given bytecode or the state after, so we try both - if (!Bytecodes::is_invoke(cur_code) && cur_code != Bytecodes::_athrow) { + if (!Bytecodes::is_invoke(cur_code) && falls_through(cur_code)) { // Get expression stack size for the next bytecode InterpreterOopMap next_mask; OopMapCache::compute_one_oop_map(mh, str.bci(), &next_mask); diff --git a/test/hotspot/jtreg/compiler/interpreter/Custom.jasm b/test/hotspot/jtreg/compiler/interpreter/Custom.jasm new file mode 100644 index 00000000000..e52d513d2fa --- /dev/null +++ b/test/hotspot/jtreg/compiler/interpreter/Custom.jasm @@ -0,0 +1,63 @@ +/* + * 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. + * + * 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 compiler/interpreter; + +/* JASM simplified from the following Java pattern: + * + * public class Custom { + * + * static void test(int v) { + * int i8 = 1; + * try { + * v += 1; + * } catch (ArithmeticException exc1) { + * } finally { + * for (; i8 < 100; i8++) { + * } + * } + * } + * + */ + +super public class Custom { + + public static Method test:"(I)V" stack 2 locals 3 { + iconst_1; + istore_1; + try t0; + iinc 0, 1; + endtry t0; +Loop: + iload_1; + bipush 100; + if_icmpge Lexit; + iinc 1, 1; + goto Loop; // deoptimize here on backwards branch + catch t0 java/lang/ArithmeticException; // unreachable block + astore_2; +Lexit: + return + } + +} diff --git a/test/hotspot/jtreg/compiler/interpreter/VerifyStackWithUnreachableBlock.java b/test/hotspot/jtreg/compiler/interpreter/VerifyStackWithUnreachableBlock.java new file mode 100644 index 00000000000..f8aace2b31b --- /dev/null +++ b/test/hotspot/jtreg/compiler/interpreter/VerifyStackWithUnreachableBlock.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Alibaba Group Holding Limited. All Rights Reserved. + * 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 VerifyStackWithUnreachableBlock + * @bug 8271055 + * @compile Custom.jasm VerifyStackWithUnreachableBlock.java + * @summary Using VerifyStack for method that contains unreachable basic blocks + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+VerifyStack compiler.interpreter.VerifyStackWithUnreachableBlock + */ + +package compiler.interpreter; + +public class VerifyStackWithUnreachableBlock { + public static void main(String[] strArr) { + for (int i = 0; i < 10000; i++) { + Custom.test(i); + } + } +} -- GitLab From 63e11cfa3f887515ca36ab5147c3e6fa540978d3 Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Fri, 4 Feb 2022 07:08:07 +0000 Subject: [PATCH 141/400] 8280970: Cleanup dead code in java.security.Provider Reviewed-by: valeriep --- .../share/classes/java/security/Provider.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/java.base/share/classes/java/security/Provider.java b/src/java.base/share/classes/java/security/Provider.java index c1c4bea90cd..4a458cae7f8 100644 --- a/src/java.base/share/classes/java/security/Provider.java +++ b/src/java.base/share/classes/java/security/Provider.java @@ -1116,11 +1116,6 @@ public abstract class Provider extends Properties { return new String[] {type, alg}; } - // utility method for getting a String with service type and algorithm - private static String getKey(Service s) { - return s.getType() + "." + s.getAlgorithm(); - } - private static final String ALIAS_PREFIX = "Alg.Alias."; private static final String ALIAS_PREFIX_LOWER = "alg.alias."; private static final int ALIAS_LENGTH = ALIAS_PREFIX.length(); @@ -1544,21 +1539,12 @@ public abstract class Provider extends Properties { final String name; final boolean supportsParameter; final String constructorParameterClassName; - private volatile Class constructorParameterClass; EngineDescription(String name, boolean sp, String paramName) { this.name = name; this.supportsParameter = sp; this.constructorParameterClassName = paramName; } - Class getConstructorParameterClass() throws ClassNotFoundException { - Class clazz = constructorParameterClass; - if (clazz == null) { - clazz = Class.forName(constructorParameterClassName); - constructorParameterClass = clazz; - } - return clazz; - } } // built in knowledge of the engine types shipped as part of the JDK -- GitLab From 01f93ddf18daea5c0798ac949c6717c37d9cefa0 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Fri, 4 Feb 2022 07:47:42 +0000 Subject: [PATCH 142/400] 8279385: [test] Adjust sun/security/pkcs12/KeytoolOpensslInteropTest.java after 8278344 Reviewed-by: mullan, xuelei Backport-of: 9bdf6eb7b2412ecff523015f1430dfb6a0e4dd09 --- test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java b/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java index 7fcbd95ca7d..c35bf47d56d 100644 --- a/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java +++ b/test/jdk/sun/security/pkcs12/KeytoolOpensslInteropTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -462,7 +462,7 @@ public class KeytoolOpensslInteropTest { "pkcs12", "-in", "ksnormal", "-passin", "pass:changeit", "-info", "-nokeys", "-nocerts"); output1.shouldHaveExitValue(0) - .shouldContain("MAC:").shouldContain("sha256").shouldContain("Iteration 10000") + .shouldMatch("MAC:.*sha256.*Iteration 10000") .shouldContain("Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC," + " Iteration 10000, PRF hmacWithSHA256") .shouldContain("PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC," @@ -505,7 +505,7 @@ public class KeytoolOpensslInteropTest { "ksnewic", "-passin", "pass:changeit", "-info", "-nokeys", "-nocerts"); output1.shouldHaveExitValue(0) - .shouldContain("MAC:").shouldContain("sha256").shouldContain("Iteration 5555") + .shouldMatch("MAC:.*sha256.*Iteration 5555") .shouldContain("Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC," + " Iteration 7777, PRF hmacWithSHA256") .shouldContain("Shrouded Keybag: pbeWithSHA1And128BitRC4," -- GitLab From c936e7059b848d0e0be5f3234c4367657f2af2a7 Mon Sep 17 00:00:00 2001 From: Richard Reingruber Date: Fri, 4 Feb 2022 07:57:55 +0000 Subject: [PATCH 143/400] 8280593: [PPC64, S390] redundant allocation of MacroAssembler in StubGenerator ctor Reviewed-by: mdoerr, lucy --- src/hotspot/cpu/ppc/stubGenerator_ppc.cpp | 6 ++---- src/hotspot/cpu/s390/stubGenerator_s390.cpp | 7 ++----- src/hotspot/share/runtime/stubCodeGenerator.cpp | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp index 0e68a38dbaf..901918f7b37 100644 --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2021 SAP SE. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022 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 @@ -4656,8 +4656,6 @@ class StubGenerator: public StubCodeGenerator { public: StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) { - // replace the standard masm with a special one: - _masm = new MacroAssembler(code); if (all) { generate_all(); } else { diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index 218b0b378b9..102200fc08f 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2019 SAP SE. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022 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 @@ -2404,9 +2404,6 @@ class StubGenerator: public StubCodeGenerator { public: StubGenerator(CodeBuffer* code, bool all) : StubCodeGenerator(code) { - // Replace the standard masm with a special one: - _masm = new MacroAssembler(code); - _stub_count = !all ? 0x100 : 0x200; if (all) { generate_all(); diff --git a/src/hotspot/share/runtime/stubCodeGenerator.cpp b/src/hotspot/share/runtime/stubCodeGenerator.cpp index 68a82d78326..fb546bc8ebe 100644 --- a/src/hotspot/share/runtime/stubCodeGenerator.cpp +++ b/src/hotspot/share/runtime/stubCodeGenerator.cpp @@ -69,7 +69,7 @@ void StubCodeDesc::print() const { print_on(tty); } // Implementation of StubCodeGenerator StubCodeGenerator::StubCodeGenerator(CodeBuffer* code, bool print_code) { - _masm = new MacroAssembler(code ); + _masm = new MacroAssembler(code); _print_code = PrintStubCode || print_code; } -- GitLab From 46c6c6f308b5ec0ec3b762df4b76de555287474c Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Fri, 4 Feb 2022 09:13:41 +0000 Subject: [PATCH 144/400] 8281043: Intrinsify recursive ObjectMonitor locking for PPC64 Reviewed-by: rrich, lucy --- src/hotspot/cpu/ppc/macroAssembler_ppc.cpp | 35 ++++++++++++---------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp index 57d65c3aa08..d8397ed6fa5 100644 --- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp +++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2021 SAP SE. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022 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 @@ -2732,16 +2732,17 @@ void MacroAssembler::compiler_fast_lock_object(ConditionRegister flag, Register // Store a non-null value into the box. std(box, BasicLock::displaced_header_offset_in_bytes(), box); + beq(flag, cont); -# ifdef ASSERT + // Check for recursive locking. + cmpd(flag, current_header, R16_thread); bne(flag, cont); - // We have acquired the monitor, check some invariants. - addi(/*monitor=*/temp, temp, -ObjectMonitor::owner_offset_in_bytes()); - // Invariant 1: _recursions should be 0. - //assert(ObjectMonitor::recursions_size_in_bytes() == 8, "unexpected size"); - asm_assert_mem8_is_zero(ObjectMonitor::recursions_offset_in_bytes(), temp, - "monitor->_recursions should be 0"); -# endif + + // Current thread already owns the lock. Just increment recursions. + Register recursions = displaced_header; + ld(recursions, ObjectMonitor::recursions_offset_in_bytes()-ObjectMonitor::owner_offset_in_bytes(), temp); + addi(recursions, recursions, 1); + std(recursions, ObjectMonitor::recursions_offset_in_bytes()-ObjectMonitor::owner_offset_in_bytes(), temp); #if INCLUDE_RTM_OPT } // use_rtm() @@ -2757,8 +2758,7 @@ void MacroAssembler::compiler_fast_unlock_object(ConditionRegister flag, Registe bool use_rtm) { assert_different_registers(oop, box, temp, displaced_header, current_header); assert(flag != CCR0, "bad condition register"); - Label cont; - Label object_has_monitor; + Label cont, object_has_monitor, notRecursive; #if INCLUDE_RTM_OPT if (UseRTMForStackLocks && use_rtm) { @@ -2830,11 +2830,16 @@ void MacroAssembler::compiler_fast_unlock_object(ConditionRegister flag, Registe #endif ld(displaced_header, ObjectMonitor::recursions_offset_in_bytes(), current_header); - xorr(temp, R16_thread, temp); // Will be 0 if we are the owner. - orr(temp, temp, displaced_header); // Will be 0 if there are 0 recursions. - cmpdi(flag, temp, 0); + + cmpd(flag, temp, R16_thread); bne(flag, cont); + addic_(displaced_header, displaced_header, -1); + blt(CCR0, notRecursive); // Not recursive if negative after decrement. + std(displaced_header, ObjectMonitor::recursions_offset_in_bytes(), current_header); + b(cont); // flag is already EQ here. + + bind(notRecursive); ld(temp, ObjectMonitor::EntryList_offset_in_bytes(), current_header); ld(displaced_header, ObjectMonitor::cxq_offset_in_bytes(), current_header); orr(temp, temp, displaced_header); // Will be 0 if both are 0. -- GitLab From 51b53a821bb3cfb962f80a637f5fb8cde988975a Mon Sep 17 00:00:00 2001 From: Manukumar V S Date: Fri, 4 Feb 2022 10:51:30 +0000 Subject: [PATCH 145/400] 8280913: Create a regression test for JRootPane.setDefaultButton() method Reviewed-by: aivanov --- .../swing/JRootPane/DefaultButtonTest.java | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 test/jdk/javax/swing/JRootPane/DefaultButtonTest.java diff --git a/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java b/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java new file mode 100644 index 00000000000..cff2ea73c93 --- /dev/null +++ b/test/jdk/javax/swing/JRootPane/DefaultButtonTest.java @@ -0,0 +1,111 @@ +/* + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Robot; +import java.awt.event.KeyEvent; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +/* + * @test + * @key headful + * @bug 8280913 + * @summary Check whether the default button is honored when key is pressed. + * @run main DefaultButtonTest + */ +public class DefaultButtonTest { + private volatile boolean buttonPressed; + private JFrame frame; + + public static void main(String[] s) throws Exception { + DefaultButtonTest test = new DefaultButtonTest(); + test.runTest(); + } + + private static void setLookAndFeel(String lafName) { + try { + UIManager.setLookAndFeel(lafName); + } catch (UnsupportedLookAndFeelException ignored) { + System.out.println("Ignoring Unsupported L&F: " + lafName); + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private void disposeFrame() { + if (frame != null) { + frame.dispose(); + frame = null; + } + } + + private void createUI() { + frame = new JFrame("Default Button Test"); + JPanel panel = new JPanel(); + panel.add(new JTextField("Text field")); + JButton button1 = new JButton("Default"); + button1.addActionListener(e -> buttonPressed = true); + panel.add(button1); + panel.add(new JButton("Button2")); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.getRootPane().setDefaultButton(button1); + frame.setVisible(true); + } + + public void runTest() throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { + try { + buttonPressed = false; + String lafName = laf.getClassName(); + System.out.println("Testing L&F: " + lafName); + SwingUtilities.invokeAndWait(() -> { + setLookAndFeel(lafName); + createUI(); + }); + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + robot.waitForIdle(); + + if (buttonPressed) { + System.out.println("Test Passed for L&F: " + lafName); + } else { + throw new RuntimeException("Test Failed, Default Button not pressed for L&F: " + lafName); + } + } finally { + SwingUtilities.invokeAndWait(this::disposeFrame); + } + } + } +} -- GitLab From 3d926dd66ef6551e91a4ebbbc59dcff58f5ede5a Mon Sep 17 00:00:00 2001 From: Rob McKenna Date: Fri, 4 Feb 2022 13:07:03 +0000 Subject: [PATCH 146/400] 8277795: ldap connection timeout not honoured under contention Reviewed-by: dfuchs, aefimov --- .../com/sun/jndi/ldap/LdapClientFactory.java | 16 ++ .../com/sun/jndi/ldap/pool/Connections.java | 265 ++++++++++-------- .../classes/com/sun/jndi/ldap/pool/Pool.java | 109 +++++-- .../ldap/pool/PooledConnectionFactory.java | 9 + .../sun/jndi/ldap/LdapPoolTimeoutTest.java | 139 +++++++++ 5 files changed, 395 insertions(+), 143 deletions(-) create mode 100644 test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClientFactory.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClientFactory.java index af94713155f..eaaccac2ffe 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClientFactory.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapClientFactory.java @@ -65,7 +65,23 @@ final class LdapClientFactory implements PooledConnectionFactory { connTimeout, readTimeout, trace, pcb); } + public PooledConnection createPooledConnection(PoolCallback pcb, long timeout) + throws NamingException { + return new LdapClient(host, port, socketFactory, + guardedIntegerCast(timeout), + readTimeout, trace, pcb); + } + public String toString() { return host + ":" + port; } + + private int guardedIntegerCast(long timeout) { + if (timeout < Integer.MIN_VALUE) { + return Integer.MIN_VALUE; + } else if (timeout > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } + return (int) timeout; + } } diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Connections.java b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Connections.java index f64769ad51a..d485288ccac 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Connections.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Connections.java @@ -27,6 +27,9 @@ package com.sun.jndi.ldap.pool; import java.util.ArrayList; // JDK 1.2 import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; import java.lang.ref.Reference; import java.lang.ref.SoftReference; @@ -68,13 +71,19 @@ final class Connections implements PoolCallback { com.sun.jndi.ldap.LdapPoolManager.trace; private static final int DEFAULT_SIZE = 10; + final private int initSize; private final int maxSize; private final int prefSize; private final List conns; + final private PooledConnectionFactory factory; private boolean closed = false; // Closed for business private Reference ref; // maintains reference to id to prevent premature GC + private boolean initialized = false; + private final ReentrantLock lock; + private final Condition connectionsAvailable; + /** * @param id the identity (connection request) of the connections in the list * @param initSize the number of connections to create initially @@ -87,105 +96,73 @@ final class Connections implements PoolCallback { * when one is removed. * @param factory The factory responsible for creating a connection */ - Connections(Object id, int initSize, int prefSize, int maxSize, - PooledConnectionFactory factory) throws NamingException { - + Connections(Object id, int initSize, int prefSize, int maxSize, PooledConnectionFactory factory, + ReentrantLock lock) throws NamingException { this.maxSize = maxSize; + this.lock = lock; + this.connectionsAvailable = lock.newCondition(); + this.factory = factory; + if (maxSize > 0) { // prefSize and initSize cannot exceed specified maxSize this.prefSize = Math.min(prefSize, maxSize); - initSize = Math.min(initSize, maxSize); + this.initSize = Math.min(initSize, maxSize); } else { this.prefSize = prefSize; + this.initSize = initSize; } - conns = new ArrayList<>(maxSize > 0 ? maxSize : DEFAULT_SIZE); + this.conns = new ArrayList<>(maxSize > 0 ? maxSize : DEFAULT_SIZE); + this.initialized = initSize <= 0; // Maintain soft ref to id so that this Connections' entry in // Pool doesn't get GC'ed prematurely - ref = new SoftReference<>(id); + this.ref = new SoftReference<>(id); d("init size=", initSize); d("max size=", maxSize); d("preferred size=", prefSize); + } - // Create initial connections - PooledConnection conn; - for (int i = 0; i < initSize; i++) { - conn = factory.createPooledConnection(this); - td("Create ", conn ,factory); - conns.add(new ConnectionDesc(conn)); // Add new idle conn to pool + void waitForAvailableConnection() throws InterruptedNamingException { + try { + d("get(): waiting"); + connectionsAvailable.await(); + } catch (InterruptedException e) { + throw new InterruptedNamingException( + "Interrupted while waiting for a connection"); } } - /** - * Retrieves a PooledConnection from this list of connections. - * Use an existing one if one is idle, or create one if the list's - * max size hasn't been reached. If max size has been reached, wait - * for a PooledConnection to be returned, or one to be removed (thus - * not reaching the max size any longer). - * - * @param timeout if > 0, msec to wait until connection is available - * @param factory creates the PooledConnection if one needs to be created - * - * @return A non-null PooledConnection - * @throws NamingException PooledConnection cannot be created, because this - * thread was interrupted while it waited for an available connection, - * or if it timed out while waiting, or the creation of a connection - * resulted in an error. - */ - synchronized PooledConnection get(long timeout, - PooledConnectionFactory factory) throws NamingException { - PooledConnection conn; - long start = (timeout > 0 ? System.currentTimeMillis() : 0); - long waittime = timeout; - - d("get(): before"); - while ((conn = getOrCreateConnection(factory)) == null) { - if (timeout > 0 && waittime <= 0) { - throw new CommunicationException( - "Timeout exceeded while waiting for a connection: " + - timeout + "ms"); - } - try { - d("get(): waiting"); - if (waittime > 0) { - wait(waittime); // Wait until one is released or removed - } else { - wait(); - } - } catch (InterruptedException e) { - throw new InterruptedNamingException( + void waitForAvailableConnection(long waitTime) throws InterruptedNamingException { + try { + d("get(): waiting"); + connectionsAvailable.await(waitTime, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + throw new InterruptedNamingException( "Interrupted while waiting for a connection"); - } - // Check whether we timed out - if (timeout > 0) { - long now = System.currentTimeMillis(); - waittime = timeout - (now - start); - } } - - d("get(): after"); - return conn; } /** * Retrieves an idle connection from this list if one is available. - * If none is available, create a new one if maxSize hasn't been reached. - * If maxSize has been reached, return null. - * Always called from a synchronized method. */ - private PooledConnection getOrCreateConnection( - PooledConnectionFactory factory) throws NamingException { - + PooledConnection getAvailableConnection(long timeout) throws NamingException { + if (!initialized) { + PooledConnection conn = createConnection(factory, timeout); + if (conns.size() >= initSize) { + this.initialized = true; + } + return conn; + } int size = conns.size(); // Current number of idle/nonidle conns - PooledConnection conn = null; if (prefSize <= 0 || size >= prefSize) { // If no prefSize specified, or list size already meets or // exceeds prefSize, then first look for an idle connection ConnectionDesc entry; - for (int i = 0; i < size; i++) { - entry = conns.get(i); + for (ConnectionDesc connectionDesc : conns) { + PooledConnection conn; + entry = connectionDesc; if ((conn = entry.tryUse()) != null) { d("get(): use ", conn); td("Use ", conn); @@ -193,17 +170,25 @@ final class Connections implements PoolCallback { } } } + return null; + } - // Check if list size already at maxSize specified - if (maxSize > 0 && size >= maxSize) { - return null; // List size is at limit; cannot create any more + /* + * Creates a new Connection if maxSize hasn't been reached. + * If maxSize has been reached, return null. + * Caller must hold the ReentrantLock. + */ + PooledConnection createConnection(PooledConnectionFactory factory, long timeout) + throws NamingException { + int size = conns.size(); // Current number of idle/non-idle connections + if (maxSize == 0 || size < maxSize) { + PooledConnection conn = factory.createPooledConnection(this, timeout); + td("Create and use ", conn, factory); + conns.add(new ConnectionDesc(conn, true)); // Add new conn to pool + return conn; } - conn = factory.createPooledConnection(this); - td("Create and use ", conn, factory); - conns.add(new ConnectionDesc(conn, true)); // Add new conn to pool - - return conn; + return null; } /** @@ -211,43 +196,45 @@ final class Connections implements PoolCallback { * If the list size is below prefSize, the connection may be reused. * If the list size exceeds prefSize, then the connection is closed * and removed from the list. - * + *

    * public because implemented as part of PoolCallback. */ - public synchronized boolean releasePooledConnection(PooledConnection conn) { - ConnectionDesc entry; - int loc = conns.indexOf(entry=new ConnectionDesc(conn)); - - d("release(): ", conn); - - if (loc >= 0) { - // Found entry + public boolean releasePooledConnection(PooledConnection conn) { + lock.lock(); + try { + ConnectionDesc entry; + int loc = conns.indexOf(entry = new ConnectionDesc(conn)); - if (closed || (prefSize > 0 && conns.size() > prefSize)) { - // If list size exceeds prefSize, close connection + d("release(): ", conn); - d("release(): closing ", conn); - td("Close ", conn); + if (loc >= 0) { + // Found entry - // size must be >= 2 so don't worry about empty list - conns.remove(entry); - conn.closeConnection(); + if (closed || (prefSize > 0 && conns.size() > prefSize)) { + // If list size exceeds prefSize, close connection - } else { - d("release(): release ", conn); - td("Release ", conn); + d("release(): closing ", conn); + td("Close ", conn); - // Get ConnectionDesc from list to get correct state info - entry = conns.get(loc); - // Return connection to list, ready for reuse - entry.release(); + // size must be >= 2 so don't worry about empty list + conns.remove(entry); + conn.closeConnection(); + } else { + d("release(): release ", conn); + td("Release ", conn); + // Get ConnectionDesc from list to get correct state info + entry = conns.get(loc); + // Return connection to list, ready for reuse + entry.release(); + } + connectionsAvailable.signalAll(); + d("release(): notify"); + return true; } - notifyAll(); - d("release(): notify"); - return true; - } else { - return false; + } finally { + lock.unlock(); } + return false; } /** @@ -257,29 +244,34 @@ final class Connections implements PoolCallback { * when using the connection and wants it removed from the pool. * * @return true if conn removed; false if it was not in pool - * + *

    * public because implemented as part of PoolCallback. */ - public synchronized boolean removePooledConnection(PooledConnection conn) { - if (conns.remove(new ConnectionDesc(conn))) { - d("remove(): ", conn); + public boolean removePooledConnection(PooledConnection conn) { + lock.lock(); + try { + if (conns.remove(new ConnectionDesc(conn))) { + d("remove(): ", conn); - notifyAll(); + connectionsAvailable.signalAll(); - d("remove(): notify"); - td("Remove ", conn); + d("remove(): notify"); + td("Remove ", conn); - if (conns.isEmpty()) { - // Remove softref to make pool entry eligible for GC. - // Once ref has been removed, it cannot be reinstated. - ref = null; - } + if (conns.isEmpty()) { + // Remove softref to make pool entry eligible for GC. + // Once ref has been removed, it cannot be reinstated. + ref = null; + } - return true; - } else { - d("remove(): not found ", conn); - return false; + return true; + } else { + d("remove(): not found ", conn); + } + } finally { + lock.unlock(); } + return false; } /** @@ -291,8 +283,11 @@ final class Connections implements PoolCallback { */ boolean expire(long threshold) { List clonedConns; - synchronized(this) { + lock.lock(); + try { clonedConns = new ArrayList<>(conns); + } finally { + lock.unlock(); } List expired = new ArrayList<>(); @@ -304,12 +299,15 @@ final class Connections implements PoolCallback { } } - synchronized (this) { + lock.lock(); + try { conns.removeAll(expired); // Don't need to call notify() because we're // removing only idle connections. If there were // idle connections, then there should be no waiters. return conns.isEmpty(); // whether whole list has 'expired' + } finally { + lock.unlock(); } } @@ -355,6 +353,29 @@ final class Connections implements PoolCallback { + "; idle=" + idle + "; expired=" + expired; } + boolean grabLock(long timeout) throws InterruptedNamingException { + final long start = System.nanoTime(); + long current = start; + long remaining = timeout; + boolean locked = false; + while (!locked && remaining > 0) { + try { + locked = lock.tryLock(remaining, TimeUnit.MILLISECONDS); + remaining -= TimeUnit.NANOSECONDS.toMillis(current - start); + } catch (InterruptedException ignore) { + throw new InterruptedNamingException( + "Interrupted while waiting for the connection pool lock"); + } + current = System.nanoTime(); + remaining -= TimeUnit.NANOSECONDS.toMillis(current - start); + } + return locked; + } + + void unlock() { + lock.unlock(); + } + private void d(String msg, Object o1) { if (debug) { d(msg + o1); diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Pool.java b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Pool.java index 24700cbdd13..b7bc3ba98bf 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Pool.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/Pool.java @@ -31,10 +31,13 @@ import java.util.WeakHashMap; import java.util.Collection; import java.util.Collections; import java.util.LinkedList; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; import java.io.PrintStream; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; +import javax.naming.CommunicationException; import javax.naming.NamingException; /** @@ -117,45 +120,109 @@ public final class Pool { public PooledConnection getPooledConnection(Object id, long timeout, PooledConnectionFactory factory) throws NamingException { + final long start = System.nanoTime(); + long remaining = timeout; + d("get(): ", id); if (debug) { synchronized (map) { d("size: ", map.size()); } + remaining = checkRemaining(start, remaining); } expungeStaleConnections(); + Connections conns = getOrCreateConnections(factory, id); + d("get(): size after: ", map.size()); + remaining = checkRemaining(start, remaining); + + if (!conns.grabLock(remaining)) { + throw new CommunicationException("Timed out waiting for lock"); + } + + try { + remaining = checkRemaining(start, remaining); + PooledConnection conn = null; + while (remaining > 0 && conn == null) { + conn = getOrCreatePooledConnection(factory, conns, start, remaining); + // don't loop if the timeout has expired + remaining = checkRemaining(start, timeout); + } + return conn; + } finally { + conns.unlock(); + } + } + + private Connections getOrCreateConnections(PooledConnectionFactory factory, Object id) + throws NamingException { + Connections conns; synchronized (map) { - conns = getConnections(id); - if (conns == null) { - d("get(): creating new connections list for ", id); - - // No connections for this id so create a new list - conns = new Connections(id, initSize, prefSize, maxSize, - factory); - ConnectionsRef connsRef = new ConnectionsRef(conns); - map.put(id, connsRef); - - // Create a weak reference to ConnectionsRef - Reference weakRef = - new ConnectionsWeakRef(connsRef, queue); - - // Keep the weak reference through the element of a linked list - weakRefs.add(weakRef); + ConnectionsRef ref = map.get(id); + if (ref != null) { + return ref.getConnections(); } - d("get(): size after: ", map.size()); + + d("get(): creating new connections list for ", id); + + // No connections for this id so create a new list + conns = new Connections(id, initSize, prefSize, maxSize, + factory, new ReentrantLock()); + + ConnectionsRef connsRef = new ConnectionsRef(conns); + map.put(id, connsRef); + + // Create a weak reference to ConnectionsRef + Reference weakRef = new ConnectionsWeakRef(connsRef, queue); + + // Keep the weak reference through the element of a linked list + weakRefs.add(weakRef); } + return conns; + } - return conns.get(timeout, factory); // get one connection from list + private PooledConnection getOrCreatePooledConnection( + PooledConnectionFactory factory, Connections conns, long start, long timeout) + throws NamingException { + PooledConnection conn = conns.getAvailableConnection(timeout); + if (conn != null) { + return conn; + } + // no available cached connection + // check if list size already at maxSize before creating a new one + conn = conns.createConnection(factory, timeout); + if (conn != null) { + return conn; + } + // max number of connections already created, + // try waiting around for one to become available + if (timeout <= 0) { + conns.waitForAvailableConnection(); + } else { + long remaining = checkRemaining(start, timeout); + conns.waitForAvailableConnection(remaining); + } + return null; } - private Connections getConnections(Object id) { - ConnectionsRef ref = map.get(id); - return (ref != null) ? ref.getConnections() : null; + // Check whether we timed out + private long checkRemaining(long start, long timeout) throws CommunicationException { + if (timeout > 0) { + long current = System.nanoTime(); + long remaining = timeout - TimeUnit.NANOSECONDS.toMillis(current - start); + if (remaining <= 0) { + throw new CommunicationException( + "Timeout exceeded while waiting for a connection: " + + timeout + "ms"); + } + return remaining; + } + return Long.MAX_VALUE; } + /** * Goes through the connections in this Pool and expires ones that * have been idle before 'threshold'. An expired connection is closed diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PooledConnectionFactory.java b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PooledConnectionFactory.java index 3aa41769d4a..3f294497968 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PooledConnectionFactory.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/pool/PooledConnectionFactory.java @@ -44,4 +44,13 @@ public interface PooledConnectionFactory { */ public abstract PooledConnection createPooledConnection(PoolCallback pcb) throws NamingException; + + /** + * Creates a pooled connection. + * @param pcb callback responsible for removing and releasing the pooled + * connection from the pool. + * @param timeout the connection timeout + */ + public abstract PooledConnection createPooledConnection(PoolCallback pcb, long timeout) + throws NamingException; }; diff --git a/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java b/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java new file mode 100644 index 00000000000..7a5df545655 --- /dev/null +++ b/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8277795 + * @summary Multi-threaded client timeout tests for ldap pool + * @library /test/lib + * lib/ + * @run testng/othervm LdapPoolTimeoutTest + */ + +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.IOException; +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.directory.InitialDirContext; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.TimeUnit; + +import static jdk.test.lib.Utils.adjustTimeout; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.expectThrows; + +public class LdapPoolTimeoutTest { + /* + * Practical representation of an infinite timeout. + */ + private static final long INFINITY_MILLIS = adjustTimeout(20_000); + /* + * The acceptable variation in timeout measurements. + */ + private static final long TOLERANCE = adjustTimeout( 3_500); + + private static final long CONNECT_MILLIS = adjustTimeout( 3_000); + private static final long READ_MILLIS = adjustTimeout(10_000); + + static { + // a series of checks to make sure this timeouts configuration is + // consistent and the timeouts do not overlap + + assert (TOLERANCE >= 0); + // context creation + assert (2 * CONNECT_MILLIS + TOLERANCE < READ_MILLIS); + // context creation immediately followed by search + assert (2 * CONNECT_MILLIS + READ_MILLIS + TOLERANCE < INFINITY_MILLIS); + } + + @Test + public void test() throws Exception { + List> futures = new ArrayList<>(); + ExecutorService executorService = Executors.newCachedThreadPool(); + + Hashtable env = new Hashtable<>(); + env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + env.put("com.sun.jndi.ldap.read.timeout", String.valueOf(READ_MILLIS)); + env.put("com.sun.jndi.ldap.connect.timeout", String.valueOf(CONNECT_MILLIS)); + env.put("com.sun.jndi.ldap.connect.pool", "true"); + env.put(Context.PROVIDER_URL, "ldap://example.com:1234"); + + try { + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + } finally { + executorService.shutdown(); + } + int failedCount = 0; + for (var f : futures) { + try { + f.get(); + } catch (ExecutionException e) { + failedCount++; + e.getCause().printStackTrace(System.out); + } + } + if (failedCount > 0) + throw new RuntimeException(failedCount + " (sub)tests failed"); + } + + private static void attemptConnect(Hashtable env) throws Exception { + try { + LdapTimeoutTest.assertCompletion(CONNECT_MILLIS - 1000, + 2 * CONNECT_MILLIS + TOLERANCE, + () -> new InitialDirContext(env)); + } catch (RuntimeException e) { + String msg = e.getCause() == null ? e.getMessage() : e.getCause().getMessage(); + System.err.println("MSG RTE: " + msg); + // assertCompletion may wrap a CommunicationException in an RTE + assertTrue(msg != null && msg.contains("Network is unreachable")); + } catch (NamingException ex) { + String msg = ex.getCause() == null ? ex.getMessage() : ex.getCause().getMessage(); + System.err.println("MSG: " + msg); + assertTrue(msg != null && + (msg.contains("Network is unreachable") + || msg.contains("Timed out waiting for lock") + || msg.contains("Connect timed out") + || msg.contains("Timeout exceeded while waiting for a connection"))); + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + +} + -- GitLab From 66b2c3b66e253ac3d8718c0c6d7c7551dbe04001 Mon Sep 17 00:00:00 2001 From: Manukumar V S Date: Fri, 4 Feb 2022 15:25:13 +0000 Subject: [PATCH 147/400] 8280948: [TESTBUG] Write a regression test for JDK-4659800 Reviewed-by: aivanov --- .../4659800/EnterKeyActivatesButton.java | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 test/jdk/javax/swing/JButton/4659800/EnterKeyActivatesButton.java diff --git a/test/jdk/javax/swing/JButton/4659800/EnterKeyActivatesButton.java b/test/jdk/javax/swing/JButton/4659800/EnterKeyActivatesButton.java new file mode 100644 index 00000000000..9bbb794fdbe --- /dev/null +++ b/test/jdk/javax/swing/JButton/4659800/EnterKeyActivatesButton.java @@ -0,0 +1,124 @@ +/* + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.event.KeyEvent; +import java.awt.Robot; +import java.util.Arrays; +import java.util.List; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; + +import static java.util.stream.Collectors.toList; + +/* + * @test + * @key headful + * @requires (os.family == "windows") + * @bug 4659800 + * @summary Check whether pressing key generates + * ActionEvent on focused Button or not. This is applicable only for + * WindowsLookAndFeel and WindowsClassicLookAndFeel. + * @run main EnterKeyActivatesButton + */ +public class EnterKeyActivatesButton { + private static volatile boolean buttonPressed; + private static JFrame frame; + + public static void main(String[] s) throws Exception { + runTest(); + } + + private static void setLookAndFeel(String lafName) { + try { + UIManager.setLookAndFeel(lafName); + } catch (UnsupportedLookAndFeelException ignored) { + System.out.println("Ignoring Unsupported L&F: " + lafName); + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private static void disposeFrame() { + if (frame != null) { + frame.dispose(); + frame = null; + } + } + + private static void createUI() { + frame = new JFrame(); + JPanel panel = new JPanel(); + JButton focusedButton = new JButton("Button1"); + focusedButton.addActionListener(e -> buttonPressed = true); + panel.add(focusedButton); + panel.add(new JButton("Button2")); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + focusedButton.requestFocusInWindow(); + } + + public static void runTest() throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + // Consider only Windows and Windows Classic LnFs. + List winlafs = Arrays.stream(UIManager.getInstalledLookAndFeels()) + .filter(laf -> laf.getName().startsWith("Windows")) + .map(laf -> laf.getClassName()) + .collect(toList()); + + for (String laf : winlafs) { + try { + buttonPressed = false; + System.out.println("Testing L&F: " + laf); + SwingUtilities.invokeAndWait(() -> { + setLookAndFeel(laf); + createUI(); + }); + + robot.waitForIdle(); + robot.keyPress(KeyEvent.VK_ENTER); + robot.keyRelease(KeyEvent.VK_ENTER); + robot.waitForIdle(); + + if (buttonPressed) { + System.out.println("Test Passed for L&F: " + laf); + } else { + throw new RuntimeException("Test Failed, button not pressed for L&F: " + laf); + } + + } finally { + SwingUtilities.invokeAndWait(EnterKeyActivatesButton::disposeFrame); + } + } + + } +} -- GitLab From d4b99bc029771d29c2119a9b5f381cae3fe21ec1 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Fri, 4 Feb 2022 16:03:50 +0000 Subject: [PATCH 148/400] 8281120: G1: Rename G1BlockOffsetTablePart::alloc_block to update_for_block Reviewed-by: tschatzl, iwalulya, sjohanss --- src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp | 10 +++++----- src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp | 10 +++++----- src/hotspot/share/gc/g1/g1EvacFailure.cpp | 6 +++--- src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp | 2 +- src/hotspot/share/gc/g1/heapRegion.cpp | 4 ++-- src/hotspot/share/gc/g1/heapRegion.hpp | 2 +- src/hotspot/share/gc/g1/heapRegion.inline.hpp | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp index 7bbfe60e8a8..d5032957d78 100644 --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp @@ -87,7 +87,7 @@ void G1BlockOffsetTablePart::update() { while (next_addr < limit) { prev_addr = next_addr; next_addr = prev_addr + block_size(prev_addr); - alloc_block(prev_addr, next_addr); + update_for_block(prev_addr, next_addr); } assert(next_addr == limit, "Should stop the scan at the limit."); } @@ -212,8 +212,8 @@ void G1BlockOffsetTablePart::check_all_cards(size_t start_card, size_t end_card) // ( ^ ] // blk_start // -void G1BlockOffsetTablePart::alloc_block_work(HeapWord* blk_start, - HeapWord* blk_end) { +void G1BlockOffsetTablePart::update_for_block_work(HeapWord* blk_start, + HeapWord* blk_end) { HeapWord* const cur_card_boundary = align_up_by_card_size(blk_start); size_t const index = _bot->index_for_raw(cur_card_boundary); @@ -335,8 +335,8 @@ void G1BlockOffsetTablePart::print_on(outputStream* out) { #endif // !PRODUCT void G1BlockOffsetTablePart::set_for_starts_humongous(HeapWord* obj_top, size_t fill_size) { - alloc_block(_hr->bottom(), obj_top); + update_for_block(_hr->bottom(), obj_top); if (fill_size > 0) { - alloc_block(obj_top, fill_size); + update_for_block(obj_top, fill_size); } } diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp index 04c966a29cc..b70435bf21d 100644 --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp @@ -138,7 +138,7 @@ private: const void* addr) const; // Update BOT entries corresponding to the mem range [blk_start, blk_end). - void alloc_block_work(HeapWord* blk_start, HeapWord* blk_end); + void update_for_block_work(HeapWord* blk_start, HeapWord* blk_end); void check_all_cards(size_t left_card, size_t right_card) const; @@ -168,14 +168,14 @@ public: // in a space covered by the table.) inline HeapWord* block_start(const void* addr); - void alloc_block(HeapWord* blk_start, HeapWord* blk_end) { + void update_for_block(HeapWord* blk_start, HeapWord* blk_end) { if (is_crossing_card_boundary(blk_start, blk_end)) { - alloc_block_work(blk_start, blk_end); + update_for_block_work(blk_start, blk_end); } } - void alloc_block(HeapWord* blk_start, size_t size) { - alloc_block(blk_start, blk_start + size); + void update_for_block(HeapWord* blk_start, size_t size) { + update_for_block(blk_start, blk_start + size); } void set_for_starts_humongous(HeapWord* obj_top, size_t fill_size); diff --git a/src/hotspot/share/gc/g1/g1EvacFailure.cpp b/src/hotspot/share/gc/g1/g1EvacFailure.cpp index 2a4f46ff16e..7d9dd4d7ead 100644 --- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp +++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp @@ -98,7 +98,7 @@ public: HeapWord* obj_end = obj_addr + obj_size; _last_forwarded_object_end = obj_end; - _hr->alloc_block_in_bot(obj_addr, obj_end); + _hr->update_bot_for_block(obj_addr, obj_end); return obj_size; } @@ -116,13 +116,13 @@ public: CollectedHeap::fill_with_objects(start, gap_size); HeapWord* end_first_obj = start + cast_to_oop(start)->size(); - _hr->alloc_block_in_bot(start, end_first_obj); + _hr->update_bot_for_block(start, end_first_obj); // Fill_with_objects() may have created multiple (i.e. two) // objects, as the max_fill_size() is half a region. // After updating the BOT for the first object, also update the // BOT for the second object to make the BOT complete. if (end_first_obj != end) { - _hr->alloc_block_in_bot(end_first_obj, end); + _hr->update_bot_for_block(end_first_obj, end); #ifdef ASSERT size_t size_second_obj = cast_to_oop(end_first_obj)->size(); HeapWord* end_of_second_obj = end_first_obj + size_second_obj; diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp index 0e7543ec63d..195707424c3 100644 --- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp @@ -107,7 +107,7 @@ void G1FullGCCompactionPoint::forward(oop object, size_t size) { // Update compaction values. _compaction_top += size; - _current_region->alloc_block_in_bot(_compaction_top - size, _compaction_top); + _current_region->update_bot_for_block(_compaction_top - size, _compaction_top); } void G1FullGCCompactionPoint::add(HeapRegion* hr) { diff --git a/src/hotspot/share/gc/g1/heapRegion.cpp b/src/hotspot/share/gc/g1/heapRegion.cpp index 93baa238351..3fc709bba94 100644 --- a/src/hotspot/share/gc/g1/heapRegion.cpp +++ b/src/hotspot/share/gc/g1/heapRegion.cpp @@ -787,8 +787,8 @@ void HeapRegion::mangle_unused_area() { } #endif -void HeapRegion::alloc_block_in_bot(HeapWord* start, HeapWord* end) { - _bot_part.alloc_block(start, end); +void HeapRegion::update_bot_for_block(HeapWord* start, HeapWord* end) { + _bot_part.update_for_block(start, end); } void HeapRegion::object_iterate(ObjectClosure* blk) { diff --git a/src/hotspot/share/gc/g1/heapRegion.hpp b/src/hotspot/share/gc/g1/heapRegion.hpp index d3af9faf9c7..dbca49f93c4 100644 --- a/src/hotspot/share/gc/g1/heapRegion.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.hpp @@ -167,7 +167,7 @@ public: // Full GC support methods. - void alloc_block_in_bot(HeapWord* start, HeapWord* end); + void update_bot_for_block(HeapWord* start, HeapWord* end); // Update heap region that has been compacted to be consistent after Full GC. void reset_compacted_after_full_gc(); diff --git a/src/hotspot/share/gc/g1/heapRegion.inline.hpp b/src/hotspot/share/gc/g1/heapRegion.inline.hpp index 2f78f30b419..3d61cc1620a 100644 --- a/src/hotspot/share/gc/g1/heapRegion.inline.hpp +++ b/src/hotspot/share/gc/g1/heapRegion.inline.hpp @@ -237,7 +237,7 @@ inline void HeapRegion::update_bot_for_obj(HeapWord* obj_start, size_t obj_size) HR_FORMAT_PARAMS(this), p2i(obj_start), p2i(obj_end)); - _bot_part.alloc_block(obj_start, obj_end); + _bot_part.update_for_block(obj_start, obj_end); } inline void HeapRegion::note_start_of_marking() { -- GitLab From f5d6fddc6df8c5c5456a2544b131833d5227292b Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Fri, 4 Feb 2022 17:37:01 +0000 Subject: [PATCH 149/400] 8280476: [macOS] : hotspot arm64 bug exposed by latest clang Reviewed-by: kbarrett, adinn --- src/hotspot/cpu/aarch64/immediate_aarch64.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/hotspot/cpu/aarch64/immediate_aarch64.cpp b/src/hotspot/cpu/aarch64/immediate_aarch64.cpp index 3e38b7cca04..916494605bc 100644 --- a/src/hotspot/cpu/aarch64/immediate_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/immediate_aarch64.cpp @@ -129,8 +129,17 @@ static inline uint32_t uimm(uint32_t val, int hi, int lo) uint64_t replicate(uint64_t bits, int nbits, int count) { + assert(count > 0, "must be"); + assert(nbits > 0, "must be"); + assert(count * nbits <= 64, "must be"); + + // Special case nbits == 64 since the shift below with that nbits value + // would result in undefined behavior. + if (nbits == 64) { + return bits; + } + uint64_t result = 0; - // nbits may be 64 in which case we want mask to be -1 uint64_t mask = ones(nbits); for (int i = 0; i < count ; i++) { result <<= nbits; -- GitLab From 8e4ef818a90de35ae75e7f82a780653d623bb29c Mon Sep 17 00:00:00 2001 From: Yumin Qi Date: Fri, 4 Feb 2022 19:20:22 +0000 Subject: [PATCH 150/400] 8280767: -XX:ArchiveClassesAtExit does not archive BoundMethodHandle$Species classes Reviewed-by: iklam, ccheung --- src/hotspot/share/cds/lambdaFormInvokers.cpp | 27 ++++--- src/hotspot/share/cds/lambdaFormInvokers.hpp | 3 +- .../classfile/systemDictionaryShared.cpp | 7 +- src/hotspot/share/oops/klass.hpp | 10 ++- src/hotspot/share/prims/jvm.cpp | 4 +- .../dynamicArchive/CDSLambdaInvoker.java | 58 +++++++++++++++ .../dynamicArchive/TestLambdaInvokers.java | 73 +++++++++++++++++++ 7 files changed, 167 insertions(+), 15 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/CDSLambdaInvoker.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/TestLambdaInvokers.java diff --git a/src/hotspot/share/cds/lambdaFormInvokers.cpp b/src/hotspot/share/cds/lambdaFormInvokers.cpp index 59666085d04..bf49f94b682 100644 --- a/src/hotspot/share/cds/lambdaFormInvokers.cpp +++ b/src/hotspot/share/cds/lambdaFormInvokers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -67,12 +67,6 @@ static bool should_be_archived(char* line) { } return false; } - -void LambdaFormInvokers::append_filtered(char* line) { - if (should_be_archived(line)) { - append(line); - } -} #undef NUM_FILTER void LambdaFormInvokers::append(char* line) { @@ -180,6 +174,15 @@ void LambdaFormInvokers::regenerate_holder_classes(TRAPS) { } } +// check if a class name is a species +bool is_a_species(const char* species_name) { + log_info(cds)("Checking class %s", species_name); + if (strstr(species_name, "java/lang/invoke/BoundMethodHandle$Species_") != nullptr) { + return true; + } + return false; +} + void LambdaFormInvokers::regenerate_class(char* name, ClassFileStream& st, TRAPS) { Symbol* class_name = SymbolTable::new_symbol((const char*)name); // the class must exist @@ -188,6 +191,12 @@ void LambdaFormInvokers::regenerate_class(char* name, ClassFileStream& st, TRAPS log_info(cds)("Class %s not present, skip", name); return; } + // the species is shared in base archive, skip it. + if (klass->is_regenerated() && is_a_species(name)) { + log_info(cds)("Skip regenerating for shared %s", name); + return; + } + assert(klass->is_instance_klass(), "Should be"); ClassLoaderData* cld = ClassLoaderData::the_null_class_loader_data(); @@ -211,8 +220,8 @@ void LambdaFormInvokers::regenerate_class(char* name, ClassFileStream& st, TRAPS MetaspaceShared::try_link_class(THREAD, result); assert(!HAS_PENDING_EXCEPTION, "Invariant"); - // exclude the existing class from dump - SystemDictionaryShared::set_excluded(InstanceKlass::cast(klass)); + result->set_regenerated(); // mark for regenerated + SystemDictionaryShared::set_excluded(InstanceKlass::cast(klass)); // exclude the existing class from dump SystemDictionaryShared::init_dumptime_info(result); log_info(cds, lambda)("Regenerated class %s, old: " INTPTR_FORMAT " new: " INTPTR_FORMAT, name, p2i(klass), p2i(result)); diff --git a/src/hotspot/share/cds/lambdaFormInvokers.hpp b/src/hotspot/share/cds/lambdaFormInvokers.hpp index c3b151790f1..9463427eeca 100644 --- a/src/hotspot/share/cds/lambdaFormInvokers.hpp +++ b/src/hotspot/share/cds/lambdaFormInvokers.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -43,7 +43,6 @@ class LambdaFormInvokers : public AllStatic { static void add_regenerated_class(oop regenerated_class); public: static void append(char* line); - static void append_filtered(char* line); static void dump_static_archive_invokers(); static void read_static_archive_invokers(); static void regenerate_holder_classes(TRAPS); diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index 6272503fe93..29b01851ac8 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -1415,6 +1415,11 @@ InstanceKlass* SystemDictionaryShared::find_builtin_class(Symbol* name) { if (record != NULL) { assert(!record->_klass->is_hidden(), "hidden class cannot be looked up by name"); assert(check_alignment(record->_klass), "Address not aligned"); + // We did not save the classfile data of the regenerated LambdaForm invoker classes, + // so we cannot support CLFH for such classes. + if (record->_klass->is_regenerated() && JvmtiExport::should_post_class_file_load_hook()) { + return NULL; + } return record->_klass; } else { return NULL; diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index 7bbff72e25a..24f7df02cc8 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -175,7 +175,8 @@ private: enum { _archived_lambda_proxy_is_available = 2, _has_value_based_class_annotation = 4, - _verified_at_dump_time = 8 + _verified_at_dump_time = 8, + _regenerated = 16 }; #endif @@ -339,6 +340,13 @@ protected: NOT_CDS(return false;) } + void set_regenerated() { + CDS_ONLY(_shared_class_flags |= _regenerated;) + } + bool is_regenerated() const { + CDS_ONLY(return (_shared_class_flags & _regenerated) != 0;) + NOT_CDS(return false;) + } // Obtain the module or package for this class virtual ModuleEntry* module() const = 0; diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 4f54235cd4d..d8a5a025b9d 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -3689,9 +3689,9 @@ JVM_ENTRY(void, JVM_LogLambdaFormInvoker(JNIEnv *env, jstring line)) Handle h_line (THREAD, JNIHandles::resolve_non_null(line)); char* c_line = java_lang_String::as_utf8_string(h_line()); if (DynamicDumpSharedSpaces) { - // Note: LambdaFormInvokers::append_filtered and LambdaFormInvokers::append take same format which is not + // Note: LambdaFormInvokers::append take same format which is not // same as below the print format. The line does not include LAMBDA_FORM_TAG. - LambdaFormInvokers::append_filtered(os::strdup((const char*)c_line, mtInternal)); + LambdaFormInvokers::append(os::strdup((const char*)c_line, mtInternal)); } if (ClassListWriter::is_enabled()) { ClassListWriter w; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/CDSLambdaInvoker.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/CDSLambdaInvoker.java new file mode 100644 index 00000000000..ae0772427d4 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/CDSLambdaInvoker.java @@ -0,0 +1,58 @@ +/* + * 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. + * + * 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.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class CDSLambdaInvoker { + public static void main(String args[]) throws Throwable { + invoke(MethodHandles.identity(double.class), 1.0); + invoke(MethodHandles.identity(long.class), 1); + invoke(MethodHandles.identity(int.class), 1); + invoke(MethodHandles.identity(float.class), 1.0f); + + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.methodType(void.class, float.class, double.class, int.class, + boolean.class, Object.class, long.class, double.class); + MethodHandle mh = lookup.findStatic(CDSLambdaInvoker.class, "callme", mt); + mh.invokeExact(4.0f, 5.0, 6, true, (Object)args, 7L, 8.0); + } + + private static Object invoke(MethodHandle mh, Object ... args) throws Throwable { + try { + for (Object o : args) { + mh = MethodHandles.insertArguments(mh, 0, o); + } + return mh.invoke(); + } catch (Throwable t) { + System.out.println("Failed to find, link and/or invoke " + mh.toString() + ": " + t.getMessage()); + throw t; + } + } + + private static void callme(float f, double d, int i, boolean b, Object o, long l, double d2) { + + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/TestLambdaInvokers.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/TestLambdaInvokers.java new file mode 100644 index 00000000000..69a8d4219e2 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/TestLambdaInvokers.java @@ -0,0 +1,73 @@ +/* + * 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. + * + * 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 + * @key randomness + * @summary test archive lambda invoker species type in dynamic dump + * @bug 8280767 + * @requires vm.cds + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive + * @compile CDSLambdaInvoker.java + * @build sun.hotspot.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar cds-test.jar CDSLambdaInvoker + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. TestLambdaInvokers + */ + +public class TestLambdaInvokers extends DynamicArchiveTestBase { + private static final String mainClass = "CDSLambdaInvoker"; + private static final String jarFile = "cds-test.jar"; + private static void doTest(String topArchiveName) throws Exception { + dump(topArchiveName, + "-Xlog:cds", + "-Xlog:cds+dynamic=debug", + "-cp", + jarFile, + mainClass) + .assertNormalExit(output -> { + output.shouldContain("Skip regenerating for shared"); + }); + run(topArchiveName, + "-Xlog:cds", + "-Xlog:cds+dynamic=debug", + "-Xlog:class+load", + "-cp", + jarFile, + mainClass) + .assertNormalExit(output -> { + // java.lang.invoke.BoundMethodHandle$Species_JL is generated from CDSLambdaInvoker + output.shouldContain("java.lang.invoke.BoundMethodHandle$Species_JL source: shared objects file (top)"); + }); + } + + static void testWithDefaultBase() throws Exception { + String topArchiveName = getNewArchiveName("top"); + doTest(topArchiveName); + } + + public static void main(String[] args) throws Exception { + runTest(TestLambdaInvokers::testWithDefaultBase); + } +} -- GitLab From 48523b090886f7b24ed4009f0c150efaa6f7b056 Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Fri, 4 Feb 2022 21:23:58 +0000 Subject: [PATCH 151/400] 8281049: man page update for jstatd Security Manager dependency removal Reviewed-by: cjplummer --- src/jdk.jstatd/share/man/jstatd.1 | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/jdk.jstatd/share/man/jstatd.1 b/src/jdk.jstatd/share/man/jstatd.1 index d13f06b59b1..d5181f3668c 100644 --- a/src/jdk.jstatd/share/man/jstatd.1 +++ b/src/jdk.jstatd/share/man/jstatd.1 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. +.\" Copyright (c) 2004, 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 @@ -120,15 +120,12 @@ local security policies should be considered before you start the \f[CB]jstatd\f[R] process, particularly in production environments or on networks that aren\[aq]t secure. .PP -The \f[CB]jstatd\f[R] server installs an instance of -\f[CB]RMISecurityPolicy\f[R] when no other security manager is installed, -and therefore, requires a security policy file to be specified. -The policy file must conform to Default Policy Implementation and Policy -File Syntax. +For security purposes, the \f[CB]jstatd\f[R] server uses an RMI +ObjectInputFilter to allow only essential classes to be deserialized. .PP -If your security concerns can\[aq]t be addressed with a customized -policy file, then the safest action is to not run the \f[CB]jstatd\f[R] -server and use the \f[CB]jstat\f[R] and \f[CB]jps\f[R] tools locally. +If your security concerns can\[aq]t be addressed, then the safest action +is to not run the \f[CB]jstatd\f[R] server and use the \f[CB]jstat\f[R] and +\f[CB]jps\f[R] tools locally. However, when using \f[CB]jps\f[R] to get a list of instrumented JVMs, the list will not include any JVMs running in docker containers. .SH REMOTE INTERFACE @@ -149,7 +146,7 @@ This example assumes that no other server is bound to the default RMI registry port (port \f[CB]1099\f[R]). .RS .PP -\f[CB]jstatd\ \-J\-Djava.security.policy=all.policy\f[R] +\f[CB]jstatd\f[R] .RE .SH EXTERNAL RMI REGISTRY .PP @@ -159,7 +156,7 @@ registry. .nf \f[CB] rmiregistry& -jstatd\ \-J\-Djava.security.policy=all.policy +jstatd \f[R] .fi .PP @@ -169,7 +166,7 @@ registry server on port \f[CB]2020\f[R]. .nf \f[CB] jrmiregistry\ 2020& -jstatd\ \-J\-Djava.security.policy=all.policy\ \-p\ 2020 +jstatd\ \-p\ 2020 \f[R] .fi .PP @@ -180,7 +177,7 @@ registry server on port \f[CB]2020\f[R] and JMX connector bound to port .nf \f[CB] jrmiregistry\ 2020& -jstatd\ \-J\-Djava.security.policy=all.policy\ \-p\ 2020\ \-r\ 2021 +jstatd\ \-p\ 2020\ \-r\ 2021 \f[R] .fi .PP @@ -191,7 +188,7 @@ registry on port 2020 that\[aq]s bound to .nf \f[CB] rmiregistry\ 2020& -jstatd\ \-J\-Djava.security.policy=all.policy\ \-p\ 2020\ \-n\ AlternateJstatdServerName +jstatd\ \-p\ 2020\ \-n\ AlternateJstatdServerName \f[R] .fi .SH STOP THE CREATION OF AN IN\-PROCESS RMI REGISTRY @@ -203,7 +200,7 @@ If an RMI registry isn\[aq]t running, then an error message is displayed. .RS .PP -\f[CB]jstatd\ \-J\-Djava.security.policy=all.policy\ \-nr\f[R] +\f[CB]jstatd\ \-nr\f[R] .RE .SH ENABLE RMI LOGGING .PP @@ -213,5 +210,5 @@ This technique is useful as a troubleshooting aid or for monitoring server activities. .RS .PP -\f[CB]jstatd\ \-J\-Djava.security.policy=all.policy\ \-J\-Djava.rmi.server.logCalls=true\f[R] +\f[CB]jstatd\ \-J\-Djava.rmi.server.logCalls=true\f[R] .RE -- GitLab From 42e272e181f188c89fa88f144715f19235943fca Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Sat, 5 Feb 2022 07:44:57 +0000 Subject: [PATCH 152/400] 8281289: Improve with List.copyOf Reviewed-by: jnimeh, hchao --- .../share/classes/javax/net/ssl/SSLParameters.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/javax/net/ssl/SSLParameters.java b/src/java.base/share/classes/javax/net/ssl/SSLParameters.java index 83b83c84270..5fbf52436a5 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLParameters.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLParameters.java @@ -29,7 +29,6 @@ import java.security.AlgorithmConstraints; import java.util.Map; import java.util.List; import java.util.HashMap; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; @@ -391,8 +390,7 @@ public class SSLParameters { public final List getServerNames() { if (sniNames != null) { if (!sniNames.isEmpty()) { - return Collections.unmodifiableList( - new ArrayList<>(sniNames.values())); + return List.copyOf(sniNames.values()); } else { return Collections.emptyList(); } @@ -466,8 +464,7 @@ public class SSLParameters { public final Collection getSNIMatchers() { if (sniMatchers != null) { if (!sniMatchers.isEmpty()) { - return Collections.unmodifiableList( - new ArrayList<>(sniMatchers.values())); + return List.copyOf(sniMatchers.values()); } else { return Collections.emptyList(); } -- GitLab From 77b0240d44fd356711d75bc241e198f6f89ada8f Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Sun, 6 Feb 2022 02:19:32 +0000 Subject: [PATCH 153/400] 8281183: RandomGenerator:NextDouble() default behavior partially fixed by JDK-8280950 Reviewed-by: jlaskey --- .../classes/jdk/internal/util/random/RandomSupport.java | 2 +- test/jdk/java/util/Random/RandomNextDoubleBoundary.java | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java b/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java index 14fe0d3906d..1fc1eeff46a 100644 --- a/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java +++ b/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java @@ -677,7 +677,7 @@ public class RandomSupport { double r = rng.nextDouble(); r = r * bound; if (r >= bound) // may need to correct a rounding problem - r = Math.nextDown(r); + r = Math.nextDown(bound); return r; } diff --git a/test/jdk/java/util/Random/RandomNextDoubleBoundary.java b/test/jdk/java/util/Random/RandomNextDoubleBoundary.java index 971b22d55c1..f913d22ab02 100644 --- a/test/jdk/java/util/Random/RandomNextDoubleBoundary.java +++ b/test/jdk/java/util/Random/RandomNextDoubleBoundary.java @@ -24,7 +24,7 @@ /* * @test * @summary Verify nextDouble stays within range - * @bug 8280550 8280950 + * @bug 8280550 8280950 8281183 */ import java.util.SplittableRandom; @@ -79,8 +79,11 @@ public class RandomNextDoubleBoundary { }; double value = rg.nextDouble(origin, bound); - assertTrue(value >= origin); - assertTrue(value < bound); + if (bound > 0) { + value = rg.nextDouble(bound); // Equivalent to nextDouble(0.0, bound) + assertTrue(value >= 0.0); + assertTrue(value < bound); + } } public static void assertTrue(boolean condition) { -- GitLab From f7814c120bf84d7e9b459f81a6ce19b44fa122ec Mon Sep 17 00:00:00 2001 From: Toshio Nakamura Date: Sun, 6 Feb 2022 18:39:44 +0000 Subject: [PATCH 154/400] 8139173: [macosx] JInternalFrame shadow is not properly drawn Reviewed-by: prr, serb --- .../apple/laf/AquaInternalFrameBorder.java | 6 +- .../plaf/aqua/JInternalFrameBorderTest.java | 143 ++++++++++++++++++ 2 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 test/jdk/javax/swing/plaf/aqua/JInternalFrameBorderTest.java diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameBorder.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameBorder.java index a5165710ea7..74697ed417b 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameBorder.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameBorder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -378,9 +378,7 @@ public class AquaInternalFrameBorder implements Border, UIResource { final int x = inX; final int y = inY; final int w = inW; - int h = inH; - - h = metrics.titleBarHeight + inH; + final int h = inH; // paint the background titleBarPainter.state.set(frame.isSelected() ? State.ACTIVE : State.INACTIVE); diff --git a/test/jdk/javax/swing/plaf/aqua/JInternalFrameBorderTest.java b/test/jdk/javax/swing/plaf/aqua/JInternalFrameBorderTest.java new file mode 100644 index 00000000000..ef6c517fe3c --- /dev/null +++ b/test/jdk/javax/swing/plaf/aqua/JInternalFrameBorderTest.java @@ -0,0 +1,143 @@ +/* + * 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. + * + * 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 + * @key headful + * @bug 8139173 + * @requires (os.family == "mac") + * @summary Verify JInternalFrame's border + * @run main JInternalFrameBorderTest + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +public class JInternalFrameBorderTest { + + private static JFrame frame; + private static JDesktopPane desktopPane; + private static JInternalFrame internalFrame; + private static final int LIMIT = 100; + private static Robot robot; + private static Point pos; + private static Rectangle rect; + private static Insets insets; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + createUI(); + robot.waitForIdle(); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + pos = internalFrame.getLocationOnScreen(); + rect = internalFrame.getBounds(); + insets = internalFrame.getInsets(); + }); + robot.waitForIdle(); + + // bottom + int x = pos.x + rect.x + rect.width/2; + int y = pos.y + rect.y + rect.height - insets.bottom + 1; + Color colorBottom = robot.getPixelColor(x, y); + + // left + x = pos.x + rect.x + insets.left - 1; + y = pos.y + rect.y + rect.height/2; + Color colorLeft = robot.getPixelColor(x, y); + + // right + x = pos.x + rect.x + rect.width - insets.left + 1; + y = pos.y + rect.y + rect.height/2; + Color colorRight = robot.getPixelColor(x, y); + + robot.waitForIdle(); + cleanUp(); + + int diff = getDiff(colorLeft, colorBottom); + if (diff > LIMIT) { + throw new RuntimeException("Unexpected border bottom=" + + colorBottom + " left=" + colorLeft); + } + diff = getDiff(colorRight, colorBottom); + if (diff > LIMIT) { + throw new RuntimeException("Unexpected border bottom=" + + colorBottom + " right=" + colorRight); + } + } + + private static void createUI() throws Exception { + SwingUtilities.invokeAndWait(() -> { + try { + UIManager.setLookAndFeel("com.apple.laf.AquaLookAndFeel"); + } catch (Exception e) { + throw new RuntimeException("Cannot initialize Aqua L&F"); + } + desktopPane = new JDesktopPane() { + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + g.setColor(Color.BLUE); + g.fillRect(0, 0, getWidth(), getHeight()); + } + }; + internalFrame = new JInternalFrame(); + frame = new JFrame(); + internalFrame.setSize(500, 200); + internalFrame.setVisible(true); + desktopPane.add(internalFrame); + + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().setLayout(new BorderLayout()); + frame.getContentPane().add(desktopPane, "Center"); + frame.setSize(500, 500); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.toFront(); + }); + } + + private static int getDiff(Color c1, Color c2) { + int r = Math.abs(c1.getRed() - c2.getRed()); + int g = Math.abs(c1.getGreen() - c2.getGreen()); + int b = Math.abs(c1.getBlue() - c2.getBlue()); + return r + g + b; + } + + private static void cleanUp() throws Exception { + SwingUtilities.invokeAndWait(() -> { + frame.dispose(); + }); + } +} -- GitLab From 2f48a3f032dcfe159a7ab4a3d0afd0a0760d0a04 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Sun, 6 Feb 2022 21:13:17 +0000 Subject: [PATCH 155/400] 8279878: java/awt/font/JNICheck/JNICheck.sh test fails on Ubuntu 21.10 Reviewed-by: serb --- test/jdk/java/awt/font/JNICheck/JNICheck.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/java/awt/font/JNICheck/JNICheck.sh b/test/jdk/java/awt/font/JNICheck/JNICheck.sh index 4244b510b23..cc019e72d56 100644 --- a/test/jdk/java/awt/font/JNICheck/JNICheck.sh +++ b/test/jdk/java/awt/font/JNICheck/JNICheck.sh @@ -49,7 +49,7 @@ else fi $JAVA_HOME/bin/java ${TESTVMOPTS} \ - -cp "${CP}" -Xcheck:jni JNICheck | grep -v SIG | grep -v Signal | grep -v CallStatic > "${CP}"/log.txt + -cp "${CP}" -Xcheck:jni JNICheck | grep -v SIG | grep -v Signal | grep -v Handler | grep -v jsig | grep -v CallStatic > "${CP}"/log.txt # any messages logged may indicate a failure. if [ -s "${CP}"/log.txt ]; then -- GitLab From 5dfff7406ef3dc37a77ce9545f6f56c49b41e466 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Mon, 7 Feb 2022 04:48:02 +0000 Subject: [PATCH 156/400] 8166050: partialArray is not created in javax.swing.text.html.parser.NPrintWriter.println(...) method Reviewed-by: prr --- .../swing/text/html/parser/TagStack.java | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/text/html/parser/TagStack.java b/src/java.desktop/share/classes/javax/swing/text/html/parser/TagStack.java index e9f7dfcd0e9..ab33370b14b 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/parser/TagStack.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/TagStack.java @@ -162,43 +162,3 @@ class TagStack implements DTDConstants { next + " <" + tag.getElement().getName() + ">"; } } - -class NPrintWriter extends PrintWriter { - - private int numLines = 5; - private int numPrinted = 0; - - public NPrintWriter (int numberOfLines) { - super(System.out); - numLines = numberOfLines; - } - - public void println(char[] array) { - if (numPrinted >= numLines) { - return; - } - - char[] partialArray = null; - - for (int i = 0; i < array.length; i++) { - if (array[i] == '\n') { - numPrinted++; - } - - if (numPrinted == numLines) { - System.arraycopy(array, 0, partialArray, 0, i); - } - } - - if (partialArray != null) { - super.print(partialArray); - } - - if (numPrinted == numLines) { - return; - } - - super.println(array); - numPrinted++; - } -} -- GitLab From f2302822c0ef30fbf7cb4e31b8dc1513e9413a23 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Mon, 7 Feb 2022 06:30:10 +0000 Subject: [PATCH 157/400] 8281298: Revise the creation of unmodifiable list Reviewed-by: redestad --- .../classes/javax/net/ssl/SSLParameters.java | 99 +++++++++---------- 1 file changed, 46 insertions(+), 53 deletions(-) diff --git a/src/java.base/share/classes/javax/net/ssl/SSLParameters.java b/src/java.base/share/classes/javax/net/ssl/SSLParameters.java index 5fbf52436a5..5926c48aed0 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLParameters.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLParameters.java @@ -26,12 +26,7 @@ package javax.net.ssl; import java.security.AlgorithmConstraints; -import java.util.Map; -import java.util.List; -import java.util.HashMap; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; +import java.util.*; /** * Encapsulates parameters for an SSL/TLS/DTLS connection. The parameters @@ -81,8 +76,8 @@ public class SSLParameters { private boolean needClientAuth; private String identificationAlgorithm; private AlgorithmConstraints algorithmConstraints; - private Map sniNames = null; - private Map sniMatchers = null; + private List sniNames = null; // immutable list + private Collection sniMatchers = null; // immutable collection private boolean preferLocalCipherSuites; private boolean enableRetransmissions = true; private int maximumPacketSize = 0; @@ -331,22 +326,29 @@ public class SSLParameters { * @since 1.8 */ public final void setServerNames(List serverNames) { - if (serverNames != null) { - if (!serverNames.isEmpty()) { - sniNames = new LinkedHashMap<>(serverNames.size()); - for (SNIServerName serverName : serverNames) { - if (sniNames.put(serverName.getType(), - serverName) != null) { - throw new IllegalArgumentException( - "Duplicated server name of type " + + if (this.sniNames == serverNames) { + return; + } + + if (serverNames == null) { + sniNames = null; + } else if (serverNames.isEmpty()) { + sniNames = Collections.emptyList(); + } else { + List sniTypes = new ArrayList<>(serverNames.size()); + List sniValues = new ArrayList<>(serverNames.size()); + for (SNIServerName serverName : serverNames) { + if (sniTypes.contains(serverName.getType())) { + throw new IllegalArgumentException( + "Duplicated server name of type " + serverName.getType()); - } + } else { + sniTypes.add(serverName.getType()); + sniValues.add(serverName); } - } else { - sniNames = Collections.emptyMap(); } - } else { - sniNames = null; + + sniNames = Collections.unmodifiableList(sniValues); } } @@ -388,15 +390,7 @@ public class SSLParameters { * @since 1.8 */ public final List getServerNames() { - if (sniNames != null) { - if (!sniNames.isEmpty()) { - return List.copyOf(sniNames.values()); - } else { - return Collections.emptyList(); - } - } - - return null; + return sniNames; } /** @@ -424,22 +418,29 @@ public class SSLParameters { * @since 1.8 */ public final void setSNIMatchers(Collection matchers) { - if (matchers != null) { - if (!matchers.isEmpty()) { - sniMatchers = new HashMap<>(matchers.size()); - for (SNIMatcher matcher : matchers) { - if (sniMatchers.put(matcher.getType(), - matcher) != null) { - throw new IllegalArgumentException( - "Duplicated server name of type " + - matcher.getType()); - } + if (this.sniMatchers == matchers) { + return; + } + + if (matchers == null) { + this.sniMatchers = null; + } else if (matchers.isEmpty()) { + sniMatchers = Collections.emptyList(); + } else { + List matcherTypes = new ArrayList<>(matchers.size()); + List matcherValues = new ArrayList<>(matchers.size()); + for (SNIMatcher matcher : matchers) { + if (matcherTypes.contains(matcher.getType())) { + throw new IllegalArgumentException( + "Duplicated server name of type " + + matcher.getType()); + } else { + matcherTypes.add(matcher.getType()); + matcherValues.add(matcher); } - } else { - sniMatchers = Collections.emptyMap(); } - } else { - sniMatchers = null; + + this.sniMatchers = Collections.unmodifiableList(matcherValues); } } @@ -462,15 +463,7 @@ public class SSLParameters { * @since 1.8 */ public final Collection getSNIMatchers() { - if (sniMatchers != null) { - if (!sniMatchers.isEmpty()) { - return List.copyOf(sniMatchers.values()); - } else { - return Collections.emptyList(); - } - } - - return null; + return sniMatchers; } /** -- GitLab From f5e0870091ad9534e7a3dd08ef2e3ee7cd781c6d Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Mon, 7 Feb 2022 08:18:07 +0000 Subject: [PATCH 158/400] 8281117: Add regression test for JDK-8280587 Reviewed-by: chagedorn, thartmann, xliu --- .../TestCastIIMakesMainLoopPhiDead2.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/loopopts/TestCastIIMakesMainLoopPhiDead2.java diff --git a/test/hotspot/jtreg/compiler/loopopts/TestCastIIMakesMainLoopPhiDead2.java b/test/hotspot/jtreg/compiler/loopopts/TestCastIIMakesMainLoopPhiDead2.java new file mode 100644 index 00000000000..1aa233abe5f --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestCastIIMakesMainLoopPhiDead2.java @@ -0,0 +1,54 @@ +/* + * 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. + * + * 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 8280600 + * @summary C2: assert(!had_error) failed: bad dominance + * @run main/othervm -Xcomp -XX:CompileOnly=TestCastIIMakesMainLoopPhiDead2 TestCastIIMakesMainLoopPhiDead2 + */ + +public class TestCastIIMakesMainLoopPhiDead2 { + static int zero = 0; + + public static void main(String[] args) { + for (int i = 0; i < 100000; i++) { + test(); + } + } + + static void test() { + int h[] = new int[zero]; + for (int m = 0; m < 5; m++) { + try { + for (int f = -400; f < 1; f++) { + h[f] = 1; // Out of bounds store. + } + } catch (ArrayIndexOutOfBoundsException i) { + // Expected + } + } + } +} + + -- GitLab From 95fd9d20f329b15d68e613ec7f932254715e9130 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Mon, 7 Feb 2022 09:08:34 +0000 Subject: [PATCH 159/400] 8281243: Test java/lang/instrument/RetransformWithMethodParametersTest.java is failing Reviewed-by: sspitsyn, dcubed, lmesnik --- .../RetransformWithMethodParametersTest.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/jdk/java/lang/instrument/RetransformWithMethodParametersTest.java b/test/jdk/java/lang/instrument/RetransformWithMethodParametersTest.java index ef7e3818eb0..74be14f33cf 100644 --- a/test/jdk/java/lang/instrument/RetransformWithMethodParametersTest.java +++ b/test/jdk/java/lang/instrument/RetransformWithMethodParametersTest.java @@ -35,7 +35,7 @@ import java.io.File; import java.io.FileOutputStream; import java.lang.instrument.ClassFileTransformer; -import java.lang.reflect.Method; +import java.lang.reflect.Executable; import java.lang.reflect.Parameter; import java.nio.file.Files; import java.nio.file.Paths; @@ -59,7 +59,8 @@ import jdk.test.lib.util.ClassTransformer; class MethodParametersTarget { // The class contains the only method, so we don't have issue with method sorting // and ClassFileReconstituter should restore the same bytes as original classbytes. - public void method1( + // This method should be ctor, otherwise default ctor will be implicitly declared. + public MethodParametersTarget( int intParam1, String stringParam1 // @1 commentout // @1 uncomment int intParam2, String stringParam2 ) @@ -99,8 +100,8 @@ public class RetransformWithMethodParametersTest extends ATransformerManagementT private Parameter[] getTargetMethodParameters() throws ClassNotFoundException { Class cls = Class.forName(targetClassName); - // the class contains 1 method (method1) - Method method = cls.getDeclaredMethods()[0]; + // the class contains 1 method (ctor) + Executable method = cls.getDeclaredConstructors()[0]; Parameter[] params = method.getParameters(); log("Params of " + method.getName() + " method (" + params.length + "):"); for (int i = 0; i < params.length; i++) { @@ -174,7 +175,7 @@ public class RetransformWithMethodParametersTest extends ATransformerManagementT } log("Class bytes are different."); printDisassembled("expected", expected); - printDisassembled("expected", actual); + printDisassembled("actual", actual); fail(targetClassName + " did not match .class file"); } -- GitLab From f3e8242683f6c729d89e2f49b0977889b4786f4a Mon Sep 17 00:00:00 2001 From: Julia Boes Date: Mon, 7 Feb 2022 09:28:05 +0000 Subject: [PATCH 160/400] 8280965: Tests com/sun/net/httpserver/simpleserver fail with FileSystemException on Windows 11 Reviewed-by: dfuchs --- .../simpleserver/CustomFileSystemTest.java | 17 ++++++++++++++--- .../simpleserver/SimpleFileServerTest.java | 17 ++++++++++++++--- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/test/jdk/com/sun/net/httpserver/simpleserver/CustomFileSystemTest.java b/test/jdk/com/sun/net/httpserver/simpleserver/CustomFileSystemTest.java index 0826ca259ae..d6ec3eb0695 100644 --- a/test/jdk/com/sun/net/httpserver/simpleserver/CustomFileSystemTest.java +++ b/test/jdk/com/sun/net/httpserver/simpleserver/CustomFileSystemTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -74,6 +74,7 @@ import jdk.test.lib.net.URIBuilder; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import org.testng.SkipException; import static java.net.http.HttpClient.Builder.NO_PROXY; import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.file.StandardOpenOption.CREATE; @@ -395,7 +396,7 @@ public class CustomFileSystemTest { var root = createDirectoryInCustomFs("testSymlinkGET"); var symlink = root.resolve("symlink"); var target = Files.writeString(root.resolve("target.txt"), "some text", CREATE); - Files.createSymbolicLink(symlink, target); + createSymLink(symlink, target); var server = SimpleFileServer.createFileServer(LOOPBACK_ADDR, root, OutputLevel.VERBOSE); server.start(); @@ -422,7 +423,7 @@ public class CustomFileSystemTest { var symlink = root.resolve("symlink"); var target = Files.createDirectory(root.resolve("target")); Files.writeString(target.resolve("aFile.txt"), "some text", CREATE); - Files.createSymbolicLink(symlink, target); + createSymLink(symlink, target); var server = SimpleFileServer.createFileServer(LOOPBACK_ADDR, root, OutputLevel.VERBOSE); server.start(); @@ -438,6 +439,16 @@ public class CustomFileSystemTest { } } + private void createSymLink(Path symlink, Path target) { + try { + Files.createSymbolicLink(symlink, target); + } catch (UnsupportedOperationException uoe) { + throw new SkipException("sym link creation not supported", uoe); + } catch (IOException ioe) { + throw new SkipException("probably insufficient privileges to create sym links (Windows)", ioe); + } + } + @Test public void testHiddenFileGET() throws Exception { var root = createDirectoryInCustomFs("testHiddenFileGET"); diff --git a/test/jdk/com/sun/net/httpserver/simpleserver/SimpleFileServerTest.java b/test/jdk/com/sun/net/httpserver/simpleserver/SimpleFileServerTest.java index 440e106c682..b3134640925 100644 --- a/test/jdk/com/sun/net/httpserver/simpleserver/SimpleFileServerTest.java +++ b/test/jdk/com/sun/net/httpserver/simpleserver/SimpleFileServerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -56,6 +56,7 @@ import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import org.testng.SkipException; import static java.net.http.HttpClient.Builder.NO_PROXY; import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.file.StandardOpenOption.CREATE; @@ -387,7 +388,7 @@ public class SimpleFileServerTest { var root = Files.createDirectory(TEST_DIR.resolve("testSymlinkGET")); var symlink = root.resolve("symlink"); var target = Files.writeString(root.resolve("target.txt"), "some text", CREATE); - Files.createSymbolicLink(symlink, target); + createSymLink(symlink, target); var server = SimpleFileServer.createFileServer(LOOPBACK_ADDR, root, OutputLevel.VERBOSE); server.start(); @@ -414,7 +415,7 @@ public class SimpleFileServerTest { var symlink = root.resolve("symlink"); var target = Files.createDirectory(root.resolve("target")); Files.writeString(target.resolve("aFile.txt"), "some text", CREATE); - Files.createSymbolicLink(symlink, target); + createSymLink(symlink, target); var server = SimpleFileServer.createFileServer(LOOPBACK_ADDR, root, OutputLevel.VERBOSE); server.start(); @@ -430,6 +431,16 @@ public class SimpleFileServerTest { } } + private void createSymLink(Path symlink, Path target) { + try { + Files.createSymbolicLink(symlink, target); + } catch (UnsupportedOperationException uoe) { + throw new SkipException("sym link creation not supported", uoe); + } catch (IOException ioe) { + throw new SkipException("probably insufficient privileges to create sym links (Windows)", ioe); + } + } + @Test public void testHiddenFileGET() throws Exception { var root = Files.createDirectory(TEST_DIR.resolve("testHiddenFileGET")); -- GitLab From 4c169495a2c4bfdcbc82e94e9ca1ee0cc050daf9 Mon Sep 17 00:00:00 2001 From: Aleksei Efimov Date: Mon, 7 Feb 2022 12:10:14 +0000 Subject: [PATCH 161/400] 8272996: JNDI DNS provider fails to resolve SRV entries when IPV6 stack is enabled Reviewed-by: dfuchs --- .../classes/com/sun/jndi/dns/DnsClient.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java index a5508ec45db..7083b4cd115 100644 --- a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java +++ b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -26,10 +26,12 @@ package com.sun.jndi.dns; import java.io.IOException; +import java.io.UncheckedIOException; import java.net.DatagramSocket; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.net.PortUnreachableException; import java.net.Socket; import java.net.SocketTimeoutException; import java.security.SecureRandom; @@ -275,7 +277,16 @@ public class DnsClient { } // servers } return new ResourceRecords(msg, msg.length, hdr, false); - + } catch (UncheckedIOException | PortUnreachableException ex) { + // DatagramSocket.connect in doUdpQuery can throw UncheckedIOException + // DatagramSocket.send in doUdpQuery can throw PortUnreachableException + if (debug) { + dprint("Caught Exception:" + ex); + } + if (caughtException == null) { + caughtException = ex; + } + doNotRetry[i] = true; } catch (IOException e) { if (debug) { dprint("Caught IOException:" + e); @@ -283,12 +294,6 @@ public class DnsClient { if (caughtException == null) { caughtException = e; } - // Use reflection to allow pre-1.4 compilation. - // This won't be needed much longer. - if (e.getClass().getName().equals( - "java.net.PortUnreachableException")) { - doNotRetry[i] = true; - } } catch (NameNotFoundException e) { // This is authoritative, so return immediately throw e; -- GitLab From 76677716abf1124992c8f5d4d5b159b1ec0f3cab Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Mon, 7 Feb 2022 12:26:47 +0000 Subject: [PATCH 162/400] 8281114: G1: Remove PreservedMarks::init_forwarded_mark Reviewed-by: tschatzl, sjohanss --- src/hotspot/share/gc/g1/g1EvacFailure.cpp | 6 +++--- src/hotspot/share/gc/shared/preservedMarks.hpp | 3 +-- src/hotspot/share/gc/shared/preservedMarks.inline.hpp | 6 +----- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1EvacFailure.cpp b/src/hotspot/share/gc/g1/g1EvacFailure.cpp index 7d9dd4d7ead..9f93239bab0 100644 --- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp +++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -33,7 +33,6 @@ #include "gc/g1/g1OopClosures.inline.hpp" #include "gc/g1/heapRegion.hpp" #include "gc/g1/heapRegionRemSet.inline.hpp" -#include "gc/shared/preservedMarks.inline.hpp" #include "oops/access.inline.hpp" #include "oops/compressedOops.inline.hpp" #include "oops/oop.inline.hpp" @@ -94,7 +93,8 @@ public: size_t obj_size = obj->size(); _marked_words += obj_size; - PreservedMarks::init_forwarded_mark(obj); + // Reset the markWord + obj->init_mark(); HeapWord* obj_end = obj_addr + obj_size; _last_forwarded_object_end = obj_end; diff --git a/src/hotspot/share/gc/shared/preservedMarks.hpp b/src/hotspot/share/gc/shared/preservedMarks.hpp index 9a09e78bd46..959287ef99d 100644 --- a/src/hotspot/share/gc/shared/preservedMarks.hpp +++ b/src/hotspot/share/gc/shared/preservedMarks.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -66,7 +66,6 @@ public: void adjust_during_full_gc(); void restore_and_increment(volatile size_t* const _total_size_addr); - inline static void init_forwarded_mark(oop obj); // Assert the stack is empty and has no cached segments. void assert_empty() PRODUCT_RETURN; diff --git a/src/hotspot/share/gc/shared/preservedMarks.inline.hpp b/src/hotspot/share/gc/shared/preservedMarks.inline.hpp index e35ba38e429..107acdba510 100644 --- a/src/hotspot/share/gc/shared/preservedMarks.inline.hpp +++ b/src/hotspot/share/gc/shared/preservedMarks.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -48,10 +48,6 @@ inline void PreservedMarks::push_always(oop obj, markWord m) { _stack.push(elem); } -inline void PreservedMarks::init_forwarded_mark(oop obj) { - obj->init_mark(); -} - inline PreservedMarks::PreservedMarks() : _stack(OopAndMarkWordStack::default_segment_size(), // This stack should be used very infrequently so there's -- GitLab From 22a1a32c7e5ceb7be6725f5369dcfc2a11fecc2f Mon Sep 17 00:00:00 2001 From: Stephanie Crater Date: Mon, 7 Feb 2022 12:43:28 +0000 Subject: [PATCH 163/400] 8268387: Rename maximum compaction to maximal compaction in G1 Reviewed-by: ayang, tschatzl --- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 24 ++++++++++----------- src/hotspot/share/gc/g1/g1CollectedHeap.hpp | 6 +++--- src/hotspot/share/gc/g1/g1FullCollector.cpp | 4 ++-- src/hotspot/share/gc/g1/g1FullCollector.hpp | 2 +- src/hotspot/share/gc/g1/g1FullGCScope.cpp | 4 ++-- src/hotspot/share/gc/g1/g1VMOperations.cpp | 2 +- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index adc3e66d316..bfa29e39ccc 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1098,7 +1098,7 @@ void G1CollectedHeap::verify_after_full_collection() { bool G1CollectedHeap::do_full_collection(bool explicit_gc, bool clear_all_soft_refs, - bool do_maximum_compaction) { + bool do_maximal_compaction) { assert_at_safepoint_on_vm_thread(); if (GCLocker::check_active_before_gc()) { @@ -1111,7 +1111,7 @@ bool G1CollectedHeap::do_full_collection(bool explicit_gc, G1FullGCMark gc_mark; GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause(), true); - G1FullCollector collector(this, explicit_gc, do_clear_all_soft_refs, do_maximum_compaction); + G1FullCollector collector(this, explicit_gc, do_clear_all_soft_refs, do_maximal_compaction); collector.prepare_collection(); collector.collect(); @@ -1125,12 +1125,12 @@ void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) { // Currently, there is no facility in the do_full_collection(bool) API to notify // the caller that the collection did not succeed (e.g., because it was locked // out by the GC locker). So, right now, we'll ignore the return value. - // When clear_all_soft_refs is set we want to do a maximum compaction + // When clear_all_soft_refs is set we want to do a maximal compaction // not leaving any dead wood. - bool do_maximum_compaction = clear_all_soft_refs; + bool do_maximal_compaction = clear_all_soft_refs; bool dummy = do_full_collection(true, /* explicit_gc */ clear_all_soft_refs, - do_maximum_compaction); + do_maximal_compaction); } bool G1CollectedHeap::upgrade_to_full_collection() { @@ -1138,7 +1138,7 @@ bool G1CollectedHeap::upgrade_to_full_collection() { log_info(gc, ergo)("Attempting full compaction clearing soft references"); bool success = do_full_collection(false /* explicit gc */, true /* clear_all_soft_refs */, - false /* do_maximum_compaction */); + false /* do_maximal_compaction */); // do_full_collection only fails if blocked by GC locker and that can't // be the case here since we only call this when already completed one gc. assert(success, "invariant"); @@ -1162,7 +1162,7 @@ void G1CollectedHeap::resize_heap_if_necessary() { HeapWord* G1CollectedHeap::satisfy_failed_allocation_helper(size_t word_size, bool do_gc, - bool maximum_compaction, + bool maximal_compaction, bool expect_null_mutator_alloc_region, bool* gc_succeeded) { *gc_succeeded = true; @@ -1186,16 +1186,16 @@ HeapWord* G1CollectedHeap::satisfy_failed_allocation_helper(size_t word_size, if (do_gc) { GCCauseSetter compaction(this, GCCause::_g1_compaction_pause); // Expansion didn't work, we'll try to do a Full GC. - // If maximum_compaction is set we clear all soft references and don't + // If maximal_compaction is set we clear all soft references and don't // allow any dead wood to be left on the heap. - if (maximum_compaction) { - log_info(gc, ergo)("Attempting maximum full compaction clearing soft references"); + if (maximal_compaction) { + log_info(gc, ergo)("Attempting maximal full compaction clearing soft references"); } else { log_info(gc, ergo)("Attempting full compaction"); } *gc_succeeded = do_full_collection(false, /* explicit_gc */ - maximum_compaction /* clear_all_soft_refs */ , - maximum_compaction /* do_maximum_compaction */); + maximal_compaction /* clear_all_soft_refs */ , + maximal_compaction /* do_maximal_compaction */); } return NULL; diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp index 83da03019af..d6a8fe026d7 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -486,13 +486,13 @@ private: // otherwise it's for a failed allocation. // - if clear_all_soft_refs is true, all soft references should be // cleared during the GC. - // - if do_maximum_compaction is true, full gc will do a maximally + // - if do_maximal_compaction is true, full gc will do a maximally // compacting collection, leaving no dead wood. // - it returns false if it is unable to do the collection due to the // GC locker being active, true otherwise. bool do_full_collection(bool explicit_gc, bool clear_all_soft_refs, - bool do_maximum_compaction); + bool do_maximal_compaction); // Callback from VM_G1CollectFull operation, or collect_as_vm_thread. void do_full_collection(bool clear_all_soft_refs) override; @@ -518,7 +518,7 @@ private: // Helper method for satisfy_failed_allocation() HeapWord* satisfy_failed_allocation_helper(size_t word_size, bool do_gc, - bool maximum_compaction, + bool maximal_compaction, bool expect_null_mutator_alloc_region, bool* gc_succeeded); diff --git a/src/hotspot/share/gc/g1/g1FullCollector.cpp b/src/hotspot/share/gc/g1/g1FullCollector.cpp index e6e7dd25c0a..7e07ff4757c 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.cpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp @@ -111,9 +111,9 @@ uint G1FullCollector::calc_active_workers() { G1FullCollector::G1FullCollector(G1CollectedHeap* heap, bool explicit_gc, bool clear_soft_refs, - bool do_maximum_compaction) : + bool do_maximal_compaction) : _heap(heap), - _scope(heap->monitoring_support(), explicit_gc, clear_soft_refs, do_maximum_compaction), + _scope(heap->monitoring_support(), explicit_gc, clear_soft_refs, do_maximal_compaction), _num_workers(calc_active_workers()), _oop_queue_set(_num_workers), _array_queue_set(_num_workers), diff --git a/src/hotspot/share/gc/g1/g1FullCollector.hpp b/src/hotspot/share/gc/g1/g1FullCollector.hpp index f9087298b86..2d4bfc26feb 100644 --- a/src/hotspot/share/gc/g1/g1FullCollector.hpp +++ b/src/hotspot/share/gc/g1/g1FullCollector.hpp @@ -93,7 +93,7 @@ public: G1FullCollector(G1CollectedHeap* heap, bool explicit_gc, bool clear_soft_refs, - bool do_maximum_compaction); + bool do_maximal_compaction); ~G1FullCollector(); void prepare_collection(); diff --git a/src/hotspot/share/gc/g1/g1FullGCScope.cpp b/src/hotspot/share/gc/g1/g1FullGCScope.cpp index 0437d157eb0..38752db1bff 100644 --- a/src/hotspot/share/gc/g1/g1FullGCScope.cpp +++ b/src/hotspot/share/gc/g1/g1FullGCScope.cpp @@ -38,7 +38,7 @@ G1FullGCJFRTracerMark::~G1FullGCJFRTracerMark() { G1FullGCScope::G1FullGCScope(G1MonitoringSupport* monitoring_support, bool explicit_gc, bool clear_soft, - bool do_maximum_compaction) : + bool do_maximal_compaction) : _rm(), _explicit_gc(explicit_gc), _g1h(G1CollectedHeap::heap()), @@ -50,7 +50,7 @@ G1FullGCScope::G1FullGCScope(G1MonitoringSupport* monitoring_support, _soft_refs(clear_soft, _g1h->soft_ref_policy()), _monitoring_scope(monitoring_support, true /* full_gc */, true /* all_memory_pools_affected */), _heap_printer(_g1h), - _region_compaction_threshold(do_maximum_compaction ? + _region_compaction_threshold(do_maximal_compaction ? HeapRegion::GrainWords : (1 - MarkSweepDeadRatio / 100.0) * HeapRegion::GrainWords) { } diff --git a/src/hotspot/share/gc/g1/g1VMOperations.cpp b/src/hotspot/share/gc/g1/g1VMOperations.cpp index 94699a0c718..a4633f9c2b9 100644 --- a/src/hotspot/share/gc/g1/g1VMOperations.cpp +++ b/src/hotspot/share/gc/g1/g1VMOperations.cpp @@ -52,7 +52,7 @@ void VM_G1CollectFull::doit() { GCCauseSetter x(g1h, _gc_cause); _gc_succeeded = g1h->do_full_collection(true /* explicit_gc */, false /* clear_all_soft_refs */, - false /* do_maximum_compaction */); + false /* do_maximal_compaction */); } VM_G1TryInitiateConcMark::VM_G1TryInitiateConcMark(uint gc_count_before, -- GitLab From a0f6f2409ea61ff9ed9dc2e2b46e309c751d456d Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Mon, 7 Feb 2022 14:06:08 +0000 Subject: [PATCH 164/400] 8280890: Cannot use '-Djava.system.class.loader' with class loader in signed JAR Reviewed-by: weijun, hchao --- .../sun/security/tools/keytool/Main.java | 13 --- .../util/DisabledAlgorithmConstraints.java | 52 +++++----- .../security/SignedJar/CustomClassLoader.java | 43 +++++++++ .../SignedJarWithCustomClassLoader.java | 94 +++++++++++++++++++ 4 files changed, 158 insertions(+), 44 deletions(-) create mode 100644 test/jdk/java/security/SignedJar/CustomClassLoader.java create mode 100644 test/jdk/java/security/SignedJar/SignedJarWithCustomClassLoader.java diff --git a/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/src/java.base/share/classes/sun/security/tools/keytool/Main.java index de13f75aea9..c9fb5178de5 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -47,8 +47,6 @@ import java.security.interfaces.EdECKey; import java.security.spec.ECParameterSpec; import java.text.Collator; import java.text.MessageFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.*; import java.util.function.BiFunction; import java.util.jar.JarEntry; @@ -4926,17 +4924,6 @@ public final class Main { "Unable.to.parse.denyAfter.string.in.exception.message")); } - SimpleDateFormat formatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy"); - Date dateObj = null; - try { - dateObj = formatter.parse(denyAfterDate); - } catch (ParseException e2) { - throw new Exception(rb.getString( - "Unable.to.parse.denyAfter.string.in.exception.message")); - } - formatter = new SimpleDateFormat("yyyy-MM-dd"); - denyAfterDate = formatter.format(dateObj); - weakWarnings.add(String.format( rb.getString("whose.sigalg.usagesignedjar"), label, sigAlg, denyAfterDate)); diff --git a/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java b/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java index 8a2650ff580..03e9cf6a2c6 100644 --- a/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java +++ b/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -39,9 +39,12 @@ import java.security.spec.InvalidParameterSpecException; import java.security.spec.MGF1ParameterSpec; import java.security.spec.NamedParameterSpec; import java.security.spec.PSSParameterSpec; +import java.time.DateTimeException; +import java.time.Instant; +import java.time.ZonedDateTime; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Arrays; -import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -51,7 +54,6 @@ import java.util.Map; import java.util.Set; import java.util.Collection; import java.util.StringTokenizer; -import java.util.TimeZone; import java.util.regex.Pattern; import java.util.regex.Matcher; @@ -686,41 +688,30 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { * timezone. */ private static class DenyAfterConstraint extends Constraint { - private Date denyAfterDate; + private ZonedDateTime zdt; + private Instant denyAfterDate; DenyAfterConstraint(String algo, int year, int month, int day) { - Calendar c; algorithm = algo; if (debug != null) { - debug.println("DenyAfterConstraint read in as: year " + + debug.println("DenyAfterConstraint read in as: year " + year + ", month = " + month + ", day = " + day); } - c = new Calendar.Builder().setTimeZone(TimeZone.getTimeZone("GMT")) - .setDate(year, month - 1, day).build(); - - if (year > c.getActualMaximum(Calendar.YEAR) || - year < c.getActualMinimum(Calendar.YEAR)) { - throw new IllegalArgumentException( - "Invalid year given in constraint: " + year); - } - if ((month - 1) > c.getActualMaximum(Calendar.MONTH) || - (month - 1) < c.getActualMinimum(Calendar.MONTH)) { - throw new IllegalArgumentException( - "Invalid month given in constraint: " + month); - } - if (day > c.getActualMaximum(Calendar.DAY_OF_MONTH) || - day < c.getActualMinimum(Calendar.DAY_OF_MONTH)) { + try { + zdt = ZonedDateTime + .of(year, month, day, 0, 0, 0, 0, ZoneId.of("GMT")); + denyAfterDate = zdt.toInstant(); + } catch (DateTimeException dte) { throw new IllegalArgumentException( - "Invalid Day of Month given in constraint: " + day); + "Invalid denyAfter date", dte); } - denyAfterDate = c.getTime(); if (debug != null) { debug.println("DenyAfterConstraint date set to: " + - denyAfterDate); + zdt.toLocalDate()); } } @@ -735,23 +726,22 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { @Override public void permits(ConstraintsParameters cp) throws CertPathValidatorException { - Date currentDate; - String errmsg; + Instant currentDate; if (cp.getDate() != null) { - currentDate = cp.getDate(); + currentDate = cp.getDate().toInstant(); } else { - currentDate = new Date(); + currentDate = Instant.now(); } - if (!denyAfterDate.after(currentDate)) { + if (!denyAfterDate.isAfter(currentDate)) { if (next(cp)) { return; } throw new CertPathValidatorException( "denyAfter constraint check failed: " + algorithm + " used with Constraint date: " + - denyAfterDate + "; params date: " + + zdt.toLocalDate() + "; params date: " + currentDate + cp.extendedExceptionMsg(), null, null, -1, BasicReason.ALGORITHM_CONSTRAINED); } @@ -770,7 +760,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints { debug.println("DenyAfterConstraints.permits(): " + algorithm); } - return denyAfterDate.after(new Date()); + return denyAfterDate.isAfter(Instant.now()); } } diff --git a/test/jdk/java/security/SignedJar/CustomClassLoader.java b/test/jdk/java/security/SignedJar/CustomClassLoader.java new file mode 100644 index 00000000000..99242f3a877 --- /dev/null +++ b/test/jdk/java/security/SignedJar/CustomClassLoader.java @@ -0,0 +1,43 @@ +/* + * 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. + * + * 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.InputStream; + +public class CustomClassLoader extends ClassLoader { + + public CustomClassLoader(ClassLoader parent) { + super(parent); + } + + @Override + public Class findClass(String name) throws ClassNotFoundException { + try (InputStream is = getClass().getClassLoader() + .getResourceAsStream(name + ".class")) { + byte[] buf = is.readAllBytes(); + return defineClass(name, buf, 0, buf.length); + } catch (IOException e) { + throw new ClassNotFoundException(e.getMessage()); + } + } +} diff --git a/test/jdk/java/security/SignedJar/SignedJarWithCustomClassLoader.java b/test/jdk/java/security/SignedJar/SignedJarWithCustomClassLoader.java new file mode 100644 index 00000000000..1f335c87f14 --- /dev/null +++ b/test/jdk/java/security/SignedJar/SignedJarWithCustomClassLoader.java @@ -0,0 +1,94 @@ +/* + * 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. + * + * 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 8280890 + * @library /test/lib + * @build SignedJarWithCustomClassLoader CustomClassLoader + * @run main/othervm SignedJarWithCustomClassLoader + * @summary Make sure java.system.class.loader property can be used when custom + * class loader is inside signed jar + */ + +import java.nio.file.Path; +import java.nio.file.Paths; + +import jdk.test.lib.SecurityTools; +import jdk.test.lib.compiler.InMemoryJavaCompiler; +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.util.JarUtils; + +public class SignedJarWithCustomClassLoader { + + public static void main(String[] args) throws Exception { + + // compile the Main program + String main = """ + public class Main { + public static void main(String[] args) {} + } + """; + String testClasses = System.getProperty("test.classes", ""); + ClassFileInstaller.writeClassToDisk("Main", + InMemoryJavaCompiler.compile("Main", main), + testClasses); + + // create the jar file + Path classes = Paths.get(testClasses); + JarUtils.createJarFile(Paths.get("test.jar"), classes, + classes.resolve("CustomClassLoader.class"), + classes.resolve("Main.class")); + + // create signer's keypair + SecurityTools.keytool("-genkeypair -keyalg RSA -keystore ks " + + "-storepass changeit -dname CN=test -alias test") + .shouldHaveExitValue(0); + + // sign jar + SecurityTools.jarsigner("-keystore ks -storepass changeit " + + "-signedjar signed.jar test.jar test") + .shouldHaveExitValue(0); + + // run app with system class loader set to custom classloader + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-cp", "signed.jar", + "-Djava.system.class.loader=CustomClassLoader", "Main"); + ProcessTools.executeProcess(pb) + .shouldHaveExitValue(0); + + // sign jar again, but this time with SHA-1 which is disabled + SecurityTools.jarsigner("-keystore ks -storepass changeit " + + "-digestalg SHA-1 -sigalg SHA1withRSA " + + "-signedjar signed.jar test.jar test") + .shouldHaveExitValue(0); + + // run app again, should still succeed even though SHA-1 is disabled + pb = ProcessTools.createJavaProcessBuilder( + "-cp", "signed.jar", + "-Djava.system.class.loader=CustomClassLoader", "Main"); + ProcessTools.executeProcess(pb) + .shouldHaveExitValue(0); + } +} -- GitLab From 2ed1f4cf32b1cef4ccb129d622f9368c3469d1d4 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Mon, 7 Feb 2022 15:05:30 +0000 Subject: [PATCH 165/400] 8281175: Add a -providerPath option to jarsigner Reviewed-by: xuelei, hchao --- .../sun/security/tools/keytool/Main.java | 4 +--- .../sun/security/tools/jarsigner/Main.java | 24 +++++++++++++++++-- .../security/tools/jarsigner/Resources.java | 4 +++- .../security/tools/jarsigner/AltProvider.java | 19 ++++++--------- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/java.base/share/classes/sun/security/tools/keytool/Main.java b/src/java.base/share/classes/sun/security/tools/keytool/Main.java index c9fb5178de5..ae012d3747a 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/Main.java +++ b/src/java.base/share/classes/sun/security/tools/keytool/Main.java @@ -824,9 +824,7 @@ public final class Main { if (providerClasses != null) { ClassLoader cl = null; if (pathlist != null) { - String path = null; - path = PathList.appendPath( - path, System.getProperty("java.class.path")); + String path = System.getProperty("java.class.path"); path = PathList.appendPath( path, System.getProperty("env.class.path")); path = PathList.appendPath(path, pathlist); diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java index 8758b99e18e..87ff579a7c1 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -27,6 +27,7 @@ package sun.security.tools.jarsigner; import java.io.*; import java.net.UnknownHostException; +import java.net.URLClassLoader; import java.security.cert.CertPathValidatorException; import java.security.cert.PKIXBuilderParameters; import java.util.*; @@ -59,6 +60,7 @@ import sun.security.pkcs.SignerInfo; import sun.security.provider.certpath.CertPathConstraintsParameters; import sun.security.timestamp.TimestampToken; import sun.security.tools.KeyStoreUtil; +import sun.security.tools.PathList; import sun.security.validator.Validator; import sun.security.validator.ValidatorException; import sun.security.x509.*; @@ -152,6 +154,7 @@ public class Main { List providerClasses = null; // list of provider classes // arguments for provider constructors HashMap providerArgs = new HashMap<>(); + String pathlist = null; char[] keypass; // private key password String sigfile; // name of .SF file String sigalg; // name of signature algorithm @@ -246,7 +249,18 @@ public class Main { } if (providerClasses != null) { - ClassLoader cl = ClassLoader.getSystemClassLoader(); + ClassLoader cl; + if (pathlist != null) { + String path = System.getProperty("java.class.path"); + path = PathList.appendPath( + path, System.getProperty("env.class.path")); + path = PathList.appendPath(path, pathlist); + + URL[] urls = PathList.pathToURLs(path); + cl = new URLClassLoader(urls); + } else { + cl = ClassLoader.getSystemClassLoader(); + } for (String provClass: providerClasses) { try { KeyStoreUtil.loadProviderByClass(provClass, @@ -434,6 +448,9 @@ public class Main { n += 2; } } + } else if (collator.compare(flags, "-providerpath") == 0) { + if (++n == args.length) usageNoArg(); + pathlist = args[n]; } else if (collator.compare(flags, "-protected") ==0) { protectedPath = true; } else if (collator.compare(flags, "-certchain") ==0) { @@ -705,6 +722,9 @@ public class Main { System.out.println(rb.getString (".providerArg.option.2")); System.out.println(); + System.out.println(rb.getString + (".providerPath.option")); + System.out.println(); System.out.println(rb.getString (".strict.treat.warnings.as.errors")); System.out.println(); diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java index 45e56f4d049..265af66f9b3 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -119,6 +119,8 @@ public class Resources extends java.util.ListResourceBundle { "[-providerClass add security provider by fully-qualified class name"}, {".providerArg.option.2", " [-providerArg ]] ... configure argument for -providerClass"}, + {".providerPath.option", + "[-providerPath ] provider classpath"}, {".strict.treat.warnings.as.errors", "[-strict] treat warnings as errors"}, {".conf.url.specify.a.pre.configured.options.file", diff --git a/test/jdk/sun/security/tools/jarsigner/AltProvider.java b/test/jdk/sun/security/tools/jarsigner/AltProvider.java index c359734b8c7..d4a57ca55da 100644 --- a/test/jdk/sun/security/tools/jarsigner/AltProvider.java +++ b/test/jdk/sun/security/tools/jarsigner/AltProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 4906940 8130302 8194152 + * @bug 4906940 8130302 8194152 8281175 * @summary -providerPath, -providerClass, -addprovider, and -providerArg * @library /test/lib * @modules java.base/jdk.internal.misc @@ -81,33 +81,28 @@ public class AltProvider { // Without new provider testBoth("", 1, "DUMMYKS not found"); - // legacy use (-providerPath only supported by keytool) - testKeytool("-providerPath mods/test.dummy " + - "-providerClass org.test.dummy.DummyProvider -providerArg full", - 0, "loadProviderByClass: org.test.dummy.DummyProvider"); - // legacy, on classpath - testBoth("-J-cp -Jmods/test.dummy " + + testBoth("-providerpath mods/test.dummy " + "-providerClass org.test.dummy.DummyProvider -providerArg full", 0, "loadProviderByClass: org.test.dummy.DummyProvider"); // Wrong name - testBoth("-J-cp -Jmods/test.dummy " + + testBoth("-providerpath mods/test.dummy " + "-providerClass org.test.dummy.Dummy -providerArg full", 1, "Provider \"org.test.dummy.Dummy\" not found"); // Not a provider name - testBoth("-J-cp -Jmods/test.dummy " + + testBoth("-providerpath mods/test.dummy " + "-providerClass java.lang.Object -providerArg full", 1, "java.lang.Object not a provider"); // without arg - testBoth("-J-cp -Jmods/test.dummy " + + testBoth("-providerpath mods/test.dummy " + "-providerClass org.test.dummy.DummyProvider", 1, "DUMMYKS not found"); // old -provider still works - testBoth("-J-cp -Jmods/test.dummy " + + testBoth("-providerpath mods/test.dummy " + "-provider org.test.dummy.DummyProvider -providerArg full", 0, "loadProviderByClass: org.test.dummy.DummyProvider"); -- GitLab From 1dfc94dd561f6a91ef3784fe28c83f839f8188c4 Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Mon, 7 Feb 2022 17:36:40 +0000 Subject: [PATCH 166/400] 8281377: Remove vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Deadlock/JavaDeadlock001/TestDescription.java from problemlist. Reviewed-by: sspitsyn --- test/hotspot/jtreg/ProblemList.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index e08217cd776..a09185a4b19 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -145,7 +145,6 @@ vmTestbase/nsk/monitoring/MemoryPoolMBean/isUsageThresholdExceeded/isexceeded002 vmTestbase/nsk/monitoring/MemoryPoolMBean/isUsageThresholdExceeded/isexceeded003/TestDescription.java 8198668 generic-all vmTestbase/nsk/monitoring/MemoryPoolMBean/isUsageThresholdExceeded/isexceeded004/TestDescription.java 8153598 generic-all vmTestbase/nsk/monitoring/MemoryPoolMBean/isUsageThresholdExceeded/isexceeded005/TestDescription.java 8153598 generic-all -vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Deadlock/JavaDeadlock001/TestDescription.java 8060733 generic-all vmTestbase/nsk/jdi/HiddenClass/events/events001.java 8257705 generic-all vmTestbase/nsk/jdi/ThreadReference/stop/stop001/TestDescription.java 7034630 generic-all -- GitLab From 8a662105c2da1f0fb9b7ecc5058fc85858439ed9 Mon Sep 17 00:00:00 2001 From: Kevin Walls Date: Mon, 7 Feb 2022 18:16:23 +0000 Subject: [PATCH 167/400] 6779701: Wrong defect ID in the code of test LocalRMIServerSocketFactoryTest.java Reviewed-by: cjplummer, dfuchs --- .../jmxremote/LocalRMIServerSocketFactoryTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/jdk/sun/management/jmxremote/LocalRMIServerSocketFactoryTest.java b/test/jdk/sun/management/jmxremote/LocalRMIServerSocketFactoryTest.java index 223d252686f..3b51f32c99e 100644 --- a/test/jdk/sun/management/jmxremote/LocalRMIServerSocketFactoryTest.java +++ b/test/jdk/sun/management/jmxremote/LocalRMIServerSocketFactoryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -64,17 +64,17 @@ public class LocalRMIServerSocketFactoryTest { } - // case of 6674166: this is very unlikely to happen, even if - // both 6674166 and 6774170 aren't fixed. If it happens + // case of 6774166: this is very unlikely to happen, even if + // both 6774166 and 6774170 aren't fixed. If it happens // however, it might indicate that neither defects are fixed. if (x instanceof NullPointerException) { throw new Exception(message + " - " + - "Congratulations! it seems you have triggered 6674166. " + - "Neither 6674166 nor 6774170 seem to be fixed: " + x, x); + "Congratulations! it seems you have triggered 6774166. " + + "Neither 6774166 nor 6774170 seem to be fixed: " + x, x); } else if (x instanceof IOException) { throw new Exception(message + " - " + - "Unexpected IOException. Maybe you triggered 6674166? " + + "Unexpected IOException. Maybe you triggered 6774166? " + x, x); } else if (x != null) { throw new Exception(message + " - " + -- GitLab From 2f71a6b39ed6bb869b4eb3e81bc1d87f4b3328ff Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Mon, 7 Feb 2022 19:54:05 +0000 Subject: [PATCH 168/400] 8279613: JFR: Snippify Javadoc Reviewed-by: mgronlun --- .../classes/jdk/jfr/AnnotationElement.java | 17 +- src/jdk.jfr/share/classes/jdk/jfr/Event.java | 22 +- .../share/classes/jdk/jfr/EventFactory.java | 24 +- .../share/classes/jdk/jfr/EventSettings.java | 16 +- .../share/classes/jdk/jfr/FlightRecorder.java | 10 +- .../classes/jdk/jfr/MetadataDefinition.java | 31 +- .../share/classes/jdk/jfr/Recording.java | 22 +- .../share/classes/jdk/jfr/SettingControl.java | 71 +---- .../classes/jdk/jfr/consumer/EventStream.java | 20 +- .../jdk/jfr/consumer/RecordedObject.java | 18 +- .../jdk/jfr/consumer/RecordingFile.java | 9 +- .../jdk/jfr/consumer/RecordingStream.java | 43 +-- .../jdk/jfr/consumer/package-info.java | 23 +- .../jfr/consumer/snippet-files/Snippets.java | 169 ++++++++++ .../jdk/jfr/snippet-files/Snippets.java | 291 ++++++++++++++++++ 15 files changed, 487 insertions(+), 299 deletions(-) create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/consumer/snippet-files/Snippets.java create mode 100644 src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java diff --git a/src/jdk.jfr/share/classes/jdk/jfr/AnnotationElement.java b/src/jdk.jfr/share/classes/jdk/jfr/AnnotationElement.java index 19c1f4db14f..f35b4911b15 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/AnnotationElement.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/AnnotationElement.java @@ -46,22 +46,7 @@ import jdk.jfr.internal.Utils; *

    * The following example shows how {@code AnnotationElement} can be used to dynamically define events. * - *

    {@literal
    - *   List typeAnnotations = new ArrayList<>();
    - *   typeAnnotations.add(new AnnotationElement(Name.class, "com.example.HelloWorld"));
    - *   typeAnnotations.add(new AnnotationElement(Label.class, "Hello World"));
    - *   typeAnnotations.add(new AnnotationElement(Description.class, "Helps programmer getting started"));
    - *
    - *   List fieldAnnotations = new ArrayList<>();
    - *   fieldAnnotations.add(new AnnotationElement(Label.class, "Message"));
    - *
    - *   List fields = new ArrayList<>();
    - *   fields.add(new ValueDescriptor(String.class, "message", fieldAnnotations));
    - *
    - *   EventFactory f = EventFactory.create(typeAnnotations, fields);
    - *   Event event = f.newEvent();
    - *   event.commit();
    - * }
    + * {@snippet class="Snippets" region="AnnotationElementOverview"} * * @since 9 */ diff --git a/src/jdk.jfr/share/classes/jdk/jfr/Event.java b/src/jdk.jfr/share/classes/jdk/jfr/Event.java index be9ed57eebe..c33d7749b5c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/Event.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/Event.java @@ -31,27 +31,7 @@ package jdk.jfr; *

    * The following example shows how to implement an {@code Event} class. * - *

    {@literal
    - * import jdk.jfr.Event;
    - * import jdk.jfr.Description;
    - * import jdk.jfr.Label;
    - *
    - * public class Example {
    - *
    - *   @Label("Hello World")
    - *   @Description("Helps programmer getting started")
    - *   static class HelloWorld extends Event {
    - *       @Label("Message")
    - *       String message;
    - *   }
    - *
    - *   public static void main(String... args) {
    - *       HelloWorld event = new HelloWorld();
    - *       event.message = "hello, world!";
    - *       event.commit();
    - *   }
    - * }
    - * }
    + * {@snippet class="Snippets" region="EventOverview"} *

    * After an event is allocated and its field members are populated, it can be * written to the Flight Recorder system by using the {@link #commit()} method. diff --git a/src/jdk.jfr/share/classes/jdk/jfr/EventFactory.java b/src/jdk.jfr/share/classes/jdk/jfr/EventFactory.java index 71b08e74baa..a918bed40cf 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/EventFactory.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/EventFactory.java @@ -52,29 +52,7 @@ import jdk.jfr.internal.Utils; *

    * The following example shows how to implement a dynamic {@code Event} class. * - *

    - * {@code
    - * List fields = new ArrayList<>();
    - * List messageAnnotations = Collections.singletonList(new AnnotationElement(Label.class, "Message"));
    - * fields.add(new ValueDescriptor(String.class, "message", messageAnnotations));
    - * List numberAnnotations = Collections.singletonList(new AnnotationElement(Label.class, "Number"));
    - * fields.add(new ValueDescriptor(int.class, "number", numberAnnotations));
    - *
    - * String[] category = { "Example", "Getting Started" };
    - * List eventAnnotations = new ArrayList<>();
    - * eventAnnotations.add(new AnnotationElement(Name.class, "com.example.HelloWorld"));
    - * eventAnnotations.add(new AnnotationElement(Label.class, "Hello World"));
    - * eventAnnotations.add(new AnnotationElement(Description.class, "Helps programmer getting started"));
    - * eventAnnotations.add(new AnnotationElement(Category.class, category));
    - *
    - * EventFactory f = EventFactory.create(eventAnnotations, fields);
    - *
    - * Event event = f.newEvent();
    - * event.set(0, "hello, world!");
    - * event.set(1, 4711);
    - * event.commit();
    - * }
    - * 
    + * {@snippet class="Snippets" region="EventFactoryOverview"} * * @since 9 */ diff --git a/src/jdk.jfr/share/classes/jdk/jfr/EventSettings.java b/src/jdk.jfr/share/classes/jdk/jfr/EventSettings.java index 0d4c20aad45..128ae2b20a3 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/EventSettings.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/EventSettings.java @@ -38,21 +38,9 @@ import jdk.jfr.internal.management.EventSettingsModifier; * chaining. *

    * The following example shows how to use the {@code EventSettings} class. - *

    - * {@code
    - * Recording r = new Recording();
    - * r.enable("jdk.CPULoad")
    - *    .withPeriod(Duration.ofSeconds(1));
    - * r.enable("jdk.FileWrite")
    - *    .withoutStackTrace()
    - *    .withThreshold(Duration.ofNanos(10));
    - * r.start();
    - * Thread.sleep(10_000);
    - * r.stop();
    - * r.dump(Files.createTempFile("recording", ".jfr"));
      *
    - * }
    - * 
    + * {@snippet class="Snippets" region="EventSettingOverview"} + * * @since 9 */ public abstract class EventSettings { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java b/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java index 5e2bac1ba74..398fe2eb13a 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/FlightRecorder.java @@ -92,15 +92,7 @@ public final class FlightRecorder { *

    * The following example shows how to create a snapshot and write a subset of the data to a file. * - *

    {@literal
    -     * try (Recording snapshot = FlightRecorder.getFlightRecorder().takeSnapshot()) {
    -     *   if (snapshot.getSize() > 0) {
    -     *     snapshot.setMaxSize(100_000_000);
    -     *     snapshot.setMaxAge(Duration.ofMinutes(5));
    -     *     snapshot.dump(Paths.get("snapshot.jfr"));
    -     *   }
    -     * }
    -     * }
    + * {@snippet class="Snippets" region="FlightRecorderTakeSnapshot"} * * The caller must close the recording when access to the data is no longer * needed. diff --git a/src/jdk.jfr/share/classes/jdk/jfr/MetadataDefinition.java b/src/jdk.jfr/share/classes/jdk/jfr/MetadataDefinition.java index 919c7b01cff..56c669a2b34 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/MetadataDefinition.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/MetadataDefinition.java @@ -36,36 +36,7 @@ import java.lang.annotation.Target; * In the following example, a transaction event is defined with two * user-defined annotations, {@code @Severity} and {@code @TransactionId}. * - *
    {@literal
    - * @MetadataDefinition
    - * @Label("Severity")
    - * @Description("Value between 0 and 100 that indicates severity. 100 is most severe.")
    - * @Retention(RetentionPolicy.RUNTIME)
    - * @Target({ElementType.TYPE})
    - * public @interface Severity {
    - *     int value() default 50;
    - * }
    - *
    - * @MetadataDefinition
    - * @Label("Transaction Id")
    - * @Relational
    - * @Retention(RetentionPolicy.RUNTIME)
    - * @Target({ElementType.FIELD})
    - * public @interface TransactionId {
    - * }
    - *
    - * @Severity(80)
    - * @Label("Transaction Blocked")
    - * class TransactionBlocked extends Event {
    - *     @TransactionId
    - *     @Label("Transaction")
    - *     long transactionId1;
    - *
    - *     @TransactionId
    - *     @Label("Transaction Blocker")
    - *     long transactionId2;
    - * }
    - * }
    + * {@snippet class="Snippets" region="MetadataDefinitionOverview"} * * Adding {@code @MetadataDefinition} to the declaration of {@code @Severity} and {@code @TransactionId} * ensures the information is saved by Flight Recorder. diff --git a/src/jdk.jfr/share/classes/jdk/jfr/Recording.java b/src/jdk.jfr/share/classes/jdk/jfr/Recording.java index 1dd4b303013..4f07bca6641 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/Recording.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/Recording.java @@ -46,15 +46,7 @@ import jdk.jfr.internal.WriteableUserPath; *

    * The following example shows how configure, start, stop and dump recording data to disk. * - *

    {@literal
    - *   Configuration c = Configuration.getConfiguration("default");
    - *   Recording r = new Recording(c);
    - *   r.start();
    - *   System.gc();
    - *   Thread.sleep(5000);
    - *   r.stop();
    - *   r.dump(Files.createTempFile("my-recording", ".jfr"));
    - * }
    + * {@snippet class="Snippets" region="RecordingOverview"} * * @since 9 */ @@ -143,9 +135,9 @@ public final class Recording implements Closeable { *

    * The following example shows how create a recording that uses a predefined configuration. * - *

    {@literal
    +     * {@snippet :
          * Recording r = new Recording(Configuration.getConfiguration("default"));
    -     * }
    + * } * * The newly created recording is in the {@link RecordingState#NEW} state. To * start the recording, invoke the {@link Recording#start()} method. @@ -307,21 +299,21 @@ public final class Recording implements Closeable { *

    * The following example shows how to set event settings for a recording. * - *

    {@literal
    +     * {@snippet :
          *     Map settings = new HashMap<>();
          *     settings.putAll(EventSettings.enabled("jdk.CPUSample").withPeriod(Duration.ofSeconds(2)).toMap());
          *     settings.putAll(EventSettings.enabled(MyEvent.class).withThreshold(Duration.ofSeconds(2)).withoutStackTrace().toMap());
          *     settings.put("jdk.ExecutionSample#period", "10 ms");
          *     recording.setSettings(settings);
    -     * }
    + * } * * The following example shows how to merge settings. * - *
    {@literal
    +     * {@snippet :
          *     Map settings = recording.getSettings();
          *     settings.putAll(additionalSettings);
          *     recording.setSettings(settings);
    -     * }
    + * } * * @param settings the settings to set, not {@code null} */ diff --git a/src/jdk.jfr/share/classes/jdk/jfr/SettingControl.java b/src/jdk.jfr/share/classes/jdk/jfr/SettingControl.java index 431b984ebf2..1c699247800 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/SettingControl.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/SettingControl.java @@ -37,30 +37,7 @@ import jdk.jfr.internal.settings.JDKSettingControl; * The following example shows a naive implementation of a setting control for * regular expressions: * - *
    {@literal
    - * final class RegExpControl extends SettingControl {
    - *   private Pattern pattern = Pattern.compile(".*");
    - *
    - *   @Override
    - *   public void setValue(String value) {
    - *     this.pattern = Pattern.compile(value);
    - *   }
    - *
    - *   @Override
    - *   public String combine(Set values) {
    - *     return String.join("|", values);
    - *   }
    - *
    - *   @Override
    - *   public String getValue() {
    - *     return pattern.toString();
    - *   }
    - *
    - *   public boolean matches(String s) {
    - *     return pattern.matcher(s).find();
    - *   }
    - * }
    - * }
    + * {@snippet class="Snippets" region="SettingControlOverview1"} * * The {@code setValue(String)}, {@code getValue()} and * {@code combine(Set)} methods are invoked when a setting value @@ -85,55 +62,13 @@ import jdk.jfr.internal.settings.JDKSettingControl; * The following example shows how to create an event that uses the * regular expression filter defined above. * - *
    {@literal
    - * abstract class HTTPRequest extends Event {
    - *   @Label("Request URI")
    - *   protected String uri;
    - *
    - *   @Label("Servlet URI Filter")
    - *   @SettingDefinition
    - *   protected boolean uriFilter(RegExpControl regExp) {
    - *     return regExp.matches(uri);
    - *   }
    - * }
    - *
    - * @Label("HTTP Get Request")
    - * class HTTPGetRequest extends HTTPRequest {
    - * }
    - *
    - * @Label("HTTP Post Request")
    - * class HTTPPostRequest extends HTTPRequest {
    - * }
    - *
    - * class ExampleServlet extends HttpServlet {
    - *   protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
    - *     HTTPGetRequest request = new HTTPGetRequest();
    - *     request.begin();
    - *     request.uri = req.getRequestURI();
    - *     ...
    - *     request.commit();
    - *   }
    - *
    - *   protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
    - *     HTTPPostRequest request = new HTTPPostRequest();
    - *     request.begin();
    - *     request.uri = req.getRequestURI();
    - *     ...
    - *     request.commit();
    - *   }
    - * }
    - * }
    + * {@snippet class="Snippets" region="SettingControlOverview2"} * *

    * The following example shows how an event can be filtered by assigning the * {@code "uriFilter"} setting with the specified regular expressions. * - *

    {@literal
    - * Recording r = new Recording();
    - * r.enable("HTTPGetRequest").with("uriFilter", "https://www.example.com/list/.*");
    - * r.enable("HTTPPostRequest").with("uriFilter", "https://www.example.com/login/.*");
    - * r.start();
    - * }
    + * {@snippet class="Snippets" region="SettingControlOverview3"} * * @see SettingDefinition * diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/EventStream.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/EventStream.java index dc877b52efd..8b55f669ef2 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/EventStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/EventStream.java @@ -95,25 +95,7 @@ import jdk.jfr.internal.consumer.FileAccess; * The following example shows how an {@code EventStream} can be used to listen * to events on a JVM running Flight Recorder * - *
    {@literal
    - * try (var es = EventStream.openRepository()) {
    - *   es.onEvent("jdk.CPULoad", event -> {
    - *     System.out.println("CPU Load " + event.getEndTime());
    - *     System.out.println(" Machine total: " + 100 * event.getFloat("machineTotal") + "%");
    - *     System.out.println(" JVM User: " + 100 * event.getFloat("jvmUser") + "%");
    - *     System.out.println(" JVM System: " + 100 * event.getFloat("jvmSystem") + "%");
    - *     System.out.println();
    - *   });
    - *   es.onEvent("jdk.GarbageCollection", event -> {
    - *     System.out.println("Garbage collection: " + event.getLong("gcId"));
    - *     System.out.println(" Cause: " + event.getString("cause"));
    - *     System.out.println(" Total pause: " + event.getDuration("sumOfPauses"));
    - *     System.out.println(" Longest pause: " + event.getDuration("longestPause"));
    - *     System.out.println();
    - *   });
    - *   es.start();
    - * }
    - * }
    + * {@snippet class="Snippets" region="EventStreamOverview"} *

    * To start recording together with the stream, see {@link RecordingStream}. * 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 d9def94ff8a..277c9899def 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordedObject.java @@ -225,23 +225,7 @@ public class RecordedObject { * for callers of this method is to validate the field before attempting access. *

    * Example - * - *

    {@literal
    -     * if (event.hasField("intValue")) {
    -     *   int intValue = event.getValue("intValue");
    -     *   System.out.println("Int value: " + intValue);
    -     * }
    -     *
    -     * if (event.hasField("objectClass")) {
    -     *   RecordedClass clazz = event.getValue("objectClass");
    -     *   System.out.println("Class name: " + clazz.getName());
    -     * }
    -     *
    -     * if (event.hasField("sampledThread")) {
    -     *   RecordedThread sampledThread = event.getValue("sampledThread");
    -     *   System.out.println("Sampled thread: " + sampledThread.getJavaName());
    -     * }
    -     * }
    + * {@snippet class="Snippets" region="RecordedObjectGetValue"} * * @param the return type * @param name of the field to get, not {@code null} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java index 3b8163e717b..15501bc6880 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingFile.java @@ -49,14 +49,7 @@ import jdk.jfr.internal.consumer.RecordingInput; *

    * The following example shows how read and print all events in a recording file. * - *

    {@literal
    - * try (RecordingFile recordingFile = new RecordingFile(Paths.get("recording.jfr"))) {
    - *   while (recordingFile.hasMoreEvents()) {
    - *     RecordedEvent event = recordingFile.readEvent();
    - *     System.out.println(event);
    - *   }
    - * }
    - * }
    + * {@snippet class="Snippets" region="RecordingFileOverview"} * * @since 9 */ diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingStream.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingStream.java index ea6d2a05bf9..64347196948 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingStream.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/RecordingStream.java @@ -56,15 +56,8 @@ import jdk.jfr.internal.consumer.EventDirectoryStream; * The following example shows how to record events using the default * configuration and print the Garbage Collection, CPU Load and JVM Information * event to standard out. - *
    {@literal
    - * Configuration c = Configuration.getConfiguration("default");
    - * try (var rs = new RecordingStream(c)) {
    - *     rs.onEvent("jdk.GarbageCollection", System.out::println);
    - *     rs.onEvent("jdk.CPULoad", System.out::println);
    - *     rs.onEvent("jdk.JVMInformation", System.out::println);
    - *     rs.start();
    - * }
    - * }
    + * + * {@snippet class="Snippets" region="RecordingStreamOverview"} * * @since 14 */ @@ -140,13 +133,7 @@ public final class RecordingStream implements AutoCloseable, EventStream { * The following example shows how to create a recording stream that uses a * predefined configuration. * - *
    {@literal
    -     * var c = Configuration.getConfiguration("default");
    -     * try (var rs = new RecordingStream(c)) {
    -     *   rs.onEvent(System.out::println);
    -     *   rs.start();
    -     * }
    -     * }
    + * {@snippet class="Snippets" region="RecordingStreamConstructor"} * * @param configuration configuration that contains the settings to use, * not {@code null} @@ -189,17 +176,7 @@ public final class RecordingStream implements AutoCloseable, EventStream { * The following example records 20 seconds using the "default" configuration * and then changes settings to the "profile" configuration. * - *
    {@literal
    -     * Configuration defaultConfiguration = Configuration.getConfiguration("default");
    -     * Configuration profileConfiguration = Configuration.getConfiguration("profile");
    -     * try (var rs = new RecordingStream(defaultConfiguration)) {
    -     *    rs.onEvent(System.out::println);
    -     *    rs.startAsync();
    -     *    Thread.sleep(20_000);
    -     *    rs.setSettings(profileConfiguration.getSettings());
    -     *    Thread.sleep(20_000);
    -     * }
    -     * }
    + * {@snippet class="Snippets" region="RecordingStreamSetSettings"} * * @param settings the settings to set, not {@code null} * @@ -384,16 +361,8 @@ public final class RecordingStream implements AutoCloseable, EventStream { * The following example prints the CPU usage for ten seconds. When * the current thread leaves the try-with-resources block the * stream is stopped/closed. - *
    {@literal
    -     * try (var stream = new RecordingStream()) {
    -     *   stream.enable("jdk.CPULoad").withPeriod(Duration.ofSeconds(1));
    -     *   stream.onEvent("jdk.CPULoad", event -> {
    -     *     System.out.println(event);
    -     *   });
    -     *   stream.startAsync();
    -     *   Thread.sleep(10_000);
    -     * }
    -     * }
    + * + * {@snippet class="Snippets" region="RecordingStreamStartAsync"} * * @throws IllegalStateException if the stream is already started or closed */ diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/package-info.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/package-info.java index 5b34deaf249..81f7977deba 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/consumer/package-info.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/package-info.java @@ -27,29 +27,8 @@ * This package contains classes for consuming Flight Recorder data. *

    * In the following example, the program prints a histogram of all method samples in a recording. - *

    {@literal
    - * public static void main(String[] args) throws IOException {
    - *     if (args.length != 1) {
    - *         System.err.println("Must specify a recording file.");
    - *         return;
    - *     }
      *
    - *     RecordingFile.readAllEvents(Path.of(args[0])).stream()
    - *         .filter(e -> e.getEventType().getName().equals("jdk.ExecutionSample"))
    - *         .map(e -> e.getStackTrace())
    - *         .filter(s -> s != null)
    - *         .map(s -> s.getFrames().get(0))
    - *         .filter(f -> f.isJavaFrame())
    - *         .map(f -> f.getMethod())
    - *         .collect(
    - *             Collectors.groupingBy(m -> m.getType().getName() + "." + m.getName() + " " + m.getDescriptor(),
    - *             Collectors.counting()))
    - *         .entrySet()
    - *         .stream()
    - *         .sorted((a, b) -> b.getValue().compareTo(a.getValue()))
    - *         .forEach(e -> System.out.printf("%8d %s\n", e.getValue(), e.getKey()));
    - *     }
    - * }
    + * {@snippet class="Snippets" region="PackageOverview"} *

    * Null-handling *

    diff --git a/src/jdk.jfr/share/classes/jdk/jfr/consumer/snippet-files/Snippets.java b/src/jdk.jfr/share/classes/jdk/jfr/consumer/snippet-files/Snippets.java new file mode 100644 index 00000000000..d80879a22ec --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/consumer/snippet-files/Snippets.java @@ -0,0 +1,169 @@ +/* + * 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 example2; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.Duration; +import java.util.stream.Collectors; +import jdk.jfr.consumer.EventStream; +import jdk.jfr.consumer.RecordingFile; +import jdk.jfr.consumer.RecordedClass; +import jdk.jfr.consumer.RecordedThread; +import jdk.jfr.consumer.RecordingStream; +import jdk.jfr.Configuration; +import jdk.jfr.consumer.RecordedEvent; + +public class Snippets { + + class PackageOveriview { + // @start region="PackageOverview" + public static void main(String[] args) throws IOException { + if (args.length != 1) { + System.err.println("Must specify a recording file."); + return; + } + + RecordingFile.readAllEvents(Path.of(args[0])).stream() + .filter(e -> e.getEventType().getName().equals("jdk.ExecutionSample")) + .map(e -> e.getStackTrace()) + .filter(s -> s != null) + .map(s -> s.getFrames().get(0)) + .filter(f -> f.isJavaFrame()) + .map(f -> f.getMethod()) + .collect( + Collectors.groupingBy(m -> m.getType().getName() + "." + m.getName() + " " + m.getDescriptor(), + Collectors.counting())) + .entrySet() + .stream() + .sorted((a, b) -> b.getValue().compareTo(a.getValue())) + .forEach(e -> System.out.printf("%8d %s\n", e.getValue(), e.getKey())); + } + // @end + } + + void EventStreamOverview() throws Exception { + // @start region="EventStreamOverview" + try (var es = EventStream.openRepository()) { + es.onEvent("jdk.CPULoad", event -> { + System.out.println("CPU Load " + event.getEndTime()); + System.out.println(" Machine total: " + 100 * event.getFloat("machineTotal") + "%"); + System.out.println(" JVM User: " + 100 * event.getFloat("jvmUser") + "%"); + System.out.println(" JVM System: " + 100 * event.getFloat("jvmSystem") + "%"); + System.out.println(); + }); + es.onEvent("jdk.GarbageCollection", event -> { + System.out.println("Garbage collection: " + event.getLong("gcId")); + System.out.println(" Cause: " + event.getString("cause")); + System.out.println(" Total pause: " + event.getDuration("sumOfPauses")); + System.out.println(" Longest pause: " + event.getDuration("longestPause")); + System.out.println(); + }); + es.start(); + } + // @end + } + + void RecordingFileOverview() throws Exception { + // @start region="RecordingFileOverview" + try (RecordingFile recordingFile = new RecordingFile(Paths.get("recording.jfr"))) { + while (recordingFile.hasMoreEvents()) { + RecordedEvent event = recordingFile.readEvent(); + System.out.println(event); + } + } + // @end + } + + void RecordedObjectGetValue() { + RecordedEvent event = null; + // @start region="RecordedObjectGetValue" + if (event.hasField("intValue")) { + int intValue = event.getValue("intValue"); + System.out.println("Int value: " + intValue); + } + + if (event.hasField("objectClass")) { + RecordedClass clazz = event.getValue("objectClass"); + System.out.println("Class name: " + clazz.getName()); + } + + if (event.hasField("sampledThread")) { + RecordedThread sampledThread = event.getValue("sampledThread"); + System.out.println("Sampled thread: " + sampledThread.getJavaName()); + } + // @end + } + + void RecordingStreamOverview() throws Exception { + // @start region="RecordingStreamOverview" + Configuration c = Configuration.getConfiguration("default"); + try (var rs = new RecordingStream(c)) { + rs.onEvent("jdk.GarbageCollection", System.out::println); + rs.onEvent("jdk.CPULoad", System.out::println); + rs.onEvent("jdk.JVMInformation", System.out::println); + rs.start(); + } + // @end + } + + void RecordingStreamConstructor() throws Exception { + // @start region="RecordingStreamConstructor" + var c = Configuration.getConfiguration("default"); + try (var rs = new RecordingStream(c)) { + rs.onEvent(System.out::println); + rs.start(); + } + // @end + } + + void RecordingStreamSetSettings() throws Exception { + // @start region="RecordingStreamSetSettings" + Configuration defaultConfiguration = Configuration.getConfiguration("default"); + Configuration profileConfiguration = Configuration.getConfiguration("profile"); + try (var rs = new RecordingStream(defaultConfiguration)) { + rs.onEvent(System.out::println); + rs.startAsync(); + Thread.sleep(20_000); + rs.setSettings(profileConfiguration.getSettings()); + Thread.sleep(20_000); + } + // @end + } + + void RecordingStreamStartAsync() throws Exception { + // @start region="RecordingStreamStartAsync" + try (var stream = new RecordingStream()) { + stream.enable("jdk.CPULoad").withPeriod(Duration.ofSeconds(1)); + stream.onEvent("jdk.CPULoad", event -> { + System.out.println(event); + }); + stream.startAsync(); + Thread.sleep(10_000); + } + // @end + } +} diff --git a/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java b/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java new file mode 100644 index 00000000000..b2d4fff29de --- /dev/null +++ b/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java @@ -0,0 +1,291 @@ +/* + * 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 example1; + +import jdk.jfr.AnnotationElement; +import jdk.jfr.ValueDescriptor; +import jdk.jfr.EventFactory; +import jdk.jfr.Event; +import jdk.jfr.Name; +import jdk.jfr.Label; +import jdk.jfr.Description; +import jdk.jfr.Category; +import jdk.jfr.Recording; +import jdk.jfr.MetadataDefinition; +import jdk.jfr.Relational; +import jdk.jfr.consumer.RecordingFile; +import jdk.jfr.Configuration; +import jdk.jfr.SettingDefinition; +import jdk.jfr.SettingControl; +import jdk.jfr.FlightRecorder; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +public class Snippets { + + void AnnotationElementOverview() { + // @start region="AnnotationElementOverview" + List typeAnnotations = new ArrayList<>(); + typeAnnotations.add(new AnnotationElement(Name.class, "com.example.HelloWorld")); + typeAnnotations.add(new AnnotationElement(Label.class, "Hello World")); + typeAnnotations.add(new AnnotationElement(Description.class, "Helps programmer getting started")); + + List fieldAnnotations = new ArrayList<>(); + fieldAnnotations.add(new AnnotationElement(Label.class, "Message")); + + List fields = new ArrayList<>(); + fields.add(new ValueDescriptor(String.class, "message", fieldAnnotations)); + + EventFactory f = EventFactory.create(typeAnnotations, fields); + Event event = f.newEvent(); + event.commit(); + // @end + } + + // @start region="EventOverview" + public class Example { + + @Label("Hello World") + @Description("Helps programmer getting started") + static class HelloWorld extends Event { + @Label("Message") + String message; + } + + public static void main(String... args) { + HelloWorld event = new HelloWorld(); + event.message = "hello, world!"; + event.commit(); + } + } + // @end + + void EventFactoryOverview() { + // @start region="EventFactoryOverview" + List fields = new ArrayList<>(); + List messageAnnotations = Collections.singletonList(new AnnotationElement(Label.class, "Message")); + fields.add(new ValueDescriptor(String.class, "message", messageAnnotations)); + List numberAnnotations = Collections.singletonList(new AnnotationElement(Label.class, "Number")); + fields.add(new ValueDescriptor(int.class, "number", numberAnnotations)); + + String[] category = { "Example", "Getting Started" }; + List eventAnnotations = new ArrayList<>(); + eventAnnotations.add(new AnnotationElement(Name.class, "com.example.HelloWorld")); + eventAnnotations.add(new AnnotationElement(Label.class, "Hello World")); + eventAnnotations.add(new AnnotationElement(Description.class, "Helps programmer getting started")); + eventAnnotations.add(new AnnotationElement(Category.class, category)); + + EventFactory f = EventFactory.create(eventAnnotations, fields); + + Event event = f.newEvent(); + event.set(0, "hello, world!"); + event.set(1, 4711); + event.commit(); + // @end + } + + void EventSettingOverview() throws Exception { + // @start region="EventSettingOverview" + Recording r = new Recording(); + r.enable("jdk.CPULoad") + .withPeriod(Duration.ofSeconds(1)); + r.enable("jdk.FileWrite") + .withoutStackTrace() + .withThreshold(Duration.ofNanos(10)); + r.start(); + Thread.sleep(10_000); + r.stop(); + r.dump(Files.createTempFile("recording", ".jfr")); + // @end + } + + void FlightRecorderTakeSnapshot() throws Exception { + // @start region="FlightRecorderTakeSnapshot" + try (Recording snapshot = FlightRecorder.getFlightRecorder().takeSnapshot()) { + if (snapshot.getSize() > 0) { + snapshot.setMaxSize(100_000_000); + snapshot.setMaxAge(Duration.ofMinutes(5)); + snapshot.dump(Paths.get("snapshot.jfr")); + } + } + // @end + } + + // @start region="MetadataDefinitionOverview" + @MetadataDefinition + @Label("Severity") + @Description("Value between 0 and 100 that indicates severity. 100 is most severe.") + @Retention(RetentionPolicy.RUNTIME) + @Target({ ElementType.TYPE }) + public @interface Severity { + int value() default 50; + } + + @MetadataDefinition + @Label("Transaction Id") + @Relational + @Retention(RetentionPolicy.RUNTIME) + @Target({ ElementType.FIELD }) + public @interface TransactionId { + } + + @Severity(80) + @Label("Transaction Blocked") + class TransactionBlocked extends Event { + @TransactionId + @Label("Transaction") + long transactionId1; + + @TransactionId + @Label("Transaction Blocker") + long transactionId2; + } + // @end + + void RecordingnOverview() throws Exception { + // @start region="RecordingOverview" + Configuration c = Configuration.getConfiguration("default"); + Recording r = new Recording(c); + r.start(); + System.gc(); + Thread.sleep(5000); + r.stop(); + r.dump(Files.createTempFile("my-recording", ".jfr")); + // @end + } + + // @start region="SettingControlOverview1" + final class RegExpControl extends SettingControl { + private Pattern pattern = Pattern.compile(".*"); + + @Override + public void setValue(String value) { + this.pattern = Pattern.compile(value); + } + + @Override + public String combine(Set values) { + return String.join("|", values); + } + + @Override + public String getValue() { + return pattern.toString(); + } + + public boolean matches(String s) { + return pattern.matcher(s).find(); + } + } + // @end + + class HttpServlet { + } + + class HttpServletRequest { + public String getRequestURI() { + return null; + } + } + + class HttpServletResponse { + } + + // @start region="SettingControlOverview2" + abstract class HTTPRequest extends Event { + @Label("Request URI") + protected String uri; + + @Label("Servlet URI Filter") + @SettingDefinition + protected boolean uriFilter(RegExpControl regExp) { + return regExp.matches(uri); + } + } + + @Label("HTTP Get Request") + class HTTPGetRequest extends HTTPRequest { + } + + @Label("HTTP Post Request") + class HTTPPostRequest extends HTTPRequest { + } + + class ExampleServlet extends HttpServlet { + protected void doGet(HttpServletRequest req, HttpServletResponse resp) { + HTTPGetRequest request = new HTTPGetRequest(); + request.begin(); + request.uri = req.getRequestURI(); + code: // @replace regex='code:' replacement="..." + request.commit(); + } + + protected void doPost(HttpServletRequest req, HttpServletResponse resp) { + HTTPPostRequest request = new HTTPPostRequest(); + request.begin(); + request.uri = req.getRequestURI(); + code: // @replace regex='code:' replacement="..." + request.commit(); + } + } + // @end + + void SettingControlOverview3() { + // @start region="SettingControlOverview3" + Recording r = new Recording(); + r.enable("HTTPGetRequest").with("uriFilter", "https://www.example.com/list/.*"); + r.enable("HTTPPostRequest").with("uriFilter", "https://www.example.com/login/.*"); + r.start(); + // @end + } + + // @start region="SettingDefinitionOverview" + class HelloWorld extends Event { + + @Label("Message") + String message; + + @SettingDefinition + @Label("Message Filter") + public boolean filter(RegExpControl regExp) { + return regExp.matches(message); + } + } + // @end +} -- GitLab From 4eacacb5ad61020c11a521111c40af9fa72e2ff5 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 8 Feb 2022 07:19:57 +0000 Subject: [PATCH 169/400] 8281314: Rename Stack{Red,Yellow,Reserved,Shadow}Pages multipliers Reviewed-by: stuefe, coleenp, xliu --- src/hotspot/share/runtime/stackOverflow.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/hotspot/share/runtime/stackOverflow.cpp b/src/hotspot/share/runtime/stackOverflow.cpp index 942f3a29e3f..1004ca265d3 100644 --- a/src/hotspot/share/runtime/stackOverflow.cpp +++ b/src/hotspot/share/runtime/stackOverflow.cpp @@ -39,19 +39,20 @@ void StackOverflow::initialize_stack_zone_sizes() { // Stack zone sizes must be page aligned. size_t page_size = os::vm_page_size(); - // We need to adapt the configured number of stack protection pages given - // in 4K pages to the actual os page size. We must do this before setting - // up minimal stack sizes etc. in os::init_2(). - size_t alignment = 4*K; + // We need to adapt the configured number of stack protection pages to the + // actual OS page size. We must do this before setting up minimal stack + // sizes etc. in os::init_2(). The option values are given in 4K units, + // matching the smallest page size in supported platforms. + size_t unit = 4*K; assert(_stack_red_zone_size == 0, "This should be called only once."); - _stack_red_zone_size = align_up(StackRedPages * alignment, page_size); + _stack_red_zone_size = align_up(StackRedPages * unit, page_size); assert(_stack_yellow_zone_size == 0, "This should be called only once."); - _stack_yellow_zone_size = align_up(StackYellowPages * alignment, page_size); + _stack_yellow_zone_size = align_up(StackYellowPages * unit, page_size); assert(_stack_reserved_zone_size == 0, "This should be called only once."); - _stack_reserved_zone_size = align_up(StackReservedPages * alignment, page_size); + _stack_reserved_zone_size = align_up(StackReservedPages * unit, page_size); // The shadow area is not allocated or protected, so // it needs not be page aligned. @@ -63,7 +64,7 @@ void StackOverflow::initialize_stack_zone_sizes() { // suffices to touch all pages. (Some pages are banged // several times, though.) assert(_stack_shadow_zone_size == 0, "This should be called only once."); - _stack_shadow_zone_size = align_up(StackShadowPages * alignment, page_size); + _stack_shadow_zone_size = align_up(StackShadowPages * unit, page_size); } bool StackOverflow::stack_guards_enabled() const { -- GitLab From f2a9627c05f9ef82eb83d8c1b9d4209bf42e7d8d Mon Sep 17 00:00:00 2001 From: Masanori Yano Date: Tue, 8 Feb 2022 08:31:10 +0000 Subject: [PATCH 170/400] 8279329: Remove hardcoded IPv4 available policy on Windows Reviewed-by: djelinski, alanb, dfuchs, aefimov --- src/java.base/windows/native/libnet/net_util_md.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/java.base/windows/native/libnet/net_util_md.c b/src/java.base/windows/native/libnet/net_util_md.c index 83e30287196..3282ff64402 100644 --- a/src/java.base/windows/native/libnet/net_util_md.c +++ b/src/java.base/windows/native/libnet/net_util_md.c @@ -215,7 +215,12 @@ NET_GetFileDescriptorID(JNIEnv *env) jint IPv4_supported() { - /* TODO: properly check for IPv4 support on Windows */ + SOCKET s = socket(AF_INET, SOCK_STREAM, 0); + if (s == INVALID_SOCKET) { + return JNI_FALSE; + } + closesocket(s); + return JNI_TRUE; } -- GitLab From 861f2797f7d56ab185117f27dae2660af9250f6a Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 8 Feb 2022 09:02:53 +0000 Subject: [PATCH 171/400] 8280917: Simplify G1ConcurrentRefineThread activation Reviewed-by: iwalulya, sjohanss --- src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 8 +- .../share/gc/g1/g1ConcurrentRefine.cpp | 68 ++++-- .../share/gc/g1/g1ConcurrentRefine.hpp | 18 +- .../share/gc/g1/g1ConcurrentRefineThread.cpp | 225 +++++++++++++----- .../share/gc/g1/g1ConcurrentRefineThread.hpp | 77 ++++-- src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp | 19 +- src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp | 37 +-- 7 files changed, 300 insertions(+), 152 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp index bfa29e39ccc..3d885b862be 100644 --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -1726,12 +1726,6 @@ jint G1CollectedHeap::initialize() { _free_segmented_array_memory_task = new G1SegmentedArrayFreeMemoryTask("Card Set Free Memory Task"); _service_thread->register_task(_free_segmented_array_memory_task); - { - G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); - dcqs.set_process_cards_threshold(concurrent_refine()->yellow_zone()); - dcqs.set_max_cards(concurrent_refine()->red_zone()); - } - // Here we allocate the dummy HeapRegion that is required by the // G1AllocRegion class. HeapRegion* dummy_region = _hrm.get_dummy_region(); diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp index 3393d3b6012..d879568e34c 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -42,7 +42,7 @@ G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thread(uint worker_id, bool initializing) { G1ConcurrentRefineThread* result = NULL; if (initializing || !InjectGCWorkerCreationFailure) { - result = new G1ConcurrentRefineThread(_cr, worker_id); + result = G1ConcurrentRefineThread::create(_cr, worker_id); } if (result == NULL || result->osthread() == NULL) { log_warning(gc)("Failed to create refinement thread %u, no more %s", @@ -53,8 +53,9 @@ G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thr } G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl() : - _cr(NULL), - _threads(NULL), + _cr(nullptr), + _primary_thread(nullptr), + _threads(nullptr), _num_max_threads(0) { } @@ -76,22 +77,27 @@ jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr, uint nu _threads = NEW_C_HEAP_ARRAY(G1ConcurrentRefineThread*, num_max_threads, mtGC); - for (uint i = 0; i < num_max_threads; i++) { - if (UseDynamicNumberOfGCThreads && i != 0 /* Always start first thread. */) { - _threads[i] = NULL; - } else { - _threads[i] = create_refinement_thread(i, true); - if (_threads[i] == NULL) { - vm_shutdown_during_initialization("Could not allocate refinement threads."); - return JNI_ENOMEM; + if (num_max_threads > 0) { + auto primary = G1PrimaryConcurrentRefineThread::create(cr); + if (primary == nullptr) { + vm_shutdown_during_initialization("Could not allocate primary refinement thread"); + return JNI_ENOMEM; + } + _threads[0] = _primary_thread = primary; + + for (uint i = 1; i < num_max_threads; ++i) { + if (UseDynamicNumberOfGCThreads) { + _threads[i] = nullptr; + } else { + _threads[i] = create_refinement_thread(i, true); + if (_threads[i] == nullptr) { + vm_shutdown_during_initialization("Could not allocate refinement threads."); + return JNI_ENOMEM; + } } } } - if (num_max_threads > 0) { - G1BarrierSet::dirty_card_queue_set().set_primary_refinement_thread(_threads[0]); - } - return JNI_OK; } @@ -237,7 +243,18 @@ G1ConcurrentRefine::G1ConcurrentRefine(size_t green_zone, } jint G1ConcurrentRefine::initialize() { - return _thread_control.initialize(this, max_num_threads()); + jint result = _thread_control.initialize(this, max_num_threads()); + if (result != JNI_OK) return result; + + G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); + dcqs.set_max_cards(red_zone()); + if (max_num_threads() > 0) { + G1PrimaryConcurrentRefineThread* primary_thread = _thread_control.primary_thread(); + primary_thread->update_notify_threshold(primary_activation_threshold()); + dcqs.set_refinement_notification_thread(primary_thread); + } + + return JNI_OK; } static size_t calc_min_yellow_zone_size() { @@ -392,14 +409,9 @@ void G1ConcurrentRefine::adjust(double logged_cards_scan_time, update_zones(logged_cards_scan_time, processed_logged_cards, goal_ms); // Change the barrier params - if (max_num_threads() == 0) { - // Disable dcqs notification when there are no threads to notify. - dcqs.set_process_cards_threshold(G1DirtyCardQueueSet::ProcessCardsThresholdNever); - } else { - // Worker 0 is the primary; wakeup is via dcqs notification. - STATIC_ASSERT(max_yellow_zone <= INT_MAX); - size_t activate = activation_threshold(0); - dcqs.set_process_cards_threshold(activate); + if (max_num_threads() > 0) { + size_t threshold = primary_activation_threshold(); + _thread_control.primary_thread()->update_notify_threshold(threshold); } dcqs.set_max_cards(red_zone()); } @@ -411,7 +423,6 @@ void G1ConcurrentRefine::adjust(double logged_cards_scan_time, } else { dcqs.set_max_cards_padding(0); } - dcqs.notify_if_necessary(); } G1ConcurrentRefineStats G1ConcurrentRefine::get_and_reset_refinement_stats() { @@ -438,6 +449,11 @@ size_t G1ConcurrentRefine::deactivation_threshold(uint worker_id) const { return deactivation_level(thresholds); } +size_t G1ConcurrentRefine::primary_activation_threshold() const { + assert(max_num_threads() > 0, "No primary refinement thread"); + return activation_threshold(0); +} + uint G1ConcurrentRefine::worker_id_offset() { return G1DirtyCardQueueSet::num_par_ids(); } diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp index b904e47a76a..feb82dd2067 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -27,20 +27,20 @@ #include "gc/g1/g1ConcurrentRefineStats.hpp" #include "memory/allocation.hpp" +#include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" -#include "utilities/ticks.hpp" // Forward decl class G1ConcurrentRefine; class G1ConcurrentRefineThread; -class outputStream; +class G1PrimaryConcurrentRefineThread; class ThreadClosure; // Helper class for refinement thread management. Used to start, stop and // iterate over them. class G1ConcurrentRefineThreadControl { G1ConcurrentRefine* _cr; - + G1PrimaryConcurrentRefineThread* _primary_thread; G1ConcurrentRefineThread** _threads; uint _num_max_threads; @@ -53,6 +53,12 @@ public: jint initialize(G1ConcurrentRefine* cr, uint num_max_threads); + G1PrimaryConcurrentRefineThread* primary_thread() const { + assert(_num_max_threads > 0, "precondition"); + assert(_primary_thread != nullptr, "uninitialized"); + return _primary_thread; + } + // If there is a "successor" thread that can be activated given the current id, // activate it. void maybe_activate_next(uint cur_worker_id); @@ -116,6 +122,10 @@ public: void stop(); + // The minimum number of pending cards for activation of the primary + // refinement thread. + size_t primary_activation_threshold() const; + // Adjust refinement thresholds based on work done during the pause and the goal time. void adjust(double logged_cards_scan_time, size_t processed_logged_cards, double goal_ms); diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp index 45defd5e713..ece63ed805a 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -31,6 +31,8 @@ #include "gc/shared/suspendibleThreadSet.hpp" #include "logging/log.hpp" #include "runtime/atomic.hpp" +#include "runtime/init.hpp" +#include "runtime/safepoint.hpp" #include "runtime/thread.hpp" G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr, uint worker_id) : @@ -39,71 +41,20 @@ G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr, uint _vtime_accum(0.0), _refinement_stats(new G1ConcurrentRefineStats()), _worker_id(worker_id), - _notifier(new Semaphore(0)), - _should_notify(true), _cr(cr) { // set name set_name("G1 Refine#%d", worker_id); - create_and_start(); } G1ConcurrentRefineThread::~G1ConcurrentRefineThread() { delete _refinement_stats; - delete _notifier; -} - -void G1ConcurrentRefineThread::wait_for_completed_buffers() { - assert(this == Thread::current(), "precondition"); - while (Atomic::load_acquire(&_should_notify)) { - _notifier->wait(); - } -} - -void G1ConcurrentRefineThread::activate() { - assert(this != Thread::current(), "precondition"); - // Notify iff transitioning from needing activation to not. This helps - // keep the semaphore count bounded and minimizes the work done by - // activators when the thread is already active. - if (Atomic::load_acquire(&_should_notify) && - Atomic::cmpxchg(&_should_notify, true, false)) { - _notifier->signal(); - } -} - -bool G1ConcurrentRefineThread::maybe_deactivate(bool more_work) { - assert(this == Thread::current(), "precondition"); - - if (more_work) { - // Suppress unnecessary notifications. - Atomic::release_store(&_should_notify, false); - return false; - } else if (Atomic::load_acquire(&_should_notify)) { - // Deactivate if no notifications since enabled (see below). - return true; - } else { - // Try for more refinement work with notifications enabled, to close - // race; there could be a plethora of suppressed activation attempts - // after we found no work but before we enable notifications here - // (so there could be lots of work for this thread to do), followed - // by a long time without activation after enabling notifications. - // But first, clear any pending signals to prevent accumulation. - while (_notifier->trywait()) {} - Atomic::release_store(&_should_notify, true); - return false; - } } void G1ConcurrentRefineThread::run_service() { _vtime_start = os::elapsedVTime(); - while (!should_terminate()) { - // Wait for work - wait_for_completed_buffers(); - if (should_terminate()) { - break; - } - + while (wait_for_completed_buffers()) { // For logging. G1ConcurrentRefineStats start_stats = *_refinement_stats; G1ConcurrentRefineStats total_stats; // Accumulate over activation. @@ -125,8 +76,11 @@ void G1ConcurrentRefineThread::run_service() { continue; // Re-check for termination after yield delay. } - bool more_work = _cr->do_refinement_step(_worker_id, _refinement_stats); - if (maybe_deactivate(more_work)) break; + if (!_cr->do_refinement_step(_worker_id, _refinement_stats)) { + if (maybe_deactivate()) { + break; + } + } } } @@ -151,3 +105,164 @@ void G1ConcurrentRefineThread::run_service() { void G1ConcurrentRefineThread::stop_service() { activate(); } + +G1PrimaryConcurrentRefineThread* +G1PrimaryConcurrentRefineThread::create(G1ConcurrentRefine* cr) { + G1PrimaryConcurrentRefineThread* crt = + new (std::nothrow) G1PrimaryConcurrentRefineThread(cr); + if (crt != nullptr) { + crt->create_and_start(); + } + return crt; +} + +G1PrimaryConcurrentRefineThread::G1PrimaryConcurrentRefineThread(G1ConcurrentRefine* cr) : + G1ConcurrentRefineThread(cr, 0), + _notifier(0), + _threshold(0) +{} + +void G1PrimaryConcurrentRefineThread::stop_service() { + G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); + dcqs.set_refinement_notification_thread(nullptr); + G1ConcurrentRefineThread::stop_service(); +} + +// The primary refinement thread is notified when buffers/cards are added to +// the dirty card queue. That can happen in fairly arbitrary contexts. +// This means there may be arbitrary other locks held when notifying. We +// also don't want to have to take a lock on the fairly common notification +// path, as contention for that lock can significantly impact performance. +// +// We use a semaphore to implement waiting and unblocking, to avoid +// lock rank checking issues. (We could alternatively use an +// arbitrarily low ranked mutex.) The atomic variable _threshold is +// used to decide when to signal the semaphore. When its value is +// SIZE_MAX then the thread is running. Otherwise, the thread should +// be requested to run when notified that the number of cards has +// exceeded the threshold value. + +bool G1PrimaryConcurrentRefineThread::wait_for_completed_buffers() { + assert(this == Thread::current(), "precondition"); + _notifier.wait(); + assert(Atomic::load(&_threshold) == SIZE_MAX || should_terminate(), "incorrect state"); + return !should_terminate(); +} + +bool G1PrimaryConcurrentRefineThread::maybe_deactivate() { + assert(this == Thread::current(), "precondition"); + assert(Atomic::load(&_threshold) == SIZE_MAX, "incorrect state"); + Atomic::store(&_threshold, cr()->primary_activation_threshold()); + // Always deactivate when no refinement work found. New refinement + // work may have arrived after we tried, but checking for that would + // still be racy. Instead, the next time additional work is made + // available we'll get reactivated. + return true; +} + +void G1PrimaryConcurrentRefineThread::activate() { + assert(this != Thread::current(), "precondition"); + // The thread is running when notifications are disabled, so shouldn't + // signal is this case. But there's a race between stop requests and + // maybe_deactivate, so also signal if stop requested. + size_t threshold = Atomic::load(&_threshold); + if (((threshold != SIZE_MAX) && + (threshold == Atomic::cmpxchg(&_threshold, threshold, SIZE_MAX))) || + should_terminate()) { + _notifier.signal(); + } +} + +void G1PrimaryConcurrentRefineThread::notify(size_t num_cards) { + // Only activate if the number of pending cards exceeds the activation + // threshold. Notification is disabled when the thread is running, by + // setting _threshold to SIZE_MAX. A relaxed load is sufficient; we don't + // need to be precise about this. + if (num_cards > Atomic::load(&_threshold)) { + // Discard notifications occurring during a safepoint. A GC safepoint + // may dirty some cards (such as during reference processing), possibly + // leading to notification. End-of-GC update_notify_threshold activates + // the primary thread if needed. Non-GC safepoints are expected to + // rarely (if ever) dirty cards, so defer activation to a post-safepoint + // notification. + if (!SafepointSynchronize::is_at_safepoint()) { + activate(); + } + } +} + +void G1PrimaryConcurrentRefineThread::update_notify_threshold(size_t threshold) { +#ifdef ASSERT + if (is_init_completed()) { + assert_at_safepoint(); + assert(Thread::current()->is_VM_thread(), "precondition"); + } +#endif // ASSERT + // If _threshold is SIZE_MAX then the thread is active and the value + // of _threshold shouldn't be changed. + if (Atomic::load(&_threshold) != SIZE_MAX) { + Atomic::store(&_threshold, threshold); + if (G1BarrierSet::dirty_card_queue_set().num_cards() > threshold) { + activate(); + } + } +} + +class G1SecondaryConcurrentRefineThread final : public G1ConcurrentRefineThread { + Monitor _notifier; + bool _requested_active; + + bool wait_for_completed_buffers() override; + bool maybe_deactivate() override; + +public: + G1SecondaryConcurrentRefineThread(G1ConcurrentRefine* cr, uint worker_id); + + void activate() override; +}; + +G1SecondaryConcurrentRefineThread::G1SecondaryConcurrentRefineThread(G1ConcurrentRefine* cr, + uint worker_id) : + G1ConcurrentRefineThread(cr, worker_id), + _notifier(Mutex::nosafepoint, this->name(), true), + _requested_active(false) +{ + assert(worker_id > 0, "precondition"); +} + +bool G1SecondaryConcurrentRefineThread::wait_for_completed_buffers() { + assert(this == Thread::current(), "precondition"); + MonitorLocker ml(&_notifier, Mutex::_no_safepoint_check_flag); + while (!_requested_active && !should_terminate()) { + ml.wait(); + } + return !should_terminate(); +} + +void G1SecondaryConcurrentRefineThread::activate() { + assert(this != Thread::current(), "precondition"); + MonitorLocker ml(&_notifier, Mutex::_no_safepoint_check_flag); + if (!_requested_active || should_terminate()) { + _requested_active = true; + ml.notify(); + } +} + +bool G1SecondaryConcurrentRefineThread::maybe_deactivate() { + assert(this == Thread::current(), "precondition"); + MutexLocker ml(&_notifier, Mutex::_no_safepoint_check_flag); + bool requested = _requested_active; + _requested_active = false; + return !requested; // Deactivate if not recently requested active. +} + +G1ConcurrentRefineThread* +G1ConcurrentRefineThread::create(G1ConcurrentRefine* cr, uint worker_id) { + assert(worker_id > 0, "precondition"); + G1ConcurrentRefineThread* crt = + new (std::nothrow) G1SecondaryConcurrentRefineThread(cr, worker_id); + if (crt != nullptr) { + crt->create_and_start(); + } + return crt; +} diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp index cdcab6b2285..218609dd76c 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -26,7 +26,9 @@ #define SHARE_GC_G1_G1CONCURRENTREFINETHREAD_HPP #include "gc/shared/concurrentGCThread.hpp" -#include "utilities/ticks.hpp" +#include "memory/padded.hpp" +#include "runtime/semaphore.hpp" +#include "utilities/macros.hpp" // Forward Decl. class G1ConcurrentRefine; @@ -45,36 +47,34 @@ class G1ConcurrentRefineThread: public ConcurrentGCThread { uint _worker_id; - // _notifier and _should_notify form a single-reader / multi-writer - // notification mechanism. The owning concurrent refinement thread is the - // single reader. The writers are (other) threads that call activate() on - // the thread. The i-th concurrent refinement thread is responsible for - // activating thread i+1 if the number of buffers in the queue exceeds a - // threshold for that i+1th thread. The 0th (primary) thread is activated - // by threads that add cards to the dirty card queue set when the primary - // thread's threshold is exceeded. activate() is also used to wake up the - // threads during termination, so even the non-primary thread case is - // multi-writer. - Semaphore* _notifier; - volatile bool _should_notify; + G1ConcurrentRefine* _cr; + + NONCOPYABLE(G1ConcurrentRefineThread); + +protected: + G1ConcurrentRefineThread(G1ConcurrentRefine* cr, uint worker_id); + + // Returns !should_terminate(). + // precondition: this is the current thread. + virtual bool wait_for_completed_buffers() = 0; // Called when no refinement work found for this thread. // Returns true if should deactivate. - bool maybe_deactivate(bool more_work); + // precondition: this is the current thread. + virtual bool maybe_deactivate() = 0; - G1ConcurrentRefine* _cr; - - void wait_for_completed_buffers(); + G1ConcurrentRefine* cr() const { return _cr; } - virtual void run_service(); - virtual void stop_service(); + void run_service() override; + void stop_service() override; public: - G1ConcurrentRefineThread(G1ConcurrentRefine* cg1r, uint worker_id); + static G1ConcurrentRefineThread* create(G1ConcurrentRefine* cr, uint worker_id); virtual ~G1ConcurrentRefineThread(); // Activate this thread. - void activate(); + // precondition: this is not the current thread. + virtual void activate() = 0; G1ConcurrentRefineStats* refinement_stats() const { return _refinement_stats; @@ -84,4 +84,37 @@ public: double vtime_accum() { return _vtime_accum; } }; +// Singleton special refinement thread, registered with the dirty card queue. +// This thread supports notification of increases to the number of cards in +// the dirty card queue, which may trigger activation of this thread when it +// is not already running. +class G1PrimaryConcurrentRefineThread final : public G1ConcurrentRefineThread { + // Support for activation. The thread waits on this semaphore when idle. + // Calls to activate signal it to wake the thread. + Semaphore _notifier; + DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, 0); + // Used as both the activation threshold and also the "is active" state. + // The value is SIZE_MAX when the thread is active, otherwise the threshold + // for signaling the semaphore. + volatile size_t _threshold; + DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t)); + + bool wait_for_completed_buffers() override; + bool maybe_deactivate() override; + + G1PrimaryConcurrentRefineThread(G1ConcurrentRefine* cr); + + void stop_service() override; + +public: + static G1PrimaryConcurrentRefineThread* create(G1ConcurrentRefine* cr); + + void activate() override; + + // Used by the write barrier support to activate the thread if needed when + // there are new refinement buffers. + void notify(size_t num_cards); + void update_notify_threshold(size_t threshold); +}; + #endif // SHARE_GC_G1_G1CONCURRENTREFINETHREAD_HPP diff --git a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp index 22e8e218057..136f5849dbb 100644 --- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp +++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp @@ -66,12 +66,11 @@ static uint par_ids_start() { return 0; } G1DirtyCardQueueSet::G1DirtyCardQueueSet(BufferNode::Allocator* allocator) : PtrQueueSet(allocator), - _primary_refinement_thread(NULL), + _refinement_notification_thread(nullptr), _num_cards(0), _completed(), _paused(), _free_ids(par_ids_start(), num_par_ids()), - _process_cards_threshold(ProcessCardsThresholdNever), _max_cards(MaxCardsUnlimited), _padded_max_cards(MaxCardsUnlimited), _detached_refinement_stats() @@ -118,6 +117,10 @@ void G1DirtyCardQueueSet::handle_zero_index_for_thread(Thread* t) { G1BarrierSet::dirty_card_queue_set().handle_zero_index(queue); } +size_t G1DirtyCardQueueSet::num_cards() const { + return Atomic::load(&_num_cards); +} + void G1DirtyCardQueueSet::enqueue_completed_buffer(BufferNode* cbn) { assert(cbn != NULL, "precondition"); // Increment _num_cards before adding to queue, so queue removal doesn't @@ -130,9 +133,8 @@ void G1DirtyCardQueueSet::enqueue_completed_buffer(BufferNode* cbn) { GlobalCounter::CriticalSection cs(Thread::current()); _completed.push(*cbn); } - if ((new_num_cards > process_cards_threshold()) && - (_primary_refinement_thread != NULL)) { - _primary_refinement_thread->activate(); + if (_refinement_notification_thread != nullptr) { + _refinement_notification_thread->notify(new_num_cards); } } @@ -323,13 +325,6 @@ void G1DirtyCardQueueSet::abandon_completed_buffers() { } } -void G1DirtyCardQueueSet::notify_if_necessary() { - if ((_primary_refinement_thread != NULL) && - (num_cards() > process_cards_threshold())) { - _primary_refinement_thread->activate(); - } -} - // Merge lists of buffers. The source queue set is emptied as a // result. The queue sets must share the same allocator. void G1DirtyCardQueueSet::merge_bufferlists(G1RedirtyCardsQueueSet* src) { diff --git a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp index 051e29058eb..097efe957f7 100644 --- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp +++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp @@ -34,7 +34,7 @@ #include "memory/padded.hpp" #include "utilities/nonblockingQueue.hpp" -class G1ConcurrentRefineThread; +class G1PrimaryConcurrentRefineThread; class G1DirtyCardQueueSet; class G1RedirtyCardsQueueSet; class Thread; @@ -156,10 +156,10 @@ class G1DirtyCardQueueSet: public PtrQueueSet { HeadTail take_all(); }; - // The primary refinement thread, for activation when the processing - // threshold is reached. NULL if there aren't any refinement threads. - G1ConcurrentRefineThread* _primary_refinement_thread; - DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(G1ConcurrentRefineThread*)); + // The refinement notification thread, for activation when the notification + // threshold is reached. nullptr if there aren't any refinement threads. + G1PrimaryConcurrentRefineThread* _refinement_notification_thread; + DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(G1PrimaryConcurrentRefineThread*)); // Upper bound on the number of cards in the completed and paused buffers. volatile size_t _num_cards; DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(size_t)); @@ -174,9 +174,6 @@ class G1DirtyCardQueueSet: public PtrQueueSet { G1FreeIdSet _free_ids; - // Activation threshold for the primary refinement thread. - size_t _process_cards_threshold; - // If the queue contains more cards than configured here, the // mutator must start doing some of the concurrent refinement work. size_t _max_cards; @@ -242,10 +239,6 @@ public: G1DirtyCardQueueSet(BufferNode::Allocator* allocator); ~G1DirtyCardQueueSet(); - void set_primary_refinement_thread(G1ConcurrentRefineThread* thread) { - _primary_refinement_thread = thread; - } - // The number of parallel ids that can be claimed to allow collector or // mutator threads to do card-processing work. static uint num_par_ids(); @@ -254,24 +247,16 @@ public: virtual void enqueue_completed_buffer(BufferNode* node); - // Upper bound on the number of cards currently in in this queue set. + // Upper bound on the number of cards currently in this queue set. // Read without synchronization. The value may be high because there // is a concurrent modification of the set of buffers. - size_t num_cards() const { return _num_cards; } + size_t num_cards() const; - // Get/Set the number of cards that triggers log processing. - // Log processing should be done when the number of cards exceeds the - // threshold. - void set_process_cards_threshold(size_t sz) { - _process_cards_threshold = sz; + // Record the primary concurrent refinement thread. This is the thread to + // be notified when num_cards() exceeds the refinement notification threshold. + void set_refinement_notification_thread(G1PrimaryConcurrentRefineThread* thread) { + _refinement_notification_thread = thread; } - size_t process_cards_threshold() const { - return _process_cards_threshold; - } - static const size_t ProcessCardsThresholdNever = SIZE_MAX; - - // Notify the consumer if the number of buffers crossed the threshold - void notify_if_necessary(); void merge_bufferlists(G1RedirtyCardsQueueSet* src); -- GitLab From f5d8cebbb6f1b38247c3b30ba8859874a0e98115 Mon Sep 17 00:00:00 2001 From: Manukumar V S Date: Tue, 8 Feb 2022 12:39:43 +0000 Subject: [PATCH 172/400] 8281296: Create a regression test for JDK-4515999 Reviewed-by: aivanov --- .../4515999/JSpinnerMouseAndKeyPressTest.java | 201 ++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 test/jdk/javax/swing/JSpinner/4515999/JSpinnerMouseAndKeyPressTest.java diff --git a/test/jdk/javax/swing/JSpinner/4515999/JSpinnerMouseAndKeyPressTest.java b/test/jdk/javax/swing/JSpinner/4515999/JSpinnerMouseAndKeyPressTest.java new file mode 100644 index 00000000000..6e5fb3ad97f --- /dev/null +++ b/test/jdk/javax/swing/JSpinner/4515999/JSpinnerMouseAndKeyPressTest.java @@ -0,0 +1,201 @@ +/* + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.ComponentOrientation; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.SpinnerDateModel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + + +import static javax.swing.UIManager.getInstalledLookAndFeels; + +/* + * @test + * @key headful + * @bug 4515999 + * @summary Check whether incrementing dates via the keyboard (up/down) gives + * the same results as using mouse press on the arrow buttons in a JSpinner. + * @run main JSpinnerMouseAndKeyPressTest + */ +public class JSpinnerMouseAndKeyPressTest { + // 2 days in milliseconds + private static final int EXPECTED_VALUE_2_DAYS = 2 * 24 * 60 * 60 * 1000; + + private static JFrame frame; + private static JSpinner spinner; + private static volatile Point spinnerUpButtonCenter; + private static volatile Point spinnerDownButtonCenter; + private static volatile Date spinnerValue; + + public static void main(String[] s) throws Exception { + runTest(); + } + + private static void setLookAndFeel(final String laf) { + try { + UIManager.setLookAndFeel(laf); + System.out.println("LookAndFeel: " + laf); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static void createUI() { + frame = new JFrame(); + JPanel panel = new JPanel(); + spinner = new JSpinner(); + spinner.setModel(new DateModel()); + JSpinner.DateEditor editor = new JSpinner.DateEditor(spinner, "dd/MM/yy"); + spinner.setEditor(editor); + spinner.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); + panel.add(spinner); + frame.add(panel); + frame.setUndecorated(true); + frame.pack(); + frame.setAlwaysOnTop(true); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + + public static void runTest() throws Exception { + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); + List lafs = Arrays.stream(getInstalledLookAndFeels()) + .map(UIManager.LookAndFeelInfo::getClassName) + .collect(Collectors.toList()); + for (final String laf : lafs) { + try { + SwingUtilities.invokeAndWait(() -> { + setLookAndFeel(laf); + createUI(); + }); + + SwingUtilities.invokeAndWait(() -> { + Point loc = spinner.getLocationOnScreen(); + int editorWidth = spinner.getEditor().getWidth(); + int buttonWidth = spinner.getWidth() - editorWidth; + int quarterHeight = spinner.getHeight() / 4; + + spinnerUpButtonCenter = new Point(loc.x + editorWidth + + (buttonWidth / 2), + loc.y + quarterHeight); + spinnerDownButtonCenter = new Point(spinnerUpButtonCenter.x, + loc.y + (3 * quarterHeight)); + }); + + // Mouse press use-case + // Move Mouse pointer to UP button center and click it + robot.mouseMove(spinnerUpButtonCenter.x, spinnerUpButtonCenter.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + updateSpinnerValue(); + long upValue = spinnerValue.getTime(); + + // Move Mouse pointer to DOWN button center and click it + robot.mouseMove(spinnerDownButtonCenter.x, spinnerDownButtonCenter.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + updateSpinnerValue(); + long downValue = spinnerValue.getTime(); + + long mouseIncrement = upValue - downValue; + + // Key press use-case + // Up Key press + robot.keyPress(KeyEvent.VK_UP); + robot.keyRelease(KeyEvent.VK_UP); + + updateSpinnerValue(); + upValue = spinnerValue.getTime(); + + // Down Key press + robot.keyPress(KeyEvent.VK_DOWN); + robot.keyRelease(KeyEvent.VK_DOWN); + + updateSpinnerValue(); + downValue = spinnerValue.getTime(); + + long keyIncrement = upValue - downValue; + + if ((keyIncrement == EXPECTED_VALUE_2_DAYS) && + (mouseIncrement == EXPECTED_VALUE_2_DAYS)) { + System.out.println("Test passed"); + } else { + throw new RuntimeException("Test failed because keyIncrement: " + + keyIncrement + " and mouseIncrement: " + + mouseIncrement + " should match with the expected value " + + EXPECTED_VALUE_2_DAYS + " for LnF " + laf); + } + + } finally { + SwingUtilities.invokeAndWait(JSpinnerMouseAndKeyPressTest::disposeFrame); + } + } + } + + private static void updateSpinnerValue() throws Exception { + SwingUtilities.invokeAndWait(() -> spinnerValue = (Date) spinner.getValue()); + } + + private static void disposeFrame() { + if (frame != null) { + frame.dispose(); + frame = null; + } + } + + private static class DateModel extends SpinnerDateModel { + + private final Calendar cal = Calendar.getInstance(); + + @Override + public Object getNextValue() { + cal.setTime(getDate()); + cal.add(Calendar.DAY_OF_MONTH, 2); // Increment two days + return cal.getTime(); + } + + @Override + public Object getPreviousValue() { + cal.setTime(getDate()); + cal.add(Calendar.DAY_OF_MONTH, -2); // Decrement two days + return cal.getTime(); + } + } +} -- GitLab From 83d67452da248db17bc72de80247a670d6813cf5 Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Tue, 8 Feb 2022 14:43:45 +0000 Subject: [PATCH 173/400] 8281450: Remove unnecessary operator new and delete from ObjectMonitor Reviewed-by: dholmes --- src/hotspot/share/runtime/objectMonitor.cpp | 15 +-------------- src/hotspot/share/runtime/objectMonitor.hpp | 7 +------ 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/hotspot/share/runtime/objectMonitor.cpp b/src/hotspot/share/runtime/objectMonitor.cpp index e56b18a84c9..a6e279cfcb2 100644 --- a/src/hotspot/share/runtime/objectMonitor.cpp +++ b/src/hotspot/share/runtime/objectMonitor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -233,19 +233,6 @@ OopStorage* ObjectMonitor::_oop_storage = NULL; // * See also http://blogs.sun.com/dave -void* ObjectMonitor::operator new (size_t size) throw() { - return AllocateHeap(size, mtInternal); -} -void* ObjectMonitor::operator new[] (size_t size) throw() { - return operator new (size); -} -void ObjectMonitor::operator delete(void* p) { - FreeHeap(p); -} -void ObjectMonitor::operator delete[] (void *p) { - operator delete(p); -} - // Check that object() and set_object() are called from the right context: static void check_object_context() { #ifdef ASSERT diff --git a/src/hotspot/share/runtime/objectMonitor.hpp b/src/hotspot/share/runtime/objectMonitor.hpp index 4f85c429b70..4ca4cc28c86 100644 --- a/src/hotspot/share/runtime/objectMonitor.hpp +++ b/src/hotspot/share/runtime/objectMonitor.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -203,11 +203,6 @@ class ObjectMonitor : public CHeapObj { static int Knob_SpinLimit; - void* operator new (size_t size) throw(); - void* operator new[] (size_t size) throw(); - void operator delete(void* p); - void operator delete[] (void* p); - // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ... // ByteSize would also be an appropriate type. static int header_offset_in_bytes() { return offset_of(ObjectMonitor, _header); } -- GitLab From 380378c551b4243ef72d868571f725b390e12124 Mon Sep 17 00:00:00 2001 From: Harold Seigel Date: Tue, 8 Feb 2022 16:00:58 +0000 Subject: [PATCH 174/400] 8281400: Remove unused wcslen() function Reviewed-by: dcubed, coleenp, lfoltan --- src/hotspot/share/utilities/globalDefinitions_gcc.hpp | 7 +------ src/hotspot/share/utilities/globalDefinitions_xlc.hpp | 6 +----- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/hotspot/share/utilities/globalDefinitions_gcc.hpp b/src/hotspot/share/utilities/globalDefinitions_gcc.hpp index 30cca9ee7ae..4aed8605182 100644 --- a/src/hotspot/share/utilities/globalDefinitions_gcc.hpp +++ b/src/hotspot/share/utilities/globalDefinitions_gcc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -127,11 +127,6 @@ inline int g_isfinite(jfloat f) { return isfinite(f); } inline int g_isfinite(jdouble f) { return isfinite(f); } -// Wide characters - -inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); } - - // Formatting. #ifdef _LP64 # ifdef __APPLE__ diff --git a/src/hotspot/share/utilities/globalDefinitions_xlc.hpp b/src/hotspot/share/utilities/globalDefinitions_xlc.hpp index 4bfb6a2d5df..80c27729c7d 100644 --- a/src/hotspot/share/utilities/globalDefinitions_xlc.hpp +++ b/src/hotspot/share/utilities/globalDefinitions_xlc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -109,10 +109,6 @@ inline int g_isnan(double f) { return isnan(f); } inline int g_isfinite(jfloat f) { return finite(f); } inline int g_isfinite(jdouble f) { return finite(f); } -// Wide characters -inline int wcslen(const jchar* x) { return wcslen((const wchar_t*)x); } - - // Formatting. #ifdef _LP64 #define FORMAT64_MODIFIER "l" -- GitLab From 7f19c700707573000a37910dd6d2f2bb6e8439ad Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Tue, 8 Feb 2022 17:48:48 +0000 Subject: [PATCH 175/400] 8281061: [s390] JFR runs into assertions while validating interpreter frames Reviewed-by: lucy, rrich --- src/hotspot/cpu/s390/frame_s390.cpp | 18 ++++++++---------- .../os_cpu/linux_s390/thread_linux_s390.cpp | 13 +++++++------ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/hotspot/cpu/s390/frame_s390.cpp b/src/hotspot/cpu/s390/frame_s390.cpp index bfb38ffcdaf..3588915f79d 100644 --- a/src/hotspot/cpu/s390/frame_s390.cpp +++ b/src/hotspot/cpu/s390/frame_s390.cpp @@ -117,8 +117,8 @@ bool frame::safe_for_sender(JavaThread *thread) { return false; } - z_abi_160* sender_abi = (z_abi_160*) fp; - intptr_t* sender_sp = (intptr_t*) sender_abi->callers_sp; + z_abi_16* sender_abi = (z_abi_16*)fp; + intptr_t* sender_sp = (intptr_t*) fp; address sender_pc = (address) sender_abi->return_pc; // We must always be able to find a recognizable pc. @@ -142,7 +142,7 @@ bool frame::safe_for_sender(JavaThread *thread) { // sender_fp must be within the stack and above (but not // equal) current frame's fp. if (!thread->is_in_stack_range_excl(sender_fp, fp)) { - return false; + return false; } // If the potential sender is the interpreter then we can do some more checking. @@ -319,8 +319,8 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const { // do some validation of frame elements // first the method - - Method* m = *interpreter_frame_method_addr(); + // Need to use "unchecked" versions to avoid "z_istate_magic_number" assertion. + Method* m = (Method*)(ijava_state_unchecked()->method); // validate the method we'd find in this potential sender if (!Method::is_valid_method(m)) return false; @@ -335,19 +335,17 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const { } // validate bci/bcx - - address bcp = interpreter_frame_bcp(); + address bcp = (address)(ijava_state_unchecked()->bcp); if (m->validate_bci_from_bcp(bcp) < 0) { return false; } // validate constantPoolCache* - ConstantPoolCache* cp = *interpreter_frame_cache_addr(); + ConstantPoolCache* cp = (ConstantPoolCache*)(ijava_state_unchecked()->cpoolCache); if (MetaspaceObj::is_valid(cp) == false) return false; // validate locals - - address locals = (address) *interpreter_frame_locals_addr(); + address locals = (address)(ijava_state_unchecked()->locals); return thread->is_in_stack_range_incl(locals, (address)fp()); } diff --git a/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp b/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp index d06b851a99f..3b16096784f 100644 --- a/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp +++ b/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2016, 2019 SAP SE. All rights reserved. + * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2022 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 @@ -58,14 +58,15 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, // if we were running Java code when SIGPROF came in. if (isInJava) { ucontext_t* uc = (ucontext_t*) ucontext; - frame ret_frame((intptr_t*)uc->uc_mcontext.gregs[15/*Z_SP*/], - (address)uc->uc_mcontext.psw.addr); + address pc = (address)uc->uc_mcontext.psw.addr; - if (ret_frame.pc() == NULL) { + if (pc == NULL) { // ucontext wasn't useful return false; } + frame ret_frame((intptr_t*)uc->uc_mcontext.gregs[15/*Z_SP*/], pc); + if (ret_frame.fp() == NULL) { // The found frame does not have a valid frame pointer. // Bail out because this will create big trouble later on, either @@ -100,7 +101,7 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, if (ret_frame.is_interpreted_frame()) { frame::z_ijava_state* istate = ret_frame.ijava_state_unchecked(); - if (is_in_full_stack((address)istate)) { + if (!is_in_full_stack((address)istate)) { return false; } const Method *m = (const Method*)(istate->method); -- GitLab From 92f4f40da6c4ff55c7ed334007c9c6ca0dc15d99 Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Tue, 8 Feb 2022 17:53:42 +0000 Subject: [PATCH 176/400] 8281104: jar --create should create missing parent directories Reviewed-by: lancea --- .../share/classes/sun/tools/jar/Main.java | 15 ++- .../sun/tools/jar/resources/jar.properties | 6 +- .../jar/CreateMissingParentDirectories.java | 114 ++++++++++++++++++ 3 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 test/jdk/tools/jar/CreateMissingParentDirectories.java diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java index 3436c01928b..c582f2d80ce 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java +++ b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 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 @@ -427,10 +427,10 @@ public class Main { fatalError(e); ok = false; } catch (Error ee) { - ee.printStackTrace(); + ee.printStackTrace(err); ok = false; } catch (Throwable t) { - t.printStackTrace(); + t.printStackTrace(err); ok = false; } finally { if (tmpFile != null && tmpFile.exists()) @@ -461,7 +461,12 @@ public class Main { try { if (ok) { if (fname != null) { - Files.move(path, Paths.get(fname), StandardCopyOption.REPLACE_EXISTING); + Path target = Paths.get(fname); + Path parent = target.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + Files.move(path, target, StandardCopyOption.REPLACE_EXISTING); } else { Files.copy(path, new FileOutputStream(FileDescriptor.out)); } @@ -1653,7 +1658,7 @@ public class Main { * A fatal exception has been caught. No recovery possible */ void fatalError(Exception e) { - e.printStackTrace(); + e.printStackTrace(err); } /** diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties index 87bff689102..c08c6ff7f06 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties +++ b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties @@ -169,7 +169,7 @@ usage.compat=\ \n\ Usage: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files] ...\n\ Options:\n\ -\ \ -c create new archive\n\ +\ \ -c create new archive (including missing parent directories)\n\ \ \ -t list table of contents for archive\n\ \ \ -x extract named (or all) files from archive\n\ \ \ -u update existing archive\n\ @@ -227,7 +227,9 @@ text file and pass it to the jar command with the at sign (@) as a prefix.\n\ main.help.opt.main=\ \ Main operation mode:\n main.help.opt.main.create=\ -\ -c, --create Create the archive +\ -c, --create Create the archive. When the archive file name specified\n\ +\ by -f or --file contains a path, missing parent directories\n\ +\ will also be created main.help.opt.main.generate-index=\ \ -i, --generate-index=FILE Generate index information for the specified jar\n\ \ archives diff --git a/test/jdk/tools/jar/CreateMissingParentDirectories.java b/test/jdk/tools/jar/CreateMissingParentDirectories.java new file mode 100644 index 00000000000..93d6d4ce01d --- /dev/null +++ b/test/jdk/tools/jar/CreateMissingParentDirectories.java @@ -0,0 +1,114 @@ +/* + * 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. + * + * 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 8281104 + * @modules jdk.jartool + * @summary jar --create --file a/b/test.jar should create directories a/b + */ + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.spi.ToolProvider; +import java.util.stream.Stream; + +public class CreateMissingParentDirectories { + private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar") + .orElseThrow(() -> + new RuntimeException("jar tool not found") + ); + + /** + * Remove dirs & files needed for test. + */ + private static void cleanup(Path dir) { + try { + if (Files.isDirectory(dir)) { + try (Stream s = Files.list(dir)) { + s.forEach(p -> cleanup(p)); + } + } + Files.delete(dir); + } catch (Exception x) { + fail(x.toString()); + } + } + + public static void realMain(String[] args) throws Throwable { + Path topDir = Files.createTempDirectory("delete"); + try { + Path entry = Files.writeString(topDir.resolve("test.txt"), "Some text..."); + + doHappyPathTest(topDir.resolve("test.jar"), entry); + doHappyPathTest(topDir.resolve("a/test.jar"), entry); + doHappyPathTest(topDir.resolve("a/b/test.jar"), entry); + + doFailingTest(topDir.toString() + "/a/*/test.jar", entry); + Path blocker = Files.writeString(topDir.resolve("blocker.txt"), "Blocked!"); + doFailingTest(topDir.resolve("blocker.txt/test.jar").toString(), entry); + } finally { + cleanup(topDir); + } + } + + private static void doHappyPathTest(Path jar, Path entry) throws Throwable { + String[] jarArgs = new String[]{"cf", jar.toString(), entry.toString()}; + if (JAR_TOOL.run(System.out, System.err, jarArgs) != 0) { + fail("Could not create jar file: " + jar); + return; + } + pass(); + } + + private static void doFailingTest(String jar, Path entry) throws Throwable { + StringWriter out = new StringWriter(); + StringWriter err = new StringWriter(); + String[] jarArgs = new String[]{"cf", jar, entry.toString()}; + + if (JAR_TOOL.run(new PrintWriter(out, true), new PrintWriter(err, true), jarArgs) == 0) { + fail("Should have failed creating jar file: " + jar); + return; + } + // non-zero exit code expected, check error message contains jar file's name + check(err.toString().contains(jar)); + pass(); + } + + //--------------------- Infrastructure --------------------------- + static volatile int passed = 0, failed = 0; + static void pass() {passed++;} + static void fail() {failed++; Thread.dumpStack();} + static void fail(String msg) {System.out.println(msg); fail();} + static void unexpected(Throwable t) {failed++; t.printStackTrace();} + static void check(boolean cond) {if (cond) pass(); else fail();} + static void equal(Object x, Object y) { + if (x == null ? y == null : x.equals(y)) pass(); + else fail(x + " not equal to " + y);} + public static void main(String[] args) throws Throwable { + try {realMain(args);} catch (Throwable t) {unexpected(t);} + System.out.println("\nPassed = " + passed + " failed = " + failed); + if (failed > 0) throw new AssertionError("Some tests failed");} +} -- GitLab From 5fb56dbb0b4e3345ca6f48ba9c01bd467f04aa6f Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Tue, 8 Feb 2022 20:16:34 +0000 Subject: [PATCH 177/400] 8281476: ProblemList tools/jar/CreateMissingParentDirectories.java Reviewed-by: azvegint, bpb, lancea --- test/jdk/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 6b54c726277..1d08673243f 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -765,6 +765,7 @@ javax/swing/JTree/4908142/bug4908142.java 8278348 macosx-all # core_tools tools/jlink/plugins/CompressorPluginTest.java 8247407 generic-all +tools/jar/CreateMissingParentDirectories.java 8281470 generic-all ############################################################################ -- GitLab From d658d945cf57bab8e61302841dcb56b36e48eff3 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 8 Feb 2022 20:29:04 +0000 Subject: [PATCH 178/400] 8280828: Improve invariants in NonblockingQueue::append Reviewed-by: iwalulya, tschatzl --- .../utilities/nonblockingQueue.inline.hpp | 65 +++++++++++-------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/src/hotspot/share/utilities/nonblockingQueue.inline.hpp b/src/hotspot/share/utilities/nonblockingQueue.inline.hpp index 2fbd26f2dca..e16c8cb57d0 100644 --- a/src/hotspot/share/utilities/nonblockingQueue.inline.hpp +++ b/src/hotspot/share/utilities/nonblockingQueue.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -94,34 +94,41 @@ size_t NonblockingQueue::length() const { // push/append operations, each may introduce another such segment. But they // all eventually get resolved by their respective updates of their old tail's // "next" value. This also means that try_pop operation must handle an object -// with a NULL "next" value specially. +// differently depending on its "next" value. // // A push operation is just a degenerate append, where the object being pushed // is both the head and the tail of the list being appended. template void NonblockingQueue::append(T& first, T& last) { assert(next(last) == NULL, "precondition"); + // Make last the new end of the queue. Any further push/appends will + // extend after last. We will try to extend from the previous end of + // queue. set_next(last, end_marker()); T* old_tail = Atomic::xchg(&_tail, &last); - bool is_old_tail_null = (old_tail == NULL); - if (is_old_tail_null || - // Try to install first as old_tail's next. - !is_end(Atomic::cmpxchg(next_ptr(*old_tail), end_marker(), &first))) { - // Install first as the new head if either - // (1) the list was empty, or - // (2) a concurrent try_pop claimed old_tail, so it is no longer in the list. - // Note that multiple concurrent push/append operations cannot modify - // _head simultaneously, because the Atomic::xchg() above orders these - // push/append operations so they perform Atomic::cmpxchg() on different - // old_tail. Thus, the cmpxchg can only fail because of a concurrent try_pop. + if (old_tail == NULL) { + // If old_tail is NULL then the queue was empty, and _head must also be + // NULL. The correctness of this assertion depends on try_pop clearing + // first _head then _tail when taking the last entry. + assert(Atomic::load(&_head) == NULL, "invariant"); + // Fall through to common update of _head. + } else if (is_end(Atomic::cmpxchg(next_ptr(*old_tail), end_marker(), &first))) { + // Successfully extended the queue list from old_tail to first. No + // other push/append could have competed with us, because we claimed + // old_tail for extension. We won any races with try_pop by changing + // away from end-marker. So we're done. + return; + } else { + // A concurrent try_pop has claimed old_tail, so it is no longer in the + // list. The queue was logically empty. _head is either NULL or + // old_tail, depending on how far try_pop operations have progressed. DEBUG_ONLY(T* old_head = Atomic::load(&_head);) - // If old_tail is NULL, old_head could be NULL, or an unseen object - // that is being popped. Otherwise, old_head must be either NULL - // or the same as old_tail. - assert(is_old_tail_null || - old_head == NULL || old_head == old_tail, "invariant"); - Atomic::store(&_head, &first); + assert((old_head == NULL) || (old_head == old_tail), "invariant"); + // Fall through to common update of _head. } + // The queue was empty, and first should become the new _head. The queue + // will appear to be empty to any further try_pops until done. + Atomic::store(&_head, &first); } template @@ -161,7 +168,9 @@ bool NonblockingQueue::try_pop(T** node_ptr) { // _head to NULL, "helping" the competing try_pop. _head will remain // NULL until a subsequent push/append. This is a lost race, and we // report it as such for consistency, though we could report the queue - // was empty. + // was empty. We don't attempt to further help [Clause 2] by also + // trying to set _tail to NULL, as that would just ensure that one or + // the other cmpxchg is a wasted failure. return false; } else { // [Clause 1c] @@ -181,17 +190,21 @@ bool NonblockingQueue::try_pop(T** node_ptr) { // Any further try_pops will consider the queue empty until a // push/append completes by installing a new head. - // Attempt to change the queue tail from result to NULL. Failure of the - // cmpxchg indicates that a concurrent push/append updated the tail first. - // That operation will eventually recognize the old tail (our result) is - // no longer in the list and update head from the list being appended. - Atomic::cmpxchg(&_tail, result, (T*)NULL); + // The order of the two cmpxchgs doesn't matter algorithmically, but + // dealing with _head first gives a stronger invariant in append, and is + // also consistent with [Clause 1b]. // Attempt to change the queue head from result to NULL. Failure of the // cmpxchg indicates a concurrent operation updated _head first. That - // could be either a push/extend or a try_pop in [Clause 1b]. + // could be either a push/append or a try_pop in [Clause 1b]. Atomic::cmpxchg(&_head, result, (T*)NULL); + // Attempt to change the queue tail from result to NULL. Failure of the + // cmpxchg indicates that a concurrent push/append updated _tail first. + // That operation will eventually recognize the old tail (our result) is + // no longer in the list and update _head from the list being appended. + Atomic::cmpxchg(&_tail, result, (T*)NULL); + // The queue has been restored to order, and we can return the result. *node_ptr = result; return true; -- GitLab From fb17a8ece0a3593c51a8be60533916bf70778a93 Mon Sep 17 00:00:00 2001 From: Quan Anh Mai Date: Tue, 8 Feb 2022 23:38:09 +0000 Subject: [PATCH 179/400] 8278947: Support for array constants in constant table Reviewed-by: kvn, vlivanov --- src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp | 20 +++ src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp | 2 + src/hotspot/cpu/x86/x86.ad | 161 ++++++------------ src/hotspot/share/asm/assembler.hpp | 27 ++- src/hotspot/share/opto/constantTable.cpp | 137 ++++++++------- src/hotspot/share/opto/constantTable.hpp | 25 ++- 6 files changed, 200 insertions(+), 172 deletions(-) diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp index 65166197616..1f86ac0ebb9 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp @@ -1493,6 +1493,26 @@ void C2_MacroAssembler::load_vector_mask(KRegister dst, XMMRegister src, XMMRegi } } +void C2_MacroAssembler::load_vector(XMMRegister dst, Address src, int vlen_in_bytes) { + switch (vlen_in_bytes) { + case 4: movdl(dst, src); break; + case 8: movq(dst, src); break; + case 16: movdqu(dst, src); break; + case 32: vmovdqu(dst, src); break; + case 64: evmovdquq(dst, src, Assembler::AVX_512bit); break; + default: ShouldNotReachHere(); + } +} + +void C2_MacroAssembler::load_vector(XMMRegister dst, AddressLiteral src, int vlen_in_bytes, Register rscratch) { + if (reachable(src)) { + load_vector(dst, as_Address(src), vlen_in_bytes); + } else { + lea(rscratch, src); + load_vector(dst, Address(rscratch, 0), vlen_in_bytes); + } +} + void C2_MacroAssembler::load_iota_indices(XMMRegister dst, Register scratch, int vlen_in_bytes) { ExternalAddress addr(StubRoutines::x86::vector_iota_indices()); if (vlen_in_bytes == 4) { diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp index b97c1ed607d..3df87043f09 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp @@ -144,6 +144,8 @@ public: void load_vector_mask(XMMRegister dst, XMMRegister src, int vlen_in_bytes, BasicType elem_bt, bool is_legacy); void load_vector_mask(KRegister dst, XMMRegister src, XMMRegister xtmp, Register tmp, bool novlbwdq, int vlen_enc); + void load_vector(XMMRegister dst, Address src, int vlen_in_bytes); + void load_vector(XMMRegister dst, AddressLiteral src, int vlen_in_bytes, Register rscratch = rscratch1); void load_iota_indices(XMMRegister dst, Register scratch, int vlen_in_bytes); // Reductions for vectors of bytes, shorts, ints, longs, floats, and doubles. diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index a9dc2997e21..664f630a8cd 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -2552,15 +2552,21 @@ void vec_spill_helper(CodeBuffer *cbuf, bool is_load, } } -static inline jlong replicate8_imm(int con, int width) { - // Load a constant of "width" (in bytes) and replicate it to fill 64bit. - assert(width == 1 || width == 2 || width == 4, "only byte, short or int types here"); - int bit_width = width * 8; - jlong val = con; - val &= (((jlong) 1) << bit_width) - 1; // mask off sign bits - while(bit_width < 64) { - val |= (val << bit_width); - bit_width <<= 1; +template +static inline GrowableArray* vreplicate_imm(BasicType bt, T con, int len) { + GrowableArray* val = new GrowableArray(len); + jvalue ele; + switch (bt) { + case T_BYTE: ele.b = con; break; + case T_SHORT: ele.s = con; break; + case T_INT: ele.i = con; break; + case T_LONG: ele.j = con; break; + case T_FLOAT: ele.f = con; break; + case T_DOUBLE: ele.d = con; break; + default: ShouldNotReachHere(); + } + for (int i = 0; i < len; i++) { + val->append(ele); } return val; } @@ -3824,14 +3830,7 @@ instruct loadV(vec dst, memory mem) %{ ins_cost(125); format %{ "load_vector $dst,$mem" %} ins_encode %{ - switch (Matcher::vector_length_in_bytes(this)) { - case 4: __ movdl ($dst$$XMMRegister, $mem$$Address); break; - case 8: __ movq ($dst$$XMMRegister, $mem$$Address); break; - case 16: __ movdqu ($dst$$XMMRegister, $mem$$Address); break; - case 32: __ vmovdqu ($dst$$XMMRegister, $mem$$Address); break; - case 64: __ evmovdqul($dst$$XMMRegister, $mem$$Address, Assembler::AVX_512bit); break; - default: ShouldNotReachHere(); - } + __ load_vector($dst$$XMMRegister, $mem$$Address, Matcher::vector_length_in_bytes(this)); %} ins_pipe( pipe_slow ); %} @@ -4009,43 +4008,12 @@ instruct ReplB_imm(vec dst, immI con) %{ match(Set dst (ReplicateB con)); format %{ "replicateB $dst,$con" %} ins_encode %{ - uint vlen = Matcher::vector_length(this); - InternalAddress const_addr = $constantaddress(replicate8_imm($con$$constant, 1)); - if (vlen == 4) { - __ movdl($dst$$XMMRegister, const_addr); - } else { - __ movq($dst$$XMMRegister, const_addr); - if (vlen >= 16) { - if (VM_Version::supports_avx2()) { - int vlen_enc = vector_length_encoding(this); - __ vpbroadcastq($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); - } else { - assert(vlen == 16, "sanity"); - __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister); - } - } - } + InternalAddress addr = $constantaddress(T_BYTE, vreplicate_imm(T_BYTE, $con$$constant, Matcher::vector_length(this))); + __ load_vector($dst$$XMMRegister, addr, Matcher::vector_length_in_bytes(this)); %} ins_pipe( pipe_slow ); %} -// Replicate byte scalar zero to be vector -instruct ReplB_zero(vec dst, immI_0 zero) %{ - match(Set dst (ReplicateB zero)); - format %{ "replicateB $dst,$zero" %} - ins_encode %{ - uint vlen = Matcher::vector_length(this); - if (vlen <= 16) { - __ pxor($dst$$XMMRegister, $dst$$XMMRegister); - } else { - // Use vpxor since AVX512F does not have 512bit vxorpd (requires AVX512DQ). - int vlen_enc = vector_length_encoding(this); - __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); - } - %} - ins_pipe( fpu_reg_reg ); -%} - // ====================ReplicateS======================================= instruct ReplS_reg(vec dst, rRegI src) %{ @@ -4091,39 +4059,10 @@ instruct ReplS_imm(vec dst, immI con) %{ match(Set dst (ReplicateS con)); format %{ "replicateS $dst,$con" %} ins_encode %{ - uint vlen = Matcher::vector_length(this); - InternalAddress const_addr = $constantaddress(replicate8_imm($con$$constant, 2)); - if (vlen == 2) { - __ movdl($dst$$XMMRegister, const_addr); - } else { - __ movq($dst$$XMMRegister, const_addr); - if (vlen >= 8) { - if (VM_Version::supports_avx2()) { - int vlen_enc = vector_length_encoding(this); - __ vpbroadcastw($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); - } else { - assert(vlen == 8, "sanity"); - __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister); - } - } - } - %} - ins_pipe( fpu_reg_reg ); -%} - -instruct ReplS_zero(vec dst, immI_0 zero) %{ - match(Set dst (ReplicateS zero)); - format %{ "replicateS $dst,$zero" %} - ins_encode %{ - uint vlen = Matcher::vector_length(this); - if (vlen <= 8) { - __ pxor($dst$$XMMRegister, $dst$$XMMRegister); - } else { - int vlen_enc = vector_length_encoding(this); - __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); - } + InternalAddress addr = $constantaddress(T_SHORT, vreplicate_imm(T_SHORT, $con$$constant, Matcher::vector_length(this))); + __ load_vector($dst$$XMMRegister, addr, Matcher::vector_length_in_bytes(this)); %} - ins_pipe( fpu_reg_reg ); + ins_pipe( pipe_slow ); %} // ====================ReplicateI======================================= @@ -4173,30 +4112,21 @@ instruct ReplI_imm(vec dst, immI con) %{ match(Set dst (ReplicateI con)); format %{ "replicateI $dst,$con" %} ins_encode %{ - uint vlen = Matcher::vector_length(this); - InternalAddress const_addr = $constantaddress(replicate8_imm($con$$constant, 4)); - if (vlen <= 4) { - __ movq($dst$$XMMRegister, const_addr); - if (vlen == 4) { - __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister); - } - } else { - assert(VM_Version::supports_avx2(), "sanity"); - int vlen_enc = vector_length_encoding(this); - __ movq($dst$$XMMRegister, const_addr); - __ vpbroadcastd($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); - } + InternalAddress addr = $constantaddress(T_INT, vreplicate_imm(T_INT, $con$$constant, Matcher::vector_length(this))); + __ load_vector($dst$$XMMRegister, addr, Matcher::vector_length_in_bytes(this)); %} ins_pipe( pipe_slow ); %} -// Replicate integer (4 byte) scalar zero to be vector +// Replicate scalar zero to be vector instruct ReplI_zero(vec dst, immI_0 zero) %{ + match(Set dst (ReplicateB zero)); + match(Set dst (ReplicateS zero)); match(Set dst (ReplicateI zero)); format %{ "replicateI $dst,$zero" %} ins_encode %{ - uint vlen = Matcher::vector_length(this); - if (vlen <= 4) { + uint vsize = Matcher::vector_length_in_bytes(this); + if (vsize <= 16) { __ pxor($dst$$XMMRegister, $dst$$XMMRegister); } else { int vlen_enc = vector_length_encoding(this); @@ -4327,17 +4257,8 @@ instruct ReplL_imm(vec dst, immL con) %{ match(Set dst (ReplicateL con)); format %{ "replicateL $dst,$con" %} ins_encode %{ - uint vlen = Matcher::vector_length(this); - InternalAddress const_addr = $constantaddress($con); - if (vlen == 2) { - __ movq($dst$$XMMRegister, const_addr); - __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister); - } else { - assert(VM_Version::supports_avx2(), "sanity"); - int vlen_enc = vector_length_encoding(this); - __ movq($dst$$XMMRegister, const_addr); - __ vpbroadcastq($dst$$XMMRegister, $dst$$XMMRegister, vlen_enc); - } + InternalAddress addr = $constantaddress(T_LONG, vreplicate_imm(T_LONG, $con$$constant, Matcher::vector_length(this))); + __ load_vector($dst$$XMMRegister, addr, Matcher::vector_length_in_bytes(this)); %} ins_pipe( pipe_slow ); %} @@ -4407,6 +4328,17 @@ instruct ReplF_mem(vec dst, memory mem) %{ ins_pipe( pipe_slow ); %} +// Replicate float scalar immediate to be vector by loading from const table. +instruct ReplF_imm(vec dst, immF con) %{ + match(Set dst (ReplicateF con)); + format %{ "replicateF $dst,$con" %} + ins_encode %{ + InternalAddress addr = $constantaddress(T_FLOAT, vreplicate_imm(T_FLOAT, $con$$constant, Matcher::vector_length(this))); + __ load_vector($dst$$XMMRegister, addr, Matcher::vector_length_in_bytes(this)); + %} + ins_pipe( pipe_slow ); +%} + instruct ReplF_zero(vec dst, immF0 zero) %{ match(Set dst (ReplicateF zero)); format %{ "replicateF $dst,$zero" %} @@ -4461,6 +4393,17 @@ instruct ReplD_mem(vec dst, memory mem) %{ ins_pipe( pipe_slow ); %} +// Replicate double (8 byte) scalar immediate to be vector by loading from const table. +instruct ReplD_imm(vec dst, immD con) %{ + match(Set dst (ReplicateD con)); + format %{ "replicateD $dst,$con" %} + ins_encode %{ + InternalAddress addr = $constantaddress(T_DOUBLE, vreplicate_imm(T_DOUBLE, $con$$constant, Matcher::vector_length(this))); + __ load_vector($dst$$XMMRegister, addr, Matcher::vector_length_in_bytes(this)); + %} + ins_pipe( pipe_slow ); +%} + instruct ReplD_zero(vec dst, immD0 zero) %{ match(Set dst (ReplicateD zero)); format %{ "replicateD $dst,$zero" %} diff --git a/src/hotspot/share/asm/assembler.hpp b/src/hotspot/share/asm/assembler.hpp index 10fa79eb30a..dc38a53b031 100644 --- a/src/hotspot/share/asm/assembler.hpp +++ b/src/hotspot/share/asm/assembler.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -429,6 +429,31 @@ class AbstractAssembler : public ResourceObj { } return ptr; } + address array_constant(BasicType bt, GrowableArray* c) { + CodeSection* c1 = _code_section; + int len = c->length(); + int size = type2aelembytes(bt) * len; + address ptr = start_a_const(size, MIN2(round_up_power_of_2(size), 8)); + if (ptr != NULL) { + for (int i = 0; i < len; i++) { + jvalue e = c->at(i); + switch(bt) { + case T_BOOLEAN: emit_int8(e.z); break; + case T_BYTE: emit_int8(e.b); break; + case T_CHAR: emit_int16(e.c); break; + case T_SHORT: emit_int16(e.s); break; + case T_INT: emit_int32(e.i); break; + case T_LONG: emit_int64(e.j); break; + case T_FLOAT: emit_float(e.f); break; + case T_DOUBLE: emit_double(e.d); break; + default: + ShouldNotReachHere(); + } + } + end_a_const(c1); + } + return ptr; + } // Bang stack to trigger StackOverflowError at a safe location // implementation delegates to machine-specific bang_stack_with_offset diff --git a/src/hotspot/share/opto/constantTable.cpp b/src/hotspot/share/opto/constantTable.cpp index 285c273bb22..c3bb5c97730 100644 --- a/src/hotspot/share/opto/constantTable.cpp +++ b/src/hotspot/share/opto/constantTable.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -35,12 +35,15 @@ bool ConstantTable::Constant::operator==(const Constant& other) { if (type() != other.type() ) return false; if (can_be_reused() != other.can_be_reused()) return false; + if (is_array() || other.is_array()) { + return is_array() && other.is_array() && _v._array == other._v._array; + } // For floating point values we compare the bit pattern. switch (type()) { - case T_INT: - case T_FLOAT: return (_v._value.i == other._v._value.i); - case T_LONG: - case T_DOUBLE: return (_v._value.j == other._v._value.j); + case T_INT: return (_v._value.i == other._v._value.i); + case T_FLOAT: return jint_cast(_v._value.f) == jint_cast(other._v._value.f); + case T_LONG: return (_v._value.j == other._v._value.j); + case T_DOUBLE: return jlong_cast(_v._value.d) == jlong_cast(other._v._value.d); case T_OBJECT: case T_ADDRESS: return (_v._value.l == other._v._value.l); case T_VOID: return (_v._value.l == other._v._value.l); // jump-table entries @@ -56,8 +59,11 @@ int ConstantTable::qsort_comparator(Constant* a, Constant* b) { return 0; } -static int type_to_size_in_bytes(BasicType t) { - switch (t) { +static int constant_size(ConstantTable::Constant* con) { + if (con->is_array()) { + return type2aelembytes(con->type()) * con->get_array()->length(); + } + switch (con->type()) { case T_INT: return sizeof(jint ); case T_LONG: return sizeof(jlong ); case T_FLOAT: return sizeof(jfloat ); @@ -96,8 +102,9 @@ void ConstantTable::calculate_offsets_and_size() { Constant* con = _constants.adr_at(i); // Align offset for type. - int typesize = type_to_size_in_bytes(con->type()); - offset = align_up(offset, typesize); + int typesize = constant_size(con); + assert(typesize <= 8 || con->is_array(), "sanity"); + offset = align_up(offset, MIN2(round_up_power_of_2(typesize), 8)); con->set_offset(offset); // set constant's offset if (con->type() == T_VOID) { @@ -119,62 +126,66 @@ bool ConstantTable::emit(CodeBuffer& cb) const { for (int i = 0; i < _constants.length(); i++) { Constant con = _constants.at(i); address constant_addr = NULL; - switch (con.type()) { - case T_INT: constant_addr = _masm.int_constant( con.get_jint() ); break; - case T_LONG: constant_addr = _masm.long_constant( con.get_jlong() ); break; - case T_FLOAT: constant_addr = _masm.float_constant( con.get_jfloat() ); break; - case T_DOUBLE: constant_addr = _masm.double_constant(con.get_jdouble()); break; - case T_OBJECT: { - jobject obj = con.get_jobject(); - int oop_index = _masm.oop_recorder()->find_index(obj); - constant_addr = _masm.address_constant((address) obj, oop_Relocation::spec(oop_index)); - break; - } - case T_ADDRESS: { - address addr = (address) con.get_jobject(); - constant_addr = _masm.address_constant(addr); - break; - } - // We use T_VOID as marker for jump-table entries (labels) which - // need an internal word relocation. - case T_VOID: { - MachConstantNode* n = (MachConstantNode*) con.get_jobject(); - // Fill the jump-table with a dummy word. The real value is - // filled in later in fill_jump_table. - address dummy = (address) n; - constant_addr = _masm.address_constant(dummy); - if (constant_addr == NULL) { - return false; + if (con.is_array()) { + constant_addr = _masm.array_constant(con.type(), con.get_array()); + } else { + switch (con.type()) { + case T_INT: constant_addr = _masm.int_constant( con.get_jint() ); break; + case T_LONG: constant_addr = _masm.long_constant( con.get_jlong() ); break; + case T_FLOAT: constant_addr = _masm.float_constant( con.get_jfloat() ); break; + case T_DOUBLE: constant_addr = _masm.double_constant(con.get_jdouble()); break; + case T_OBJECT: { + jobject obj = con.get_jobject(); + int oop_index = _masm.oop_recorder()->find_index(obj); + constant_addr = _masm.address_constant((address) obj, oop_Relocation::spec(oop_index)); + break; } - assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), - "must be: %d == %d", (int)(constant_addr - _masm.code()->consts()->start()), (int)(con.offset())); - - // Expand jump-table - address last_addr = NULL; - for (uint j = 1; j < n->outcnt(); j++) { - last_addr = _masm.address_constant(dummy + j); - if (last_addr == NULL) { + case T_ADDRESS: { + address addr = (address) con.get_jobject(); + constant_addr = _masm.address_constant(addr); + break; + } + // We use T_VOID as marker for jump-table entries (labels) which + // need an internal word relocation. + case T_VOID: { + MachConstantNode* n = (MachConstantNode*) con.get_jobject(); + // Fill the jump-table with a dummy word. The real value is + // filled in later in fill_jump_table. + address dummy = (address) n; + constant_addr = _masm.address_constant(dummy); + if (constant_addr == NULL) { return false; } - } + assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), + "must be: %d == %d", (int)(constant_addr - _masm.code()->consts()->start()), (int)(con.offset())); + + // Expand jump-table + address last_addr = NULL; + for (uint j = 1; j < n->outcnt(); j++) { + last_addr = _masm.address_constant(dummy + j); + if (last_addr == NULL) { + return false; + } + } #ifdef ASSERT - address start = _masm.code()->consts()->start(); - address new_constant_addr = last_addr - ((n->outcnt() - 1) * sizeof(address)); - // Expanding the jump-table could result in an expansion of the const code section. - // In that case, we need to check if the new constant address matches the offset. - assert((constant_addr - start == con.offset()) || (new_constant_addr - start == con.offset()), - "must be: %d == %d or %d == %d (after an expansion)", (int)(constant_addr - start), (int)(con.offset()), - (int)(new_constant_addr - start), (int)(con.offset())); + address start = _masm.code()->consts()->start(); + address new_constant_addr = last_addr - ((n->outcnt() - 1) * sizeof(address)); + // Expanding the jump-table could result in an expansion of the const code section. + // In that case, we need to check if the new constant address matches the offset. + assert((constant_addr - start == con.offset()) || (new_constant_addr - start == con.offset()), + "must be: %d == %d or %d == %d (after an expansion)", (int)(constant_addr - start), (int)(con.offset()), + (int)(new_constant_addr - start), (int)(con.offset())); #endif - continue; // Loop - } - case T_METADATA: { - Metadata* obj = con.get_metadata(); - int metadata_index = _masm.oop_recorder()->find_index(obj); - constant_addr = _masm.address_constant((address) obj, metadata_Relocation::spec(metadata_index)); - break; - } - default: ShouldNotReachHere(); + continue; // Loop + } + case T_METADATA: { + Metadata* obj = con.get_metadata(); + int metadata_index = _masm.oop_recorder()->find_index(obj); + constant_addr = _masm.address_constant((address) obj, metadata_Relocation::spec(metadata_index)); + break; + } + default: ShouldNotReachHere(); + } } if (constant_addr == NULL) { @@ -218,6 +229,12 @@ ConstantTable::Constant ConstantTable::add(Metadata* metadata) { return con; } +ConstantTable::Constant ConstantTable::add(MachConstantNode* n, BasicType bt, GrowableArray* array) { + Constant con(bt, array); + add(con); + return con; +} + ConstantTable::Constant ConstantTable::add(MachConstantNode* n, MachOper* oper) { jvalue value; BasicType type = oper->type()->basic_type(); diff --git a/src/hotspot/share/opto/constantTable.hpp b/src/hotspot/share/opto/constantTable.hpp index fe0d0e3f1a5..1452a27d046 100644 --- a/src/hotspot/share/opto/constantTable.hpp +++ b/src/hotspot/share/opto/constantTable.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -38,18 +38,21 @@ public: class Constant { private: BasicType _type; + bool _is_array; union { jvalue _value; Metadata* _metadata; + GrowableArray* _array; } _v; int _offset; // offset of this constant (in bytes) relative to the constant table base. float _freq; bool _can_be_reused; // true (default) if the value can be shared with other users. public: - Constant() : _type(T_ILLEGAL), _offset(-1), _freq(0.0f), _can_be_reused(true) { _v._value.l = 0; } + Constant() : _type(T_ILLEGAL), _is_array(false), _offset(-1), _freq(0.0f), _can_be_reused(true) { _v._value.l = 0; } Constant(BasicType type, jvalue value, float freq = 0.0f, bool can_be_reused = true) : _type(type), + _is_array(false), _offset(-1), _freq(freq), _can_be_reused(can_be_reused) @@ -59,16 +62,31 @@ public: } Constant(Metadata* metadata, bool can_be_reused = true) : _type(T_METADATA), + _is_array(false), _offset(-1), _freq(0.0f), _can_be_reused(can_be_reused) { _v._metadata = metadata; } + Constant(BasicType type, GrowableArray* array) : + _type(type), + _is_array(true), + _offset(-1), + _freq(0.0f), + _can_be_reused(false) + { + assert(is_java_primitive(type), "not applicable for %s", type2name(type)); + _v._array = new GrowableArray(array->length()); + for (jvalue ele : *array) { + _v._array->append(ele); + } + } bool operator==(const Constant& other); BasicType type() const { return _type; } + bool is_array() const { return _is_array; } jint get_jint() const { return _v._value.i; } jlong get_jlong() const { return _v._value.j; } @@ -78,6 +96,8 @@ public: Metadata* get_metadata() const { return _v._metadata; } + GrowableArray* get_array() const { return _v._array; } + int offset() const { return _offset; } void set_offset(int offset) { _offset = offset; } @@ -124,6 +144,7 @@ public: void add(Constant& con); Constant add(MachConstantNode* n, BasicType type, jvalue value); Constant add(Metadata* metadata); + Constant add(MachConstantNode* n, BasicType bt, GrowableArray* array); Constant add(MachConstantNode* n, MachOper* oper); Constant add(MachConstantNode* n, jint i) { jvalue value; value.i = i; -- GitLab From 2f46af05ce2d43e19e0095680eb3a52fd904c774 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Wed, 9 Feb 2022 01:26:42 +0000 Subject: [PATCH 180/400] 8280132: Incorrect comparator com.sun.beans.introspect.MethodInfo.MethodOrder Reviewed-by: prr --- .../com/sun/beans/introspect/MethodInfo.java | 20 +- .../Introspector/MethodOrderException.java | 1537 ++++++++++++++++- 2 files changed, 1528 insertions(+), 29 deletions(-) diff --git a/src/java.desktop/share/classes/com/sun/beans/introspect/MethodInfo.java b/src/java.desktop/share/classes/com/sun/beans/introspect/MethodInfo.java index e5e79dc2a2f..5216f4423d4 100644 --- a/src/java.desktop/share/classes/com/sun/beans/introspect/MethodInfo.java +++ b/src/java.desktop/share/classes/com/sun/beans/introspect/MethodInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -98,10 +98,7 @@ final class MethodInfo { /** * A comparator that defines a total order so that methods have the same - * name and identical signatures appear next to each others. The methods are - * sorted in such a way that methods which override each other will sit next - * to each other, with the overridden method last - e.g. is Integer getFoo() - * placed before Object getFoo(). + * name and identical signatures appear next to each others. **/ private static final class MethodOrder implements Comparator { @@ -132,18 +129,7 @@ final class MethodInfo { } final Class aret = a.getReturnType(); final Class bret = b.getReturnType(); - if (aret == bret) { - return 0; - } - - // Super type comes last: Integer, Number, Object - if (aret.isAssignableFrom(bret)) { - return 1; - } - if (bret.isAssignableFrom(aret)) { - return -1; - } - return aret.getName().compareTo(bret.getName()); + return aret == bret ? 0 : aret.getName().compareTo(bret.getName()); } static final MethodOrder instance = new MethodOrder(); diff --git a/test/jdk/java/beans/Introspector/MethodOrderException.java b/test/jdk/java/beans/Introspector/MethodOrderException.java index d6c79b5d768..b69981002e6 100644 --- a/test/jdk/java/beans/Introspector/MethodOrderException.java +++ b/test/jdk/java/beans/Introspector/MethodOrderException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -35,40 +35,1553 @@ import java.util.RandomAccess; /** * @test - * @bug 8211147 + * @bug 8211147 8280132 * @modules java.desktop/com.sun.beans.introspect:open */ public final class MethodOrderException { public static void main(final String[] args) throws Exception { - // Public API, fails rarely - testPublicAPI(); - // Test using internal API, fails always - testPrivateAPI(); + for (Class beanClass : List.of(D.class, X.class, A_258.class)) { + // Public API, fails rarely + testPublicAPI(beanClass); + // Test using internal API, fails always + testPrivateAPI(beanClass); + } } - private static void testPublicAPI() throws Exception { - Introspector.getBeanInfo(X.class); + private static void testPublicAPI(Class beanClass) throws Exception { + Introspector.getBeanInfo(beanClass); } - private static void testPrivateAPI() throws Exception { + private static void testPrivateAPI(Class beanClass) throws Exception { Class name = Class.forName( "com.sun.beans.introspect.MethodInfo$MethodOrder"); Field instance = name.getDeclaredField("instance"); instance.setAccessible(true); Comparator o = (Comparator) instance.get(name); - List methods = List.of(X.class.getDeclaredMethods()); + List methods = List.of(beanClass.getDeclaredMethods()); methods.forEach(m1 -> { methods.forEach(m2 -> { if (o.compare(m1, m2) != -o.compare(m2, m1)) { - System.err.println("Method1 = "+ m1); - System.err.println("Method2 = "+ m2); + System.err.println("Method1 = " + m1); + System.err.println("Method2 = " + m2); throw new RuntimeException("Broken contract!"); } + methods.forEach(m3 -> { + if (o.compare(m1, m2) < 0 && o.compare(m2, m3) < 0) { + if (o.compare(m1, m3) >= 0) { + System.err.println("Method1 = " + m1); + System.err.println("Method2 = " + m2); + System.err.println("Method3 = " + m3); + throw new RuntimeException("Broken contract!"); + } + } + }); }); }); } + interface C1 { + C1 foo0(); + } + interface C2 { + C2 foo0(); + } + interface C3 extends C1 { + C3 foo0(); + } + interface D extends C3, C2, C1 { + D foo0(); + } + public interface A_239 { + } + public interface A_240 { + } + public interface A_000 { + } + public interface A_238 { + } + public interface A_035 extends A_195, A_106, A_240 { + A_035 a_040(); + A_035 a_000(); + A_035 a_018(); + } + public static class A_258 implements A_053, A_196, A_200, A_070, A_106, + A_057, A_094, A_098, A_105, A_107, A_097, A_093, A_214, A_215, + A_210, A_129, A_067, A_180, A_108, A_184, A_110, A_111, A_082, + A_221, A_172, A_171, A_168, A_139, A_143, A_140, A_075, A_081, + A_080, A_163, A_165, A_164, A_159, A_161, A_155, A_158, A_157, + A_156, A_195, A_197, A_114, A_213, A_236, A_220, A_201, A_035, + A_136, A_135, A_226, A_227, A_005, A_054, A_203, A_202, A_071, + A_115, A_113, A_112, A_058, A_095, A_096, A_099, A_100, A_237, + A_091, A_092, A_217, A_218, A_216, A_211, A_130, A_063, A_062, + A_064, A_065, A_066, A_061, A_060, A_181, A_208, A_207, A_209, + A_185, A_186, A_083, A_173, A_176, A_222, A_223, A_174, A_169, + A_153, A_154, A_194, A_190, A_104, A_132, A_141, A_142, A_166, + A_167, A_160, A_162, A_076, A_077, A_078, A_079, A_074, A_085, + A_192, A_188, A_134, A_138, A_137, A_228 { + @Override + public A_258 a_052() { + return null; + } + @Override + public A_258 a_071() { + return null; + } + @Override + public A_258 a_029() { + return null; + } + @Override + public A_258 a_046() { + return null; + } + @Override + public A_258 a_045() { + return null; + } + @Override + public A_258 a_047() { + return null; + } + @Override + public A_258 a_048() { + return null; + } + @Override + public A_258 a_049() { + return null; + } + @Override + public A_258 a_044() { + return null; + } + @Override + public A_258 a_043() { + return null; + } + @Override + public A_258 a_026() { + return null; + } + @Override + public A_258 a_027() { + return null; + } + @Override + public A_258 a_074() { + return null; + } + @Override + public A_258 a_079() { + return null; + } + @Override + public A_258 a_012() { + return null; + } + @Override + public A_258 a_100() { + return null; + } + @Override + public A_258 a_085() { + return null; + } + @Override + public A_258 a_084() { + return null; + } + @Override + public A_258 a_011() { + return null; + } + @Override + public A_258 a_059() { + return null; + } + @Override + public A_258 a_058() { + return null; + } + @Override + public A_258 a_080() { + return null; + } + @Override + public A_258 a_030() { + return null; + } + @Override + public A_258 a_031() { + return null; + } + @Override + public A_258 a_081() { + return null; + } + @Override + public A_258 a_077() { + return null; + } + @Override + public A_258 a_036() { + return null; + } + @Override + public A_258 a_056() { + return null; + } + @Override + public A_258 a_078() { + return null; + } + @Override + public A_258 a_076() { + return null; + } + @Override + public A_258 a_057() { + return null; + } + @Override + public A_258 a_005() { + return null; + } + @Override + public A_258 a_089() { + return null; + } + @Override + public A_258 a_088() { + return null; + } + @Override + public A_258 a_090() { + return null; + } + @Override + public A_258 a_072() { + return null; + } + @Override + public A_258 a_002() { + return null; + } + @Override + public A_258 a_040() { + return null; + } + @Override + public A_258 a_060() { + return null; + } + @Override + public A_258 a_061() { + return null; + } + @Override + public A_258 a_039() { + return null; + } + @Override + public A_258 a_032() { + return null; + } + @Override + public A_258 a_033() { + return null; + } + @Override + public A_258 a_000() { + return null; + } + @Override + public A_258 a_037() { + return null; + } + @Override + public A_258 a_014() { + return null; + } + @Override + public A_258 a_015() { + return null; + } + @Override + public A_258 a_016() { + return null; + } + @Override + public A_258 a_017() { + return null; + } + @Override + public A_258 a_091() { + return null; + } + @Override + public A_258 a_065() { + return null; + } + @Override + public A_258 a_066() { + return null; + } + @Override + public A_258 a_018() { + return null; + } + @Override + public A_258 a_093() { + return null; + } + @Override + public A_258 a_092() { + return null; + } + @Override + public A_258 a_095() { + return null; + } + @Override + public A_258 a_096() { + return null; + } + @Override + public A_258 a_069() { + return null; + } + } + public interface A_250 extends A_239 { + A_250 a_094(); + } + public interface A_253 extends A_239 { + A_253 a_000(); + } + public interface A_256 extends A_239 { + A_256 a_009(); + } + public interface A_248 extends A_239 { + A_248 a_022(); + } + public interface A_255 extends A_239 { + A_255 a_007(); + } + public interface A_241 extends A_248, A_250, A_251, A_249, A_239 { + } + public interface A_254 extends A_239 { + A_254 a_008(); + } + public interface A_251 extends A_239 { + A_251 a_097(); + } + public interface A_252 extends A_241, A_255, A_253, A_257, A_254, A_256, + A_239 { + A_252 a_022(); + A_252 a_094(); + A_252 a_097(); + A_252 a_087(); + } + public interface A_229 extends A_239 { + A_229 a_000(); + } + public interface A_232 extends A_239 { + } + public interface A_249 extends A_239 { + A_249 a_087(); + } + public interface A_230 extends A_239 { + } + public interface A_234 extends A_239 { + A_234 a_026(); + } + public interface A_037 extends A_239 { + A_037 a_013(); + } + public interface A_233 extends A_239 { + A_233 a_018(); + } + public interface A_231 extends A_239 { + A_231 a_007(); + } + public interface A_049 extends A_239 { + A_049 a_068(); + } + public interface A_257 extends A_239 { + A_257 a_018(); + } + public interface A_235 extends A_239 { + } + public interface A_040 extends A_239 { + A_040 a_025(); + } + public interface A_133 extends A_000, A_005, A_134, A_240 { + A_133 a_040(); + A_133 a_057(); + } + public interface A_001 extends A_239 { + A_001 a_020(); + } + public interface A_031 extends A_239 { + } + public interface A_089 extends A_239 { + A_089 a_098(); + } + public interface A_166 extends A_239 { + A_166 a_065(); + } + public interface A_054 extends A_239 { + A_054 a_000(); + } + public interface A_190 extends A_239 { + A_190 a_077(); + } + public interface A_169 extends A_239 { + A_169 a_037(); + } + public interface A_217 extends A_239 { + A_217 a_093(); + } + public interface A_078 extends A_239 { + A_078 a_016(); + } + public interface A_192 extends A_239 { + } + public interface A_222 extends A_239 { + A_222 a_095(); + } + public interface A_112 extends A_239 { + A_112 a_033(); + } + public interface A_066 extends A_239 { + A_066 a_049(); + } + public interface A_074 extends A_239 { + A_074 a_012(); + } + public interface A_003 extends A_239 { + A_003 a_039(); + } + public interface A_083 extends A_239 { + } + public interface A_050 extends A_239 { + A_050 a_070(); + } + public interface A_087 extends A_239 { + } + public interface A_058 extends A_239 { + } + public interface A_128 extends A_239 { + } + public interface A_092 extends A_239 { + } + public interface A_004 extends A_240 { + A_004 a_040(); + } + public interface A_115 extends A_239 { + A_115 a_039(); + } + public interface A_176 extends A_239 { + A_176 a_071(); + } + public interface A_162 extends A_239 { + } + public interface A_132 extends A_239 { + A_132 a_056(); + } + public interface A_064 extends A_239 { + A_064 a_047(); + } + public interface A_021 extends A_239 { + } + public interface A_160 extends A_239 { + } + public interface A_141 extends A_239 { + A_141 a_060(); + } + public interface A_091 extends A_239 { + A_091 a_026(); + } + public interface A_034 extends A_239 { + A_034 a_084(); + } + public interface A_151 extends A_239 { + } + public interface A_026 extends A_239 { + A_026 a_026(); + } + public interface A_130 extends A_239 { + A_130 a_052(); + } + public interface A_242 extends A_239 { + A_242 a_001(); + } + public interface A_205 extends A_239 { + A_205 a_086(); + } + public interface A_048 extends A_239 { + A_048 a_065(); + } + public interface A_044 extends A_240 { + A_044 a_040(); + } + public interface A_023 extends A_239 { + } + public interface A_027 extends A_239 { + } + public interface A_138 extends A_239 { + A_138 a_059(); + } + public interface A_024 extends A_239 { + A_024 a_011(); + } + public interface A_038 extends A_239 { + A_038 a_021(); + } + public interface A_016 extends A_239 { + } + public interface A_118 extends A_239 { + A_118 a_045(); + } + public interface A_071 extends A_239 { + A_071 a_011(); + } + public interface A_203 extends A_239 { + A_203 a_084(); + } + public interface A_137 extends A_239 { + } + public interface A_119 extends A_239 { + A_119 a_046(); + } + public interface A_145 extends A_239 { + } + public interface A_045 extends A_239 { + A_045 a_041(); + } + public interface A_069 extends A_239 { + A_069 a_010(); + } + public interface A_150 extends A_239 { + } + public interface A_047 extends A_239 { + A_047 a_057(); + } + public interface A_179 extends A_239 { + } + public interface A_207 extends A_239 { + A_207 a_088(); + } + public interface A_228 extends A_239 { + A_228 a_100(); + } + public interface A_005 extends A_240 { + A_005 a_040(); + } + public interface A_030 extends A_239 { + A_030 a_039(); + } + public interface A_173 extends A_239 { + A_173 a_069(); + } + public interface A_060 extends A_239 { + A_060 a_043(); + } + public interface A_245 extends A_239 { + A_245 a_009(); + } + public interface A_042 extends A_239 { + A_042 a_035(); + } + public interface A_209 extends A_239 { + A_209 a_090(); + } + public interface A_216 extends A_239 { + } + public interface A_142 extends A_239 { + } + public interface A_246 extends A_239 { + A_246 a_019(); + } + public interface A_223 extends A_239 { + } + public interface A_211 extends A_239 { + A_211 a_091(); + } + public interface A_244 extends A_239 { + A_244 a_008(); + } + public interface A_019 extends A_239 { + A_019 a_050(); + } + public interface A_041 extends A_239 { + A_041 a_034(); + } + public interface A_208 extends A_239 { + A_208 a_089(); + } + public interface A_065 extends A_239 { + } + public interface A_127 extends A_239 { + A_127 a_083(); + } + public interface A_033 extends A_239 { + } + public interface A_153 extends A_239 { + } + public interface A_079 extends A_239 { + } + public interface A_025 extends A_239 { + } + public interface A_046 extends A_239 { + A_046 a_042(); + } + public interface A_002 extends A_239 { + } + public interface A_154 extends A_239 { + } + public interface A_077 extends A_239 { + A_077 a_015(); + } + public interface A_121 extends A_239 { + A_121 a_053(); + } + public interface A_036 extends A_239 { + A_036 a_003(); + } + public interface A_225 extends A_239 { + A_225 a_054(); + } + public interface A_181 extends A_239 { + A_181 a_005(); + } + public interface A_134 extends A_239 { + A_134 a_057(); + } + public interface A_017 extends A_239 { + } + public interface A_194 extends A_239 { + A_194 a_081(); + } + public interface A_243 extends A_239 { + A_243 a_006(); + } + public interface A_015 extends A_239 { + A_015 a_004(); + } + public interface A_028 extends A_239 { + A_028 a_032(); + } + public interface A_218 extends A_239 { + } + public interface A_174 extends A_239 { + } + public interface A_039 extends A_239 { + A_039 a_023(); + } + public interface A_029 extends A_239 { + } + public interface A_095 extends A_239 { + A_095 a_029(); + } + public interface A_096 extends A_239 { + } + public interface A_124 extends A_239 { + A_124 a_028(); + } + public interface A_202 extends A_239 { + A_202 a_085(); + } + public interface A_186 extends A_239 { + } + public interface A_120 extends A_239 { + } + public interface A_076 extends A_239 { + A_076 a_014(); + } + public interface A_052 extends A_239 { + A_052 a_099(); + } + public interface A_056 extends A_239 { + } + public interface A_020 extends A_239 { + A_020 a_062(); + } + public interface A_018 extends A_239 { + A_018 a_045(); + } + public interface A_149 extends A_239 { + A_149 a_051(); + } + public interface A_022 extends A_239 { + A_022 a_075(); + } + public interface A_063 extends A_239 { + A_063 a_046(); + } + public interface A_043 extends A_239 { + A_043 a_038(); + } + public interface A_167 extends A_239 { + } + public interface A_085 extends A_239 { + A_085 a_018(); + } + public interface A_032 extends A_239 { + } + public interface A_188 extends A_239 { + A_188 a_076(); + } + public interface A_126 extends A_239 { + } + public interface A_113 extends A_239 { + A_113 a_032(); + } + public interface A_051 extends A_239 { + A_051 a_082(); + } + public interface A_185 extends A_239 { + A_185 a_074(); + } + public interface A_099 extends A_239 { + } + public interface A_062 extends A_239 { + A_062 a_045(); + } + public interface A_237 extends A_239 { + A_237 a_027(); + } + public interface A_100 extends A_239 { + } + public interface A_189 extends A_000, A_005, A_190, A_240 { + A_189 a_040(); + A_189 a_077(); + } + public interface A_061 extends A_239 { + A_061 a_044(); + } + public interface A_104 extends A_239 { + A_104 a_036(); + } + public interface A_084 extends A_000, A_005, A_085, A_240 { + A_084 a_040(); + A_084 a_018(); + } + public interface A_129 extends A_000, A_005, A_130, A_240 { + A_129 a_040(); + A_129 a_052(); + } + public interface A_086 extends A_000, A_005, A_087, A_089, A_240 { + A_086 a_040(); + A_086 a_024(); + A_086 a_098(); + } + public interface A_125 extends A_239 { + } + public interface A_212 extends A_053, A_084, A_005, A_054, A_085, A_217, + A_218, A_240 { + A_212 a_040(); + A_212 a_000(); + A_212 a_018(); + A_212 a_093(); + } + public interface A_171 extends A_170, A_175, A_005, A_173, A_176, A_174, + A_240 { + A_171 a_040(); + A_171 a_069(); + A_171 a_071(); + A_171 a_072(); + } + public interface A_247 extends A_239 { + } + public interface A_183 extends A_053, A_084, A_005, A_054, A_085, A_185, + A_186, A_240 { + A_183 a_040(); + A_183 a_000(); + A_183 a_018(); + A_183 a_074(); + } + public interface A_198 extends A_053, A_196, A_070, A_131, A_005, A_054, + A_203, A_071, A_132, A_240 { + A_198 a_040(); + A_198 a_000(); + A_198 a_084(); + A_198 a_011(); + A_198 a_056(); + } + public interface A_070 extends A_000, A_005, A_071, A_240 { + A_070 a_040(); + A_070 a_011(); + } + public interface A_109 extends A_106, A_212, A_005, A_115, A_113, A_112, + A_054, A_085, A_217, A_218, A_240 { + A_109 a_040(); + A_109 a_039(); + A_109 a_032(); + A_109 a_033(); + A_109 a_000(); + A_109 a_018(); + A_109 a_093(); + } + public interface A_158 extends A_159, A_161, A_152, A_005, A_054, A_160, + A_162, A_153, A_154, A_240 { + A_158 a_040(); + A_158 a_000(); + A_158 a_079(); + } + public interface A_110 extends A_106, A_212, A_183, A_005, A_054, A_085, + A_115, A_113, A_112, A_217, A_218, A_185, A_186, A_240 { + A_110 a_040(); + A_110 a_000(); + A_110 a_018(); + A_110 a_039(); + A_110 a_032(); + A_110 a_033(); + A_110 a_093(); + A_110 a_074(); + } + public interface A_200 extends A_000, A_005, A_202, A_240 { + A_200 a_040(); + A_200 a_085(); + } + public interface A_161 extends A_053, A_005, A_054, A_162, A_240 { + A_161 a_040(); + A_161 a_000(); + } + public interface A_175 extends A_000, A_005, A_176, A_240 { + A_175 a_040(); + A_175 a_071(); + } + public interface A_103 extends A_000, A_084, A_005, A_085, A_104, A_240 { + A_103 a_040(); + A_103 a_018(); + A_103 a_036(); + } + public interface A_093 extends A_090, A_152, A_005, A_054, A_085, A_091, + A_092, A_153, A_154, A_240 { + A_093 a_040(); + A_093 a_000(); + A_093 a_018(); + A_093 a_026(); + A_093 a_079(); + A_093 a_027(); + } + public interface A_204 extends A_000, A_005, A_205, A_240 { + A_204 a_040(); + A_204 a_086(); + } + public interface A_067 extends A_059, A_152, A_005, A_054, A_085, A_063, + A_062, A_064, A_065, A_066, A_061, A_060, A_153, A_154, A_240 { + A_067 a_040(); + A_067 a_000(); + A_067 a_018(); + A_067 a_046(); + A_067 a_045(); + A_067 a_047(); + A_067 a_049(); + A_067 a_044(); + A_067 a_043(); + A_067 a_079(); + } + public interface A_101 extends A_070, A_005, A_071, A_240 { + A_101 a_040(); + A_101 a_011(); + } + public interface A_224 extends A_000, A_225, A_240 { + A_224 a_054(); + A_224 a_040(); + } + public interface A_156 extends A_053, A_084, A_155, A_059, A_005, A_054, + A_085, A_160, A_162, A_063, A_062, A_064, A_065, A_066, A_061, + A_060, A_240 { + A_156 a_040(); + A_156 a_000(); + A_156 a_018(); + A_156 a_046(); + A_156 a_045(); + A_156 a_047(); + A_156 a_049(); + A_156 a_044(); + A_156 a_043(); + } + public interface A_122 extends A_116, A_152, A_005, A_054, A_085, A_121, + A_119, A_118, A_120, A_153, A_154, A_240 { + A_122 a_040(); + A_122 a_000(); + A_122 a_018(); + A_122 a_053(); + A_122 a_046(); + A_122 a_045(); + A_122 a_048(); + A_122 a_079(); + A_122 a_080(); + } + public interface A_184 extends A_183, A_152, A_005, A_054, A_085, A_185, + A_186, A_153, A_154, A_240 { + A_184 a_040(); + A_184 a_000(); + A_184 a_018(); + A_184 a_074(); + A_184 a_079(); + } + public interface A_180 extends A_000, A_181, A_240 { + A_180 a_005(); + A_180 a_040(); + } + public interface A_191 extends A_000, A_005, A_192, A_240 { + A_191 a_040(); + A_191 a_078(); + } + public interface A_107 extends A_106, A_094, A_005, A_115, A_113, A_112, + A_095, A_096, A_240 { + A_107 a_040(); + A_107 a_039(); + A_107 a_032(); + A_107 a_033(); + A_107 a_029(); + A_107 a_000(); + A_107 a_018(); + } + public interface A_102 extends A_196, A_005, A_203, A_240 { + A_102 a_040(); + A_102 a_084(); + } + public interface A_177 extends A_000, A_005, A_179, A_240 { + A_177 a_040(); + } + public interface A_123 extends A_195, A_005, A_054, A_124, A_127, A_128, + A_126, A_125, A_240 { + A_123 a_040(); + A_123 a_000(); + A_123 a_028(); + A_123 a_083(); + A_123 a_064(); + A_123 a_055(); + A_123 a_018(); + A_123 a_079(); + A_123 a_080(); + A_123 a_081(); + A_123 a_077(); + A_123 a_036(); + A_123 a_056(); + A_123 a_012(); + A_123 a_078(); + A_123 a_076(); + A_123 a_057(); + } + public interface A_088 extends A_106, A_086, A_240 { + A_088 a_040(); + A_088 a_039(); + A_088 a_032(); + A_088 a_033(); + A_088 a_000(); + A_088 a_018(); + A_088 a_024(); + A_088 a_098(); + } + public interface A_094 extends A_084, A_005, A_085, A_095, A_096, A_240 { + A_094 a_040(); + A_094 a_018(); + A_094 a_029(); + } + public interface A_105 extends A_098, A_236, A_005, A_085, A_153, A_074, + A_099, A_100, A_240 { + A_105 a_040(); + A_105 a_018(); + A_105 a_079(); + A_105 a_012(); + A_105 a_030(); + A_105 a_031(); + A_105 a_000(); + A_105 a_081(); + A_105 a_077(); + A_105 a_036(); + A_105 a_056(); + A_105 a_078(); + A_105 a_076(); + A_105 a_057(); + } + public interface A_199 extends A_196, A_090, A_005, A_054, A_085, A_091, + A_092, A_203, A_240 { + A_199 a_040(); + A_199 a_000(); + A_199 a_018(); + A_199 a_026(); + A_199 a_084(); + A_199 a_027(); + } + public interface A_080 extends A_075, A_236, A_005, A_085, A_153, A_074, + A_076, A_077, A_078, A_079, A_240 { + A_080 a_040(); + A_080 a_018(); + A_080 a_079(); + A_080 a_012(); + A_080 a_014(); + A_080 a_015(); + A_080 a_016(); + A_080 a_000(); + A_080 a_080(); + A_080 a_081(); + A_080 a_077(); + A_080 a_036(); + A_080 a_056(); + A_080 a_078(); + A_080 a_076(); + A_080 a_057(); + } + public interface A_172 extends A_170, A_219, A_005, A_054, A_085, A_173, + A_222, A_223, A_174, A_240 { + A_172 a_040(); + A_172 a_000(); + A_172 a_018(); + A_172 a_069(); + A_172 a_095(); + A_172 a_072(); + } + public interface A_108 extends A_106, A_180, A_206, A_005, A_115, A_113, + A_112, A_181, A_208, A_207, A_209, A_240 { + A_108 a_040(); + A_108 a_039(); + A_108 a_032(); + A_108 a_033(); + A_108 a_005(); + A_108 a_089(); + A_108 a_088(); + A_108 a_090(); + A_108 a_000(); + A_108 a_018(); + } + public interface A_195 extends A_053, A_084, A_152, A_193, A_189, A_103, + A_131, A_073, A_191, A_187, A_133, A_005, A_054, A_085, A_153, + A_154, A_194, A_190, A_104, A_132, A_074, A_192, A_188, A_134, + A_240 { + A_195 a_040(); + A_195 a_000(); + A_195 a_018(); + A_195 a_079(); + A_195 a_080(); + A_195 a_081(); + A_195 a_077(); + A_195 a_036(); + A_195 a_056(); + A_195 a_012(); + A_195 a_078(); + A_195 a_076(); + A_195 a_057(); + } + public interface A_220 extends A_219, A_236, A_005, A_085, A_153, A_074, + A_240 { + A_220 a_040(); + A_220 a_018(); + A_220 a_079(); + A_220 a_012(); + A_220 a_000(); + A_220 a_095(); + A_220 a_080(); + A_220 a_081(); + A_220 a_077(); + A_220 a_036(); + A_220 a_056(); + A_220 a_078(); + A_220 a_076(); + A_220 a_057(); + } + public interface A_146 extends A_000, A_005, A_151, A_150, A_149, A_240 { + A_146 a_040(); + A_146 a_073(); + A_146 a_051(); + } + public interface A_090 extends A_000, A_053, A_084, A_005, A_054, A_085, + A_237, A_091, A_092, A_240 { + A_090 a_040(); + A_090 a_000(); + A_090 a_018(); + A_090 a_027(); + A_090 a_026(); + } + public interface A_057 extends A_106, A_058, A_240 { + A_057 a_002(); + A_057 a_040(); + A_057 a_039(); + A_057 a_032(); + A_057 a_033(); + A_057 a_000(); + A_057 a_018(); + } + public interface A_098 extends A_084, A_005, A_085, A_099, A_100, A_240 { + } + public interface A_136 extends A_084, A_005, A_085, A_138, A_137, A_240 { + } + public interface A_116 extends A_053, A_084, A_005, A_054, A_085, A_121, + A_119, A_118, A_120, A_240 { + A_116 a_040(); + A_116 a_000(); + A_116 a_018(); + A_116 a_053(); + A_116 a_046(); + A_116 a_045(); + A_116 a_048(); + } + public interface A_159 extends A_053, A_005, A_054, A_160, A_240 { + A_159 a_040(); + A_159 a_000(); + } + public interface A_140 extends A_139, A_236, A_005, A_085, A_153, A_074, + A_141, A_142, A_240 { + A_140 a_040(); + A_140 a_018(); + A_140 a_079(); + A_140 a_012(); + A_140 a_060(); + A_140 a_061(); + A_140 a_000(); + A_140 a_080(); + A_140 a_081(); + A_140 a_077(); + A_140 a_036(); + A_140 a_056(); + A_140 a_078(); + A_140 a_076(); + A_140 a_057(); + } + public interface A_178 extends A_177, A_144, A_005, A_179, A_145, A_240 { + A_178 a_040(); + } + public interface A_139 extends A_053, A_005, A_054, A_141, A_142, A_240 { + A_139 a_040(); + A_139 a_000(); + A_139 a_060(); + A_139 a_061(); + } + public interface A_165 extends A_163, A_152, A_005, A_054, A_166, A_167, + A_153, A_154, A_240 { + A_165 a_040(); + A_165 a_000(); + A_165 a_065(); + A_165 a_066(); + A_165 a_079(); + A_165 a_080(); + } + public interface A_053 extends A_000, A_238, A_005, A_054, A_240 { + A_053 a_040(); + A_053 a_000(); + } + public interface A_135 extends A_136, A_236, A_005, A_085, A_153, A_074, + A_138, A_137, A_240 { + A_135 a_040(); + A_135 a_018(); + A_135 a_079(); + A_135 a_012(); + A_135 a_059(); + A_135 a_058(); + A_135 a_000(); + A_135 a_081(); + A_135 a_077(); + A_135 a_036(); + A_135 a_056(); + A_135 a_078(); + A_135 a_076(); + A_135 a_057(); + } + public interface A_148 extends A_146, A_236, A_005, A_085, A_153, A_074, + A_240 { + A_148 a_040(); + A_148 a_018(); + A_148 a_079(); + A_148 a_012(); + A_148 a_051(); + A_148 a_000(); + A_148 a_081(); + A_148 a_077(); + A_148 a_036(); + A_148 a_056(); + A_148 a_078(); + A_148 a_076(); + A_148 a_057(); + } + public interface A_206 extends A_000, A_005, A_208, A_207, A_209, A_240 { + A_206 a_040(); + A_206 a_089(); + A_206 a_088(); + A_206 a_090(); + } + public interface A_215 extends A_000, A_005, A_216, A_240 { + A_215 a_040(); + A_215 a_092(); + } + public interface A_117 extends A_116, A_090, A_005, A_054, A_085, A_121, + A_119, A_118, A_120, A_091, A_092, A_240 { + A_117 a_040(); + A_117 a_000(); + A_117 a_018(); + A_117 a_053(); + A_117 a_046(); + A_117 a_045(); + A_117 a_048(); + A_117 a_026(); + A_117 a_027(); + } + public interface A_082 extends A_000, A_005, A_083, A_240 { + A_082 a_040(); + } + public interface A_182 extends A_053, A_084, A_152, A_193, A_189, A_005, + A_054, A_085, A_153, A_154, A_194, A_190, A_240 { + A_182 a_040(); + A_182 a_000(); + A_182 a_018(); + A_182 a_079(); + A_182 a_080(); + A_182 a_081(); + A_182 a_077(); + } + public interface A_055 extends A_000, A_005, A_056, A_240 { + } + public interface A_193 extends A_000, A_005, A_194, A_240 { + A_193 a_040(); + A_193 a_081(); + } + public interface A_214 extends A_212, A_152, A_005, A_054, A_085, A_217, + A_218, A_153, A_154, A_240 { + A_214 a_040(); + A_214 a_000(); + A_214 a_018(); + A_214 a_093(); + A_214 a_079(); + } + public interface A_059 extends A_053, A_084, A_005, A_054, A_085, A_063, + A_062, A_064, A_065, A_066, A_061, A_060, A_240 { + A_059 a_040(); + A_059 a_000(); + A_059 a_018(); + A_059 a_046(); + A_059 a_045(); + A_059 a_047(); + A_059 a_048(); + A_059 a_049(); + A_059 a_044(); + A_059 a_043(); + } + public interface A_226 extends A_000, A_228, A_240 { + A_226 a_100(); + A_226 a_040(); + } + public interface A_210 extends A_053, A_005, A_054, A_211, A_240 { + A_210 a_040(); + A_210 a_000(); + A_210 a_091(); + } + public interface A_073 extends A_000, A_005, A_074, A_240 { + A_073 a_040(); + A_073 a_012(); + } + public interface A_157 extends A_155, A_236, A_005, A_085, A_153, A_074, + A_160, A_162, A_240 { + A_157 a_040(); + A_157 a_018(); + A_157 a_079(); + A_157 a_012(); + A_157 a_000(); + A_157 a_081(); + A_157 a_077(); + A_157 a_036(); + A_157 a_056(); + A_157 a_078(); + A_157 a_076(); + A_157 a_057(); + } + public interface A_131 extends A_053, A_005, A_054, A_132, A_240 { + A_131 a_040(); + A_131 a_000(); + A_131 a_056(); + } + public interface A_152 extends A_053, A_005, A_054, A_153, A_154, A_240 { + A_152 a_040(); + A_152 a_000(); + A_152 a_079(); + } + public interface A_106 extends A_053, A_084, A_005, A_115, A_113, A_112, + A_240 { + A_106 a_040(); + A_106 a_039(); + A_106 a_032(); + A_106 a_033(); + A_106 a_000(); + A_106 a_018(); + } + public interface A_147 extends A_106, A_236, A_005, A_085, A_153, A_074, + A_240 { + A_147 a_040(); + A_147 a_018(); + A_147 a_012(); + A_147 a_039(); + A_147 a_032(); + A_147 a_033(); + A_147 a_000(); + A_147 a_081(); + A_147 a_077(); + A_147 a_036(); + A_147 a_056(); + A_147 a_078(); + A_147 a_076(); + A_147 a_057(); + } + public interface A_081 extends A_075, A_152, A_005, A_054, A_076, A_077, + A_078, A_079, A_153, A_154, A_240 { + A_081 a_040(); + A_081 a_000(); + A_081 a_014(); + A_081 a_015(); + A_081 a_016(); + A_081 a_079(); + A_081 a_080(); + } + public interface A_197 extends A_196, A_070, A_236, A_005, A_085, A_153, + A_074, A_203, A_071, A_240 { + A_197 a_040(); + A_197 a_018(); + A_197 a_079(); + A_197 a_012(); + A_197 a_084(); + A_197 a_011(); + A_197 a_000(); + A_197 a_081(); + A_197 a_077(); + A_197 a_036(); + A_197 a_056(); + A_197 a_078(); + A_197 a_076(); + A_197 a_057(); + } + public interface A_213 extends A_212, A_215, A_236, A_005, A_085, A_153, + A_074, A_240 { + A_213 a_040(); + A_213 a_018(); + A_213 a_079(); + A_213 a_012(); + A_213 a_000(); + A_213 a_093(); + A_213 a_092(); + A_213 a_081(); + A_213 a_077(); + A_213 a_036(); + A_213 a_056(); + A_213 a_078(); + A_213 a_076(); + A_213 a_057(); + } + public interface A_143 extends A_139, A_152, A_005, A_141, A_142, A_153, + A_154, A_240 { + A_143 a_040(); + A_143 a_060(); + A_143 a_061(); + A_143 a_079(); + A_143 a_080(); + A_143 a_000(); + } + public interface A_221 extends A_219, A_152, A_005, A_054, A_085, A_222, + A_223, A_153, A_154, A_240 { + A_221 a_040(); + A_221 a_000(); + A_221 a_018(); + A_221 a_095(); + A_221 a_079(); + A_221 a_080(); + } + public interface A_196 extends A_000, A_005, A_203, A_240 { + A_196 a_040(); + A_196 a_084(); + } + public interface A_155 extends A_159, A_161, A_005, A_054, A_160, A_162, + A_240 { + A_155 a_040(); + A_155 a_000(); + } + public interface A_097 extends A_094, A_152, A_005, A_085, A_095, A_096, + A_153, A_154, A_240 { + A_097 a_040(); + A_097 a_018(); + A_097 a_029(); + A_097 a_079(); + A_097 a_000(); + } + public interface A_219 extends A_053, A_084, A_005, A_054, A_085, A_222, + A_223, A_240 { + A_219 a_040(); + A_219 a_000(); + A_219 a_018(); + A_219 a_095(); + A_219 a_096(); + } + public interface A_068 extends A_053, A_005, A_054, A_069, A_240 { + A_068 a_040(); + A_068 a_000(); + A_068 a_010(); + } + public interface A_114 extends A_106, A_236, A_005, A_085, A_153, A_074, + A_115, A_113, A_240 { + A_114 a_040(); + A_114 a_018(); + A_114 a_079(); + A_114 a_012(); + A_114 a_039(); + A_114 a_032(); + A_114 a_033(); + A_114 a_000(); + A_114 a_080(); + A_114 a_081(); + A_114 a_077(); + A_114 a_036(); + A_114 a_056(); + A_114 a_078(); + A_114 a_076(); + A_114 a_057(); + } + public interface A_163 extends A_053, A_005, A_054, A_166, A_167, A_240 { + A_163 a_040(); + A_163 a_000(); + A_163 a_065(); + A_163 a_066(); + } + public interface A_187 extends A_000, A_005, A_188, A_240 { + A_187 a_040(); + A_187 a_076(); + } + public interface A_144 extends A_000, A_005, A_145, A_240 { + A_144 a_040(); + } + public interface A_111 extends A_106, A_212, A_219, A_170, A_005, A_054, + A_085, A_115, A_113, A_112, A_217, A_218, A_222, A_223, A_173, + A_240 { + A_111 a_040(); + A_111 a_000(); + A_111 a_018(); + A_111 a_039(); + A_111 a_032(); + A_111 a_033(); + A_111 a_093(); + A_111 a_095(); + A_111 a_069(); + } + public interface A_168 extends A_000, A_053, A_005, A_054, A_169, A_240 { + A_168 a_040(); + A_168 a_000(); + A_168 a_037(); + } + public interface A_227 extends A_226, A_236, A_005, A_085, A_153, A_074, + A_228, A_240 { + A_227 a_040(); + A_227 a_018(); + A_227 a_079(); + A_227 a_012(); + A_227 a_100(); + A_227 a_000(); + A_227 a_081(); + A_227 a_077(); + A_227 a_036(); + A_227 a_056(); + A_227 a_078(); + A_227 a_076(); + A_227 a_057(); + } + public interface A_075 extends A_053, A_005, A_054, A_076, A_077, A_078, + A_079, A_240 { + A_075 a_040(); + A_075 a_000(); + A_075 a_014(); + A_075 a_015(); + A_075 a_016(); + A_075 a_017(); + } + public interface A_008 extends A_239 { + A_008 a_040(); + } + public interface A_072 extends A_070, A_090, A_005, A_054, A_085, A_091, + A_092, A_071, A_240 { + A_072 a_040(); + A_072 a_000(); + A_072 a_018(); + A_072 a_026(); + A_072 a_011(); + A_072 a_027(); + } + public interface A_170 extends A_000, A_005, A_173, A_174, A_240 { + A_170 a_040(); + A_170 a_069(); + A_170 a_072(); + } + public interface A_012 extends A_239 { + A_012 a_063(); + } + public interface A_164 extends A_163, A_236, A_005, A_085, A_153, A_074, + A_166, A_167, A_240 { + A_164 a_040(); + A_164 a_018(); + A_164 a_079(); + A_164 a_012(); + A_164 a_065(); + A_164 a_066(); + A_164 a_000(); + A_164 a_080(); + A_164 a_081(); + A_164 a_077(); + A_164 a_036(); + A_164 a_056(); + A_164 a_078(); + A_164 a_076(); + A_164 a_057(); + } + public interface A_006 extends A_239 { + A_006 a_004(); + } + public interface A_007 extends A_239 { + } + public interface A_201 extends A_200, A_236, A_005, A_085, A_153, A_074, + A_240 { + A_201 a_040(); + A_201 a_018(); + A_201 a_079(); + A_201 a_012(); + A_201 a_085(); + A_201 a_000(); + A_201 a_081(); + A_201 a_077(); + A_201 a_036(); + A_201 a_056(); + A_201 a_078(); + A_201 a_076(); + A_201 a_057(); + } + public interface A_011 extends A_239 { + A_011 a_062(); + } + public interface A_014 extends A_239 { + A_014 a_075(); + } + public interface A_009 extends A_239 { + A_009 a_045(); + } + public interface A_010 extends A_239 { + A_010 a_050(); + } + public interface A_013 extends A_239 { + A_013 a_067(); + } + public interface A_236 extends A_195, A_005, A_085, A_153, A_074, A_240 { + A_236 a_040(); + A_236 a_018(); + A_236 a_079(); + A_236 a_012(); + A_236 a_000(); + A_236 a_081(); + A_236 a_077(); + A_236 a_036(); + A_236 a_056(); + A_236 a_078(); + A_236 a_076(); + A_236 a_057(); + } + interface X_1 { AbstractList x_8(); -- GitLab From 13f739d330e393f840d134f5327a025957e1f795 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Wed, 9 Feb 2022 04:10:37 +0000 Subject: [PATCH 181/400] 8280830: Change NonblockingQueue::try_pop variable named "result" Reviewed-by: dholmes --- .../utilities/nonblockingQueue.inline.hpp | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/hotspot/share/utilities/nonblockingQueue.inline.hpp b/src/hotspot/share/utilities/nonblockingQueue.inline.hpp index e16c8cb57d0..2845822b204 100644 --- a/src/hotspot/share/utilities/nonblockingQueue.inline.hpp +++ b/src/hotspot/share/utilities/nonblockingQueue.inline.hpp @@ -135,36 +135,36 @@ template bool NonblockingQueue::try_pop(T** node_ptr) { // We only need memory_order_consume. Upgrade it to "load_acquire" // as the memory_order_consume API is not ready for use yet. - T* result = Atomic::load_acquire(&_head); - if (result == NULL) { + T* old_head = Atomic::load_acquire(&_head); + if (old_head == NULL) { *node_ptr = NULL; return true; // Queue is empty. } - T* next_node = Atomic::load_acquire(next_ptr(*result)); + T* next_node = Atomic::load_acquire(next_ptr(*old_head)); if (!is_end(next_node)) { // [Clause 1] // There are several cases for next_node. // (1) next_node is the extension of the queue's list. - // (2) next_node is NULL, because a competing try_pop took result. + // (2) next_node is NULL, because a competing try_pop took old_head. // (3) next_node is the extension of some unrelated list, because a - // competing try_pop took result and put it in some other list. + // competing try_pop took old_head and put it in some other list. // - // Attempt to advance the list, replacing result with next_node in + // Attempt to advance the list, replacing old_head with next_node in // _head. The success or failure of that attempt, along with the value // of next_node, are used to partially determine which case we're in and // how to proceed. In particular, advancement will fail for case (3). - if (result != Atomic::cmpxchg(&_head, result, next_node)) { + if (old_head != Atomic::cmpxchg(&_head, old_head, next_node)) { // [Clause 1a] // The cmpxchg to advance the list failed; a concurrent try_pop won - // the race and claimed result. This can happen for any of the + // the race and claimed old_head. This can happen for any of the // next_node cases. return false; } else if (next_node == NULL) { // [Clause 1b] // The cmpxchg to advance the list succeeded, but a concurrent try_pop - // has already claimed result (see [Clause 2] - result was the last - // entry in the list) by nulling result's next field. The advance set + // has already claimed old_head (see [Clause 2] - old_head was the last + // entry in the list) by nulling old_head's next field. The advance set // _head to NULL, "helping" the competing try_pop. _head will remain // NULL until a subsequent push/append. This is a lost race, and we // report it as such for consistency, though we could report the queue @@ -174,17 +174,17 @@ bool NonblockingQueue::try_pop(T** node_ptr) { return false; } else { // [Clause 1c] - // Successfully advanced the list and claimed result. next_node was - // in the extension of the queue's list. Return result after + // Successfully advanced the list and claimed old_head. next_node was + // in the extension of the queue's list. Return old_head after // unlinking it from next_node. - set_next(*result, NULL); - *node_ptr = result; + set_next(*old_head, NULL); + *node_ptr = old_head; return true; } - } else if (is_end(Atomic::cmpxchg(next_ptr(*result), next_node, (T*)NULL))) { + } else if (is_end(Atomic::cmpxchg(next_ptr(*old_head), next_node, (T*)NULL))) { // [Clause 2] - // Result was the last entry and we've claimed it by setting its next + // Old_head was the last entry and we've claimed it by setting its next // value to NULL. However, this leaves the queue in disarray. Fix up // the queue, possibly in conjunction with other concurrent operations. // Any further try_pops will consider the queue empty until a @@ -194,24 +194,24 @@ bool NonblockingQueue::try_pop(T** node_ptr) { // dealing with _head first gives a stronger invariant in append, and is // also consistent with [Clause 1b]. - // Attempt to change the queue head from result to NULL. Failure of the + // Attempt to change the queue head from old_head to NULL. Failure of the // cmpxchg indicates a concurrent operation updated _head first. That // could be either a push/append or a try_pop in [Clause 1b]. - Atomic::cmpxchg(&_head, result, (T*)NULL); + Atomic::cmpxchg(&_head, old_head, (T*)NULL); - // Attempt to change the queue tail from result to NULL. Failure of the + // Attempt to change the queue tail from old_head to NULL. Failure of the // cmpxchg indicates that a concurrent push/append updated _tail first. - // That operation will eventually recognize the old tail (our result) is + // That operation will eventually recognize the old tail (our old_head) is // no longer in the list and update _head from the list being appended. - Atomic::cmpxchg(&_tail, result, (T*)NULL); + Atomic::cmpxchg(&_tail, old_head, (T*)NULL); - // The queue has been restored to order, and we can return the result. - *node_ptr = result; + // The queue has been restored to order, and we can return old_head. + *node_ptr = old_head; return true; } else { // [Clause 3] - // Result was the last entry in the list, but either a concurrent + // Old_head was the last entry in the list, but either a concurrent // try_pop claimed it first or a concurrent push/append extended the // list from it. Either way, we lost the race to claim it. return false; -- GitLab From bce5dd17665d1cdf2901690ca54f84ec200560af Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Wed, 9 Feb 2022 04:38:11 +0000 Subject: [PATCH 182/400] 8280438: Improve BufferNode::Allocator::release to avoid walking pending list Reviewed-by: iwalulya, tschatzl --- src/hotspot/share/gc/shared/ptrQueue.cpp | 93 +++++++++++++++--------- src/hotspot/share/gc/shared/ptrQueue.hpp | 33 +++++++-- 2 files changed, 87 insertions(+), 39 deletions(-) diff --git a/src/hotspot/share/gc/shared/ptrQueue.cpp b/src/hotspot/share/gc/shared/ptrQueue.cpp index 3838b4f37ee..0a95e36de2b 100644 --- a/src/hotspot/share/gc/shared/ptrQueue.cpp +++ b/src/hotspot/share/gc/shared/ptrQueue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -56,11 +56,38 @@ void BufferNode::deallocate(BufferNode* node) { FREE_C_HEAP_ARRAY(char, node); } +BufferNode::Allocator::PendingList::PendingList() : + _tail(nullptr), _head(nullptr), _count(0) {} + +BufferNode::Allocator::PendingList::~PendingList() { + delete_list(Atomic::load(&_head)); +} + +size_t BufferNode::Allocator::PendingList::add(BufferNode* node) { + assert(node->next() == nullptr, "precondition"); + BufferNode* old_head = Atomic::xchg(&_head, node); + if (old_head != nullptr) { + node->set_next(old_head); + } else { + assert(_tail == nullptr, "invariant"); + _tail = node; + } + return Atomic::add(&_count, size_t(1)); +} + +BufferNodeList BufferNode::Allocator::PendingList::take_all() { + BufferNodeList result{Atomic::load(&_head), _tail, Atomic::load(&_count)}; + Atomic::store(&_head, (BufferNode*)nullptr); + _tail = nullptr; + Atomic::store(&_count, size_t(0)); + return result; +} + BufferNode::Allocator::Allocator(const char* name, size_t buffer_size) : _buffer_size(buffer_size), - _pending_list(), + _pending_lists(), + _active_pending_list(0), _free_list(), - _pending_count(0), _free_count(0), _transfer_lock(false) { @@ -70,7 +97,6 @@ BufferNode::Allocator::Allocator(const char* name, size_t buffer_size) : BufferNode::Allocator::~Allocator() { delete_list(_free_list.pop_all()); - delete_list(_pending_list.pop_all()); } void BufferNode::Allocator::delete_list(BufferNode* list) { @@ -109,14 +135,11 @@ BufferNode* BufferNode::Allocator::allocate() { // pop inside a critical section, and release synchronizes on the // critical sections before adding to the _free_list. But we don't // want to make every release have to do a synchronize. Instead, we -// initially place released nodes on the _pending_list, and transfer +// initially place released nodes on the pending list, and transfer // them to the _free_list in batches. Only one transfer at a time is -// permitted, with a lock bit to control access to that phase. A -// transfer takes all the nodes from the _pending_list, synchronizes on -// the _free_list pops, and then adds the former pending nodes to the -// _free_list. While that's happening, other threads might be adding -// other nodes to the _pending_list, to be dealt with by some later -// transfer. +// permitted, with a lock bit to control access to that phase. While +// a transfer is in progress, other threads might be adding other nodes +// to the pending list, to be dealt with by some later transfer. void BufferNode::Allocator::release(BufferNode* node) { assert(node != NULL, "precondition"); assert(node->next() == NULL, "precondition"); @@ -130,15 +153,20 @@ void BufferNode::Allocator::release(BufferNode* node) { // similar, due to how the buffers are used. const size_t trigger_transfer = 10; - // Add to pending list. Update count first so no underflow in transfer. - size_t pending_count = Atomic::add(&_pending_count, 1u); - _pending_list.push(*node); - if (pending_count > trigger_transfer) { - try_transfer_pending(); + // The pending list is double-buffered. Add node to the currently active + // pending list, within a critical section so a transfer will wait until + // we're done with what might be the pending list to be transferred. + { + GlobalCounter::CriticalSection cs(Thread::current()); + uint index = Atomic::load_acquire(&_active_pending_list); + size_t count = _pending_lists[index].add(node); + if (count <= trigger_transfer) return; } + // Attempt transfer when number pending exceeds the transfer threshold. + try_transfer_pending(); } -// Try to transfer nodes from _pending_list to _free_list, with a +// Try to transfer nodes from the pending list to _free_list, with a // synchronization delay for any in-progress pops from the _free_list, // to solve ABA there. Return true if performed a (possibly empty) // transfer, false if blocked from doing so by some other thread's @@ -151,27 +179,26 @@ bool BufferNode::Allocator::try_transfer_pending() { } // Have the lock; perform the transfer. - // Claim all the pending nodes. - BufferNode* first = _pending_list.pop_all(); - if (first != NULL) { - // Prepare to add the claimed nodes, and update _pending_count. - BufferNode* last = first; - size_t count = 1; - for (BufferNode* next = first->next(); next != NULL; next = next->next()) { - last = next; - ++count; - } - Atomic::sub(&_pending_count, count); + // Change which pending list is active. Don't need an atomic RMW since + // we have the lock and we're the only writer. + uint index = Atomic::load(&_active_pending_list); + uint new_active = (index + 1) % ARRAY_SIZE(_pending_lists); + Atomic::release_store(&_active_pending_list, new_active); - // Wait for any in-progress pops, to avoid ABA for them. - GlobalCounter::write_synchronize(); + // Wait for all critical sections in the buffer life-cycle to complete. + // This includes _free_list pops and adding to the now inactive pending + // list. + GlobalCounter::write_synchronize(); - // Add synchronized nodes to _free_list. + // Transfer the inactive pending list to _free_list. + BufferNodeList transfer_list = _pending_lists[index].take_all(); + size_t count = transfer_list._entry_count; + if (count > 0) { // Update count first so no underflow in allocate(). Atomic::add(&_free_count, count); - _free_list.prepend(*first, *last); + _free_list.prepend(*transfer_list._head, *transfer_list._tail); log_trace(gc, ptrqueue, freelist) - ("Transferred %s pending to free: " SIZE_FORMAT, name(), count); + ("Transferred %s pending to free: %zu", name(), count); } Atomic::release_store(&_transfer_lock, false); return true; diff --git a/src/hotspot/share/gc/shared/ptrQueue.hpp b/src/hotspot/share/gc/shared/ptrQueue.hpp index f1533e5128d..be07f3e58b3 100644 --- a/src/hotspot/share/gc/shared/ptrQueue.hpp +++ b/src/hotspot/share/gc/shared/ptrQueue.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -25,6 +25,7 @@ #ifndef SHARE_GC_SHARED_PTRQUEUE_HPP #define SHARE_GC_SHARED_PTRQUEUE_HPP +#include "gc/shared/bufferNodeList.hpp" #include "memory/padded.hpp" #include "utilities/align.hpp" #include "utilities/debug.hpp" @@ -181,17 +182,37 @@ class BufferNode::Allocator { #define DECLARE_PADDED_MEMBER(Id, Type, Name) \ Type Name; DEFINE_PAD_MINUS_SIZE(Id, DEFAULT_CACHE_LINE_SIZE, sizeof(Type)) + class PendingList { + BufferNode* _tail; + DECLARE_PADDED_MEMBER(1, BufferNode* volatile, _head); + DECLARE_PADDED_MEMBER(2, volatile size_t, _count); + + NONCOPYABLE(PendingList); + + public: + PendingList(); + ~PendingList(); + + // Add node to the list. Returns the number of nodes in the list. + // Thread-safe against concurrent add operations. + size_t add(BufferNode* node); + + // Return the nodes in the list, leaving the list empty. + // Not thread-safe. + BufferNodeList take_all(); + }; + const size_t _buffer_size; char _name[DEFAULT_CACHE_LINE_SIZE - sizeof(size_t)]; // Use name as padding. - DECLARE_PADDED_MEMBER(1, Stack, _pending_list); + PendingList _pending_lists[2]; + DECLARE_PADDED_MEMBER(1, volatile uint, _active_pending_list); DECLARE_PADDED_MEMBER(2, Stack, _free_list); - DECLARE_PADDED_MEMBER(3, volatile size_t, _pending_count); - DECLARE_PADDED_MEMBER(4, volatile size_t, _free_count); - DECLARE_PADDED_MEMBER(5, volatile bool, _transfer_lock); + DECLARE_PADDED_MEMBER(3, volatile size_t, _free_count); + DECLARE_PADDED_MEMBER(4, volatile bool, _transfer_lock); #undef DECLARE_PADDED_MEMBER - void delete_list(BufferNode* list); + static void delete_list(BufferNode* list); bool try_transfer_pending(); NONCOPYABLE(Allocator); -- GitLab From fc77217814eb1a346d7380299abdc2b01a69b4de Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Wed, 9 Feb 2022 06:28:00 +0000 Subject: [PATCH 183/400] 8281168: Micro-optimize VarForm.getMemberName for interpreter Reviewed-by: redestad, vlivanov, mchung --- .../share/classes/java/lang/invoke/VarForm.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/invoke/VarForm.java b/src/java.base/share/classes/java/lang/invoke/VarForm.java index 7b118dbe470..1308c48cebb 100644 --- a/src/java.base/share/classes/java/lang/invoke/VarForm.java +++ b/src/java.base/share/classes/java/lang/invoke/VarForm.java @@ -109,9 +109,14 @@ final class VarForm { @ForceInline final MemberName getMemberName(int mode) { - MemberName mn = getMemberNameOrNull(mode); + // Can be simplified by calling getMemberNameOrNull, but written in this + // form to improve interpreter/coldpath performance. + MemberName mn = memberName_table[mode]; if (mn == null) { - throw new UnsupportedOperationException(); + mn = resolveMemberName(mode); + if (mn == null) { + throw new UnsupportedOperationException(); + } } return mn; } -- GitLab From cb2f8caed2de1bf0a85a7ebfd232c36371e06c98 Mon Sep 17 00:00:00 2001 From: Artem Semenov Date: Wed, 9 Feb 2022 06:50:35 +0000 Subject: [PATCH 184/400] 8281338: NSAccessibilityPressAction action for tree node and NSAccessibilityShowMenuAcgtion action not working Reviewed-by: ant, kizune --- .../awt/JavaAccessibilityAction.m | 4 +- .../java/awt/a11y/AccessibleActionsTest.java | 183 ++++++++++++++++++ 2 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 test/jdk/java/awt/a11y/AccessibleActionsTest.java diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityAction.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityAction.m index 06e998ec409..173ad891051 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityAction.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaAccessibilityAction.m @@ -161,8 +161,8 @@ void initializeActions() { [sActions setObject:NSAccessibilityPressAction forKey:@"click"]; [sActions setObject:NSAccessibilityIncrementAction forKey:@"increment"]; [sActions setObject:NSAccessibilityDecrementAction forKey:@"decrement"]; - [sActions setObject:NSAccessibilityShowMenuAction forKey:@"togglePopup"]; - [sActions setObject:NSAccessibilityPressAction forKey:@"toggleExpand"]; + [sActions setObject:NSAccessibilityShowMenuAction forKey:@"toggle popup"]; + [sActions setObject:NSAccessibilityPressAction forKey:@"toggleexpand"]; sActionSelectors = [[NSMutableDictionary alloc] initWithCapacity:actionsCount]; diff --git a/test/jdk/java/awt/a11y/AccessibleActionsTest.java b/test/jdk/java/awt/a11y/AccessibleActionsTest.java new file mode 100644 index 00000000000..b8f6e5d28f9 --- /dev/null +++ b/test/jdk/java/awt/a11y/AccessibleActionsTest.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, JetBrains s.r.o.. All rights reserved. + * 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 8281338 + * @summary Test for an element that has more than one Accessibility Action + * @author Artem.Semenov@jetbrains.com + * @run main/manual AccessibleActionsTest + * @requires (os.family == "mac") + */ + +import javax.accessibility.Accessible; +import javax.accessibility.AccessibleAction; +import javax.accessibility.AccessibleContext; +import javax.swing.*; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Hashtable; +import java.util.concurrent.CountDownLatch; + +public class AccessibleActionsTest extends AccessibleComponentTest { + + @Override + public CountDownLatch createCountDownLatch() { + return new CountDownLatch(1); + } + + void createTest() { + INSTRUCTIONS = "INSTRUCTIONS:\n" + + "Check a11y actions.\n\n" + + "Turn screen reader on, and Tab to the label.\n\n" + + "Perform the VO action \"Press\" (VO+space)\n" + + "Perform the VO action \"Show menu\" (VO+m)\n\n" + + "If after the first action the text of the label has changed, and after the second action the menu appears tab further and press PASS, otherwise press FAIL."; + + exceptionString = "AccessibleAction test failed!"; + super.createUI(new AccessibleActionsTestFrame(), "AccessibleActionsTest"); + } + + void createTree() { + INSTRUCTIONS = "INSTRUCTIONS:\n" + + "Check a11y actions.\n\n" + + "Turn screen reader on, and Tab to the label.\n\n" + + "Perform the VO action \"Press\" (VO+space) on tree nodes\n\n" + + "If after press the tree node is expanded tab further and press PASS, otherwise press FAIL."; + + String root = "Root"; + String[] nodes = new String[] {"One node", "Two node"}; + String[][] leafs = new String[][]{{"leaf 1.1", "leaf 1.2", "leaf 1.3", "leaf 1.4"}, + {"leaf 2.1", "leaf 2.2", "leaf 2.3", "leaf 2.4"}}; + + Hashtable data = new Hashtable(); + for (int i = 0; i < nodes.length; i++) { + data.put(nodes[i], leafs[i]); + } + + JTree tree = new JTree(data); + tree.setRootVisible(true); + + JPanel panel = new JPanel(); + panel.setLayout(new FlowLayout()); + JScrollPane scrollPane = new JScrollPane(tree); + panel.add(scrollPane); + panel.setFocusable(false); + + exceptionString = "AccessibleAction test failed!"; + super.createUI(panel, "AccessibleActionsTest"); + } + + public static void main(String[] args) throws Exception { + AccessibleActionsTest test = new AccessibleActionsTest(); + + countDownLatch = test.createCountDownLatch(); + SwingUtilities.invokeLater(test::createTest); + countDownLatch.await(); + + if (!testResult) { + throw new RuntimeException(a11yTest.exceptionString); + } + + countDownLatch = test.createCountDownLatch(); + SwingUtilities.invokeLater(test::createTree); + countDownLatch.await(); + + if (!testResult) { + throw new RuntimeException(a11yTest.exceptionString); + } + } + + private class AccessibleActionsTestFrame extends JPanel { + + public AccessibleActionsTestFrame() { + MyLabel label = new MyLabel("I'm waiting for the push"); + label.setComponentPopupMenu(createPopup()); + label.setFocusable(true); + add(label); + setLayout(new FlowLayout()); + } + + private static class MyLabel extends JLabel { + public MyLabel(String text) { + super(text); + } + + @Override + public AccessibleContext getAccessibleContext() { + if (accessibleContext == null) { + accessibleContext = new MyAccessibleJLabel(); + } + return accessibleContext; + } + + private class MyAccessibleJLabel extends JLabel.AccessibleJLabel { + @Override + public AccessibleAction getAccessibleAction() { + return new AccessibleAction() { + @Override + public int getAccessibleActionCount() { + return 2; + } + + @Override + public String getAccessibleActionDescription(int i) { + if (i == 0) { + return AccessibleAction.CLICK; + } + return AccessibleAction.TOGGLE_POPUP; + } + + @Override + public boolean doAccessibleAction(int i) { + if (i == 0) { + changeText(MyLabel.this, "label is pressed"); + return true; + } + JPopupMenu popup = createPopup(); + popup.show(MyLabel.this, 0, 0); + return true; + } + }; + } + } + } + + private static JPopupMenu createPopup() { + JPopupMenu popup = new JPopupMenu("MENU"); + popup.add("One"); + popup.add("Two"); + popup.add("Three"); + return popup; + } + + private static void changeText(JLabel label, String text) { + label.setText(text); + } + + } +} -- GitLab From 072e7b4da0449ab7c1ab1ba0cfbb3db233823e7c Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Wed, 9 Feb 2022 06:53:09 +0000 Subject: [PATCH 185/400] 8272807: Permit use of memory concurrent with pretouch Reviewed-by: shade, stuefe --- src/hotspot/share/runtime/os.cpp | 30 ++++++++++++++++++++++++------ src/hotspot/share/runtime/os.hpp | 7 +++---- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index 29a3d7622f6..a85be30ec48 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -1745,13 +1745,31 @@ void os::print_memory_mappings(outputStream* st) { os::print_memory_mappings(nullptr, (size_t)-1, st); } +// Pretouching must use a store, not just a load. On many OSes loads from +// fresh memory would be satisfied from a single mapped page containing all +// zeros. We need to store something to each page to get them backed by +// their own memory, which is the effect we want here. An atomic add of +// zero is used instead of a simple store, allowing the memory to be used +// while pretouch is in progress, rather than requiring users of the memory +// to wait until the entire range has been touched. This is technically +// a UB data race, but doesn't cause any problems for us. void os::pretouch_memory(void* start, void* end, size_t page_size) { - for (volatile char *p = (char*)start; p < (char*)end; p += page_size) { - // Note: this must be a store, not a load. On many OSes loads from fresh - // memory would be satisfied from a single mapped page containing all zeros. - // We need to store something to each page to get them backed by their own - // memory, which is the effect we want here. - *p = 0; + assert(start <= end, "invalid range: " PTR_FORMAT " -> " PTR_FORMAT, p2i(start), p2i(end)); + assert(is_power_of_2(page_size), "page size misaligned: %zu", page_size); + assert(page_size >= sizeof(int), "page size too small: %zu", page_size); + if (start < end) { + // We're doing concurrent-safe touch and memory state has page + // granularity, so we can touch anywhere in a page. Touch at the + // beginning of each page to simplify iteration. + char* cur = static_cast(align_down(start, page_size)); + void* last = align_down(static_cast(end) - 1, page_size); + assert(cur <= last, "invariant"); + // Iterate from first page through last (inclusive), being careful to + // avoid overflow if the last page abuts the end of the address range. + for ( ; true; cur += page_size) { + Atomic::add(reinterpret_cast(cur), 0, memory_order_relaxed); + if (cur >= last) break; + } } } diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index b63637e3576..1ad15f0d8ea 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp @@ -365,10 +365,9 @@ class os: AllStatic { // Prints all mappings static void print_memory_mappings(outputStream* st); - // Touch memory pages that cover the memory range from start to end (exclusive) - // to make the OS back the memory range with actual memory. - // Current implementation may not touch the last page if unaligned addresses - // are passed. + // Touch memory pages that cover the memory range from start to end + // (exclusive) to make the OS back the memory range with actual memory. + // Other threads may use the memory range concurrently with pretouch. static void pretouch_memory(void* start, void* end, size_t page_size = vm_page_size()); enum ProtType { MEM_PROT_NONE, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX }; -- GitLab From f924e50c42c2f9548d2983449a98c45af40b0d35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jeli=C5=84ski?= Date: Wed, 9 Feb 2022 08:34:47 +0000 Subject: [PATCH 186/400] 8281440: AWT: Conversion from string literal loses const qualifier Reviewed-by: prr, aivanov --- .../windows/native/libawt/windows/WPrinterJob.cpp | 6 +++--- .../windows/native/libawt/windows/awt_Debug.cpp | 2 +- .../libawt/windows/awt_DesktopProperties.cpp | 14 +++++++------- .../native/libawt/windows/awt_DrawingSurface.cpp | 2 +- .../windows/native/libawt/windows/awt_Font.cpp | 6 +++--- .../windows/native/libawt/windows/awt_Font.h | 2 +- .../native/libawt/windows/awt_PrintControl.cpp | 2 +- .../windows/native/libawt/windows/awt_PrintJob.cpp | 6 +++--- .../windows/native/libawt/windows/awt_Toolkit.cpp | 2 +- .../native/libawt/windows/awt_Win32GraphicsEnv.cpp | 2 +- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp b/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp index 812d0df3bbb..16b20afd030 100644 --- a/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp +++ b/src/java.desktop/windows/native/libawt/windows/WPrinterJob.cpp @@ -729,7 +729,7 @@ Java_sun_print_Win32PrintService_getPrinterPort(JNIEnv *env, } jstring jPort; - LPTSTR printerName = NULL, printerPort = TEXT("LPT1"); + LPTSTR printerName = NULL, printerPort = (LPTSTR)TEXT("LPT1"); LPBYTE buffer = NULL; DWORD cbBuf = 0; @@ -745,7 +745,7 @@ Java_sun_print_Win32PrintService_getPrinterPort(JNIEnv *env, } if (printerPort == NULL) { - printerPort = TEXT("LPT1"); + printerPort = (LPTSTR)TEXT("LPT1"); } jPort = JNU_NewStringPlatform(env, printerPort); delete [] buffer; @@ -1110,7 +1110,7 @@ Java_sun_print_Win32PrintJob_startPrintRawData(JNIEnv *env, // Fill in the structure with info about this "document." DocInfo.pDocName = jname; DocInfo.pOutputFile = NULL; - DocInfo.pDatatype = TEXT("RAW"); + DocInfo.pDatatype = (LPTSTR)TEXT("RAW"); // Inform the spooler the document is beginning. if( (::StartDocPrinter(hPrinter, 1, (LPBYTE)&DocInfo)) == 0 ) { diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Debug.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Debug.cpp index 5faa5f3a634..88dc0f17abe 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Debug.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Debug.cpp @@ -193,7 +193,7 @@ void AwtDebugSupport::AssertCallback(const char * expr, const char * file, int l NULL); if (msgBuffer == NULL) { - msgBuffer = ""; + msgBuffer = (LPSTR)""; } // format the assertion message _snprintf(assertMsg, ASSERT_MSG_SIZE, AssertFmt, expr, file, line, lastError, msgBuffer); diff --git a/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp b/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp index e9d4161c89b..9b3668c1798 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp @@ -138,7 +138,7 @@ void AwtDesktopProperties::GetSystemProperties() { // Note that it uses malloc() and returns the pointer to allocated // memory, so remember to use free() when you are done with its // result. -static LPTSTR resolveShellDialogFont(LPTSTR fontName, HKEY handle) { +static LPTSTR resolveShellDialogFont(LPCTSTR fontName, HKEY handle) { DWORD valueType, valueSize; if (RegQueryValueEx((HKEY)handle, fontName, NULL, &valueType, NULL, &valueSize) != 0) { @@ -164,7 +164,7 @@ static LPTSTR resolveShellDialogFont(LPTSTR fontName, HKEY handle) { // memory, so remember to use free() when you are done with its // result. static LPTSTR resolveShellDialogFont() { - LPTSTR subKey = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes"); + LPCTSTR subKey = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes"); HKEY handle; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &handle) != 0) { @@ -183,7 +183,7 @@ static LPTSTR resolveShellDialogFont() { // Note that it uses malloc() and returns the pointer to allocated // memory, so remember to use free() when you are done with its // result. -static LPTSTR getWindowsPropFromReg(LPTSTR subKey, LPTSTR valueName, DWORD *valueType) { +static LPTSTR getWindowsPropFromReg(LPCTSTR subKey, LPCTSTR valueName, DWORD *valueType) { HKEY handle; if (RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_READ, &handle) != 0) { return NULL; @@ -221,7 +221,7 @@ static LPTSTR getWindowsPropFromReg(LPTSTR subKey, LPTSTR valueName, DWORD *valu } } -static LPTSTR getXPStylePropFromReg(LPTSTR valueName) { +static LPTSTR getXPStylePropFromReg(LPCTSTR valueName) { DWORD valueType; return getWindowsPropFromReg(TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager"), valueName, &valueType); @@ -651,11 +651,11 @@ void AwtDesktopProperties::GetOtherParameters() { throw; } - LPTSTR valueName = TEXT("PlaceN"); + LPCTSTR valueName = TEXT("PlaceN"); LPTSTR valueNameBuf = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (lstrlen(valueName) + 1), sizeof(TCHAR)); lstrcpy(valueNameBuf, valueName); - LPTSTR propKey = TEXT("win.comdlg.placesBarPlaceN"); + LPCTSTR propKey = TEXT("win.comdlg.placesBarPlaceN"); LPTSTR propKeyBuf; try { @@ -672,7 +672,7 @@ void AwtDesktopProperties::GetOtherParameters() { valueNameBuf[5] = _T('0' + i++); propKeyBuf[25] = valueNameBuf[5]; - LPTSTR key = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\comdlg32\\PlacesBar"); + LPCTSTR key = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\comdlg32\\PlacesBar"); try { value = NULL; if ((value = getWindowsPropFromReg(key, valueNameBuf, &valueType)) != NULL) { diff --git a/src/java.desktop/windows/native/libawt/windows/awt_DrawingSurface.cpp b/src/java.desktop/windows/native/libawt/windows/awt_DrawingSurface.cpp index 019295ac2b5..de7f7fd895c 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_DrawingSurface.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_DrawingSurface.cpp @@ -275,7 +275,7 @@ extern "C" JNIEXPORT void JNICALL DSUnlockAWT(JNIEnv* env) // EmbeddedFrame support -static char *const embeddedClassName = "sun/awt/windows/WEmbeddedFrame"; +static const char *const embeddedClassName = "sun/awt/windows/WEmbeddedFrame"; JNIEXPORT jobject JNICALL awt_CreateEmbeddedFrame (JNIEnv* env, void* platformInfo) diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp index cef2e3d1046..48b78183b20 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp @@ -345,7 +345,7 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale) wName = L"Arial"; } - WCHAR* wEName; + LPCWSTR wEName; if (!wcscmp(wName, L"Helvetica") || !wcscmp(wName, L"SansSerif")) { wEName = L"Arial"; } else if (!wcscmp(wName, L"TimesRoman") || @@ -388,7 +388,7 @@ AwtFont* AwtFont::Create(JNIEnv *env, jobject font, jint angle, jfloat awScale) return awtFont; } -static void strip_tail(wchar_t* text, wchar_t* tail) { // strips tail and any possible whitespace before it from the end of text +static void strip_tail(wchar_t* text, const wchar_t* tail) { // strips tail and any possible whitespace before it from the end of text if (wcslen(text)<=wcslen(tail)) { return; } @@ -495,7 +495,7 @@ static HFONT CreateHFont_sub(LPCWSTR name, int style, int height, return hFont; } -HFONT AwtFont::CreateHFont(WCHAR* name, int style, int height, +HFONT AwtFont::CreateHFont(LPCWSTR name, int style, int height, int angle, float awScale) { WCHAR longName[80]; diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Font.h b/src/java.desktop/windows/native/libawt/windows/awt_Font.h index 3f4d8e6a67d..aa1d7241f10 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Font.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_Font.h @@ -155,7 +155,7 @@ public: */ static AwtFont* Create(JNIEnv *env, jobject font, jint angle = 0, jfloat awScale=1.0f); - static HFONT CreateHFont(WCHAR* name, int style, int height, + static HFONT CreateHFont(LPCWSTR name, int style, int height, int angle = 0, float awScale=1.0f); static void Cleanup(); diff --git a/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp b/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp index c29d4c4e7ac..5064bb4fb45 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp @@ -1045,7 +1045,7 @@ BOOL AwtPrintControl::UpdateAttributes(JNIEnv *env, DEVNAMES *devnames = (DEVNAMES*)::GlobalLock(pd.hDevNames); DASSERT(!IsBadReadPtr(devnames, sizeof(DEVNAMES))); LPTSTR lpcNames = (LPTSTR)devnames; - LPTSTR pbuf = (_tcslen(lpcNames + devnames->wDeviceOffset) == 0 ? + LPCTSTR pbuf = (_tcslen(lpcNames + devnames->wDeviceOffset) == 0 ? TEXT("") : lpcNames + devnames->wDeviceOffset); if (pbuf != NULL) { jstring jstr = JNU_NewStringPlatform(env, pbuf); diff --git a/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp b/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp index 9eec4d89b15..874ce94c434 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_PrintJob.cpp @@ -64,8 +64,8 @@ extern "C" { /*** Private Constants ***/ -static char *kJavaIntStr = "I"; -static char *kJavaLongStr = "J"; +static const char *kJavaIntStr = "I"; +static const char *kJavaLongStr = "J"; /* 2D printing uses 3 byte BGR pixels in Raster printing */ static int J2DRasterBPP = 3; @@ -1353,7 +1353,7 @@ Java_sun_awt_windows_WPrinterJob__1startDoc(JNIEnv *env, jobject self, } else { destination = VerifyDestination(env, self); } - LPTSTR docname = NULL; + LPCTSTR docname = NULL; if (jobname != NULL) { LPTSTR tmp = (LPTSTR)JNU_GetStringPlatformChars(env, jobname, NULL); if (tmp == NULL) { diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp index 17e69d70b15..687eba5deff 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp @@ -530,7 +530,7 @@ void ToolkitThreadProc(void *param) JNIEnv *env; JavaVMAttachArgs attachArgs; attachArgs.version = JNI_VERSION_1_2; - attachArgs.name = "AWT-Windows"; + attachArgs.name = (char*)"AWT-Windows"; attachArgs.group = data->threadGroup; jint res = jvm->AttachCurrentThreadAsDaemon((void **)&env, &attachArgs); diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp index bc0d6a939fa..434050215a3 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsEnv.cpp @@ -234,7 +234,7 @@ Java_sun_awt_Win32FontManager_getEUDCFontFile(JNIEnv *env, jclass cl) { unsigned long fontPathLen = MAX_PATH + 1; WCHAR tmpPath[MAX_PATH + 1]; LPWSTR fontPath = fontPathBuf; - LPWSTR eudcKey = NULL; + LPCWSTR eudcKey = NULL; LANGID langID = GetSystemDefaultLangID(); //lookup for encoding ID, EUDC only supported in -- GitLab From f092babafb58563a4044463e157e02c397d8c9bc Mon Sep 17 00:00:00 2001 From: Alexey Pavlyutkin Date: Wed, 9 Feb 2022 09:33:35 +0000 Subject: [PATCH 187/400] 8281195: Mistakenly used logging causes significant overhead in interpreter Reviewed-by: shade, dholmes --- src/hotspot/share/interpreter/oopMapCache.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/interpreter/oopMapCache.cpp b/src/hotspot/share/interpreter/oopMapCache.cpp index 8799275683a..84bef74bed9 100644 --- a/src/hotspot/share/interpreter/oopMapCache.cpp +++ b/src/hotspot/share/interpreter/oopMapCache.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -276,26 +276,26 @@ bool OopMapCacheEntry::verify_mask(CellTypeState* vars, CellTypeState* stack, in // Check if map is generated correctly // (Use ?: operator to make sure all 'true' & 'false' are represented exactly the same so we can use == afterwards) - Log(interpreter, oopmap) logv; - LogStream st(logv.trace()); + const bool log = log_is_enabled(Trace, interpreter, oopmap); + LogStream st(Log(interpreter, oopmap)::trace()); - st.print("Locals (%d): ", max_locals); + if (log) st.print("Locals (%d): ", max_locals); for(int i = 0; i < max_locals; i++) { bool v1 = is_oop(i) ? true : false; bool v2 = vars[i].is_reference() ? true : false; assert(v1 == v2, "locals oop mask generation error"); - st.print("%d", v1 ? 1 : 0); + if (log) st.print("%d", v1 ? 1 : 0); } - st.cr(); + if (log) st.cr(); - st.print("Stack (%d): ", stack_top); + if (log) st.print("Stack (%d): ", stack_top); for(int j = 0; j < stack_top; j++) { bool v1 = is_oop(max_locals + j) ? true : false; bool v2 = stack[j].is_reference() ? true : false; assert(v1 == v2, "stack oop mask generation error"); - st.print("%d", v1 ? 1 : 0); + if (log) st.print("%d", v1 ? 1 : 0); } - st.cr(); + if (log) st.cr(); return true; } -- GitLab From 69e390a0e86f82eaa7bcdbc3ef509734dbe3b22f Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Wed, 9 Feb 2022 10:18:27 +0000 Subject: [PATCH 188/400] 8262721: Add Tests to verify single iteration loops are properly optimized Reviewed-by: neliasso, chagedorn, kvn --- .../irTests/TestFewIterationsCountedLoop.java | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/c2/irTests/TestFewIterationsCountedLoop.java diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestFewIterationsCountedLoop.java b/test/hotspot/jtreg/compiler/c2/irTests/TestFewIterationsCountedLoop.java new file mode 100644 index 00000000000..1d3fed1c87a --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestFewIterationsCountedLoop.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.c2.irTests; + +import compiler.lib.ir_framework.*; + +/* + * @test + * @bug 8262721 + * @summary Add Tests to verify single iteration loops are properly optimized + * @library /test/lib / + * @run driver compiler.c2.irTests.TestFewIterationsCountedLoop + */ + +public class TestFewIterationsCountedLoop { + + public static void main(String[] args) { + TestFramework.runWithFlags("-XX:LoopUnrollLimit=0"); + TestFramework.run(); + } + + static volatile int barrier; + static final Object object = new Object(); + + @Test + @IR(failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void singleIterationFor() { + for (int i = 0; i < 1; i++) { + barrier = 0x42; // something that can't be optimized out + } + } + + @Test + @IR(failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void singleIterationWhile() { + int i = 0; + while (i < 1) { + barrier = 0x42; + i++; + } + } + + @Test + @IR(failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + @Warmup(1) // So C2 can't rely on profile data + public static void singleIterationDoWhile() { + int i = 0; + do { + synchronized(object) {} // so loop head is not cloned by ciTypeFlow + barrier = 0x42; + i++; + } while (i < 1); + } + + @Test + @IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" }) + @IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void twoIterationsFor() { + for (int i = 0; i < 2; i++) { + barrier = 0x42; // something that can't be optimized out + } + } + + @Test + @IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" }) + @IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void twoIterationsWhile() { + int i = 0; + while (i < 2) { + barrier = 0x42; + i++; + } + } + + @Test + @IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" }) + @IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void twoIterationsDoWhile() { + int i = 0; + do { + synchronized(object) {} // so loop head is not cloned by ciTypeFlow + barrier = 0x42; + i++; + } while (i < 2); + } + + @Test + @IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" }) + @IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void threadIterationsFor() { + for (int i = 0; i < 2; i++) { + barrier = 0x42; // something that can't be optimized out + } + } + + @Test + @IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" }) + @IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void threeIterationsWhile() { + int i = 0; + while (i < 2) { + barrier = 0x42; + i++; + } + } + + @Test + @IR(applyIf = { "LoopUnrollLimit", "0" }, counts = { IRNode.COUNTEDLOOP, "1" }) + @IR(applyIf = { "LoopUnrollLimit", "> 0" }, failOn = { IRNode.COUNTEDLOOP, IRNode.LOOP }) + public static void threeIterationsDoWhile() { + int i = 0; + do { + synchronized(object) {} // so loop head is not cloned by ciTypeFlow + barrier = 0x42; + i++; + } while (i < 2); + } +} -- GitLab From bb2e10ccea0c0b89b06ace034c99253e9999ec47 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Wed, 9 Feb 2022 11:33:16 +0000 Subject: [PATCH 189/400] 8281274: deal with ActiveProcessorCount in os::Linux::print_container_info Reviewed-by: stuefe, sgehwolf, dholmes, iklam --- src/hotspot/os/linux/os_linux.cpp | 6 +++++- test/hotspot/jtreg/containers/docker/TestMisc.java | 12 +++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index 28477ba8bcb..18b908cfc8f 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -2174,7 +2174,11 @@ bool os::Linux::print_container_info(outputStream* st) { int i = OSContainer::active_processor_count(); st->print("active_processor_count: "); if (i > 0) { - st->print_cr("%d", i); + if (ActiveProcessorCount > 0) { + st->print_cr("%d, but overridden by -XX:ActiveProcessorCount %d", i, ActiveProcessorCount); + } else { + st->print_cr("%d", i); + } } else { st->print_cr("not supported"); } diff --git a/test/hotspot/jtreg/containers/docker/TestMisc.java b/test/hotspot/jtreg/containers/docker/TestMisc.java index e242bdf6632..5625fe828bb 100644 --- a/test/hotspot/jtreg/containers/docker/TestMisc.java +++ b/test/hotspot/jtreg/containers/docker/TestMisc.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -56,6 +56,7 @@ public class TestMisc { testMinusContainerSupport(); testIsContainerized(); testPrintContainerInfo(); + testPrintContainerInfoActiveProcessorCount(); } finally { DockerTestUtils.removeDockerImage(imageName); } @@ -92,6 +93,15 @@ public class TestMisc { checkContainerInfo(Common.run(opts)); } + private static void testPrintContainerInfoActiveProcessorCount() throws Exception { + Common.logNewTestCase("Test print_container_info()"); + + DockerRunOptions opts = Common.newOpts(imageName, "PrintContainerInfo").addJavaOpts("-XX:ActiveProcessorCount=2"); + Common.addWhiteBoxOpts(opts); + + OutputAnalyzer out = Common.run(opts); + out.shouldContain("but overridden by -XX:ActiveProcessorCount 2"); + } private static void checkContainerInfo(OutputAnalyzer out) throws Exception { String[] expectedToContain = new String[] { -- GitLab From 8b384b986a0a6a972c29a2f7a4d9fd40dc479b48 Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Wed, 9 Feb 2022 11:34:22 +0000 Subject: [PATCH 190/400] 8281470: tools/jar/CreateMissingParentDirectories.java fails with "Should have failed creating jar file" Reviewed-by: lancea --- test/jdk/ProblemList.txt | 1 - .../jdk/tools/jar/CreateMissingParentDirectories.java | 11 +++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 1d08673243f..6b54c726277 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -765,7 +765,6 @@ javax/swing/JTree/4908142/bug4908142.java 8278348 macosx-all # core_tools tools/jlink/plugins/CompressorPluginTest.java 8247407 generic-all -tools/jar/CreateMissingParentDirectories.java 8281470 generic-all ############################################################################ diff --git a/test/jdk/tools/jar/CreateMissingParentDirectories.java b/test/jdk/tools/jar/CreateMissingParentDirectories.java index 93d6d4ce01d..1f8fa4deb38 100644 --- a/test/jdk/tools/jar/CreateMissingParentDirectories.java +++ b/test/jdk/tools/jar/CreateMissingParentDirectories.java @@ -32,6 +32,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; import java.util.spi.ToolProvider; import java.util.stream.Stream; @@ -66,7 +67,6 @@ public class CreateMissingParentDirectories { doHappyPathTest(topDir.resolve("a/test.jar"), entry); doHappyPathTest(topDir.resolve("a/b/test.jar"), entry); - doFailingTest(topDir.toString() + "/a/*/test.jar", entry); Path blocker = Files.writeString(topDir.resolve("blocker.txt"), "Blocked!"); doFailingTest(topDir.resolve("blocker.txt/test.jar").toString(), entry); } finally { @@ -77,7 +77,12 @@ public class CreateMissingParentDirectories { private static void doHappyPathTest(Path jar, Path entry) throws Throwable { String[] jarArgs = new String[]{"cf", jar.toString(), entry.toString()}; if (JAR_TOOL.run(System.out, System.err, jarArgs) != 0) { - fail("Could not create jar file: " + jar); + fail("Could not create jar file: " + List.of(jarArgs)); + return; + } + jarArgs = new String[]{"--create", "--file", jar.toString(), entry.toString()}; + if (JAR_TOOL.run(System.out, System.err, jarArgs) != 0) { + fail("Could not create jar file: " + List.of(jarArgs)); return; } pass(); @@ -92,8 +97,6 @@ public class CreateMissingParentDirectories { fail("Should have failed creating jar file: " + jar); return; } - // non-zero exit code expected, check error message contains jar file's name - check(err.toString().contains(jar)); pass(); } -- GitLab From f823bed043dc38d838baaf8c2024ef24b8a50e9b Mon Sep 17 00:00:00 2001 From: Bhavana Kilambi Date: Wed, 9 Feb 2022 13:18:29 +0000 Subject: [PATCH 191/400] 8280007: Enable Neoverse N1 optimizations for Arm Neoverse V1 & N2 Reviewed-by: phh --- src/hotspot/cpu/aarch64/vm_version_aarch64.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp index 833a6ec9f6d..b0c0c64f6d9 100644 --- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -197,8 +197,10 @@ void VM_Version::initialize() { } } - // Neoverse N1 - if (_cpu == CPU_ARM && (_model == 0xd0c || _model2 == 0xd0c)) { + // Neoverse N1, N2 and V1 + if (_cpu == CPU_ARM && ((_model == 0xd0c || _model2 == 0xd0c) + || (_model == 0xd49 || _model2 == 0xd49) + || (_model == 0xd40 || _model2 == 0xd40))) { if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) { FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true); } -- GitLab From c5c8c0644d9442846de15422285fffeb91c3e0a1 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Wed, 9 Feb 2022 13:56:23 +0000 Subject: [PATCH 192/400] 8279822: CI: Constant pool entries in error state are not supported Reviewed-by: kvn, thartmann --- src/hotspot/share/ci/bcEscapeAnalyzer.cpp | 6 +- src/hotspot/share/ci/ciConstant.hpp | 11 + src/hotspot/share/ci/ciEnv.cpp | 40 +-- src/hotspot/share/ci/ciStreams.cpp | 8 + src/hotspot/share/ci/ciStreams.hpp | 19 +- src/hotspot/share/ci/ciTypeFlow.cpp | 19 +- src/hotspot/share/oops/constantPool.cpp | 38 ++- src/hotspot/share/opto/parse2.cpp | 36 +-- src/hotspot/share/utilities/constantTag.hpp | 33 +- .../runtime/TestConstantsInError.java | 283 ++++++++++++++++++ 10 files changed, 403 insertions(+), 90 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java diff --git a/src/hotspot/share/ci/bcEscapeAnalyzer.cpp b/src/hotspot/share/ci/bcEscapeAnalyzer.cpp index a10a9d3d551..7fd8b5c04f3 100644 --- a/src/hotspot/share/ci/bcEscapeAnalyzer.cpp +++ b/src/hotspot/share/ci/bcEscapeAnalyzer.cpp @@ -416,11 +416,11 @@ void BCEscapeAnalyzer::iterate_one_block(ciBlock *blk, StateInfo &state, Growabl // Avoid calling get_constant() which will try to allocate // unloaded constant. We need only constant's type. int index = s.get_constant_pool_index(); - constantTag tag = s.get_constant_pool_tag(index); - if (tag.is_long() || tag.is_double()) { + BasicType con_bt = s.get_basic_type_for_constant_at(index); + if (con_bt == T_LONG || con_bt == T_DOUBLE) { // Only longs and doubles use 2 stack slots. state.lpush(); - } else if (tag.basic_type() == T_OBJECT) { + } else if (con_bt == T_OBJECT) { state.apush(unknown_obj); } else { state.spush(); diff --git a/src/hotspot/share/ci/ciConstant.hpp b/src/hotspot/share/ci/ciConstant.hpp index c9351771d17..25591699045 100644 --- a/src/hotspot/share/ci/ciConstant.hpp +++ b/src/hotspot/share/ci/ciConstant.hpp @@ -127,6 +127,17 @@ public: bool is_valid() const { return basic_type() != T_ILLEGAL; } + + bool is_loaded() const { + if (is_valid()) { + if (is_reference_type(basic_type())) { + return as_object()->is_loaded(); + } else { + return true; + } + } + return false; + } // Debugging output void print(); }; diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index 323d67c986f..bdbd86d9018 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -503,13 +503,6 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, domain = Handle(current, accessing_klass->protection_domain()); } - // setup up the proper type to return on OOM - ciKlass* fail_type; - if (sym->char_at(0) == JVM_SIGNATURE_ARRAY) { - fail_type = _unloaded_ciobjarrayklass; - } else { - fail_type = _unloaded_ciinstance_klass; - } Klass* found_klass; { ttyUnlocker ttyul; // release tty lock to avoid ordering problems @@ -591,7 +584,6 @@ ciKlass* ciEnv::get_klass_by_index_impl(const constantPoolHandle& cpool, int index, bool& is_accessible, ciInstanceKlass* accessor) { - EXCEPTION_CONTEXT; Klass* klass = NULL; Symbol* klass_name = NULL; @@ -599,7 +591,7 @@ ciKlass* ciEnv::get_klass_by_index_impl(const constantPoolHandle& cpool, klass_name = cpool->symbol_at(index); } else { // Check if it's resolved if it's not a symbol constant pool entry. - klass = ConstantPool::klass_at_if_loaded(cpool, index); + klass = ConstantPool::klass_at_if_loaded(cpool, index); // Try to look it up by name. if (klass == NULL) { klass_name = cpool->klass_name_at(index); @@ -666,7 +658,6 @@ ciConstant ciEnv::get_constant_by_index_impl(const constantPoolHandle& cpool, int pool_index, int cache_index, ciInstanceKlass* accessor) { bool ignore_will_link; - EXCEPTION_CONTEXT; int index = pool_index; if (cache_index >= 0) { assert(index < 0, "only one kind of index at a time"); @@ -677,12 +668,14 @@ ciConstant ciEnv::get_constant_by_index_impl(const constantPoolHandle& cpool, return ciConstant(T_OBJECT, get_object(NULL)); } BasicType bt = T_OBJECT; - if (cpool->tag_at(index).is_dynamic_constant()) + if (cpool->tag_at(index).is_dynamic_constant()) { bt = Signature::basic_type(cpool->uncached_signature_ref_at(index)); - if (is_reference_type(bt)) { - } else { + } + if (!is_reference_type(bt)) { // we have to unbox the primitive value - if (!is_java_primitive(bt)) return ciConstant(); + if (!is_java_primitive(bt)) { + return ciConstant(); + } jvalue value; BasicType bt2 = java_lang_boxing_object::get_value(obj, &value); assert(bt2 == bt, ""); @@ -717,6 +710,7 @@ ciConstant ciEnv::get_constant_by_index_impl(const constantPoolHandle& cpool, } else if (tag.is_double()) { return ciConstant((jdouble)cpool->double_at(index)); } else if (tag.is_string()) { + EXCEPTION_CONTEXT; oop string = NULL; assert(cache_index >= 0, "should have a cache index"); string = cpool->string_at(index, cache_index, THREAD); @@ -733,24 +727,18 @@ ciConstant ciEnv::get_constant_by_index_impl(const constantPoolHandle& cpool, return ciConstant(T_OBJECT, constant); } } else if (tag.is_unresolved_klass_in_error()) { - return ciConstant(); + return ciConstant(T_OBJECT, get_unloaded_klass_mirror(NULL)); } else if (tag.is_klass() || tag.is_unresolved_klass()) { - // 4881222: allow ldc to take a class type ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore_will_link, accessor); - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; - record_out_of_memory_failure(); - return ciConstant(); - } assert (klass->is_instance_klass() || klass->is_array_klass(), "must be an instance or array klass "); return ciConstant(T_OBJECT, klass->java_mirror()); - } else if (tag.is_method_type()) { + } else if (tag.is_method_type() || tag.is_method_type_in_error()) { // must execute Java code to link this CP entry into cache[i].f1 ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index)); ciObject* ciobj = get_unloaded_method_type_constant(signature); return ciConstant(T_OBJECT, ciobj); - } else if (tag.is_method_handle()) { + } else if (tag.is_method_handle() || tag.is_method_handle_in_error()) { // must execute Java code to link this CP entry into cache[i].f1 int ref_kind = cpool->method_handle_ref_kind_at(index); int callee_index = cpool->method_handle_klass_index_at(index); @@ -759,10 +747,10 @@ ciConstant ciEnv::get_constant_by_index_impl(const constantPoolHandle& cpool, ciSymbol* signature = get_symbol(cpool->method_handle_signature_ref_at(index)); ciObject* ciobj = get_unloaded_method_handle_constant(callee, name, signature, ref_kind); return ciConstant(T_OBJECT, ciobj); - } else if (tag.is_dynamic_constant()) { - return ciConstant(); + } else if (tag.is_dynamic_constant() || tag.is_dynamic_constant_in_error()) { + return ciConstant(); // not supported } else { - ShouldNotReachHere(); + assert(false, "unknown tag: %d (%s)", tag.value(), tag.internal_name()); return ciConstant(); } } diff --git a/src/hotspot/share/ci/ciStreams.cpp b/src/hotspot/share/ci/ciStreams.cpp index a1e6c5bffe8..46f52f19412 100644 --- a/src/hotspot/share/ci/ciStreams.cpp +++ b/src/hotspot/share/ci/ciStreams.cpp @@ -251,6 +251,14 @@ constantTag ciBytecodeStream::get_constant_pool_tag(int index) const { return _method->get_Method()->constants()->constant_tag_at(index); } +// ------------------------------------------------------------------ +// ciBytecodeStream::get_basic_type_for_constant_at +// +BasicType ciBytecodeStream::get_basic_type_for_constant_at(int index) const { + VM_ENTRY_MARK; + return _method->get_Method()->constants()->basic_type_for_constant_at(index); +} + // ------------------------------------------------------------------ // ciBytecodeStream::get_field_index // diff --git a/src/hotspot/share/ci/ciStreams.hpp b/src/hotspot/share/ci/ciStreams.hpp index 8f46510a0d2..e46b2e2bfa2 100644 --- a/src/hotspot/share/ci/ciStreams.hpp +++ b/src/hotspot/share/ci/ciStreams.hpp @@ -140,7 +140,7 @@ public: bool is_wide() const { return ( _pc == _was_wide ); } - // Does this instruction contain an index which refes into the CP cache? + // Does this instruction contain an index which refers into the CP cache? bool has_cache_index() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); } int get_index_u1() const { @@ -226,8 +226,9 @@ public: // constant. Do not attempt to resolve it, since that would require // execution of Java code. If it is not resolved, return an unloaded // object (ciConstant.as_object()->is_loaded() == false). - ciConstant get_constant(); + ciConstant get_constant(); constantTag get_constant_pool_tag(int index) const; + BasicType get_basic_type_for_constant_at(int index) const; // True if the klass-using bytecode points to an unresolved klass bool is_unresolved_klass() const { @@ -235,9 +236,17 @@ public: return tag.is_unresolved_klass(); } - bool is_unresolved_klass_in_error() const { - constantTag tag = get_constant_pool_tag(get_klass_index()); - return tag.is_unresolved_klass_in_error(); + bool is_in_error() const { + assert(cur_bc() == Bytecodes::_ldc || + cur_bc() == Bytecodes::_ldc_w || + cur_bc() == Bytecodes::_ldc2_w, "not supported: %s", Bytecodes::name(cur_bc())); + + int index = get_constant_pool_index(); + constantTag tag = get_constant_pool_tag(index); + return tag.is_unresolved_klass_in_error() || + tag.is_method_handle_in_error() || + tag.is_method_type_in_error() || + tag.is_dynamic_constant_in_error(); } // If this bytecode is one of get_field, get_static, put_field, diff --git a/src/hotspot/share/ci/ciTypeFlow.cpp b/src/hotspot/share/ci/ciTypeFlow.cpp index fc8553aac48..2d7c60356d1 100644 --- a/src/hotspot/share/ci/ciTypeFlow.cpp +++ b/src/hotspot/share/ci/ciTypeFlow.cpp @@ -720,6 +720,11 @@ void ciTypeFlow::StateVector::do_jsr(ciBytecodeStream* str) { // ------------------------------------------------------------------ // ciTypeFlow::StateVector::do_ldc void ciTypeFlow::StateVector::do_ldc(ciBytecodeStream* str) { + if (str->is_in_error()) { + trap(str, NULL, Deoptimization::make_trap_request(Deoptimization::Reason_unhandled, + Deoptimization::Action_none)); + return; + } ciConstant con = str->get_constant(); if (con.is_valid()) { BasicType basic_type = con.basic_type(); @@ -735,14 +740,10 @@ void ciTypeFlow::StateVector::do_ldc(ciBytecodeStream* str) { push_translate(ciType::make(basic_type)); } } else { - if (str->is_unresolved_klass_in_error()) { - trap(str, NULL, Deoptimization::make_trap_request(Deoptimization::Reason_unhandled, - Deoptimization::Action_none)); - } else { - // OutOfMemoryError in the CI while loading constant - push_null(); - outer()->record_failure("ldc did not link"); - } + // OutOfMemoryError in the CI while loading constant. + // Unresolved condy also lands here (not yet supported). + push_null(); + outer()->record_failure("ldc did not link"); } } @@ -2173,7 +2174,7 @@ bool ciTypeFlow::can_trap(ciBytecodeStream& str) { case Bytecodes::_ldc: case Bytecodes::_ldc_w: case Bytecodes::_ldc2_w: - return str.is_unresolved_klass_in_error(); + return str.is_in_error(); case Bytecodes::_aload_0: // These bytecodes can trap for rewriting. We need to assume that diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index 1ff1abbb57d..d12ccd64cb6 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -885,11 +885,9 @@ void ConstantPool::save_and_throw_exception(const constantPoolHandle& this_cp, i constantTag ConstantPool::constant_tag_at(int which) { constantTag tag = tag_at(which); - if (tag.is_dynamic_constant() || - tag.is_dynamic_constant_in_error()) { + if (tag.is_dynamic_constant()) { BasicType bt = basic_type_for_constant_at(which); - // dynamic constant could return an array, treat as object - return constantTag::ofBasicType(is_reference_type(bt) ? T_OBJECT : bt); + return constantTag(constantTag::type2tag(bt)); } return tag; } @@ -976,7 +974,6 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp, switch (tag.value()) { case JVM_CONSTANT_UnresolvedClass: - case JVM_CONSTANT_UnresolvedClassInError: case JVM_CONSTANT_Class: { assert(cache_index == _no_index_sentinel, "should not have been set"); @@ -1044,14 +1041,6 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp, result_oop = string_at_impl(this_cp, index, cache_index, CHECK_NULL); break; - case JVM_CONSTANT_DynamicInError: - case JVM_CONSTANT_MethodHandleInError: - case JVM_CONSTANT_MethodTypeInError: - { - throw_resolution_error(this_cp, index, CHECK_NULL); - break; - } - case JVM_CONSTANT_MethodHandle: { int ref_kind = this_cp->method_handle_ref_kind_at(index); @@ -1065,11 +1054,14 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp, callee_index, name->as_C_string(), signature->as_C_string()); } - Klass* callee = klass_at_impl(this_cp, callee_index, CHECK_NULL); + Klass* callee = klass_at_impl(this_cp, callee_index, THREAD); + if (HAS_PENDING_EXCEPTION) { + save_and_throw_exception(this_cp, index, tag, CHECK_NULL); + } // Check constant pool method consistency if ((callee->is_interface() && m_tag.is_method()) || - ((!callee->is_interface() && m_tag.is_interface_method()))) { + (!callee->is_interface() && m_tag.is_interface_method())) { ResourceMark rm(THREAD); stringStream ss; ss.print("Inconsistent constant pool data in classfile for class %s. " @@ -1081,17 +1073,18 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp, index, callee->is_interface() ? "CONSTANT_MethodRef" : "CONSTANT_InterfaceMethodRef", callee->is_interface() ? "CONSTANT_InterfaceMethodRef" : "CONSTANT_MethodRef"); - THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), ss.as_string()); + Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IncompatibleClassChangeError(), "%s", ss.as_string()); + save_and_throw_exception(this_cp, index, tag, CHECK_NULL); } Klass* klass = this_cp->pool_holder(); Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind, callee, name, signature, THREAD); - result_oop = value(); if (HAS_PENDING_EXCEPTION) { save_and_throw_exception(this_cp, index, tag, CHECK_NULL); } + result_oop = value(); break; } @@ -1136,10 +1129,15 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp, result_oop = java_lang_boxing_object::create(T_DOUBLE, &prim_value, CHECK_NULL); break; + case JVM_CONSTANT_UnresolvedClassInError: + case JVM_CONSTANT_DynamicInError: + case JVM_CONSTANT_MethodHandleInError: + case JVM_CONSTANT_MethodTypeInError: + throw_resolution_error(this_cp, index, CHECK_NULL); + break; + default: - DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d", - this_cp(), index, cache_index, tag.value())); - assert(false, "unexpected constant tag"); + fatal("unexpected constant tag at CP %p[%d/%d] = %d", this_cp(), index, cache_index, tag.value()); break; } diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp index 7ad08841476..14cca6cac26 100644 --- a/src/hotspot/share/opto/parse2.cpp +++ b/src/hotspot/share/opto/parse2.cpp @@ -1865,33 +1865,35 @@ void Parse::do_one_bytecode() { case Bytecodes::_bipush: push(intcon(iter().get_constant_u1())); break; case Bytecodes::_sipush: push(intcon(iter().get_constant_u2())); break; case Bytecodes::_aconst_null: push(null()); break; + case Bytecodes::_ldc: case Bytecodes::_ldc_w: - case Bytecodes::_ldc2_w: - // If the constant is unresolved, run this BC once in the interpreter. - { - ciConstant constant = iter().get_constant(); - if (!constant.is_valid() || - (constant.basic_type() == T_OBJECT && - !constant.as_object()->is_loaded())) { - int index = iter().get_constant_pool_index(); - constantTag tag = iter().get_constant_pool_tag(index); - uncommon_trap(Deoptimization::make_trap_request - (Deoptimization::Reason_unloaded, - Deoptimization::Action_reinterpret, - index), - NULL, tag.internal_name()); - break; - } + case Bytecodes::_ldc2_w: { + ciConstant constant = iter().get_constant(); + if (constant.is_loaded()) { assert(constant.basic_type() != T_OBJECT || constant.as_object()->is_instance(), "must be java_mirror of klass"); const Type* con_type = Type::make_from_constant(constant); if (con_type != NULL) { push_node(con_type->basic_type(), makecon(con_type)); } - } + } else { + // If the constant is unresolved or in error state, run this BC in the interpreter. + if (iter().is_in_error()) { + uncommon_trap(Deoptimization::make_trap_request(Deoptimization::Reason_unhandled, + Deoptimization::Action_none), + NULL, "constant in error state", true /* must_throw */); + } else { + int index = iter().get_constant_pool_index(); + uncommon_trap(Deoptimization::make_trap_request(Deoptimization::Reason_unloaded, + Deoptimization::Action_reinterpret, + index), + NULL, "unresolved constant", false /* must_throw */); + } + } break; + } case Bytecodes::_aload_0: push( local(0) ); diff --git a/src/hotspot/share/utilities/constantTag.hpp b/src/hotspot/share/utilities/constantTag.hpp index 4926eafa81c..d826fc0acc0 100644 --- a/src/hotspot/share/utilities/constantTag.hpp +++ b/src/hotspot/share/utilities/constantTag.hpp @@ -86,6 +86,13 @@ class constantTag { return _tag == JVM_CONSTANT_DynamicInError; } + bool is_in_error() const { + return is_unresolved_klass_in_error() || + is_method_handle_in_error() || + is_method_type_in_error() || + is_dynamic_constant_in_error(); + } + bool is_klass_index() const { return _tag == JVM_CONSTANT_ClassIndex; } bool is_string_index() const { return _tag == JVM_CONSTANT_StringIndex; } @@ -121,18 +128,24 @@ class constantTag { _tag = tag; } - static constantTag ofBasicType(BasicType bt) { - if (is_subword_type(bt)) bt = T_INT; + static jbyte type2tag(BasicType bt) { + if (is_subword_type(bt)) { + bt = T_INT; + } + if (bt == T_ARRAY) { + bt = T_OBJECT; + } switch (bt) { - case T_OBJECT: return constantTag(JVM_CONSTANT_String); - case T_INT: return constantTag(JVM_CONSTANT_Integer); - case T_LONG: return constantTag(JVM_CONSTANT_Long); - case T_FLOAT: return constantTag(JVM_CONSTANT_Float); - case T_DOUBLE: return constantTag(JVM_CONSTANT_Double); - default: break; + case T_INT: return JVM_CONSTANT_Integer; + case T_LONG: return JVM_CONSTANT_Long; + case T_FLOAT: return JVM_CONSTANT_Float; + case T_DOUBLE: return JVM_CONSTANT_Double; + case T_OBJECT: return JVM_CONSTANT_String; + + default: + assert(false, "not supported: %s", type2name(bt)); + return JVM_CONSTANT_Invalid; } - assert(false, "bad basic type for tag"); - return constantTag(); } jbyte value() const { return _tag; } diff --git a/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java b/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java new file mode 100644 index 00000000000..be5225bee4c --- /dev/null +++ b/test/hotspot/jtreg/compiler/runtime/TestConstantsInError.java @@ -0,0 +1,283 @@ +/* + * 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. + * + * 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 8279822 + * @requires vm.flagless + * @library /test/lib + * @modules java.base/jdk.internal.org.objectweb.asm + * + * @run main compiler.runtime.TestConstantsInError + */ +package compiler.runtime; + +import jdk.internal.org.objectweb.asm.*; +import jdk.test.lib.Platform; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandleProxies; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.ArrayList; +import java.util.List; + +import static jdk.internal.org.objectweb.asm.ClassWriter.*; +import static jdk.internal.org.objectweb.asm.Opcodes.*; + +interface OutputProcessor { + default void process(OutputAnalyzer output, boolean isC1) {} +} + +public abstract class TestConstantsInError implements OutputProcessor { + static final String TEST_PREFIX = class2desc(TestConstantsInError.class) + "$Test"; + + public interface Test extends Runnable {} + + + interface Generator { + void generate(MethodVisitor mv); + } + + static String class2desc(Class cls) { + return cls.getName().replace('.', '/'); + } + + public static final String PATH = System.getProperty("test.classes", ".") + java.io.File.separator; + + static byte[] generateClassFile(String suffix, Generator g) throws IOException { + var cw = new ClassWriter(COMPUTE_MAXS | COMPUTE_FRAMES); + String name = TEST_PREFIX + "_" + suffix; + cw.visit(V19, ACC_PUBLIC | ACC_SUPER, name, null, "java/lang/Object", null); + + { + var mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "test", "()V", null, null); + mv.visitCode(); + g.generate(mv); + mv.visitInsn(RETURN); + mv.visitMaxs(0, 0); + } + byte[] classFile = cw.toByteArray(); + + try (FileOutputStream fos = new FileOutputStream(PATH + name + ".class")) { + fos.write(classFile); + } + + return classFile; + } + + static Test generate(String suffix, Class expectedError, Generator g) { + try { + byte[] classFile = generateClassFile(suffix, g); + MethodHandles.Lookup testLookup = MethodHandles.lookup().defineHiddenClass(classFile, true); + MethodHandle testMH = testLookup.findStatic(testLookup.lookupClass(), "test", MethodType.methodType(void.class)); + + testMH = MethodHandles.filterReturnValue(testMH, + MethodHandles.insertArguments( + MethodHandles.throwException(void.class, AssertionError.class), + 0, new AssertionError("no exception thrown"))); + + // Install empty handler for linkage exceptions. + testMH = MethodHandles.catchException(testMH, expectedError, + MethodHandles.empty(MethodType.methodType(void.class, expectedError))); + + return MethodHandleProxies.asInterfaceInstance(Test.class, testMH); + } catch (Throwable e) { + throw new InternalError(e); + } + } + + static void run(String name, Class expectedError, Generator g) { + Test test = generate(name, expectedError, g); + for (int i = 0; i < 1000; i++) { + test.run(); + } + } + + static class TestConstantClass extends TestConstantsInError { + public static void main(String[] args) { + run("C1", NoClassDefFoundError.class, mv -> mv.visitLdcInsn(Type.getType("LUnknownClass;"))); // non-existent class + run("C2", IllegalAccessError.class, mv -> mv.visitLdcInsn(Type.getType("Ljava/lang/invoke/LambdaForm;"))); // inaccessible + + // class loader constraints? + } + + public void process(OutputAnalyzer results, boolean isC1) { + results.shouldMatch("Test_C1/.*::test \\(3 bytes\\)$") + .shouldMatch("Test_C2/.*::test \\(3 bytes\\)$"); + + if (isC1 && Platform.isAArch64()) { // no code patching + results.shouldMatch("Test_C1/.*::test \\(3 bytes\\) made not entrant") + .shouldMatch("Test_C2/.*::test \\(3 bytes\\) made not entrant"); + } else { + results.shouldNotContain("made not entrant"); + } + } + + public void processC2(OutputAnalyzer results) { + results.shouldNotContain("made not entrant"); + } + } + + static class TestConstantMethodHandle extends TestConstantsInError { + public static void main(String[] args) { + // Non-existent holder class + run("MH1", NoClassDefFoundError.class, + mv -> mv.visitLdcInsn(new Handle(H_INVOKESTATIC, "UnknownClass", "ignored", "()V", false))); + + // Inaccessible holder class + run("MH2", IllegalAccessError.class, + mv -> mv.visitLdcInsn(new Handle(H_INVOKESTATIC, "java/lang/invoke/LambdaForm", "ignored", "()V", false))); + + // Method vs InterfaceMethod mismatch + run("MH3", IncompatibleClassChangeError.class, + mv -> mv.visitLdcInsn(new Handle(H_INVOKESTATIC, "java/lang/Object", "ignored", "()V", true))); + + // Non-existent method + run("MH4", NoSuchMethodError.class, + mv -> mv.visitLdcInsn(new Handle(H_INVOKESTATIC, "java/lang/Object", "cast", "()V", false))); + } + + public void process(OutputAnalyzer results, boolean isC1) { + results.shouldMatch("Test_MH1/.*::test \\(3 bytes\\)$") + .shouldMatch("Test_MH2/.*::test \\(3 bytes\\)$") + .shouldMatch("Test_MH3/.*::test \\(3 bytes\\)$") + .shouldMatch("Test_MH4/.*::test \\(3 bytes\\)$"); + + if (isC1 && Platform.isAArch64()) { // no code patching + results.shouldMatch("Test_MH1/.*::test \\(3 bytes\\) made not entrant") + .shouldMatch("Test_MH2/.*::test \\(3 bytes\\) made not entrant") + .shouldMatch("Test_MH3/.*::test \\(3 bytes\\) made not entrant") + .shouldMatch("Test_MH4/.*::test \\(3 bytes\\) made not entrant"); + } else { + results.shouldNotContain("made not entrant"); + } + } + } + + static class TestConstantMethodType extends TestConstantsInError { + public static void main(String[] args) { + run("MT1", NoClassDefFoundError.class, + mv -> mv.visitLdcInsn(Type.getMethodType("(LUnknownClass;)V"))); + run("MT2", NoClassDefFoundError.class, + mv -> mv.visitLdcInsn(Type.getMethodType("()LUnknownClass;"))); + } + + public void process(OutputAnalyzer results, boolean isC1) { + results.shouldMatch("Test_MT1/.*::test \\(3 bytes\\)$") + .shouldMatch("Test_MT2/.*::test \\(3 bytes\\)$"); + + if (isC1 && Platform.isAArch64()) { // no code patching + results.shouldMatch("Test_MT1/.*::test \\(3 bytes\\) made not entrant") + .shouldMatch("Test_MT2/.*::test \\(3 bytes\\) made not entrant"); + } else { + results.shouldNotContain("made not entrant"); + } + } + } + + static class TestConstantDynamic extends TestConstantsInError { + static int bsm1() throws Exception { + throw new AssertionError("should not be invoked"); + } + + static int bsm2(MethodHandles.Lookup lookup, String name, Class c) throws Exception { + throw new Exception("expected"); + } + + static final Handle BSM1 = new Handle(H_INVOKESTATIC, class2desc(TestConstantDynamic.class), "bsm1", "()I", false); + static final Handle BSM2 = new Handle(H_INVOKESTATIC, class2desc(TestConstantDynamic.class), "bsm2", + "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)I", + false); + + public static void main(String[] args) { + run("CD1", NoClassDefFoundError.class, + mv -> { + Handle bsm = new Handle(H_INVOKESTATIC, "UnknownClass", "unknown", "()LUnknownClass;", false); + mv.visitLdcInsn(new ConstantDynamic("tmp", "LUnknownClass;", bsm)); + }); + run("CD2", NoSuchMethodError.class, + mv -> { + Handle bsm = new Handle(H_INVOKESTATIC, class2desc(TestConstantDynamic.class), "unknown", "()I", false); + mv.visitLdcInsn(new ConstantDynamic("tmp", "LUnknownClass;", bsm)); + }); + run("CD3", BootstrapMethodError.class, mv -> mv.visitLdcInsn(new ConstantDynamic("tmp", "I", BSM1))); + run("CD4", BootstrapMethodError.class, mv -> mv.visitLdcInsn(new ConstantDynamic("tmp", "I", BSM2))); + } + + public void process(OutputAnalyzer results, boolean isC1) { + if (isC1) { + results.shouldMatch("Test_CD1.*::test \\(3 bytes\\) COMPILE SKIPPED: could not resolve a constant") + .shouldMatch("Test_CD2.*::test \\(3 bytes\\) COMPILE SKIPPED: could not resolve a constant") + .shouldMatch("Test_CD3.*::test \\(3 bytes\\) COMPILE SKIPPED: could not resolve a constant") + .shouldMatch("Test_CD4.*::test \\(3 bytes\\) COMPILE SKIPPED: could not resolve a constant"); + } else { + results.shouldMatch("Test_CD1.*::test \\(3 bytes\\)$") + .shouldMatch("Test_CD2.*::test \\(3 bytes\\)$") + .shouldMatch("Test_CD3.*::test \\(3 bytes\\)$") + .shouldMatch("Test_CD4.*::test \\(3 bytes\\)$"); + } + } + } + + static void run(TestConstantsInError test) throws Exception { + List commonArgs = List.of( + "--add-exports", "java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED", + "-Xbatch", "-XX:CompileThreshold=100", + "-XX:CompileCommand=quiet", "-XX:CompileCommand=compileonly,*::test", + "-XX:+PrintCompilation", + "-XX:CompileCommand=print,*::test", + "-Dtest.classes=" + System.getProperty("test.classes", "."), + "-XX:+IgnoreUnrecognizedVMOptions", + test.getClass().getName()); + + ArrayList c1Args = new ArrayList<>(); + c1Args.addAll(List.of("-XX:+TieredCompilation", "-XX:TieredStopAtLevel=1", "-XX:+TracePatching")); + c1Args.addAll(commonArgs); + + OutputAnalyzer outputC1 = ProcessTools.executeTestJvm(c1Args) + .shouldHaveExitValue(0); + + test.process(outputC1, true); + + ArrayList c2Args = new ArrayList<>(); + c2Args.add("-XX:-TieredCompilation"); + c2Args.addAll(commonArgs); + + OutputAnalyzer outputC2 = ProcessTools.executeTestJvm(c2Args) + .shouldHaveExitValue(0); + + test.process(outputC2, false); + } + + public static void main(String[] args) throws Exception { + run(new TestConstantClass()); + run(new TestConstantMethodType()); + run(new TestConstantMethodHandle()); + run(new TestConstantDynamic()); + } +} -- GitLab From 178b962e01cc6c150442bf41dc6bd199caff0042 Mon Sep 17 00:00:00 2001 From: Hai-May Chao Date: Wed, 9 Feb 2022 16:53:48 +0000 Subject: [PATCH 193/400] 8265765: DomainKeyStore may stop enumerating aliases if a constituting KeyStore is empty Reviewed-by: weijun --- .../sun/security/provider/DomainKeyStore.java | 16 ++- .../KeyStore/DksWithEmptyKeystore.java | 125 ++++++++++++++++++ 2 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 test/jdk/sun/security/provider/KeyStore/DksWithEmptyKeystore.java diff --git a/src/java.base/share/classes/sun/security/provider/DomainKeyStore.java b/src/java.base/share/classes/sun/security/provider/DomainKeyStore.java index be0e91a55a3..588f2ed78e6 100644 --- a/src/java.base/share/classes/sun/security/provider/DomainKeyStore.java +++ b/src/java.base/share/classes/sun/security/provider/DomainKeyStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -419,20 +419,22 @@ abstract class DomainKeyStore extends KeyStoreSpi { if (aliases.hasMoreElements()) { return true; } else { - if (iterator.hasNext()) { + while (iterator.hasNext()) { keystoresEntry = iterator.next(); prefix = keystoresEntry.getKey() + - entryNameSeparator; + entryNameSeparator; aliases = keystoresEntry.getValue().aliases(); - } else { - return false; + if (aliases.hasMoreElements()) { + return true; + } else { + continue; + } } + return false; } } catch (KeyStoreException e) { return false; } - - return aliases.hasMoreElements(); } public String nextElement() { diff --git a/test/jdk/sun/security/provider/KeyStore/DksWithEmptyKeystore.java b/test/jdk/sun/security/provider/KeyStore/DksWithEmptyKeystore.java new file mode 100644 index 00000000000..050c470a3d0 --- /dev/null +++ b/test/jdk/sun/security/provider/KeyStore/DksWithEmptyKeystore.java @@ -0,0 +1,125 @@ +/* + * 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. + * + * 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 8265765 + * @summary Test DomainKeyStore with a collection of keystores that has an empty one in between + * based on the test in the bug report + */ + +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.DomainLoadStoreParameter; +import java.security.KeyStore; +import java.util.Enumeration; +import java.util.LinkedHashMap; +import java.util.Map; +import javax.crypto.KeyGenerator; + +public class DksWithEmptyKeystore { + private static void write(Path p, KeyStore keystore) throws Exception { + try (OutputStream outputStream = Files.newOutputStream(p)) { + keystore.store(outputStream, new char[] { 'x' }); + } + } + + public static void main(String[] args) throws Exception { + KeyGenerator kg = KeyGenerator.getInstance("AES"); + kg.init(256); + + // Create a keystore with one key + KeyStore nonEmptyKeystore = KeyStore.getInstance("PKCS12"); + nonEmptyKeystore.load(null, null); + + Path nonEmptyPath = Path.of("non_empty.p12"); + nonEmptyKeystore.setKeyEntry("aeskey", kg.generateKey(), new char[] { 'a' }, null); + write(nonEmptyPath, nonEmptyKeystore); + + // Create an empty keystore + KeyStore emptyKeystore = KeyStore.getInstance("PKCS12"); + emptyKeystore.load(null, null); + + Path emptyPath = Path.of("empty.p12"); + write(emptyPath, emptyKeystore); + + // Create a domain keystore with two non-empty keystores + Path dksWithTwoPartsPath = Path.of("two-parts.dks"); + var twoPartsConfiguration = """ + domain Combo { + keystore a keystoreURI="%s"; + keystore b keystoreURI="%s"; + }; + """; + Files.writeString(dksWithTwoPartsPath, String.format(twoPartsConfiguration, + nonEmptyPath.toUri(), nonEmptyPath.toUri())); + Map protectionParameters = new LinkedHashMap<>(); + + KeyStore dksKeystore = KeyStore.getInstance("DKS"); + dksKeystore.load(new DomainLoadStoreParameter(dksWithTwoPartsPath.toUri(), protectionParameters)); + System.out.printf("%s size: %d%n", dksWithTwoPartsPath, dksKeystore.size()); + + int index = 0; + for (Enumeration enumeration = dksKeystore.aliases(); enumeration.hasMoreElements(); ) { + System.out.printf("%d: %s%n", index, enumeration.nextElement()); + index++; + } + + System.out.printf("enumerated aliases from %s: %d%n", dksWithTwoPartsPath, index); + if (index != dksKeystore.size()) { + throw new Exception("Failed to get the number of aliases in the domain keystore " + + "that has two keystores."); + } + + // Create a domain keystore with two non-empty keystores and an empty one in between + Path dksWithThreePartsPath = Path.of("three-parts.dks"); + var threePartsConfiguration = """ + domain Combo { + keystore a keystoreURI="%s"; + keystore b keystoreURI="%s"; + keystore c keystoreURI="%s"; + }; + """; + Files.writeString(dksWithThreePartsPath, String.format(threePartsConfiguration, + nonEmptyPath.toUri(), emptyPath.toUri(), nonEmptyPath.toUri())); + + KeyStore dksKeystore1 = KeyStore.getInstance("DKS"); + dksKeystore1.load(new DomainLoadStoreParameter(dksWithThreePartsPath.toUri(), protectionParameters)); + System.out.printf("%s size: %d%n", dksWithThreePartsPath, dksKeystore1.size()); + + index = 0; + for (Enumeration enumeration = dksKeystore1.aliases(); enumeration.hasMoreElements(); ) { + System.out.printf("%d: %s%n", index, enumeration.nextElement()); + index++; + } + + System.out.printf("enumerated aliases from %s: %d%n", dksWithThreePartsPath, index); + if (index != dksKeystore1.size()) { + throw new Exception("Failed to get the number of aliases in the domain keystore " + + "that has three keystores with an empty one in between."); + } else { + System.out.printf("Test completed successfully"); + } + } +} -- GitLab From fd8a3dcc52dc5d6b62edd83eacef5934f6294e80 Mon Sep 17 00:00:00 2001 From: Alexey Ivanov Date: Wed, 9 Feb 2022 19:12:20 +0000 Subject: [PATCH 194/400] 8280820: Clean up bug8033699 and bug8075609.java tests: regtesthelpers aren't used Reviewed-by: prr --- .../JRadioButton/8033699/bug8033699.java | 63 +++++++++---------- .../JRadioButton/8075609/bug8075609.java | 60 +++++++++--------- 2 files changed, 62 insertions(+), 61 deletions(-) diff --git a/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java b/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java index 06622f71819..9365e6ba45b 100644 --- a/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java +++ b/test/jdk/javax/swing/JRadioButton/8033699/bug8033699.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -21,11 +21,9 @@ * questions. */ - /* +/* * @test * @key headful - * @library ../../regtesthelpers - * @build Util * @bug 8033699 8154043 8167160 8208640 8226892 * @summary Incorrect radio button behavior when pressing tab key * @run main bug8033699 @@ -34,8 +32,7 @@ import java.awt.KeyboardFocusManager; import java.awt.Robot; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; -import java.util.logging.Level; -import java.util.logging.Logger; + import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; @@ -45,7 +42,6 @@ import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.SwingUtilities; import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; public class bug8033699 { @@ -59,7 +55,7 @@ public class bug8033699 { private static JRadioButton radioBtn3; private static JRadioButton radioBtnSingle; - public static void main(String args[]) throws Throwable { + public static void main(String[] args) throws Throwable { SwingUtilities.invokeAndWait(() -> { changeLAF(); createAndShowGUI(); @@ -67,6 +63,7 @@ public class bug8033699 { robot = new Robot(); Thread.sleep(100); + robot.waitForIdle(); robot.setAutoDelay(100); @@ -76,7 +73,7 @@ public class bug8033699 { // tab key test non-grouped radio button runTest2(); - // shift tab key test grouped and non grouped radio button + // shift tab key test grouped and non-grouped radio button runTest3(); // left/up key test in grouped radio button @@ -152,16 +149,16 @@ public class bug8033699 { mainFrame.setLayout(new BoxLayout(mainFrame.getContentPane(), BoxLayout.Y_AXIS)); mainFrame.setSize(300, 300); - mainFrame.setLocation(200, 200); + mainFrame.setLocationRelativeTo(null); mainFrame.setVisible(true); mainFrame.toFront(); } // Radio button Group as a single component when traversing through tab key private static void runTest1() throws Exception { - hitKey(robot, KeyEvent.VK_TAB); - hitKey(robot, KeyEvent.VK_TAB); - hitKey(robot, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtnSingle) { @@ -173,7 +170,7 @@ public class bug8033699 { // Non-Grouped Radio button as a single component when traversing through tab key private static void runTest2() throws Exception { - hitKey(robot, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != btnEnd) { System.out.println("Non Grouped Radio Button Go To Next Component through Tab Key failed"); @@ -184,9 +181,9 @@ public class bug8033699 { // Non-Grouped Radio button and Group Radio button as a single component when traversing through shift-tab key private static void runTest3() throws Exception { - hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); - hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); - hitKey(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_SHIFT, KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn1) { System.out.println("Radio button Group/Non Grouped Radio Button SHIFT-Tab Key Test failed"); @@ -197,8 +194,8 @@ public class bug8033699 { // Using arrow key to move focus in radio button group private static void runTest4() throws Exception { - hitKey(robot, KeyEvent.VK_DOWN); - hitKey(robot, KeyEvent.VK_RIGHT); + hitKey(KeyEvent.VK_DOWN); + hitKey(KeyEvent.VK_RIGHT); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn3) { System.out.println("Radio button Group UP/LEFT Arrow Key Move Focus Failed"); @@ -208,8 +205,8 @@ public class bug8033699 { } private static void runTest5() throws Exception { - hitKey(robot, KeyEvent.VK_UP); - hitKey(robot, KeyEvent.VK_LEFT); + hitKey(KeyEvent.VK_UP); + hitKey(KeyEvent.VK_LEFT); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn1) { System.out.println("Radio button Group Left/Up Arrow Key Move Focus Failed"); @@ -219,8 +216,8 @@ public class bug8033699 { } private static void runTest6() throws Exception { - hitKey(robot, KeyEvent.VK_UP); - hitKey(robot, KeyEvent.VK_UP); + hitKey(KeyEvent.VK_UP); + hitKey(KeyEvent.VK_UP); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtn2) { System.out.println("Radio button Group Circle Back To First Button Test"); @@ -230,7 +227,7 @@ public class bug8033699 { } private static void runTest7() throws Exception { - hitKey(robot, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != btnMiddle) { System.out.println("Separate Component added in button group layout"); @@ -240,7 +237,7 @@ public class bug8033699 { } private static void runTest8() throws Exception { - hitKey(robot, KeyEvent.VK_TAB); + hitKey(KeyEvent.VK_TAB); SwingUtilities.invokeAndWait(() -> { if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() != radioBtnSingle) { System.out.println("Separate Component added in button group layout"); @@ -249,9 +246,9 @@ public class bug8033699 { }); } - private static Boolean actRB1 = false; - private static Boolean actRB2 = false; - private static Boolean actRB3 = false; + private static boolean actRB1 = false; + private static boolean actRB2 = false; + private static boolean actRB3 = false; // JDK-8226892: Verify that ActionListener is called when a RadioButton is selected using arrow key. private static void runTest9() throws Exception { @@ -268,9 +265,9 @@ public class bug8033699 { radioBtn2.addActionListener(actLrRB2); radioBtn3.addActionListener(actLrRB3); - hitKey(robot, KeyEvent.VK_DOWN); - hitKey(robot, KeyEvent.VK_DOWN); - hitKey(robot, KeyEvent.VK_DOWN); + hitKey(KeyEvent.VK_DOWN); + hitKey(KeyEvent.VK_DOWN); + hitKey(KeyEvent.VK_DOWN); String failMessage = "ActionListener not invoked when selected using arrow key."; if (!actRB2) { @@ -288,13 +285,13 @@ public class bug8033699 { radioBtn3.removeActionListener(actLrRB3); } - private static void hitKey(Robot robot, int keycode) { + private static void hitKey(int keycode) { robot.keyPress(keycode); robot.keyRelease(keycode); robot.waitForIdle(); } - private static void hitKey(Robot robot, int mode, int keycode) { + private static void hitKey(int mode, int keycode) { robot.keyPress(mode); robot.keyPress(keycode); robot.keyRelease(keycode); diff --git a/test/jdk/javax/swing/JRadioButton/8075609/bug8075609.java b/test/jdk/javax/swing/JRadioButton/8075609/bug8075609.java index 31c99206b7a..4c29a33ffa0 100644 --- a/test/jdk/javax/swing/JRadioButton/8075609/bug8075609.java +++ b/test/jdk/javax/swing/JRadioButton/8075609/bug8075609.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -21,44 +21,49 @@ * questions. */ - /* +/* * @test * @key headful - * @library ../../regtesthelpers - * @build Util * @bug 8075609 * @summary IllegalArgumentException when transferring focus from JRadioButton using tab - * @author Vivi An * @run main bug8075609 */ - -import javax.swing.*; -import javax.swing.event.*; -import java.awt.event.*; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Robot; +import java.awt.event.KeyEvent; + +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JRadioButton; +import javax.swing.JTextField; +import javax.swing.LayoutFocusTraversalPolicy; +import javax.swing.SwingUtilities; public class bug8075609 { private static Robot robot; private static JTextField textField; private static JFrame mainFrame; - public static void main(String args[]) throws Throwable { + public static void main(String[] args) throws Throwable { try { - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - createAndShowGUI(); - } - }); + SwingUtilities.invokeAndWait(bug8075609::createAndShowGUI); robot = new Robot(); Thread.sleep(100); + robot.waitForIdle(); robot.setAutoDelay(100); // Radio button group tab key test runTest1(); } finally { - if (mainFrame != null) SwingUtilities.invokeAndWait(() -> mainFrame.dispose()); + SwingUtilities.invokeAndWait(() -> { + if (mainFrame != null) { + mainFrame.dispose(); + } + }); } } @@ -91,26 +96,25 @@ public class bug8075609 { mainFrame.add(rootPanel); mainFrame.pack(); + mainFrame.setLocationRelativeTo(null); mainFrame.setVisible(true); mainFrame.toFront(); } // Radio button Group as a single component when traversing through tab key - private static void runTest1() throws Exception{ - hitKey(robot, KeyEvent.VK_TAB); - - robot.delay(1000 ); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - if (!textField.hasFocus()) { - System.out.println("Radio Button Group Go To Next Component through Tab Key failed"); - throw new RuntimeException("Focus is not on textField as Expected"); - } + private static void runTest1() throws Exception { + hitKey(KeyEvent.VK_TAB); + + robot.delay(1000); + SwingUtilities.invokeAndWait(() -> { + if (!textField.hasFocus()) { + System.out.println("Radio Button Group Go To Next Component through Tab Key failed"); + throw new RuntimeException("Focus is not on textField as Expected"); } }); } - private static void hitKey(Robot robot, int keycode) { + private static void hitKey(int keycode) { robot.keyPress(keycode); robot.keyRelease(keycode); robot.waitForIdle(); -- GitLab From 7218d8449bfaa3f121b66088a88a194f77f06753 Mon Sep 17 00:00:00 2001 From: John Jiang Date: Thu, 10 Feb 2022 08:11:08 +0000 Subject: [PATCH 195/400] 8281567: Remove @throws IOException from X509CRLImpl::getExtension docs Reviewed-by: xuelei, jiefu --- src/java.base/share/classes/sun/security/x509/X509CRLImpl.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java b/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java index 1523cde227d..551e38ad31c 100644 --- a/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java +++ b/src/java.base/share/classes/sun/security/x509/X509CRLImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -1047,7 +1047,6 @@ public class X509CRLImpl extends X509CRL implements DerEncoder { * * @param oid ObjectIdentifier of extension desired * @return Object of type {@code } or null, if not found - * @throws IOException on error */ public Object getExtension(ObjectIdentifier oid) { if (extensions == null) -- GitLab From fa0a72c030432f9ea4ad9913a2bb4096324410aa Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Thu, 10 Feb 2022 09:29:53 +0000 Subject: [PATCH 196/400] 8252496: C2: Useless code in MergeMemNode::Ideal Reviewed-by: thartmann, chagedorn, vlivanov --- src/hotspot/share/opto/memnode.cpp | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index 815cbb2f450..c2e2e939bf3 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -4752,29 +4752,6 @@ Node *MergeMemNode::Ideal(PhaseGVN *phase, bool can_reshape) { // the base memory might contribute new slices beyond my req() if (old_mbase) grow_to_match(old_mbase); - // Look carefully at the base node if it is a phi. - PhiNode* phi_base; - if (new_base != NULL && new_base->is_Phi()) - phi_base = new_base->as_Phi(); - else - phi_base = NULL; - - Node* phi_reg = NULL; - uint phi_len = (uint)-1; - if (phi_base != NULL) { - phi_reg = phi_base->region(); - phi_len = phi_base->req(); - // see if the phi is unfinished - for (uint i = 1; i < phi_len; i++) { - if (phi_base->in(i) == NULL) { - // incomplete phi; do not look at it yet! - phi_reg = NULL; - phi_len = (uint)-1; - break; - } - } - } - // Note: We do not call verify_sparse on entry, because inputs // can normalize to the base_memory via subsume_node or similar // mechanisms. This method repairs that damage. @@ -4975,7 +4952,6 @@ Node* MergeMemNode::memory_at(uint alias_idx) const { // Otherwise, it is a narrow slice. Node* n = alias_idx < req() ? in(alias_idx) : empty_memory(); - Compile *C = Compile::current(); if (is_empty_memory(n)) { // the array is sparse; empty slots are the "top" node n = base_memory(); -- GitLab From c820d1acb7c6e600a890e4205eef0be8a4c7a791 Mon Sep 17 00:00:00 2001 From: Leo Korinth Date: Thu, 10 Feb 2022 10:34:16 +0000 Subject: [PATCH 197/400] 8281379: Assign package declarations to all jtreg test cases under gc Reviewed-by: kbarrett, tschatzl --- test/hotspot/jtreg/gc/g1/TestG1SkipCompaction.java | 4 +++- test/hotspot/jtreg/gc/g1/numa/TestG1NUMATouchRegions.java | 8 +++++--- test/hotspot/jtreg/gc/z/TestGarbageCollectorMXBean.java | 8 +++++--- test/hotspot/jtreg/gc/z/TestMemoryMXBean.java | 8 +++++--- test/hotspot/jtreg/gc/z/TestMemoryManagerMXBean.java | 6 ++++-- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/test/hotspot/jtreg/gc/g1/TestG1SkipCompaction.java b/test/hotspot/jtreg/gc/g1/TestG1SkipCompaction.java index f5fadcbb880..9824186c43c 100644 --- a/test/hotspot/jtreg/gc/g1/TestG1SkipCompaction.java +++ b/test/hotspot/jtreg/gc/g1/TestG1SkipCompaction.java @@ -21,6 +21,8 @@ * questions. */ +package gc.g1; + /* * @test TestG1SkipCompaction * @summary Test for JDK-8262068 Improve G1 Full GC by skipping compaction @@ -29,7 +31,7 @@ * @library /test/lib * @modules java.base/jdk.internal.misc * java.management - * @run main/othervm -Xms256m -Xmx256m TestG1SkipCompaction + * @run main/othervm -Xms256m -Xmx256m gc.g1.TestG1SkipCompaction */ import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/test/hotspot/jtreg/gc/g1/numa/TestG1NUMATouchRegions.java b/test/hotspot/jtreg/gc/g1/numa/TestG1NUMATouchRegions.java index 6cdbd2c797a..868e5b185f2 100644 --- a/test/hotspot/jtreg/gc/g1/numa/TestG1NUMATouchRegions.java +++ b/test/hotspot/jtreg/gc/g1/numa/TestG1NUMATouchRegions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -21,7 +21,7 @@ * questions. */ -package gc.g1; +package gc.g1.numa; /** * @test TestG1NUMATouchRegions @@ -33,7 +33,9 @@ package gc.g1; * java.management * @build sun.hotspot.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -XX:+UseG1GC -Xbootclasspath/a:. -XX:+UseNUMA -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.g1.TestG1NUMATouchRegions + * @run main/othervm -XX:+UseG1GC -Xbootclasspath/a:. -XX:+UseNUMA + * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * gc.g1.numa.TestG1NUMATouchRegions */ import java.util.LinkedList; diff --git a/test/hotspot/jtreg/gc/z/TestGarbageCollectorMXBean.java b/test/hotspot/jtreg/gc/z/TestGarbageCollectorMXBean.java index e29d75b009c..7a011edd8c9 100644 --- a/test/hotspot/jtreg/gc/z/TestGarbageCollectorMXBean.java +++ b/test/hotspot/jtreg/gc/z/TestGarbageCollectorMXBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -21,13 +21,15 @@ * questions. */ +package gc.z; + /** * @test TestGarbageCollectorMXBean * @requires vm.gc.Z * @summary Test ZGC garbage collector MXBean * @modules java.management - * @run main/othervm -XX:+UseZGC -Xms256M -Xmx512M -Xlog:gc TestGarbageCollectorMXBean 256 512 - * @run main/othervm -XX:+UseZGC -Xms512M -Xmx512M -Xlog:gc TestGarbageCollectorMXBean 512 512 + * @run main/othervm -XX:+UseZGC -Xms256M -Xmx512M -Xlog:gc gc.z.TestGarbageCollectorMXBean 256 512 + * @run main/othervm -XX:+UseZGC -Xms512M -Xmx512M -Xlog:gc gc.z.TestGarbageCollectorMXBean 512 512 */ import java.lang.management.ManagementFactory; diff --git a/test/hotspot/jtreg/gc/z/TestMemoryMXBean.java b/test/hotspot/jtreg/gc/z/TestMemoryMXBean.java index 47545d1bcf5..18c18985759 100644 --- a/test/hotspot/jtreg/gc/z/TestMemoryMXBean.java +++ b/test/hotspot/jtreg/gc/z/TestMemoryMXBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -21,13 +21,15 @@ * questions. */ +package gc.z; + /** * @test TestMemoryMXBean * @requires vm.gc.Z * @summary Test ZGC heap memory MXBean * @modules java.management - * @run main/othervm -XX:+UseZGC -Xms128M -Xmx256M -Xlog:gc* TestMemoryMXBean 128 256 - * @run main/othervm -XX:+UseZGC -Xms256M -Xmx256M -Xlog:gc* TestMemoryMXBean 256 256 + * @run main/othervm -XX:+UseZGC -Xms128M -Xmx256M -Xlog:gc* gc.z.TestMemoryMXBean 128 256 + * @run main/othervm -XX:+UseZGC -Xms256M -Xmx256M -Xlog:gc* gc.z.TestMemoryMXBean 256 256 */ import java.lang.management.ManagementFactory; diff --git a/test/hotspot/jtreg/gc/z/TestMemoryManagerMXBean.java b/test/hotspot/jtreg/gc/z/TestMemoryManagerMXBean.java index a5c5c1367e7..803201d576e 100644 --- a/test/hotspot/jtreg/gc/z/TestMemoryManagerMXBean.java +++ b/test/hotspot/jtreg/gc/z/TestMemoryManagerMXBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -21,12 +21,14 @@ * questions. */ +package gc.z; + /** * @test TestMemoryManagerMXBean * @requires vm.gc.Z * @summary Test ZGC memory manager MXBean * @modules java.management - * @run main/othervm -XX:+UseZGC -Xmx128M TestMemoryManagerMXBean + * @run main/othervm -XX:+UseZGC -Xmx128M gc.z.TestMemoryManagerMXBean */ import java.lang.management.ManagementFactory; -- GitLab From d442328bc2f2f4bc35dd054487a78552e3d9a759 Mon Sep 17 00:00:00 2001 From: Maxim Kartashev Date: Thu, 10 Feb 2022 10:46:35 +0000 Subject: [PATCH 198/400] 8281262: Windows builds in different directories are not fully reproducible Co-authored-by: Erik Joelsson Reviewed-by: erikj, ihse --- make/TestImage.gmk | 4 ++-- make/autoconf/flags-cflags.m4 | 4 +--- test/jdk/build/AbsPathsInImage.java | 7 +++++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/make/TestImage.gmk b/make/TestImage.gmk index 26d10f95d3b..b719d6824da 100644 --- a/make/TestImage.gmk +++ b/make/TestImage.gmk @@ -35,8 +35,8 @@ BUILD_INFO_PROPERTIES := $(TEST_IMAGE_DIR)/build-info.properties $(BUILD_INFO_PROPERTIES): $(call MakeTargetDir) $(ECHO) "# Build info properties for JDK tests" > $@ - $(ECHO) "build.workspace.root=$(call FixPath, $(WORKSPACE_ROOT))" >> $@ - $(ECHO) "build.output.root=$(call FixPath, $(OUTPUTDIR))" >> $@ + $(ECHO) 'build.workspace.root=$(call FixPath, $(WORKSPACE_ROOT))' >> $@ + $(ECHO) 'build.output.root=$(call FixPath, $(OUTPUTDIR))' >> $@ README := $(TEST_IMAGE_DIR)/Readme.txt diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index ba4cb3e9ac7..76724235ec4 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -782,10 +782,8 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], test "x$ENABLE_REPRODUCIBLE_BUILD" = xtrue; then # There is a known issue with the pathmap if the mapping is made to the # empty string. Add a minimal string "s" as prefix to work around this. - workspace_root_win=`$FIXPATH_BASE print "${WORKSPACE_ROOT%/}"` # PATHMAP_FLAGS is also added to LDFLAGS in flags-ldflags.m4. - PATHMAP_FLAGS="-pathmap:${workspace_root_win//\//\\\\}=s \ - -pathmap:${workspace_root_win}=s" + PATHMAP_FLAGS="-pathmap:${WORKSPACE_ROOT}=s" FILE_MACRO_CFLAGS="$PATHMAP_FLAGS" FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${FILE_MACRO_CFLAGS}], PREFIX: $3, diff --git a/test/jdk/build/AbsPathsInImage.java b/test/jdk/build/AbsPathsInImage.java index 3fd7dda239a..0e4b6d8caff 100644 --- a/test/jdk/build/AbsPathsInImage.java +++ b/test/jdk/build/AbsPathsInImage.java @@ -96,6 +96,13 @@ public class AbsPathsInImage { if (buildOutputRoot == null) { throw new Error("Could not find build output root, test cannot run"); } + // Validate the root paths + if (!Paths.get(buildWorkspaceRoot).isAbsolute()) { + throw new Error("Workspace root is not an absolute path: " + buildWorkspaceRoot); + } + if (!Paths.get(buildOutputRoot).isAbsolute()) { + throw new Error("Output root is not an absolute path: " + buildOutputRoot); + } List searchPatterns = new ArrayList<>(); expandPatterns(searchPatterns, buildWorkspaceRoot); -- GitLab From 3ce1c5b6ce02749ef8f9d35409b7bcbf27f47203 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Thu, 10 Feb 2022 11:28:04 +0000 Subject: [PATCH 199/400] 8280832: Update usage docs for NonblockingQueue Reviewed-by: iwalulya, dholmes --- src/hotspot/share/utilities/nonblockingQueue.hpp | 4 +++- src/hotspot/share/utilities/nonblockingQueue.inline.hpp | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/utilities/nonblockingQueue.hpp b/src/hotspot/share/utilities/nonblockingQueue.hpp index 6f8936b019f..a271aaa38d8 100644 --- a/src/hotspot/share/utilities/nonblockingQueue.hpp +++ b/src/hotspot/share/utilities/nonblockingQueue.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -96,9 +96,11 @@ public: inline size_t length() const; // Thread-safe add the object to the end of the queue. + // Subject to ABA behavior; callers must ensure usage is safe. inline void push(T& node) { append(node, node); } // Thread-safe add the objects from first to last to the end of the queue. + // Subject to ABA behavior; callers must ensure usage is safe. inline void append(T& first, T& last); // Thread-safe attempt to remove and return the first object in the queue. diff --git a/src/hotspot/share/utilities/nonblockingQueue.inline.hpp b/src/hotspot/share/utilities/nonblockingQueue.inline.hpp index 2845822b204..2ecb1663e45 100644 --- a/src/hotspot/share/utilities/nonblockingQueue.inline.hpp +++ b/src/hotspot/share/utilities/nonblockingQueue.inline.hpp @@ -117,6 +117,12 @@ void NonblockingQueue::append(T& first, T& last) { // other push/append could have competed with us, because we claimed // old_tail for extension. We won any races with try_pop by changing // away from end-marker. So we're done. + // + // Note that ABA is possible here. A concurrent try_pop could take + // old_tail before our update of old_tail's next_ptr, old_tail gets + // recycled and re-added to the end of this queue, and then we + // successfully cmpxchg, making the list in _tail circular. Callers + // must ensure this can't happen. return; } else { // A concurrent try_pop has claimed old_tail, so it is no longer in the -- GitLab From 039313d65d47dc85cb8c91d3e1d2752d365f70f9 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Thu, 10 Feb 2022 12:02:05 +0000 Subject: [PATCH 200/400] 8054449: Incompatible type in example code in TreePath Reviewed-by: aivanov, dmarkov --- src/java.desktop/share/classes/javax/swing/tree/TreePath.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/tree/TreePath.java b/src/java.desktop/share/classes/javax/swing/tree/TreePath.java index e8abb0597df..f55cbe4961b 100644 --- a/src/java.desktop/share/classes/javax/swing/tree/TreePath.java +++ b/src/java.desktop/share/classes/javax/swing/tree/TreePath.java @@ -51,8 +51,8 @@ import java.beans.ConstructorProperties; * ... * TreePath selectedPath = tree.getSelectionPath(); * DefaultMutableTreeNode selectedNode = - * ((DefaultMutableTreeNode)selectedPath.getLastPathComponent()). - * getUserObject(); + * ((DefaultMutableTreeNode)selectedPath.getLastPathComponent()); + * Object myObject= selectedNode.getUserObject(); * * Subclasses typically need override only {@code * getLastPathComponent}, and {@code getParentPath}. As {@code JTree} -- GitLab From 83b6e4bc04db89a846a1b6c2d0666efe139f8f61 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Thu, 10 Feb 2022 18:37:21 +0000 Subject: [PATCH 201/400] 8281294: [vectorapi] FIRST_NONZERO reduction operation throws IllegalArgumentExcept on zero vectors Reviewed-by: jrose --- .../jdk/incubator/vector/ByteVector.java | 36 +---- .../jdk/incubator/vector/DoubleVector.java | 32 +---- .../jdk/incubator/vector/FloatVector.java | 32 +---- .../jdk/incubator/vector/IntVector.java | 36 +---- .../jdk/incubator/vector/LongVector.java | 36 +---- .../jdk/incubator/vector/ShortVector.java | 36 +---- .../incubator/vector/X-Vector.java.template | 40 +----- .../incubator/vector/Byte128VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Byte256VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Byte512VectorTests.java | 129 +++++++++++++++--- .../incubator/vector/Byte64VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/ByteMaxVectorTests.java | 129 +++++++++++++++--- .../vector/Double128VectorTests.java | 127 ++++++++++++++--- .../vector/Double256VectorTests.java | 127 ++++++++++++++--- .../vector/Double512VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Double64VectorTests.java | 127 ++++++++++++++--- .../vector/DoubleMaxVectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Float128VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Float256VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Float512VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Float64VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/FloatMaxVectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Int128VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Int256VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Int512VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Int64VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/IntMaxVectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Long128VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Long256VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Long512VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Long64VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/LongMaxVectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Short128VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Short256VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Short512VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/Short64VectorTests.java | 127 ++++++++++++++--- .../incubator/vector/ShortMaxVectorTests.java | 127 ++++++++++++++--- test/jdk/jdk/incubator/vector/gen-template.sh | 36 ++--- .../Kernel-Reduction-Masked-Min-op.template | 21 --- ... Kernel-Reduction-Masked-op-func.template} | 2 +- .../Kernel-Reduction-Min-op.template | 19 --- ...late => Kernel-Reduction-op-func.template} | 2 +- .../Unit-Reduction-Masked-Min-op.template | 6 - ...=> Unit-Reduction-Masked-op-func.template} | 0 .../templates/Unit-Reduction-Min-op.template | 6 - ...it-Reduction-Scalar-Masked-Min-op.template | 19 --- ...-Reduction-Scalar-Masked-op-func.template} | 9 +- .../Unit-Reduction-Scalar-Min-op.template | 17 --- ...=> Unit-Reduction-Scalar-op-func.template} | 6 +- ...mplate => Unit-Reduction-op-func.template} | 0 .../vector/templates/Unit-header.template | 4 + 51 files changed, 3272 insertions(+), 937 deletions(-) delete mode 100644 test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Masked-Min-op.template rename test/jdk/jdk/incubator/vector/templates/{Kernel-Reduction-Masked-Max-op.template => Kernel-Reduction-Masked-op-func.template} (90%) delete mode 100644 test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Min-op.template rename test/jdk/jdk/incubator/vector/templates/{Kernel-Reduction-Max-op.template => Kernel-Reduction-op-func.template} (89%) delete mode 100644 test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Masked-Min-op.template rename test/jdk/jdk/incubator/vector/templates/{Unit-Reduction-Masked-Max-op.template => Unit-Reduction-Masked-op-func.template} (100%) delete mode 100644 test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Min-op.template delete mode 100644 test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Masked-Min-op.template rename test/jdk/jdk/incubator/vector/templates/{Unit-Reduction-Scalar-Masked-Max-op.template => Unit-Reduction-Scalar-Masked-op-func.template} (60%) delete mode 100644 test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Min-op.template rename test/jdk/jdk/incubator/vector/templates/{Unit-Reduction-Scalar-Max-op.template => Unit-Reduction-Scalar-op-func.template} (65%) rename test/jdk/jdk/incubator/vector/templates/{Unit-Reduction-Max-op.template => Unit-Reduction-op-func.template} (100%) diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java index 256e1a5700f..d67f86f7985 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ByteVector.java @@ -2595,7 +2595,8 @@ public abstract class ByteVector extends AbstractVector { VectorMask m) { m.check(maskClass, this); if (op == FIRST_NONZERO) { - ByteVector v = reduceIdentityVector(op).blend(this, m); + // FIXME: The JIT should handle this. + ByteVector v = broadcast((byte) 0).blend(this, m); return v.reduceLanesTemplate(op); } int opc = opCode(op); @@ -2610,10 +2611,11 @@ public abstract class ByteVector extends AbstractVector { final byte reduceLanesTemplate(VectorOperators.Associative op) { if (op == FIRST_NONZERO) { - // FIXME: The JIT should handle this, and other scan ops alos. + // FIXME: The JIT should handle this. VectorMask thisNZ = this.viewAsIntegralLanes().compare(NE, (byte) 0); - return this.lane(thisNZ.firstTrue()); + int ft = thisNZ.firstTrue(); + return ft < length() ? this.lane(ft) : (byte) 0; } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( @@ -2646,34 +2648,6 @@ public abstract class ByteVector extends AbstractVector { } } - private - @ForceInline - ByteVector reduceIdentityVector(VectorOperators.Associative op) { - int opc = opCode(op); - UnaryOperator fn - = REDUCE_ID_IMPL.find(op, opc, (opc_) -> { - switch (opc_) { - case VECTOR_OP_ADD: - case VECTOR_OP_OR: - case VECTOR_OP_XOR: - return v -> v.broadcast(0); - case VECTOR_OP_MUL: - return v -> v.broadcast(1); - case VECTOR_OP_AND: - return v -> v.broadcast(-1); - case VECTOR_OP_MIN: - return v -> v.broadcast(MAX_OR_INF); - case VECTOR_OP_MAX: - return v -> v.broadcast(MIN_OR_INF); - default: return null; - } - }); - return fn.apply(this); - } - private static final - ImplCache> REDUCE_ID_IMPL - = new ImplCache<>(Associative.class, ByteVector.class); - private static final byte MIN_OR_INF = Byte.MIN_VALUE; private static final byte MAX_OR_INF = Byte.MAX_VALUE; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java index 8455e354678..063a4bbb191 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/DoubleVector.java @@ -2419,7 +2419,8 @@ public abstract class DoubleVector extends AbstractVector { VectorMask m) { m.check(maskClass, this); if (op == FIRST_NONZERO) { - DoubleVector v = reduceIdentityVector(op).blend(this, m); + // FIXME: The JIT should handle this. + DoubleVector v = broadcast((double) 0).blend(this, m); return v.reduceLanesTemplate(op); } int opc = opCode(op); @@ -2434,10 +2435,11 @@ public abstract class DoubleVector extends AbstractVector { final double reduceLanesTemplate(VectorOperators.Associative op) { if (op == FIRST_NONZERO) { - // FIXME: The JIT should handle this, and other scan ops alos. + // FIXME: The JIT should handle this. VectorMask thisNZ = this.viewAsIntegralLanes().compare(NE, (long) 0); - return this.lane(thisNZ.firstTrue()); + int ft = thisNZ.firstTrue(); + return ft < length() ? this.lane(ft) : (double) 0; } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( @@ -2464,30 +2466,6 @@ public abstract class DoubleVector extends AbstractVector { } } - private - @ForceInline - DoubleVector reduceIdentityVector(VectorOperators.Associative op) { - int opc = opCode(op); - UnaryOperator fn - = REDUCE_ID_IMPL.find(op, opc, (opc_) -> { - switch (opc_) { - case VECTOR_OP_ADD: - return v -> v.broadcast(0); - case VECTOR_OP_MUL: - return v -> v.broadcast(1); - case VECTOR_OP_MIN: - return v -> v.broadcast(MAX_OR_INF); - case VECTOR_OP_MAX: - return v -> v.broadcast(MIN_OR_INF); - default: return null; - } - }); - return fn.apply(this); - } - private static final - ImplCache> REDUCE_ID_IMPL - = new ImplCache<>(Associative.class, DoubleVector.class); - private static final double MIN_OR_INF = Double.NEGATIVE_INFINITY; private static final double MAX_OR_INF = Double.POSITIVE_INFINITY; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java index 1dc63aa1de3..f78d9814514 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.java @@ -2439,7 +2439,8 @@ public abstract class FloatVector extends AbstractVector { VectorMask m) { m.check(maskClass, this); if (op == FIRST_NONZERO) { - FloatVector v = reduceIdentityVector(op).blend(this, m); + // FIXME: The JIT should handle this. + FloatVector v = broadcast((float) 0).blend(this, m); return v.reduceLanesTemplate(op); } int opc = opCode(op); @@ -2454,10 +2455,11 @@ public abstract class FloatVector extends AbstractVector { final float reduceLanesTemplate(VectorOperators.Associative op) { if (op == FIRST_NONZERO) { - // FIXME: The JIT should handle this, and other scan ops alos. + // FIXME: The JIT should handle this. VectorMask thisNZ = this.viewAsIntegralLanes().compare(NE, (int) 0); - return this.lane(thisNZ.firstTrue()); + int ft = thisNZ.firstTrue(); + return ft < length() ? this.lane(ft) : (float) 0; } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( @@ -2484,30 +2486,6 @@ public abstract class FloatVector extends AbstractVector { } } - private - @ForceInline - FloatVector reduceIdentityVector(VectorOperators.Associative op) { - int opc = opCode(op); - UnaryOperator fn - = REDUCE_ID_IMPL.find(op, opc, (opc_) -> { - switch (opc_) { - case VECTOR_OP_ADD: - return v -> v.broadcast(0); - case VECTOR_OP_MUL: - return v -> v.broadcast(1); - case VECTOR_OP_MIN: - return v -> v.broadcast(MAX_OR_INF); - case VECTOR_OP_MAX: - return v -> v.broadcast(MIN_OR_INF); - default: return null; - } - }); - return fn.apply(this); - } - private static final - ImplCache> REDUCE_ID_IMPL - = new ImplCache<>(Associative.class, FloatVector.class); - private static final float MIN_OR_INF = Float.NEGATIVE_INFINITY; private static final float MAX_OR_INF = Float.POSITIVE_INFINITY; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java index 29dbfe5a796..c80b61cb7a2 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java @@ -2594,7 +2594,8 @@ public abstract class IntVector extends AbstractVector { VectorMask m) { m.check(maskClass, this); if (op == FIRST_NONZERO) { - IntVector v = reduceIdentityVector(op).blend(this, m); + // FIXME: The JIT should handle this. + IntVector v = broadcast((int) 0).blend(this, m); return v.reduceLanesTemplate(op); } int opc = opCode(op); @@ -2609,10 +2610,11 @@ public abstract class IntVector extends AbstractVector { final int reduceLanesTemplate(VectorOperators.Associative op) { if (op == FIRST_NONZERO) { - // FIXME: The JIT should handle this, and other scan ops alos. + // FIXME: The JIT should handle this. VectorMask thisNZ = this.viewAsIntegralLanes().compare(NE, (int) 0); - return this.lane(thisNZ.firstTrue()); + int ft = thisNZ.firstTrue(); + return ft < length() ? this.lane(ft) : (int) 0; } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( @@ -2645,34 +2647,6 @@ public abstract class IntVector extends AbstractVector { } } - private - @ForceInline - IntVector reduceIdentityVector(VectorOperators.Associative op) { - int opc = opCode(op); - UnaryOperator fn - = REDUCE_ID_IMPL.find(op, opc, (opc_) -> { - switch (opc_) { - case VECTOR_OP_ADD: - case VECTOR_OP_OR: - case VECTOR_OP_XOR: - return v -> v.broadcast(0); - case VECTOR_OP_MUL: - return v -> v.broadcast(1); - case VECTOR_OP_AND: - return v -> v.broadcast(-1); - case VECTOR_OP_MIN: - return v -> v.broadcast(MAX_OR_INF); - case VECTOR_OP_MAX: - return v -> v.broadcast(MIN_OR_INF); - default: return null; - } - }); - return fn.apply(this); - } - private static final - ImplCache> REDUCE_ID_IMPL - = new ImplCache<>(Associative.class, IntVector.class); - private static final int MIN_OR_INF = Integer.MIN_VALUE; private static final int MAX_OR_INF = Integer.MAX_VALUE; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java index 365740c90c2..6934469b213 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/LongVector.java @@ -2460,7 +2460,8 @@ public abstract class LongVector extends AbstractVector { VectorMask m) { m.check(maskClass, this); if (op == FIRST_NONZERO) { - LongVector v = reduceIdentityVector(op).blend(this, m); + // FIXME: The JIT should handle this. + LongVector v = broadcast((long) 0).blend(this, m); return v.reduceLanesTemplate(op); } int opc = opCode(op); @@ -2475,10 +2476,11 @@ public abstract class LongVector extends AbstractVector { final long reduceLanesTemplate(VectorOperators.Associative op) { if (op == FIRST_NONZERO) { - // FIXME: The JIT should handle this, and other scan ops alos. + // FIXME: The JIT should handle this. VectorMask thisNZ = this.viewAsIntegralLanes().compare(NE, (long) 0); - return this.lane(thisNZ.firstTrue()); + int ft = thisNZ.firstTrue(); + return ft < length() ? this.lane(ft) : (long) 0; } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( @@ -2511,34 +2513,6 @@ public abstract class LongVector extends AbstractVector { } } - private - @ForceInline - LongVector reduceIdentityVector(VectorOperators.Associative op) { - int opc = opCode(op); - UnaryOperator fn - = REDUCE_ID_IMPL.find(op, opc, (opc_) -> { - switch (opc_) { - case VECTOR_OP_ADD: - case VECTOR_OP_OR: - case VECTOR_OP_XOR: - return v -> v.broadcast(0); - case VECTOR_OP_MUL: - return v -> v.broadcast(1); - case VECTOR_OP_AND: - return v -> v.broadcast(-1); - case VECTOR_OP_MIN: - return v -> v.broadcast(MAX_OR_INF); - case VECTOR_OP_MAX: - return v -> v.broadcast(MIN_OR_INF); - default: return null; - } - }); - return fn.apply(this); - } - private static final - ImplCache> REDUCE_ID_IMPL - = new ImplCache<>(Associative.class, LongVector.class); - private static final long MIN_OR_INF = Long.MIN_VALUE; private static final long MAX_OR_INF = Long.MAX_VALUE; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java index d527500bb1a..b3c89e87cc4 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java @@ -2595,7 +2595,8 @@ public abstract class ShortVector extends AbstractVector { VectorMask m) { m.check(maskClass, this); if (op == FIRST_NONZERO) { - ShortVector v = reduceIdentityVector(op).blend(this, m); + // FIXME: The JIT should handle this. + ShortVector v = broadcast((short) 0).blend(this, m); return v.reduceLanesTemplate(op); } int opc = opCode(op); @@ -2610,10 +2611,11 @@ public abstract class ShortVector extends AbstractVector { final short reduceLanesTemplate(VectorOperators.Associative op) { if (op == FIRST_NONZERO) { - // FIXME: The JIT should handle this, and other scan ops alos. + // FIXME: The JIT should handle this. VectorMask thisNZ = this.viewAsIntegralLanes().compare(NE, (short) 0); - return this.lane(thisNZ.firstTrue()); + int ft = thisNZ.firstTrue(); + return ft < length() ? this.lane(ft) : (short) 0; } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( @@ -2646,34 +2648,6 @@ public abstract class ShortVector extends AbstractVector { } } - private - @ForceInline - ShortVector reduceIdentityVector(VectorOperators.Associative op) { - int opc = opCode(op); - UnaryOperator fn - = REDUCE_ID_IMPL.find(op, opc, (opc_) -> { - switch (opc_) { - case VECTOR_OP_ADD: - case VECTOR_OP_OR: - case VECTOR_OP_XOR: - return v -> v.broadcast(0); - case VECTOR_OP_MUL: - return v -> v.broadcast(1); - case VECTOR_OP_AND: - return v -> v.broadcast(-1); - case VECTOR_OP_MIN: - return v -> v.broadcast(MAX_OR_INF); - case VECTOR_OP_MAX: - return v -> v.broadcast(MIN_OR_INF); - default: return null; - } - }); - return fn.apply(this); - } - private static final - ImplCache> REDUCE_ID_IMPL - = new ImplCache<>(Associative.class, ShortVector.class); - private static final short MIN_OR_INF = Short.MIN_VALUE; private static final short MAX_OR_INF = Short.MAX_VALUE; diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template index ae12e5fecff..1cd50a11b8b 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/X-Vector.java.template @@ -3021,7 +3021,8 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { VectorMask<$Boxtype$> m) { m.check(maskClass, this); if (op == FIRST_NONZERO) { - $abstractvectortype$ v = reduceIdentityVector(op).blend(this, m); + // FIXME: The JIT should handle this. + $abstractvectortype$ v = broadcast(($type$) 0).blend(this, m); return v.reduceLanesTemplate(op); } int opc = opCode(op); @@ -3036,10 +3037,11 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { final $type$ reduceLanesTemplate(VectorOperators.Associative op) { if (op == FIRST_NONZERO) { - // FIXME: The JIT should handle this, and other scan ops alos. + // FIXME: The JIT should handle this. VectorMask<$Boxbitstype$> thisNZ = this.viewAsIntegralLanes().compare(NE, ($bitstype$) 0); - return this.lane(thisNZ.firstTrue()); + int ft = thisNZ.firstTrue(); + return ft < length() ? this.lane(ft) : ($type$) 0; } int opc = opCode(op); return fromBits(VectorSupport.reductionCoerced( @@ -3074,38 +3076,6 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> { } } - private - @ForceInline - $abstractvectortype$ reduceIdentityVector(VectorOperators.Associative op) { - int opc = opCode(op); - UnaryOperator<$abstractvectortype$> fn - = REDUCE_ID_IMPL.find(op, opc, (opc_) -> { - switch (opc_) { - case VECTOR_OP_ADD: -#if[BITWISE] - case VECTOR_OP_OR: - case VECTOR_OP_XOR: -#end[BITWISE] - return v -> v.broadcast(0); - case VECTOR_OP_MUL: - return v -> v.broadcast(1); -#if[BITWISE] - case VECTOR_OP_AND: - return v -> v.broadcast(-1); -#end[BITWISE] - case VECTOR_OP_MIN: - return v -> v.broadcast(MAX_OR_INF); - case VECTOR_OP_MAX: - return v -> v.broadcast(MIN_OR_INF); - default: return null; - } - }); - return fn.apply(this); - } - private static final - ImplCache> REDUCE_ID_IMPL - = new ImplCache<>(Associative.class, $Type$Vector.class); - #if[FP] private static final $type$ MIN_OR_INF = $Boxtype$.NEGATIVE_INFINITY; private static final $type$ MAX_OR_INF = $Boxtype$.POSITIVE_INFINITY; diff --git a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java index df3e773388a..22e07e05a06 100644 --- a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java @@ -1201,6 +1201,10 @@ public class Byte128VectorTests extends AbstractVectorTest { return Byte.compareUnsigned(a, b) >= 0; } + static byte firstNonZero(byte a, byte b) { + return Byte.compare(a, (byte) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { ByteVector three = ByteVector.broadcast(SPECIES, (byte)-3); @@ -3216,7 +3220,7 @@ public class Byte128VectorTests extends AbstractVectorTest { static byte MINReduce(byte[] a, int idx) { byte res = Byte.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (byte)Math.min(res, a[i]); + res = (byte) Math.min(res, a[i]); } return res; @@ -3224,8 +3228,8 @@ public class Byte128VectorTests extends AbstractVectorTest { static byte MINReduceAll(byte[] a) { byte res = Byte.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (byte)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.min(res, MINReduce(a, i)); } return res; @@ -3247,7 +3251,7 @@ public class Byte128VectorTests extends AbstractVectorTest { ra = Byte.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (byte) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3257,8 +3261,8 @@ public class Byte128VectorTests extends AbstractVectorTest { static byte MINReduceMasked(byte[] a, int idx, boolean[] mask) { byte res = Byte.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (byte) Math.min(res, a[i]); } return res; @@ -3266,9 +3270,8 @@ public class Byte128VectorTests extends AbstractVectorTest { static byte MINReduceAllMasked(byte[] a, boolean[] mask) { byte res = Byte.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3292,7 +3295,7 @@ public class Byte128VectorTests extends AbstractVectorTest { ra = Byte.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (byte) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3302,7 +3305,7 @@ public class Byte128VectorTests extends AbstractVectorTest { static byte MAXReduce(byte[] a, int idx) { byte res = Byte.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (byte)Math.max(res, a[i]); + res = (byte) Math.max(res, a[i]); } return res; @@ -3310,8 +3313,8 @@ public class Byte128VectorTests extends AbstractVectorTest { static byte MAXReduceAll(byte[] a) { byte res = Byte.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (byte)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.max(res, MAXReduce(a, i)); } return res; @@ -3333,7 +3336,7 @@ public class Byte128VectorTests extends AbstractVectorTest { ra = Byte.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (byte) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3343,8 +3346,8 @@ public class Byte128VectorTests extends AbstractVectorTest { static byte MAXReduceMasked(byte[] a, int idx, boolean[] mask) { byte res = Byte.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (byte) Math.max(res, a[i]); } return res; @@ -3352,9 +3355,8 @@ public class Byte128VectorTests extends AbstractVectorTest { static byte MAXReduceAllMasked(byte[] a, boolean[] mask) { byte res = Byte.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3378,13 +3380,98 @@ public class Byte128VectorTests extends AbstractVectorTest { ra = Byte.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (byte) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Byte128VectorTests::MAXReduceMasked, Byte128VectorTests::MAXReduceAllMasked); } + static byte FIRST_NONZEROReduce(byte[] a, int idx) { + byte res = (byte) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static byte FIRST_NONZEROReduceAll(byte[] a) { + byte res = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "byteUnaryOpProvider") + static void FIRST_NONZEROReduceByte128VectorTests(IntFunction fa) { + byte[] a = fa.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + byte ra = (byte) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Byte128VectorTests::FIRST_NONZEROReduce, Byte128VectorTests::FIRST_NONZEROReduceAll); + } + static byte FIRST_NONZEROReduceMasked(byte[] a, int idx, boolean[] mask) { + byte res = (byte) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static byte FIRST_NONZEROReduceAllMasked(byte[] a, boolean[] mask) { + byte res = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "byteUnaryOpMaskProvider") + static void FIRST_NONZEROReduceByte128VectorTestsMasked(IntFunction fa, IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + byte ra = (byte) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Byte128VectorTests::FIRST_NONZEROReduceMasked, Byte128VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java index 85da0f82e81..9a631c47993 100644 --- a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java @@ -1201,6 +1201,10 @@ public class Byte256VectorTests extends AbstractVectorTest { return Byte.compareUnsigned(a, b) >= 0; } + static byte firstNonZero(byte a, byte b) { + return Byte.compare(a, (byte) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { ByteVector three = ByteVector.broadcast(SPECIES, (byte)-3); @@ -3216,7 +3220,7 @@ public class Byte256VectorTests extends AbstractVectorTest { static byte MINReduce(byte[] a, int idx) { byte res = Byte.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (byte)Math.min(res, a[i]); + res = (byte) Math.min(res, a[i]); } return res; @@ -3224,8 +3228,8 @@ public class Byte256VectorTests extends AbstractVectorTest { static byte MINReduceAll(byte[] a) { byte res = Byte.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (byte)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.min(res, MINReduce(a, i)); } return res; @@ -3247,7 +3251,7 @@ public class Byte256VectorTests extends AbstractVectorTest { ra = Byte.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (byte) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3257,8 +3261,8 @@ public class Byte256VectorTests extends AbstractVectorTest { static byte MINReduceMasked(byte[] a, int idx, boolean[] mask) { byte res = Byte.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (byte) Math.min(res, a[i]); } return res; @@ -3266,9 +3270,8 @@ public class Byte256VectorTests extends AbstractVectorTest { static byte MINReduceAllMasked(byte[] a, boolean[] mask) { byte res = Byte.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3292,7 +3295,7 @@ public class Byte256VectorTests extends AbstractVectorTest { ra = Byte.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (byte) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3302,7 +3305,7 @@ public class Byte256VectorTests extends AbstractVectorTest { static byte MAXReduce(byte[] a, int idx) { byte res = Byte.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (byte)Math.max(res, a[i]); + res = (byte) Math.max(res, a[i]); } return res; @@ -3310,8 +3313,8 @@ public class Byte256VectorTests extends AbstractVectorTest { static byte MAXReduceAll(byte[] a) { byte res = Byte.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (byte)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.max(res, MAXReduce(a, i)); } return res; @@ -3333,7 +3336,7 @@ public class Byte256VectorTests extends AbstractVectorTest { ra = Byte.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (byte) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3343,8 +3346,8 @@ public class Byte256VectorTests extends AbstractVectorTest { static byte MAXReduceMasked(byte[] a, int idx, boolean[] mask) { byte res = Byte.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (byte) Math.max(res, a[i]); } return res; @@ -3352,9 +3355,8 @@ public class Byte256VectorTests extends AbstractVectorTest { static byte MAXReduceAllMasked(byte[] a, boolean[] mask) { byte res = Byte.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3378,13 +3380,98 @@ public class Byte256VectorTests extends AbstractVectorTest { ra = Byte.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (byte) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Byte256VectorTests::MAXReduceMasked, Byte256VectorTests::MAXReduceAllMasked); } + static byte FIRST_NONZEROReduce(byte[] a, int idx) { + byte res = (byte) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static byte FIRST_NONZEROReduceAll(byte[] a) { + byte res = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "byteUnaryOpProvider") + static void FIRST_NONZEROReduceByte256VectorTests(IntFunction fa) { + byte[] a = fa.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + byte ra = (byte) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Byte256VectorTests::FIRST_NONZEROReduce, Byte256VectorTests::FIRST_NONZEROReduceAll); + } + static byte FIRST_NONZEROReduceMasked(byte[] a, int idx, boolean[] mask) { + byte res = (byte) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static byte FIRST_NONZEROReduceAllMasked(byte[] a, boolean[] mask) { + byte res = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "byteUnaryOpMaskProvider") + static void FIRST_NONZEROReduceByte256VectorTestsMasked(IntFunction fa, IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + byte ra = (byte) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Byte256VectorTests::FIRST_NONZEROReduceMasked, Byte256VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java index d7659d86871..203f233e4e8 100644 --- a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java @@ -24,7 +24,7 @@ /* * @test * @modules jdk.incubator.vector - * @run testng/othervm/timeout=240 -ea -esa -Xbatch -XX:-TieredCompilation Byte512VectorTests + * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Byte512VectorTests */ // -- This file was mechanically generated: Do not edit! -- // @@ -1201,6 +1201,10 @@ public class Byte512VectorTests extends AbstractVectorTest { return Byte.compareUnsigned(a, b) >= 0; } + static byte firstNonZero(byte a, byte b) { + return Byte.compare(a, (byte) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { ByteVector three = ByteVector.broadcast(SPECIES, (byte)-3); @@ -3216,7 +3220,7 @@ public class Byte512VectorTests extends AbstractVectorTest { static byte MINReduce(byte[] a, int idx) { byte res = Byte.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (byte)Math.min(res, a[i]); + res = (byte) Math.min(res, a[i]); } return res; @@ -3224,8 +3228,8 @@ public class Byte512VectorTests extends AbstractVectorTest { static byte MINReduceAll(byte[] a) { byte res = Byte.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (byte)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.min(res, MINReduce(a, i)); } return res; @@ -3247,7 +3251,7 @@ public class Byte512VectorTests extends AbstractVectorTest { ra = Byte.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (byte) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3257,8 +3261,8 @@ public class Byte512VectorTests extends AbstractVectorTest { static byte MINReduceMasked(byte[] a, int idx, boolean[] mask) { byte res = Byte.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (byte) Math.min(res, a[i]); } return res; @@ -3266,9 +3270,8 @@ public class Byte512VectorTests extends AbstractVectorTest { static byte MINReduceAllMasked(byte[] a, boolean[] mask) { byte res = Byte.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3292,7 +3295,7 @@ public class Byte512VectorTests extends AbstractVectorTest { ra = Byte.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (byte) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3302,7 +3305,7 @@ public class Byte512VectorTests extends AbstractVectorTest { static byte MAXReduce(byte[] a, int idx) { byte res = Byte.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (byte)Math.max(res, a[i]); + res = (byte) Math.max(res, a[i]); } return res; @@ -3310,8 +3313,8 @@ public class Byte512VectorTests extends AbstractVectorTest { static byte MAXReduceAll(byte[] a) { byte res = Byte.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (byte)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.max(res, MAXReduce(a, i)); } return res; @@ -3333,7 +3336,7 @@ public class Byte512VectorTests extends AbstractVectorTest { ra = Byte.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (byte) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3343,8 +3346,8 @@ public class Byte512VectorTests extends AbstractVectorTest { static byte MAXReduceMasked(byte[] a, int idx, boolean[] mask) { byte res = Byte.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (byte) Math.max(res, a[i]); } return res; @@ -3352,9 +3355,8 @@ public class Byte512VectorTests extends AbstractVectorTest { static byte MAXReduceAllMasked(byte[] a, boolean[] mask) { byte res = Byte.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3378,13 +3380,98 @@ public class Byte512VectorTests extends AbstractVectorTest { ra = Byte.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (byte) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Byte512VectorTests::MAXReduceMasked, Byte512VectorTests::MAXReduceAllMasked); } + static byte FIRST_NONZEROReduce(byte[] a, int idx) { + byte res = (byte) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static byte FIRST_NONZEROReduceAll(byte[] a) { + byte res = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "byteUnaryOpProvider") + static void FIRST_NONZEROReduceByte512VectorTests(IntFunction fa) { + byte[] a = fa.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + byte ra = (byte) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Byte512VectorTests::FIRST_NONZEROReduce, Byte512VectorTests::FIRST_NONZEROReduceAll); + } + static byte FIRST_NONZEROReduceMasked(byte[] a, int idx, boolean[] mask) { + byte res = (byte) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static byte FIRST_NONZEROReduceAllMasked(byte[] a, boolean[] mask) { + byte res = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "byteUnaryOpMaskProvider") + static void FIRST_NONZEROReduceByte512VectorTestsMasked(IntFunction fa, IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + byte ra = (byte) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Byte512VectorTests::FIRST_NONZEROReduceMasked, Byte512VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Byte64VectorTests.java b/test/jdk/jdk/incubator/vector/Byte64VectorTests.java index cc8c2e1c24c..110e741ea43 100644 --- a/test/jdk/jdk/incubator/vector/Byte64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte64VectorTests.java @@ -1201,6 +1201,10 @@ public class Byte64VectorTests extends AbstractVectorTest { return Byte.compareUnsigned(a, b) >= 0; } + static byte firstNonZero(byte a, byte b) { + return Byte.compare(a, (byte) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { ByteVector three = ByteVector.broadcast(SPECIES, (byte)-3); @@ -3216,7 +3220,7 @@ public class Byte64VectorTests extends AbstractVectorTest { static byte MINReduce(byte[] a, int idx) { byte res = Byte.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (byte)Math.min(res, a[i]); + res = (byte) Math.min(res, a[i]); } return res; @@ -3224,8 +3228,8 @@ public class Byte64VectorTests extends AbstractVectorTest { static byte MINReduceAll(byte[] a) { byte res = Byte.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (byte)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.min(res, MINReduce(a, i)); } return res; @@ -3247,7 +3251,7 @@ public class Byte64VectorTests extends AbstractVectorTest { ra = Byte.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (byte) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3257,8 +3261,8 @@ public class Byte64VectorTests extends AbstractVectorTest { static byte MINReduceMasked(byte[] a, int idx, boolean[] mask) { byte res = Byte.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (byte) Math.min(res, a[i]); } return res; @@ -3266,9 +3270,8 @@ public class Byte64VectorTests extends AbstractVectorTest { static byte MINReduceAllMasked(byte[] a, boolean[] mask) { byte res = Byte.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3292,7 +3295,7 @@ public class Byte64VectorTests extends AbstractVectorTest { ra = Byte.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (byte) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3302,7 +3305,7 @@ public class Byte64VectorTests extends AbstractVectorTest { static byte MAXReduce(byte[] a, int idx) { byte res = Byte.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (byte)Math.max(res, a[i]); + res = (byte) Math.max(res, a[i]); } return res; @@ -3310,8 +3313,8 @@ public class Byte64VectorTests extends AbstractVectorTest { static byte MAXReduceAll(byte[] a) { byte res = Byte.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (byte)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.max(res, MAXReduce(a, i)); } return res; @@ -3333,7 +3336,7 @@ public class Byte64VectorTests extends AbstractVectorTest { ra = Byte.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (byte) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3343,8 +3346,8 @@ public class Byte64VectorTests extends AbstractVectorTest { static byte MAXReduceMasked(byte[] a, int idx, boolean[] mask) { byte res = Byte.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (byte) Math.max(res, a[i]); } return res; @@ -3352,9 +3355,8 @@ public class Byte64VectorTests extends AbstractVectorTest { static byte MAXReduceAllMasked(byte[] a, boolean[] mask) { byte res = Byte.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3378,13 +3380,98 @@ public class Byte64VectorTests extends AbstractVectorTest { ra = Byte.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (byte) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Byte64VectorTests::MAXReduceMasked, Byte64VectorTests::MAXReduceAllMasked); } + static byte FIRST_NONZEROReduce(byte[] a, int idx) { + byte res = (byte) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static byte FIRST_NONZEROReduceAll(byte[] a) { + byte res = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "byteUnaryOpProvider") + static void FIRST_NONZEROReduceByte64VectorTests(IntFunction fa) { + byte[] a = fa.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + byte ra = (byte) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Byte64VectorTests::FIRST_NONZEROReduce, Byte64VectorTests::FIRST_NONZEROReduceAll); + } + static byte FIRST_NONZEROReduceMasked(byte[] a, int idx, boolean[] mask) { + byte res = (byte) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static byte FIRST_NONZEROReduceAllMasked(byte[] a, boolean[] mask) { + byte res = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "byteUnaryOpMaskProvider") + static void FIRST_NONZEROReduceByte64VectorTestsMasked(IntFunction fa, IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + byte ra = (byte) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Byte64VectorTests::FIRST_NONZEROReduceMasked, Byte64VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java b/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java index eb438cb2042..e4a9ebf19f5 100644 --- a/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java @@ -24,7 +24,7 @@ /* * @test * @modules jdk.incubator.vector - * @run testng/othervm/timeout=240 -ea -esa -Xbatch -XX:-TieredCompilation ByteMaxVectorTests + * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation ByteMaxVectorTests */ // -- This file was mechanically generated: Do not edit! -- // @@ -1206,6 +1206,10 @@ public class ByteMaxVectorTests extends AbstractVectorTest { return Byte.compareUnsigned(a, b) >= 0; } + static byte firstNonZero(byte a, byte b) { + return Byte.compare(a, (byte) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { ByteVector three = ByteVector.broadcast(SPECIES, (byte)-3); @@ -3221,7 +3225,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest { static byte MINReduce(byte[] a, int idx) { byte res = Byte.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (byte)Math.min(res, a[i]); + res = (byte) Math.min(res, a[i]); } return res; @@ -3229,8 +3233,8 @@ public class ByteMaxVectorTests extends AbstractVectorTest { static byte MINReduceAll(byte[] a) { byte res = Byte.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (byte)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.min(res, MINReduce(a, i)); } return res; @@ -3252,7 +3256,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest { ra = Byte.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (byte) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3262,8 +3266,8 @@ public class ByteMaxVectorTests extends AbstractVectorTest { static byte MINReduceMasked(byte[] a, int idx, boolean[] mask) { byte res = Byte.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (byte) Math.min(res, a[i]); } return res; @@ -3271,9 +3275,8 @@ public class ByteMaxVectorTests extends AbstractVectorTest { static byte MINReduceAllMasked(byte[] a, boolean[] mask) { byte res = Byte.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3297,7 +3300,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest { ra = Byte.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (byte) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3307,7 +3310,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest { static byte MAXReduce(byte[] a, int idx) { byte res = Byte.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (byte)Math.max(res, a[i]); + res = (byte) Math.max(res, a[i]); } return res; @@ -3315,8 +3318,8 @@ public class ByteMaxVectorTests extends AbstractVectorTest { static byte MAXReduceAll(byte[] a) { byte res = Byte.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (byte)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.max(res, MAXReduce(a, i)); } return res; @@ -3338,7 +3341,7 @@ public class ByteMaxVectorTests extends AbstractVectorTest { ra = Byte.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (byte) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3348,8 +3351,8 @@ public class ByteMaxVectorTests extends AbstractVectorTest { static byte MAXReduceMasked(byte[] a, int idx, boolean[] mask) { byte res = Byte.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (byte) Math.max(res, a[i]); } return res; @@ -3357,9 +3360,8 @@ public class ByteMaxVectorTests extends AbstractVectorTest { static byte MAXReduceAllMasked(byte[] a, boolean[] mask) { byte res = Byte.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (byte)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (byte) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3383,13 +3385,98 @@ public class ByteMaxVectorTests extends AbstractVectorTest { ra = Byte.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ByteVector av = ByteVector.fromArray(SPECIES, a, i); - ra = (byte)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (byte) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, ByteMaxVectorTests::MAXReduceMasked, ByteMaxVectorTests::MAXReduceAllMasked); } + static byte FIRST_NONZEROReduce(byte[] a, int idx) { + byte res = (byte) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static byte FIRST_NONZEROReduceAll(byte[] a) { + byte res = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "byteUnaryOpProvider") + static void FIRST_NONZEROReduceByteMaxVectorTests(IntFunction fa) { + byte[] a = fa.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + byte ra = (byte) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + ByteMaxVectorTests::FIRST_NONZEROReduce, ByteMaxVectorTests::FIRST_NONZEROReduceAll); + } + static byte FIRST_NONZEROReduceMasked(byte[] a, int idx, boolean[] mask) { + byte res = (byte) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static byte FIRST_NONZEROReduceAllMasked(byte[] a, boolean[] mask) { + byte res = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "byteUnaryOpMaskProvider") + static void FIRST_NONZEROReduceByteMaxVectorTestsMasked(IntFunction fa, IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + byte ra = (byte) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (byte) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + ByteMaxVectorTests::FIRST_NONZEROReduceMasked, ByteMaxVectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Double128VectorTests.java b/test/jdk/jdk/incubator/vector/Double128VectorTests.java index 646570f3752..c79b1e2f4ef 100644 --- a/test/jdk/jdk/incubator/vector/Double128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double128VectorTests.java @@ -1299,6 +1299,10 @@ public class Double128VectorTests extends AbstractVectorTest { } + static double firstNonZero(double a, double b) { + return Double.compare(a, (double) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { DoubleVector three = DoubleVector.broadcast(SPECIES, (byte)-3); @@ -2277,7 +2281,7 @@ public class Double128VectorTests extends AbstractVectorTest { static double MINReduce(double[] a, int idx) { double res = Double.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (double)Math.min(res, a[i]); + res = (double) Math.min(res, a[i]); } return res; @@ -2285,8 +2289,8 @@ public class Double128VectorTests extends AbstractVectorTest { static double MINReduceAll(double[] a) { double res = Double.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (double)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.min(res, MINReduce(a, i)); } return res; @@ -2308,7 +2312,7 @@ public class Double128VectorTests extends AbstractVectorTest { ra = Double.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -2318,8 +2322,8 @@ public class Double128VectorTests extends AbstractVectorTest { static double MINReduceMasked(double[] a, int idx, boolean[] mask) { double res = Double.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (double) Math.min(res, a[i]); } return res; @@ -2327,9 +2331,8 @@ public class Double128VectorTests extends AbstractVectorTest { static double MINReduceAllMasked(double[] a, boolean[] mask) { double res = Double.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -2353,7 +2356,7 @@ public class Double128VectorTests extends AbstractVectorTest { ra = Double.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -2363,7 +2366,7 @@ public class Double128VectorTests extends AbstractVectorTest { static double MAXReduce(double[] a, int idx) { double res = Double.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (double)Math.max(res, a[i]); + res = (double) Math.max(res, a[i]); } return res; @@ -2371,8 +2374,8 @@ public class Double128VectorTests extends AbstractVectorTest { static double MAXReduceAll(double[] a) { double res = Double.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (double)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.max(res, MAXReduce(a, i)); } return res; @@ -2394,7 +2397,7 @@ public class Double128VectorTests extends AbstractVectorTest { ra = Double.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -2404,8 +2407,8 @@ public class Double128VectorTests extends AbstractVectorTest { static double MAXReduceMasked(double[] a, int idx, boolean[] mask) { double res = Double.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (double) Math.max(res, a[i]); } return res; @@ -2413,9 +2416,8 @@ public class Double128VectorTests extends AbstractVectorTest { static double MAXReduceAllMasked(double[] a, boolean[] mask) { double res = Double.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -2439,13 +2441,98 @@ public class Double128VectorTests extends AbstractVectorTest { ra = Double.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Double128VectorTests::MAXReduceMasked, Double128VectorTests::MAXReduceAllMasked); } + static double FIRST_NONZEROReduce(double[] a, int idx) { + double res = (double) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static double FIRST_NONZEROReduceAll(double[] a) { + double res = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "doubleUnaryOpProvider") + static void FIRST_NONZEROReduceDouble128VectorTests(IntFunction fa) { + double[] a = fa.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + double ra = (double) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Double128VectorTests::FIRST_NONZEROReduce, Double128VectorTests::FIRST_NONZEROReduceAll); + } + static double FIRST_NONZEROReduceMasked(double[] a, int idx, boolean[] mask) { + double res = (double) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static double FIRST_NONZEROReduceAllMasked(double[] a, boolean[] mask) { + double res = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "doubleUnaryOpMaskProvider") + static void FIRST_NONZEROReduceDouble128VectorTestsMasked(IntFunction fa, IntFunction fm) { + double[] a = fa.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + double ra = (double) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Double128VectorTests::FIRST_NONZEROReduceMasked, Double128VectorTests::FIRST_NONZEROReduceAllMasked); + } diff --git a/test/jdk/jdk/incubator/vector/Double256VectorTests.java b/test/jdk/jdk/incubator/vector/Double256VectorTests.java index a7d0a2c0b9f..6d459901d13 100644 --- a/test/jdk/jdk/incubator/vector/Double256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double256VectorTests.java @@ -1299,6 +1299,10 @@ public class Double256VectorTests extends AbstractVectorTest { } + static double firstNonZero(double a, double b) { + return Double.compare(a, (double) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { DoubleVector three = DoubleVector.broadcast(SPECIES, (byte)-3); @@ -2277,7 +2281,7 @@ public class Double256VectorTests extends AbstractVectorTest { static double MINReduce(double[] a, int idx) { double res = Double.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (double)Math.min(res, a[i]); + res = (double) Math.min(res, a[i]); } return res; @@ -2285,8 +2289,8 @@ public class Double256VectorTests extends AbstractVectorTest { static double MINReduceAll(double[] a) { double res = Double.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (double)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.min(res, MINReduce(a, i)); } return res; @@ -2308,7 +2312,7 @@ public class Double256VectorTests extends AbstractVectorTest { ra = Double.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -2318,8 +2322,8 @@ public class Double256VectorTests extends AbstractVectorTest { static double MINReduceMasked(double[] a, int idx, boolean[] mask) { double res = Double.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (double) Math.min(res, a[i]); } return res; @@ -2327,9 +2331,8 @@ public class Double256VectorTests extends AbstractVectorTest { static double MINReduceAllMasked(double[] a, boolean[] mask) { double res = Double.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -2353,7 +2356,7 @@ public class Double256VectorTests extends AbstractVectorTest { ra = Double.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -2363,7 +2366,7 @@ public class Double256VectorTests extends AbstractVectorTest { static double MAXReduce(double[] a, int idx) { double res = Double.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (double)Math.max(res, a[i]); + res = (double) Math.max(res, a[i]); } return res; @@ -2371,8 +2374,8 @@ public class Double256VectorTests extends AbstractVectorTest { static double MAXReduceAll(double[] a) { double res = Double.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (double)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.max(res, MAXReduce(a, i)); } return res; @@ -2394,7 +2397,7 @@ public class Double256VectorTests extends AbstractVectorTest { ra = Double.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -2404,8 +2407,8 @@ public class Double256VectorTests extends AbstractVectorTest { static double MAXReduceMasked(double[] a, int idx, boolean[] mask) { double res = Double.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (double) Math.max(res, a[i]); } return res; @@ -2413,9 +2416,8 @@ public class Double256VectorTests extends AbstractVectorTest { static double MAXReduceAllMasked(double[] a, boolean[] mask) { double res = Double.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -2439,13 +2441,98 @@ public class Double256VectorTests extends AbstractVectorTest { ra = Double.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Double256VectorTests::MAXReduceMasked, Double256VectorTests::MAXReduceAllMasked); } + static double FIRST_NONZEROReduce(double[] a, int idx) { + double res = (double) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static double FIRST_NONZEROReduceAll(double[] a) { + double res = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "doubleUnaryOpProvider") + static void FIRST_NONZEROReduceDouble256VectorTests(IntFunction fa) { + double[] a = fa.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + double ra = (double) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Double256VectorTests::FIRST_NONZEROReduce, Double256VectorTests::FIRST_NONZEROReduceAll); + } + static double FIRST_NONZEROReduceMasked(double[] a, int idx, boolean[] mask) { + double res = (double) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static double FIRST_NONZEROReduceAllMasked(double[] a, boolean[] mask) { + double res = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "doubleUnaryOpMaskProvider") + static void FIRST_NONZEROReduceDouble256VectorTestsMasked(IntFunction fa, IntFunction fm) { + double[] a = fa.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + double ra = (double) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Double256VectorTests::FIRST_NONZEROReduceMasked, Double256VectorTests::FIRST_NONZEROReduceAllMasked); + } diff --git a/test/jdk/jdk/incubator/vector/Double512VectorTests.java b/test/jdk/jdk/incubator/vector/Double512VectorTests.java index 26a699454bc..82299753e65 100644 --- a/test/jdk/jdk/incubator/vector/Double512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double512VectorTests.java @@ -1299,6 +1299,10 @@ public class Double512VectorTests extends AbstractVectorTest { } + static double firstNonZero(double a, double b) { + return Double.compare(a, (double) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { DoubleVector three = DoubleVector.broadcast(SPECIES, (byte)-3); @@ -2277,7 +2281,7 @@ public class Double512VectorTests extends AbstractVectorTest { static double MINReduce(double[] a, int idx) { double res = Double.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (double)Math.min(res, a[i]); + res = (double) Math.min(res, a[i]); } return res; @@ -2285,8 +2289,8 @@ public class Double512VectorTests extends AbstractVectorTest { static double MINReduceAll(double[] a) { double res = Double.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (double)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.min(res, MINReduce(a, i)); } return res; @@ -2308,7 +2312,7 @@ public class Double512VectorTests extends AbstractVectorTest { ra = Double.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -2318,8 +2322,8 @@ public class Double512VectorTests extends AbstractVectorTest { static double MINReduceMasked(double[] a, int idx, boolean[] mask) { double res = Double.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (double) Math.min(res, a[i]); } return res; @@ -2327,9 +2331,8 @@ public class Double512VectorTests extends AbstractVectorTest { static double MINReduceAllMasked(double[] a, boolean[] mask) { double res = Double.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -2353,7 +2356,7 @@ public class Double512VectorTests extends AbstractVectorTest { ra = Double.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -2363,7 +2366,7 @@ public class Double512VectorTests extends AbstractVectorTest { static double MAXReduce(double[] a, int idx) { double res = Double.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (double)Math.max(res, a[i]); + res = (double) Math.max(res, a[i]); } return res; @@ -2371,8 +2374,8 @@ public class Double512VectorTests extends AbstractVectorTest { static double MAXReduceAll(double[] a) { double res = Double.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (double)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.max(res, MAXReduce(a, i)); } return res; @@ -2394,7 +2397,7 @@ public class Double512VectorTests extends AbstractVectorTest { ra = Double.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -2404,8 +2407,8 @@ public class Double512VectorTests extends AbstractVectorTest { static double MAXReduceMasked(double[] a, int idx, boolean[] mask) { double res = Double.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (double) Math.max(res, a[i]); } return res; @@ -2413,9 +2416,8 @@ public class Double512VectorTests extends AbstractVectorTest { static double MAXReduceAllMasked(double[] a, boolean[] mask) { double res = Double.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -2439,13 +2441,98 @@ public class Double512VectorTests extends AbstractVectorTest { ra = Double.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Double512VectorTests::MAXReduceMasked, Double512VectorTests::MAXReduceAllMasked); } + static double FIRST_NONZEROReduce(double[] a, int idx) { + double res = (double) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static double FIRST_NONZEROReduceAll(double[] a) { + double res = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "doubleUnaryOpProvider") + static void FIRST_NONZEROReduceDouble512VectorTests(IntFunction fa) { + double[] a = fa.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + double ra = (double) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Double512VectorTests::FIRST_NONZEROReduce, Double512VectorTests::FIRST_NONZEROReduceAll); + } + static double FIRST_NONZEROReduceMasked(double[] a, int idx, boolean[] mask) { + double res = (double) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static double FIRST_NONZEROReduceAllMasked(double[] a, boolean[] mask) { + double res = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "doubleUnaryOpMaskProvider") + static void FIRST_NONZEROReduceDouble512VectorTestsMasked(IntFunction fa, IntFunction fm) { + double[] a = fa.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + double ra = (double) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Double512VectorTests::FIRST_NONZEROReduceMasked, Double512VectorTests::FIRST_NONZEROReduceAllMasked); + } diff --git a/test/jdk/jdk/incubator/vector/Double64VectorTests.java b/test/jdk/jdk/incubator/vector/Double64VectorTests.java index 017889f8b9a..82fd826ffcb 100644 --- a/test/jdk/jdk/incubator/vector/Double64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double64VectorTests.java @@ -1299,6 +1299,10 @@ public class Double64VectorTests extends AbstractVectorTest { } + static double firstNonZero(double a, double b) { + return Double.compare(a, (double) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { DoubleVector three = DoubleVector.broadcast(SPECIES, (byte)-3); @@ -2277,7 +2281,7 @@ public class Double64VectorTests extends AbstractVectorTest { static double MINReduce(double[] a, int idx) { double res = Double.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (double)Math.min(res, a[i]); + res = (double) Math.min(res, a[i]); } return res; @@ -2285,8 +2289,8 @@ public class Double64VectorTests extends AbstractVectorTest { static double MINReduceAll(double[] a) { double res = Double.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (double)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.min(res, MINReduce(a, i)); } return res; @@ -2308,7 +2312,7 @@ public class Double64VectorTests extends AbstractVectorTest { ra = Double.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -2318,8 +2322,8 @@ public class Double64VectorTests extends AbstractVectorTest { static double MINReduceMasked(double[] a, int idx, boolean[] mask) { double res = Double.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (double) Math.min(res, a[i]); } return res; @@ -2327,9 +2331,8 @@ public class Double64VectorTests extends AbstractVectorTest { static double MINReduceAllMasked(double[] a, boolean[] mask) { double res = Double.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -2353,7 +2356,7 @@ public class Double64VectorTests extends AbstractVectorTest { ra = Double.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -2363,7 +2366,7 @@ public class Double64VectorTests extends AbstractVectorTest { static double MAXReduce(double[] a, int idx) { double res = Double.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (double)Math.max(res, a[i]); + res = (double) Math.max(res, a[i]); } return res; @@ -2371,8 +2374,8 @@ public class Double64VectorTests extends AbstractVectorTest { static double MAXReduceAll(double[] a) { double res = Double.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (double)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.max(res, MAXReduce(a, i)); } return res; @@ -2394,7 +2397,7 @@ public class Double64VectorTests extends AbstractVectorTest { ra = Double.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -2404,8 +2407,8 @@ public class Double64VectorTests extends AbstractVectorTest { static double MAXReduceMasked(double[] a, int idx, boolean[] mask) { double res = Double.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (double) Math.max(res, a[i]); } return res; @@ -2413,9 +2416,8 @@ public class Double64VectorTests extends AbstractVectorTest { static double MAXReduceAllMasked(double[] a, boolean[] mask) { double res = Double.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -2439,13 +2441,98 @@ public class Double64VectorTests extends AbstractVectorTest { ra = Double.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Double64VectorTests::MAXReduceMasked, Double64VectorTests::MAXReduceAllMasked); } + static double FIRST_NONZEROReduce(double[] a, int idx) { + double res = (double) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static double FIRST_NONZEROReduceAll(double[] a) { + double res = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "doubleUnaryOpProvider") + static void FIRST_NONZEROReduceDouble64VectorTests(IntFunction fa) { + double[] a = fa.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + double ra = (double) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Double64VectorTests::FIRST_NONZEROReduce, Double64VectorTests::FIRST_NONZEROReduceAll); + } + static double FIRST_NONZEROReduceMasked(double[] a, int idx, boolean[] mask) { + double res = (double) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static double FIRST_NONZEROReduceAllMasked(double[] a, boolean[] mask) { + double res = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "doubleUnaryOpMaskProvider") + static void FIRST_NONZEROReduceDouble64VectorTestsMasked(IntFunction fa, IntFunction fm) { + double[] a = fa.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + double ra = (double) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Double64VectorTests::FIRST_NONZEROReduceMasked, Double64VectorTests::FIRST_NONZEROReduceAllMasked); + } diff --git a/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java b/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java index c4eb2b2182b..af9054efbb0 100644 --- a/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java @@ -1304,6 +1304,10 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { } + static double firstNonZero(double a, double b) { + return Double.compare(a, (double) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { DoubleVector three = DoubleVector.broadcast(SPECIES, (byte)-3); @@ -2282,7 +2286,7 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { static double MINReduce(double[] a, int idx) { double res = Double.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (double)Math.min(res, a[i]); + res = (double) Math.min(res, a[i]); } return res; @@ -2290,8 +2294,8 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { static double MINReduceAll(double[] a) { double res = Double.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (double)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.min(res, MINReduce(a, i)); } return res; @@ -2313,7 +2317,7 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { ra = Double.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -2323,8 +2327,8 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { static double MINReduceMasked(double[] a, int idx, boolean[] mask) { double res = Double.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (double) Math.min(res, a[i]); } return res; @@ -2332,9 +2336,8 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { static double MINReduceAllMasked(double[] a, boolean[] mask) { double res = Double.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -2358,7 +2361,7 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { ra = Double.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -2368,7 +2371,7 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { static double MAXReduce(double[] a, int idx) { double res = Double.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (double)Math.max(res, a[i]); + res = (double) Math.max(res, a[i]); } return res; @@ -2376,8 +2379,8 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { static double MAXReduceAll(double[] a) { double res = Double.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (double)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.max(res, MAXReduce(a, i)); } return res; @@ -2399,7 +2402,7 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { ra = Double.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -2409,8 +2412,8 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { static double MAXReduceMasked(double[] a, int idx, boolean[] mask) { double res = Double.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (double) Math.max(res, a[i]); } return res; @@ -2418,9 +2421,8 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { static double MAXReduceAllMasked(double[] a, boolean[] mask) { double res = Double.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (double)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (double) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -2444,13 +2446,98 @@ public class DoubleMaxVectorTests extends AbstractVectorTest { ra = Double.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); - ra = (double)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, DoubleMaxVectorTests::MAXReduceMasked, DoubleMaxVectorTests::MAXReduceAllMasked); } + static double FIRST_NONZEROReduce(double[] a, int idx) { + double res = (double) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static double FIRST_NONZEROReduceAll(double[] a) { + double res = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "doubleUnaryOpProvider") + static void FIRST_NONZEROReduceDoubleMaxVectorTests(IntFunction fa) { + double[] a = fa.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + double ra = (double) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + DoubleMaxVectorTests::FIRST_NONZEROReduce, DoubleMaxVectorTests::FIRST_NONZEROReduceAll); + } + static double FIRST_NONZEROReduceMasked(double[] a, int idx, boolean[] mask) { + double res = (double) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static double FIRST_NONZEROReduceAllMasked(double[] a, boolean[] mask) { + double res = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "doubleUnaryOpMaskProvider") + static void FIRST_NONZEROReduceDoubleMaxVectorTestsMasked(IntFunction fa, IntFunction fm) { + double[] a = fa.apply(SPECIES.length()); + double[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + double ra = (double) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (double) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + DoubleMaxVectorTests::FIRST_NONZEROReduceMasked, DoubleMaxVectorTests::FIRST_NONZEROReduceAllMasked); + } diff --git a/test/jdk/jdk/incubator/vector/Float128VectorTests.java b/test/jdk/jdk/incubator/vector/Float128VectorTests.java index b3e7b05d2a2..c793515b6c6 100644 --- a/test/jdk/jdk/incubator/vector/Float128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float128VectorTests.java @@ -1309,6 +1309,10 @@ public class Float128VectorTests extends AbstractVectorTest { } + static float firstNonZero(float a, float b) { + return Float.compare(a, (float) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { FloatVector three = FloatVector.broadcast(SPECIES, (byte)-3); @@ -2287,7 +2291,7 @@ public class Float128VectorTests extends AbstractVectorTest { static float MINReduce(float[] a, int idx) { float res = Float.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (float)Math.min(res, a[i]); + res = (float) Math.min(res, a[i]); } return res; @@ -2295,8 +2299,8 @@ public class Float128VectorTests extends AbstractVectorTest { static float MINReduceAll(float[] a) { float res = Float.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (float)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.min(res, MINReduce(a, i)); } return res; @@ -2318,7 +2322,7 @@ public class Float128VectorTests extends AbstractVectorTest { ra = Float.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -2328,8 +2332,8 @@ public class Float128VectorTests extends AbstractVectorTest { static float MINReduceMasked(float[] a, int idx, boolean[] mask) { float res = Float.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (float) Math.min(res, a[i]); } return res; @@ -2337,9 +2341,8 @@ public class Float128VectorTests extends AbstractVectorTest { static float MINReduceAllMasked(float[] a, boolean[] mask) { float res = Float.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -2363,7 +2366,7 @@ public class Float128VectorTests extends AbstractVectorTest { ra = Float.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -2373,7 +2376,7 @@ public class Float128VectorTests extends AbstractVectorTest { static float MAXReduce(float[] a, int idx) { float res = Float.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (float)Math.max(res, a[i]); + res = (float) Math.max(res, a[i]); } return res; @@ -2381,8 +2384,8 @@ public class Float128VectorTests extends AbstractVectorTest { static float MAXReduceAll(float[] a) { float res = Float.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (float)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.max(res, MAXReduce(a, i)); } return res; @@ -2404,7 +2407,7 @@ public class Float128VectorTests extends AbstractVectorTest { ra = Float.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -2414,8 +2417,8 @@ public class Float128VectorTests extends AbstractVectorTest { static float MAXReduceMasked(float[] a, int idx, boolean[] mask) { float res = Float.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (float) Math.max(res, a[i]); } return res; @@ -2423,9 +2426,8 @@ public class Float128VectorTests extends AbstractVectorTest { static float MAXReduceAllMasked(float[] a, boolean[] mask) { float res = Float.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -2449,13 +2451,98 @@ public class Float128VectorTests extends AbstractVectorTest { ra = Float.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Float128VectorTests::MAXReduceMasked, Float128VectorTests::MAXReduceAllMasked); } + static float FIRST_NONZEROReduce(float[] a, int idx) { + float res = (float) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static float FIRST_NONZEROReduceAll(float[] a) { + float res = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "floatUnaryOpProvider") + static void FIRST_NONZEROReduceFloat128VectorTests(IntFunction fa) { + float[] a = fa.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + float ra = (float) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Float128VectorTests::FIRST_NONZEROReduce, Float128VectorTests::FIRST_NONZEROReduceAll); + } + static float FIRST_NONZEROReduceMasked(float[] a, int idx, boolean[] mask) { + float res = (float) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static float FIRST_NONZEROReduceAllMasked(float[] a, boolean[] mask) { + float res = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "floatUnaryOpMaskProvider") + static void FIRST_NONZEROReduceFloat128VectorTestsMasked(IntFunction fa, IntFunction fm) { + float[] a = fa.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + float ra = (float) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Float128VectorTests::FIRST_NONZEROReduceMasked, Float128VectorTests::FIRST_NONZEROReduceAllMasked); + } diff --git a/test/jdk/jdk/incubator/vector/Float256VectorTests.java b/test/jdk/jdk/incubator/vector/Float256VectorTests.java index 120fc4cabd2..61593a8c23a 100644 --- a/test/jdk/jdk/incubator/vector/Float256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float256VectorTests.java @@ -1309,6 +1309,10 @@ public class Float256VectorTests extends AbstractVectorTest { } + static float firstNonZero(float a, float b) { + return Float.compare(a, (float) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { FloatVector three = FloatVector.broadcast(SPECIES, (byte)-3); @@ -2287,7 +2291,7 @@ public class Float256VectorTests extends AbstractVectorTest { static float MINReduce(float[] a, int idx) { float res = Float.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (float)Math.min(res, a[i]); + res = (float) Math.min(res, a[i]); } return res; @@ -2295,8 +2299,8 @@ public class Float256VectorTests extends AbstractVectorTest { static float MINReduceAll(float[] a) { float res = Float.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (float)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.min(res, MINReduce(a, i)); } return res; @@ -2318,7 +2322,7 @@ public class Float256VectorTests extends AbstractVectorTest { ra = Float.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -2328,8 +2332,8 @@ public class Float256VectorTests extends AbstractVectorTest { static float MINReduceMasked(float[] a, int idx, boolean[] mask) { float res = Float.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (float) Math.min(res, a[i]); } return res; @@ -2337,9 +2341,8 @@ public class Float256VectorTests extends AbstractVectorTest { static float MINReduceAllMasked(float[] a, boolean[] mask) { float res = Float.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -2363,7 +2366,7 @@ public class Float256VectorTests extends AbstractVectorTest { ra = Float.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -2373,7 +2376,7 @@ public class Float256VectorTests extends AbstractVectorTest { static float MAXReduce(float[] a, int idx) { float res = Float.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (float)Math.max(res, a[i]); + res = (float) Math.max(res, a[i]); } return res; @@ -2381,8 +2384,8 @@ public class Float256VectorTests extends AbstractVectorTest { static float MAXReduceAll(float[] a) { float res = Float.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (float)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.max(res, MAXReduce(a, i)); } return res; @@ -2404,7 +2407,7 @@ public class Float256VectorTests extends AbstractVectorTest { ra = Float.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -2414,8 +2417,8 @@ public class Float256VectorTests extends AbstractVectorTest { static float MAXReduceMasked(float[] a, int idx, boolean[] mask) { float res = Float.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (float) Math.max(res, a[i]); } return res; @@ -2423,9 +2426,8 @@ public class Float256VectorTests extends AbstractVectorTest { static float MAXReduceAllMasked(float[] a, boolean[] mask) { float res = Float.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -2449,13 +2451,98 @@ public class Float256VectorTests extends AbstractVectorTest { ra = Float.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Float256VectorTests::MAXReduceMasked, Float256VectorTests::MAXReduceAllMasked); } + static float FIRST_NONZEROReduce(float[] a, int idx) { + float res = (float) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static float FIRST_NONZEROReduceAll(float[] a) { + float res = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "floatUnaryOpProvider") + static void FIRST_NONZEROReduceFloat256VectorTests(IntFunction fa) { + float[] a = fa.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + float ra = (float) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Float256VectorTests::FIRST_NONZEROReduce, Float256VectorTests::FIRST_NONZEROReduceAll); + } + static float FIRST_NONZEROReduceMasked(float[] a, int idx, boolean[] mask) { + float res = (float) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static float FIRST_NONZEROReduceAllMasked(float[] a, boolean[] mask) { + float res = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "floatUnaryOpMaskProvider") + static void FIRST_NONZEROReduceFloat256VectorTestsMasked(IntFunction fa, IntFunction fm) { + float[] a = fa.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + float ra = (float) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Float256VectorTests::FIRST_NONZEROReduceMasked, Float256VectorTests::FIRST_NONZEROReduceAllMasked); + } diff --git a/test/jdk/jdk/incubator/vector/Float512VectorTests.java b/test/jdk/jdk/incubator/vector/Float512VectorTests.java index 75fbccaed27..421338f053c 100644 --- a/test/jdk/jdk/incubator/vector/Float512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float512VectorTests.java @@ -1309,6 +1309,10 @@ public class Float512VectorTests extends AbstractVectorTest { } + static float firstNonZero(float a, float b) { + return Float.compare(a, (float) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { FloatVector three = FloatVector.broadcast(SPECIES, (byte)-3); @@ -2287,7 +2291,7 @@ public class Float512VectorTests extends AbstractVectorTest { static float MINReduce(float[] a, int idx) { float res = Float.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (float)Math.min(res, a[i]); + res = (float) Math.min(res, a[i]); } return res; @@ -2295,8 +2299,8 @@ public class Float512VectorTests extends AbstractVectorTest { static float MINReduceAll(float[] a) { float res = Float.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (float)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.min(res, MINReduce(a, i)); } return res; @@ -2318,7 +2322,7 @@ public class Float512VectorTests extends AbstractVectorTest { ra = Float.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -2328,8 +2332,8 @@ public class Float512VectorTests extends AbstractVectorTest { static float MINReduceMasked(float[] a, int idx, boolean[] mask) { float res = Float.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (float) Math.min(res, a[i]); } return res; @@ -2337,9 +2341,8 @@ public class Float512VectorTests extends AbstractVectorTest { static float MINReduceAllMasked(float[] a, boolean[] mask) { float res = Float.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -2363,7 +2366,7 @@ public class Float512VectorTests extends AbstractVectorTest { ra = Float.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -2373,7 +2376,7 @@ public class Float512VectorTests extends AbstractVectorTest { static float MAXReduce(float[] a, int idx) { float res = Float.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (float)Math.max(res, a[i]); + res = (float) Math.max(res, a[i]); } return res; @@ -2381,8 +2384,8 @@ public class Float512VectorTests extends AbstractVectorTest { static float MAXReduceAll(float[] a) { float res = Float.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (float)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.max(res, MAXReduce(a, i)); } return res; @@ -2404,7 +2407,7 @@ public class Float512VectorTests extends AbstractVectorTest { ra = Float.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -2414,8 +2417,8 @@ public class Float512VectorTests extends AbstractVectorTest { static float MAXReduceMasked(float[] a, int idx, boolean[] mask) { float res = Float.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (float) Math.max(res, a[i]); } return res; @@ -2423,9 +2426,8 @@ public class Float512VectorTests extends AbstractVectorTest { static float MAXReduceAllMasked(float[] a, boolean[] mask) { float res = Float.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -2449,13 +2451,98 @@ public class Float512VectorTests extends AbstractVectorTest { ra = Float.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Float512VectorTests::MAXReduceMasked, Float512VectorTests::MAXReduceAllMasked); } + static float FIRST_NONZEROReduce(float[] a, int idx) { + float res = (float) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static float FIRST_NONZEROReduceAll(float[] a) { + float res = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "floatUnaryOpProvider") + static void FIRST_NONZEROReduceFloat512VectorTests(IntFunction fa) { + float[] a = fa.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + float ra = (float) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Float512VectorTests::FIRST_NONZEROReduce, Float512VectorTests::FIRST_NONZEROReduceAll); + } + static float FIRST_NONZEROReduceMasked(float[] a, int idx, boolean[] mask) { + float res = (float) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static float FIRST_NONZEROReduceAllMasked(float[] a, boolean[] mask) { + float res = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "floatUnaryOpMaskProvider") + static void FIRST_NONZEROReduceFloat512VectorTestsMasked(IntFunction fa, IntFunction fm) { + float[] a = fa.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + float ra = (float) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Float512VectorTests::FIRST_NONZEROReduceMasked, Float512VectorTests::FIRST_NONZEROReduceAllMasked); + } diff --git a/test/jdk/jdk/incubator/vector/Float64VectorTests.java b/test/jdk/jdk/incubator/vector/Float64VectorTests.java index dbe87867b9a..cbe82a7e22d 100644 --- a/test/jdk/jdk/incubator/vector/Float64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float64VectorTests.java @@ -1309,6 +1309,10 @@ public class Float64VectorTests extends AbstractVectorTest { } + static float firstNonZero(float a, float b) { + return Float.compare(a, (float) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { FloatVector three = FloatVector.broadcast(SPECIES, (byte)-3); @@ -2287,7 +2291,7 @@ public class Float64VectorTests extends AbstractVectorTest { static float MINReduce(float[] a, int idx) { float res = Float.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (float)Math.min(res, a[i]); + res = (float) Math.min(res, a[i]); } return res; @@ -2295,8 +2299,8 @@ public class Float64VectorTests extends AbstractVectorTest { static float MINReduceAll(float[] a) { float res = Float.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (float)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.min(res, MINReduce(a, i)); } return res; @@ -2318,7 +2322,7 @@ public class Float64VectorTests extends AbstractVectorTest { ra = Float.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -2328,8 +2332,8 @@ public class Float64VectorTests extends AbstractVectorTest { static float MINReduceMasked(float[] a, int idx, boolean[] mask) { float res = Float.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (float) Math.min(res, a[i]); } return res; @@ -2337,9 +2341,8 @@ public class Float64VectorTests extends AbstractVectorTest { static float MINReduceAllMasked(float[] a, boolean[] mask) { float res = Float.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -2363,7 +2366,7 @@ public class Float64VectorTests extends AbstractVectorTest { ra = Float.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -2373,7 +2376,7 @@ public class Float64VectorTests extends AbstractVectorTest { static float MAXReduce(float[] a, int idx) { float res = Float.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (float)Math.max(res, a[i]); + res = (float) Math.max(res, a[i]); } return res; @@ -2381,8 +2384,8 @@ public class Float64VectorTests extends AbstractVectorTest { static float MAXReduceAll(float[] a) { float res = Float.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (float)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.max(res, MAXReduce(a, i)); } return res; @@ -2404,7 +2407,7 @@ public class Float64VectorTests extends AbstractVectorTest { ra = Float.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -2414,8 +2417,8 @@ public class Float64VectorTests extends AbstractVectorTest { static float MAXReduceMasked(float[] a, int idx, boolean[] mask) { float res = Float.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (float) Math.max(res, a[i]); } return res; @@ -2423,9 +2426,8 @@ public class Float64VectorTests extends AbstractVectorTest { static float MAXReduceAllMasked(float[] a, boolean[] mask) { float res = Float.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -2449,13 +2451,98 @@ public class Float64VectorTests extends AbstractVectorTest { ra = Float.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Float64VectorTests::MAXReduceMasked, Float64VectorTests::MAXReduceAllMasked); } + static float FIRST_NONZEROReduce(float[] a, int idx) { + float res = (float) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static float FIRST_NONZEROReduceAll(float[] a) { + float res = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "floatUnaryOpProvider") + static void FIRST_NONZEROReduceFloat64VectorTests(IntFunction fa) { + float[] a = fa.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + float ra = (float) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Float64VectorTests::FIRST_NONZEROReduce, Float64VectorTests::FIRST_NONZEROReduceAll); + } + static float FIRST_NONZEROReduceMasked(float[] a, int idx, boolean[] mask) { + float res = (float) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static float FIRST_NONZEROReduceAllMasked(float[] a, boolean[] mask) { + float res = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "floatUnaryOpMaskProvider") + static void FIRST_NONZEROReduceFloat64VectorTestsMasked(IntFunction fa, IntFunction fm) { + float[] a = fa.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + float ra = (float) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Float64VectorTests::FIRST_NONZEROReduceMasked, Float64VectorTests::FIRST_NONZEROReduceAllMasked); + } diff --git a/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java b/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java index 5d3e65b765b..e8680eb1d94 100644 --- a/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java @@ -1314,6 +1314,10 @@ public class FloatMaxVectorTests extends AbstractVectorTest { } + static float firstNonZero(float a, float b) { + return Float.compare(a, (float) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { FloatVector three = FloatVector.broadcast(SPECIES, (byte)-3); @@ -2292,7 +2296,7 @@ public class FloatMaxVectorTests extends AbstractVectorTest { static float MINReduce(float[] a, int idx) { float res = Float.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (float)Math.min(res, a[i]); + res = (float) Math.min(res, a[i]); } return res; @@ -2300,8 +2304,8 @@ public class FloatMaxVectorTests extends AbstractVectorTest { static float MINReduceAll(float[] a) { float res = Float.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (float)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.min(res, MINReduce(a, i)); } return res; @@ -2323,7 +2327,7 @@ public class FloatMaxVectorTests extends AbstractVectorTest { ra = Float.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -2333,8 +2337,8 @@ public class FloatMaxVectorTests extends AbstractVectorTest { static float MINReduceMasked(float[] a, int idx, boolean[] mask) { float res = Float.POSITIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (float) Math.min(res, a[i]); } return res; @@ -2342,9 +2346,8 @@ public class FloatMaxVectorTests extends AbstractVectorTest { static float MINReduceAllMasked(float[] a, boolean[] mask) { float res = Float.POSITIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -2368,7 +2371,7 @@ public class FloatMaxVectorTests extends AbstractVectorTest { ra = Float.POSITIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -2378,7 +2381,7 @@ public class FloatMaxVectorTests extends AbstractVectorTest { static float MAXReduce(float[] a, int idx) { float res = Float.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (float)Math.max(res, a[i]); + res = (float) Math.max(res, a[i]); } return res; @@ -2386,8 +2389,8 @@ public class FloatMaxVectorTests extends AbstractVectorTest { static float MAXReduceAll(float[] a) { float res = Float.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - res = (float)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.max(res, MAXReduce(a, i)); } return res; @@ -2409,7 +2412,7 @@ public class FloatMaxVectorTests extends AbstractVectorTest { ra = Float.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -2419,8 +2422,8 @@ public class FloatMaxVectorTests extends AbstractVectorTest { static float MAXReduceMasked(float[] a, int idx, boolean[] mask) { float res = Float.NEGATIVE_INFINITY; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (float) Math.max(res, a[i]); } return res; @@ -2428,9 +2431,8 @@ public class FloatMaxVectorTests extends AbstractVectorTest { static float MAXReduceAllMasked(float[] a, boolean[] mask) { float res = Float.NEGATIVE_INFINITY; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (float)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (float) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -2454,13 +2456,98 @@ public class FloatMaxVectorTests extends AbstractVectorTest { ra = Float.NEGATIVE_INFINITY; for (int i = 0; i < a.length; i += SPECIES.length()) { FloatVector av = FloatVector.fromArray(SPECIES, a, i); - ra = (float)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, FloatMaxVectorTests::MAXReduceMasked, FloatMaxVectorTests::MAXReduceAllMasked); } + static float FIRST_NONZEROReduce(float[] a, int idx) { + float res = (float) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static float FIRST_NONZEROReduceAll(float[] a) { + float res = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "floatUnaryOpProvider") + static void FIRST_NONZEROReduceFloatMaxVectorTests(IntFunction fa) { + float[] a = fa.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + float ra = (float) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + FloatMaxVectorTests::FIRST_NONZEROReduce, FloatMaxVectorTests::FIRST_NONZEROReduceAll); + } + static float FIRST_NONZEROReduceMasked(float[] a, int idx, boolean[] mask) { + float res = (float) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static float FIRST_NONZEROReduceAllMasked(float[] a, boolean[] mask) { + float res = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "floatUnaryOpMaskProvider") + static void FIRST_NONZEROReduceFloatMaxVectorTestsMasked(IntFunction fa, IntFunction fm) { + float[] a = fa.apply(SPECIES.length()); + float[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + float ra = (float) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (float) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + FloatVector av = FloatVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + FloatMaxVectorTests::FIRST_NONZEROReduceMasked, FloatMaxVectorTests::FIRST_NONZEROReduceAllMasked); + } diff --git a/test/jdk/jdk/incubator/vector/Int128VectorTests.java b/test/jdk/jdk/incubator/vector/Int128VectorTests.java index d23295f5b4e..99bc02b8239 100644 --- a/test/jdk/jdk/incubator/vector/Int128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int128VectorTests.java @@ -1161,6 +1161,10 @@ public class Int128VectorTests extends AbstractVectorTest { return Integer.compareUnsigned(a, b) >= 0; } + static int firstNonZero(int a, int b) { + return Integer.compare(a, (int) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { IntVector three = IntVector.broadcast(SPECIES, (byte)-3); @@ -3181,7 +3185,7 @@ public class Int128VectorTests extends AbstractVectorTest { static int MINReduce(int[] a, int idx) { int res = Integer.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (int)Math.min(res, a[i]); + res = (int) Math.min(res, a[i]); } return res; @@ -3189,8 +3193,8 @@ public class Int128VectorTests extends AbstractVectorTest { static int MINReduceAll(int[] a) { int res = Integer.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (int)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.min(res, MINReduce(a, i)); } return res; @@ -3212,7 +3216,7 @@ public class Int128VectorTests extends AbstractVectorTest { ra = Integer.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (int) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3222,8 +3226,8 @@ public class Int128VectorTests extends AbstractVectorTest { static int MINReduceMasked(int[] a, int idx, boolean[] mask) { int res = Integer.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (int) Math.min(res, a[i]); } return res; @@ -3231,9 +3235,8 @@ public class Int128VectorTests extends AbstractVectorTest { static int MINReduceAllMasked(int[] a, boolean[] mask) { int res = Integer.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3257,7 +3260,7 @@ public class Int128VectorTests extends AbstractVectorTest { ra = Integer.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (int) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3267,7 +3270,7 @@ public class Int128VectorTests extends AbstractVectorTest { static int MAXReduce(int[] a, int idx) { int res = Integer.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (int)Math.max(res, a[i]); + res = (int) Math.max(res, a[i]); } return res; @@ -3275,8 +3278,8 @@ public class Int128VectorTests extends AbstractVectorTest { static int MAXReduceAll(int[] a) { int res = Integer.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (int)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.max(res, MAXReduce(a, i)); } return res; @@ -3298,7 +3301,7 @@ public class Int128VectorTests extends AbstractVectorTest { ra = Integer.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (int) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3308,8 +3311,8 @@ public class Int128VectorTests extends AbstractVectorTest { static int MAXReduceMasked(int[] a, int idx, boolean[] mask) { int res = Integer.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (int) Math.max(res, a[i]); } return res; @@ -3317,9 +3320,8 @@ public class Int128VectorTests extends AbstractVectorTest { static int MAXReduceAllMasked(int[] a, boolean[] mask) { int res = Integer.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3343,13 +3345,98 @@ public class Int128VectorTests extends AbstractVectorTest { ra = Integer.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (int) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Int128VectorTests::MAXReduceMasked, Int128VectorTests::MAXReduceAllMasked); } + static int FIRST_NONZEROReduce(int[] a, int idx) { + int res = (int) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static int FIRST_NONZEROReduceAll(int[] a) { + int res = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "intUnaryOpProvider") + static void FIRST_NONZEROReduceInt128VectorTests(IntFunction fa) { + int[] a = fa.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + int ra = (int) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Int128VectorTests::FIRST_NONZEROReduce, Int128VectorTests::FIRST_NONZEROReduceAll); + } + static int FIRST_NONZEROReduceMasked(int[] a, int idx, boolean[] mask) { + int res = (int) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static int FIRST_NONZEROReduceAllMasked(int[] a, boolean[] mask) { + int res = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "intUnaryOpMaskProvider") + static void FIRST_NONZEROReduceInt128VectorTestsMasked(IntFunction fa, IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + int ra = (int) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Int128VectorTests::FIRST_NONZEROReduceMasked, Int128VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Int256VectorTests.java b/test/jdk/jdk/incubator/vector/Int256VectorTests.java index f6bc1f7fd4c..e4b3f491e31 100644 --- a/test/jdk/jdk/incubator/vector/Int256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int256VectorTests.java @@ -1161,6 +1161,10 @@ public class Int256VectorTests extends AbstractVectorTest { return Integer.compareUnsigned(a, b) >= 0; } + static int firstNonZero(int a, int b) { + return Integer.compare(a, (int) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { IntVector three = IntVector.broadcast(SPECIES, (byte)-3); @@ -3181,7 +3185,7 @@ public class Int256VectorTests extends AbstractVectorTest { static int MINReduce(int[] a, int idx) { int res = Integer.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (int)Math.min(res, a[i]); + res = (int) Math.min(res, a[i]); } return res; @@ -3189,8 +3193,8 @@ public class Int256VectorTests extends AbstractVectorTest { static int MINReduceAll(int[] a) { int res = Integer.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (int)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.min(res, MINReduce(a, i)); } return res; @@ -3212,7 +3216,7 @@ public class Int256VectorTests extends AbstractVectorTest { ra = Integer.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (int) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3222,8 +3226,8 @@ public class Int256VectorTests extends AbstractVectorTest { static int MINReduceMasked(int[] a, int idx, boolean[] mask) { int res = Integer.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (int) Math.min(res, a[i]); } return res; @@ -3231,9 +3235,8 @@ public class Int256VectorTests extends AbstractVectorTest { static int MINReduceAllMasked(int[] a, boolean[] mask) { int res = Integer.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3257,7 +3260,7 @@ public class Int256VectorTests extends AbstractVectorTest { ra = Integer.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (int) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3267,7 +3270,7 @@ public class Int256VectorTests extends AbstractVectorTest { static int MAXReduce(int[] a, int idx) { int res = Integer.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (int)Math.max(res, a[i]); + res = (int) Math.max(res, a[i]); } return res; @@ -3275,8 +3278,8 @@ public class Int256VectorTests extends AbstractVectorTest { static int MAXReduceAll(int[] a) { int res = Integer.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (int)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.max(res, MAXReduce(a, i)); } return res; @@ -3298,7 +3301,7 @@ public class Int256VectorTests extends AbstractVectorTest { ra = Integer.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (int) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3308,8 +3311,8 @@ public class Int256VectorTests extends AbstractVectorTest { static int MAXReduceMasked(int[] a, int idx, boolean[] mask) { int res = Integer.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (int) Math.max(res, a[i]); } return res; @@ -3317,9 +3320,8 @@ public class Int256VectorTests extends AbstractVectorTest { static int MAXReduceAllMasked(int[] a, boolean[] mask) { int res = Integer.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3343,13 +3345,98 @@ public class Int256VectorTests extends AbstractVectorTest { ra = Integer.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (int) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Int256VectorTests::MAXReduceMasked, Int256VectorTests::MAXReduceAllMasked); } + static int FIRST_NONZEROReduce(int[] a, int idx) { + int res = (int) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static int FIRST_NONZEROReduceAll(int[] a) { + int res = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "intUnaryOpProvider") + static void FIRST_NONZEROReduceInt256VectorTests(IntFunction fa) { + int[] a = fa.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + int ra = (int) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Int256VectorTests::FIRST_NONZEROReduce, Int256VectorTests::FIRST_NONZEROReduceAll); + } + static int FIRST_NONZEROReduceMasked(int[] a, int idx, boolean[] mask) { + int res = (int) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static int FIRST_NONZEROReduceAllMasked(int[] a, boolean[] mask) { + int res = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "intUnaryOpMaskProvider") + static void FIRST_NONZEROReduceInt256VectorTestsMasked(IntFunction fa, IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + int ra = (int) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Int256VectorTests::FIRST_NONZEROReduceMasked, Int256VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Int512VectorTests.java b/test/jdk/jdk/incubator/vector/Int512VectorTests.java index 7f5ce407da6..503d24ab05c 100644 --- a/test/jdk/jdk/incubator/vector/Int512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int512VectorTests.java @@ -1161,6 +1161,10 @@ public class Int512VectorTests extends AbstractVectorTest { return Integer.compareUnsigned(a, b) >= 0; } + static int firstNonZero(int a, int b) { + return Integer.compare(a, (int) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { IntVector three = IntVector.broadcast(SPECIES, (byte)-3); @@ -3181,7 +3185,7 @@ public class Int512VectorTests extends AbstractVectorTest { static int MINReduce(int[] a, int idx) { int res = Integer.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (int)Math.min(res, a[i]); + res = (int) Math.min(res, a[i]); } return res; @@ -3189,8 +3193,8 @@ public class Int512VectorTests extends AbstractVectorTest { static int MINReduceAll(int[] a) { int res = Integer.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (int)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.min(res, MINReduce(a, i)); } return res; @@ -3212,7 +3216,7 @@ public class Int512VectorTests extends AbstractVectorTest { ra = Integer.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (int) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3222,8 +3226,8 @@ public class Int512VectorTests extends AbstractVectorTest { static int MINReduceMasked(int[] a, int idx, boolean[] mask) { int res = Integer.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (int) Math.min(res, a[i]); } return res; @@ -3231,9 +3235,8 @@ public class Int512VectorTests extends AbstractVectorTest { static int MINReduceAllMasked(int[] a, boolean[] mask) { int res = Integer.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3257,7 +3260,7 @@ public class Int512VectorTests extends AbstractVectorTest { ra = Integer.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (int) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3267,7 +3270,7 @@ public class Int512VectorTests extends AbstractVectorTest { static int MAXReduce(int[] a, int idx) { int res = Integer.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (int)Math.max(res, a[i]); + res = (int) Math.max(res, a[i]); } return res; @@ -3275,8 +3278,8 @@ public class Int512VectorTests extends AbstractVectorTest { static int MAXReduceAll(int[] a) { int res = Integer.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (int)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.max(res, MAXReduce(a, i)); } return res; @@ -3298,7 +3301,7 @@ public class Int512VectorTests extends AbstractVectorTest { ra = Integer.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (int) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3308,8 +3311,8 @@ public class Int512VectorTests extends AbstractVectorTest { static int MAXReduceMasked(int[] a, int idx, boolean[] mask) { int res = Integer.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (int) Math.max(res, a[i]); } return res; @@ -3317,9 +3320,8 @@ public class Int512VectorTests extends AbstractVectorTest { static int MAXReduceAllMasked(int[] a, boolean[] mask) { int res = Integer.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3343,13 +3345,98 @@ public class Int512VectorTests extends AbstractVectorTest { ra = Integer.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (int) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Int512VectorTests::MAXReduceMasked, Int512VectorTests::MAXReduceAllMasked); } + static int FIRST_NONZEROReduce(int[] a, int idx) { + int res = (int) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static int FIRST_NONZEROReduceAll(int[] a) { + int res = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "intUnaryOpProvider") + static void FIRST_NONZEROReduceInt512VectorTests(IntFunction fa) { + int[] a = fa.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + int ra = (int) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Int512VectorTests::FIRST_NONZEROReduce, Int512VectorTests::FIRST_NONZEROReduceAll); + } + static int FIRST_NONZEROReduceMasked(int[] a, int idx, boolean[] mask) { + int res = (int) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static int FIRST_NONZEROReduceAllMasked(int[] a, boolean[] mask) { + int res = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "intUnaryOpMaskProvider") + static void FIRST_NONZEROReduceInt512VectorTestsMasked(IntFunction fa, IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + int ra = (int) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Int512VectorTests::FIRST_NONZEROReduceMasked, Int512VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Int64VectorTests.java b/test/jdk/jdk/incubator/vector/Int64VectorTests.java index 6da8ecf04e4..2bebc06d0e2 100644 --- a/test/jdk/jdk/incubator/vector/Int64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int64VectorTests.java @@ -1161,6 +1161,10 @@ public class Int64VectorTests extends AbstractVectorTest { return Integer.compareUnsigned(a, b) >= 0; } + static int firstNonZero(int a, int b) { + return Integer.compare(a, (int) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { IntVector three = IntVector.broadcast(SPECIES, (byte)-3); @@ -3181,7 +3185,7 @@ public class Int64VectorTests extends AbstractVectorTest { static int MINReduce(int[] a, int idx) { int res = Integer.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (int)Math.min(res, a[i]); + res = (int) Math.min(res, a[i]); } return res; @@ -3189,8 +3193,8 @@ public class Int64VectorTests extends AbstractVectorTest { static int MINReduceAll(int[] a) { int res = Integer.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (int)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.min(res, MINReduce(a, i)); } return res; @@ -3212,7 +3216,7 @@ public class Int64VectorTests extends AbstractVectorTest { ra = Integer.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (int) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3222,8 +3226,8 @@ public class Int64VectorTests extends AbstractVectorTest { static int MINReduceMasked(int[] a, int idx, boolean[] mask) { int res = Integer.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (int) Math.min(res, a[i]); } return res; @@ -3231,9 +3235,8 @@ public class Int64VectorTests extends AbstractVectorTest { static int MINReduceAllMasked(int[] a, boolean[] mask) { int res = Integer.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3257,7 +3260,7 @@ public class Int64VectorTests extends AbstractVectorTest { ra = Integer.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (int) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3267,7 +3270,7 @@ public class Int64VectorTests extends AbstractVectorTest { static int MAXReduce(int[] a, int idx) { int res = Integer.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (int)Math.max(res, a[i]); + res = (int) Math.max(res, a[i]); } return res; @@ -3275,8 +3278,8 @@ public class Int64VectorTests extends AbstractVectorTest { static int MAXReduceAll(int[] a) { int res = Integer.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (int)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.max(res, MAXReduce(a, i)); } return res; @@ -3298,7 +3301,7 @@ public class Int64VectorTests extends AbstractVectorTest { ra = Integer.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (int) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3308,8 +3311,8 @@ public class Int64VectorTests extends AbstractVectorTest { static int MAXReduceMasked(int[] a, int idx, boolean[] mask) { int res = Integer.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (int) Math.max(res, a[i]); } return res; @@ -3317,9 +3320,8 @@ public class Int64VectorTests extends AbstractVectorTest { static int MAXReduceAllMasked(int[] a, boolean[] mask) { int res = Integer.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3343,13 +3345,98 @@ public class Int64VectorTests extends AbstractVectorTest { ra = Integer.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (int) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Int64VectorTests::MAXReduceMasked, Int64VectorTests::MAXReduceAllMasked); } + static int FIRST_NONZEROReduce(int[] a, int idx) { + int res = (int) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static int FIRST_NONZEROReduceAll(int[] a) { + int res = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "intUnaryOpProvider") + static void FIRST_NONZEROReduceInt64VectorTests(IntFunction fa) { + int[] a = fa.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + int ra = (int) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Int64VectorTests::FIRST_NONZEROReduce, Int64VectorTests::FIRST_NONZEROReduceAll); + } + static int FIRST_NONZEROReduceMasked(int[] a, int idx, boolean[] mask) { + int res = (int) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static int FIRST_NONZEROReduceAllMasked(int[] a, boolean[] mask) { + int res = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "intUnaryOpMaskProvider") + static void FIRST_NONZEROReduceInt64VectorTestsMasked(IntFunction fa, IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + int ra = (int) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Int64VectorTests::FIRST_NONZEROReduceMasked, Int64VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java b/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java index 0e59f7f0ed5..faf232e2985 100644 --- a/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java @@ -1166,6 +1166,10 @@ public class IntMaxVectorTests extends AbstractVectorTest { return Integer.compareUnsigned(a, b) >= 0; } + static int firstNonZero(int a, int b) { + return Integer.compare(a, (int) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { IntVector three = IntVector.broadcast(SPECIES, (byte)-3); @@ -3186,7 +3190,7 @@ public class IntMaxVectorTests extends AbstractVectorTest { static int MINReduce(int[] a, int idx) { int res = Integer.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (int)Math.min(res, a[i]); + res = (int) Math.min(res, a[i]); } return res; @@ -3194,8 +3198,8 @@ public class IntMaxVectorTests extends AbstractVectorTest { static int MINReduceAll(int[] a) { int res = Integer.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (int)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.min(res, MINReduce(a, i)); } return res; @@ -3217,7 +3221,7 @@ public class IntMaxVectorTests extends AbstractVectorTest { ra = Integer.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (int) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3227,8 +3231,8 @@ public class IntMaxVectorTests extends AbstractVectorTest { static int MINReduceMasked(int[] a, int idx, boolean[] mask) { int res = Integer.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (int) Math.min(res, a[i]); } return res; @@ -3236,9 +3240,8 @@ public class IntMaxVectorTests extends AbstractVectorTest { static int MINReduceAllMasked(int[] a, boolean[] mask) { int res = Integer.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3262,7 +3265,7 @@ public class IntMaxVectorTests extends AbstractVectorTest { ra = Integer.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (int) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3272,7 +3275,7 @@ public class IntMaxVectorTests extends AbstractVectorTest { static int MAXReduce(int[] a, int idx) { int res = Integer.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (int)Math.max(res, a[i]); + res = (int) Math.max(res, a[i]); } return res; @@ -3280,8 +3283,8 @@ public class IntMaxVectorTests extends AbstractVectorTest { static int MAXReduceAll(int[] a) { int res = Integer.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (int)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.max(res, MAXReduce(a, i)); } return res; @@ -3303,7 +3306,7 @@ public class IntMaxVectorTests extends AbstractVectorTest { ra = Integer.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (int) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3313,8 +3316,8 @@ public class IntMaxVectorTests extends AbstractVectorTest { static int MAXReduceMasked(int[] a, int idx, boolean[] mask) { int res = Integer.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (int) Math.max(res, a[i]); } return res; @@ -3322,9 +3325,8 @@ public class IntMaxVectorTests extends AbstractVectorTest { static int MAXReduceAllMasked(int[] a, boolean[] mask) { int res = Integer.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (int)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (int) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3348,13 +3350,98 @@ public class IntMaxVectorTests extends AbstractVectorTest { ra = Integer.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { IntVector av = IntVector.fromArray(SPECIES, a, i); - ra = (int)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (int) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, IntMaxVectorTests::MAXReduceMasked, IntMaxVectorTests::MAXReduceAllMasked); } + static int FIRST_NONZEROReduce(int[] a, int idx) { + int res = (int) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static int FIRST_NONZEROReduceAll(int[] a) { + int res = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "intUnaryOpProvider") + static void FIRST_NONZEROReduceIntMaxVectorTests(IntFunction fa) { + int[] a = fa.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + int ra = (int) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + IntMaxVectorTests::FIRST_NONZEROReduce, IntMaxVectorTests::FIRST_NONZEROReduceAll); + } + static int FIRST_NONZEROReduceMasked(int[] a, int idx, boolean[] mask) { + int res = (int) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static int FIRST_NONZEROReduceAllMasked(int[] a, boolean[] mask) { + int res = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "intUnaryOpMaskProvider") + static void FIRST_NONZEROReduceIntMaxVectorTestsMasked(IntFunction fa, IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + int ra = (int) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (int) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + IntMaxVectorTests::FIRST_NONZEROReduceMasked, IntMaxVectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Long128VectorTests.java b/test/jdk/jdk/incubator/vector/Long128VectorTests.java index ebd7acb104d..74d251476b2 100644 --- a/test/jdk/jdk/incubator/vector/Long128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long128VectorTests.java @@ -1183,6 +1183,10 @@ public class Long128VectorTests extends AbstractVectorTest { return Long.compareUnsigned(a, b) >= 0; } + static long firstNonZero(long a, long b) { + return Long.compare(a, (long) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { LongVector three = LongVector.broadcast(SPECIES, (byte)-3); @@ -3203,7 +3207,7 @@ public class Long128VectorTests extends AbstractVectorTest { static long MINReduce(long[] a, int idx) { long res = Long.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (long)Math.min(res, a[i]); + res = (long) Math.min(res, a[i]); } return res; @@ -3211,8 +3215,8 @@ public class Long128VectorTests extends AbstractVectorTest { static long MINReduceAll(long[] a) { long res = Long.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (long)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.min(res, MINReduce(a, i)); } return res; @@ -3234,7 +3238,7 @@ public class Long128VectorTests extends AbstractVectorTest { ra = Long.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (long) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3244,8 +3248,8 @@ public class Long128VectorTests extends AbstractVectorTest { static long MINReduceMasked(long[] a, int idx, boolean[] mask) { long res = Long.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (long) Math.min(res, a[i]); } return res; @@ -3253,9 +3257,8 @@ public class Long128VectorTests extends AbstractVectorTest { static long MINReduceAllMasked(long[] a, boolean[] mask) { long res = Long.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3279,7 +3282,7 @@ public class Long128VectorTests extends AbstractVectorTest { ra = Long.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (long) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3289,7 +3292,7 @@ public class Long128VectorTests extends AbstractVectorTest { static long MAXReduce(long[] a, int idx) { long res = Long.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (long)Math.max(res, a[i]); + res = (long) Math.max(res, a[i]); } return res; @@ -3297,8 +3300,8 @@ public class Long128VectorTests extends AbstractVectorTest { static long MAXReduceAll(long[] a) { long res = Long.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (long)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.max(res, MAXReduce(a, i)); } return res; @@ -3320,7 +3323,7 @@ public class Long128VectorTests extends AbstractVectorTest { ra = Long.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (long) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3330,8 +3333,8 @@ public class Long128VectorTests extends AbstractVectorTest { static long MAXReduceMasked(long[] a, int idx, boolean[] mask) { long res = Long.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (long) Math.max(res, a[i]); } return res; @@ -3339,9 +3342,8 @@ public class Long128VectorTests extends AbstractVectorTest { static long MAXReduceAllMasked(long[] a, boolean[] mask) { long res = Long.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3365,13 +3367,98 @@ public class Long128VectorTests extends AbstractVectorTest { ra = Long.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (long) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Long128VectorTests::MAXReduceMasked, Long128VectorTests::MAXReduceAllMasked); } + static long FIRST_NONZEROReduce(long[] a, int idx) { + long res = (long) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static long FIRST_NONZEROReduceAll(long[] a) { + long res = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "longUnaryOpProvider") + static void FIRST_NONZEROReduceLong128VectorTests(IntFunction fa) { + long[] a = fa.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + long ra = (long) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Long128VectorTests::FIRST_NONZEROReduce, Long128VectorTests::FIRST_NONZEROReduceAll); + } + static long FIRST_NONZEROReduceMasked(long[] a, int idx, boolean[] mask) { + long res = (long) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static long FIRST_NONZEROReduceAllMasked(long[] a, boolean[] mask) { + long res = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "longUnaryOpMaskProvider") + static void FIRST_NONZEROReduceLong128VectorTestsMasked(IntFunction fa, IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + long ra = (long) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Long128VectorTests::FIRST_NONZEROReduceMasked, Long128VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Long256VectorTests.java b/test/jdk/jdk/incubator/vector/Long256VectorTests.java index 5065745e5f8..4d2acbddd86 100644 --- a/test/jdk/jdk/incubator/vector/Long256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long256VectorTests.java @@ -1183,6 +1183,10 @@ public class Long256VectorTests extends AbstractVectorTest { return Long.compareUnsigned(a, b) >= 0; } + static long firstNonZero(long a, long b) { + return Long.compare(a, (long) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { LongVector three = LongVector.broadcast(SPECIES, (byte)-3); @@ -3203,7 +3207,7 @@ public class Long256VectorTests extends AbstractVectorTest { static long MINReduce(long[] a, int idx) { long res = Long.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (long)Math.min(res, a[i]); + res = (long) Math.min(res, a[i]); } return res; @@ -3211,8 +3215,8 @@ public class Long256VectorTests extends AbstractVectorTest { static long MINReduceAll(long[] a) { long res = Long.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (long)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.min(res, MINReduce(a, i)); } return res; @@ -3234,7 +3238,7 @@ public class Long256VectorTests extends AbstractVectorTest { ra = Long.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (long) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3244,8 +3248,8 @@ public class Long256VectorTests extends AbstractVectorTest { static long MINReduceMasked(long[] a, int idx, boolean[] mask) { long res = Long.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (long) Math.min(res, a[i]); } return res; @@ -3253,9 +3257,8 @@ public class Long256VectorTests extends AbstractVectorTest { static long MINReduceAllMasked(long[] a, boolean[] mask) { long res = Long.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3279,7 +3282,7 @@ public class Long256VectorTests extends AbstractVectorTest { ra = Long.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (long) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3289,7 +3292,7 @@ public class Long256VectorTests extends AbstractVectorTest { static long MAXReduce(long[] a, int idx) { long res = Long.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (long)Math.max(res, a[i]); + res = (long) Math.max(res, a[i]); } return res; @@ -3297,8 +3300,8 @@ public class Long256VectorTests extends AbstractVectorTest { static long MAXReduceAll(long[] a) { long res = Long.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (long)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.max(res, MAXReduce(a, i)); } return res; @@ -3320,7 +3323,7 @@ public class Long256VectorTests extends AbstractVectorTest { ra = Long.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (long) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3330,8 +3333,8 @@ public class Long256VectorTests extends AbstractVectorTest { static long MAXReduceMasked(long[] a, int idx, boolean[] mask) { long res = Long.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (long) Math.max(res, a[i]); } return res; @@ -3339,9 +3342,8 @@ public class Long256VectorTests extends AbstractVectorTest { static long MAXReduceAllMasked(long[] a, boolean[] mask) { long res = Long.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3365,13 +3367,98 @@ public class Long256VectorTests extends AbstractVectorTest { ra = Long.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (long) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Long256VectorTests::MAXReduceMasked, Long256VectorTests::MAXReduceAllMasked); } + static long FIRST_NONZEROReduce(long[] a, int idx) { + long res = (long) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static long FIRST_NONZEROReduceAll(long[] a) { + long res = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "longUnaryOpProvider") + static void FIRST_NONZEROReduceLong256VectorTests(IntFunction fa) { + long[] a = fa.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + long ra = (long) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Long256VectorTests::FIRST_NONZEROReduce, Long256VectorTests::FIRST_NONZEROReduceAll); + } + static long FIRST_NONZEROReduceMasked(long[] a, int idx, boolean[] mask) { + long res = (long) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static long FIRST_NONZEROReduceAllMasked(long[] a, boolean[] mask) { + long res = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "longUnaryOpMaskProvider") + static void FIRST_NONZEROReduceLong256VectorTestsMasked(IntFunction fa, IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + long ra = (long) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Long256VectorTests::FIRST_NONZEROReduceMasked, Long256VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Long512VectorTests.java b/test/jdk/jdk/incubator/vector/Long512VectorTests.java index dd0c71e1dbc..9bb6f568fca 100644 --- a/test/jdk/jdk/incubator/vector/Long512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long512VectorTests.java @@ -1183,6 +1183,10 @@ public class Long512VectorTests extends AbstractVectorTest { return Long.compareUnsigned(a, b) >= 0; } + static long firstNonZero(long a, long b) { + return Long.compare(a, (long) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { LongVector three = LongVector.broadcast(SPECIES, (byte)-3); @@ -3203,7 +3207,7 @@ public class Long512VectorTests extends AbstractVectorTest { static long MINReduce(long[] a, int idx) { long res = Long.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (long)Math.min(res, a[i]); + res = (long) Math.min(res, a[i]); } return res; @@ -3211,8 +3215,8 @@ public class Long512VectorTests extends AbstractVectorTest { static long MINReduceAll(long[] a) { long res = Long.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (long)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.min(res, MINReduce(a, i)); } return res; @@ -3234,7 +3238,7 @@ public class Long512VectorTests extends AbstractVectorTest { ra = Long.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (long) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3244,8 +3248,8 @@ public class Long512VectorTests extends AbstractVectorTest { static long MINReduceMasked(long[] a, int idx, boolean[] mask) { long res = Long.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (long) Math.min(res, a[i]); } return res; @@ -3253,9 +3257,8 @@ public class Long512VectorTests extends AbstractVectorTest { static long MINReduceAllMasked(long[] a, boolean[] mask) { long res = Long.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3279,7 +3282,7 @@ public class Long512VectorTests extends AbstractVectorTest { ra = Long.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (long) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3289,7 +3292,7 @@ public class Long512VectorTests extends AbstractVectorTest { static long MAXReduce(long[] a, int idx) { long res = Long.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (long)Math.max(res, a[i]); + res = (long) Math.max(res, a[i]); } return res; @@ -3297,8 +3300,8 @@ public class Long512VectorTests extends AbstractVectorTest { static long MAXReduceAll(long[] a) { long res = Long.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (long)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.max(res, MAXReduce(a, i)); } return res; @@ -3320,7 +3323,7 @@ public class Long512VectorTests extends AbstractVectorTest { ra = Long.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (long) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3330,8 +3333,8 @@ public class Long512VectorTests extends AbstractVectorTest { static long MAXReduceMasked(long[] a, int idx, boolean[] mask) { long res = Long.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (long) Math.max(res, a[i]); } return res; @@ -3339,9 +3342,8 @@ public class Long512VectorTests extends AbstractVectorTest { static long MAXReduceAllMasked(long[] a, boolean[] mask) { long res = Long.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3365,13 +3367,98 @@ public class Long512VectorTests extends AbstractVectorTest { ra = Long.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (long) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Long512VectorTests::MAXReduceMasked, Long512VectorTests::MAXReduceAllMasked); } + static long FIRST_NONZEROReduce(long[] a, int idx) { + long res = (long) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static long FIRST_NONZEROReduceAll(long[] a) { + long res = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "longUnaryOpProvider") + static void FIRST_NONZEROReduceLong512VectorTests(IntFunction fa) { + long[] a = fa.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + long ra = (long) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Long512VectorTests::FIRST_NONZEROReduce, Long512VectorTests::FIRST_NONZEROReduceAll); + } + static long FIRST_NONZEROReduceMasked(long[] a, int idx, boolean[] mask) { + long res = (long) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static long FIRST_NONZEROReduceAllMasked(long[] a, boolean[] mask) { + long res = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "longUnaryOpMaskProvider") + static void FIRST_NONZEROReduceLong512VectorTestsMasked(IntFunction fa, IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + long ra = (long) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Long512VectorTests::FIRST_NONZEROReduceMasked, Long512VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Long64VectorTests.java b/test/jdk/jdk/incubator/vector/Long64VectorTests.java index 919f6ef0f6a..50976531dac 100644 --- a/test/jdk/jdk/incubator/vector/Long64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long64VectorTests.java @@ -1183,6 +1183,10 @@ public class Long64VectorTests extends AbstractVectorTest { return Long.compareUnsigned(a, b) >= 0; } + static long firstNonZero(long a, long b) { + return Long.compare(a, (long) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { LongVector three = LongVector.broadcast(SPECIES, (byte)-3); @@ -3203,7 +3207,7 @@ public class Long64VectorTests extends AbstractVectorTest { static long MINReduce(long[] a, int idx) { long res = Long.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (long)Math.min(res, a[i]); + res = (long) Math.min(res, a[i]); } return res; @@ -3211,8 +3215,8 @@ public class Long64VectorTests extends AbstractVectorTest { static long MINReduceAll(long[] a) { long res = Long.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (long)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.min(res, MINReduce(a, i)); } return res; @@ -3234,7 +3238,7 @@ public class Long64VectorTests extends AbstractVectorTest { ra = Long.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (long) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3244,8 +3248,8 @@ public class Long64VectorTests extends AbstractVectorTest { static long MINReduceMasked(long[] a, int idx, boolean[] mask) { long res = Long.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (long) Math.min(res, a[i]); } return res; @@ -3253,9 +3257,8 @@ public class Long64VectorTests extends AbstractVectorTest { static long MINReduceAllMasked(long[] a, boolean[] mask) { long res = Long.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3279,7 +3282,7 @@ public class Long64VectorTests extends AbstractVectorTest { ra = Long.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (long) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3289,7 +3292,7 @@ public class Long64VectorTests extends AbstractVectorTest { static long MAXReduce(long[] a, int idx) { long res = Long.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (long)Math.max(res, a[i]); + res = (long) Math.max(res, a[i]); } return res; @@ -3297,8 +3300,8 @@ public class Long64VectorTests extends AbstractVectorTest { static long MAXReduceAll(long[] a) { long res = Long.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (long)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.max(res, MAXReduce(a, i)); } return res; @@ -3320,7 +3323,7 @@ public class Long64VectorTests extends AbstractVectorTest { ra = Long.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (long) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3330,8 +3333,8 @@ public class Long64VectorTests extends AbstractVectorTest { static long MAXReduceMasked(long[] a, int idx, boolean[] mask) { long res = Long.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (long) Math.max(res, a[i]); } return res; @@ -3339,9 +3342,8 @@ public class Long64VectorTests extends AbstractVectorTest { static long MAXReduceAllMasked(long[] a, boolean[] mask) { long res = Long.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3365,13 +3367,98 @@ public class Long64VectorTests extends AbstractVectorTest { ra = Long.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (long) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Long64VectorTests::MAXReduceMasked, Long64VectorTests::MAXReduceAllMasked); } + static long FIRST_NONZEROReduce(long[] a, int idx) { + long res = (long) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static long FIRST_NONZEROReduceAll(long[] a) { + long res = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "longUnaryOpProvider") + static void FIRST_NONZEROReduceLong64VectorTests(IntFunction fa) { + long[] a = fa.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + long ra = (long) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Long64VectorTests::FIRST_NONZEROReduce, Long64VectorTests::FIRST_NONZEROReduceAll); + } + static long FIRST_NONZEROReduceMasked(long[] a, int idx, boolean[] mask) { + long res = (long) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static long FIRST_NONZEROReduceAllMasked(long[] a, boolean[] mask) { + long res = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "longUnaryOpMaskProvider") + static void FIRST_NONZEROReduceLong64VectorTestsMasked(IntFunction fa, IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + long ra = (long) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Long64VectorTests::FIRST_NONZEROReduceMasked, Long64VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java b/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java index 443de01cdb4..eb16136a0d6 100644 --- a/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java @@ -1188,6 +1188,10 @@ public class LongMaxVectorTests extends AbstractVectorTest { return Long.compareUnsigned(a, b) >= 0; } + static long firstNonZero(long a, long b) { + return Long.compare(a, (long) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { LongVector three = LongVector.broadcast(SPECIES, (byte)-3); @@ -3208,7 +3212,7 @@ public class LongMaxVectorTests extends AbstractVectorTest { static long MINReduce(long[] a, int idx) { long res = Long.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (long)Math.min(res, a[i]); + res = (long) Math.min(res, a[i]); } return res; @@ -3216,8 +3220,8 @@ public class LongMaxVectorTests extends AbstractVectorTest { static long MINReduceAll(long[] a) { long res = Long.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (long)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.min(res, MINReduce(a, i)); } return res; @@ -3239,7 +3243,7 @@ public class LongMaxVectorTests extends AbstractVectorTest { ra = Long.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (long) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3249,8 +3253,8 @@ public class LongMaxVectorTests extends AbstractVectorTest { static long MINReduceMasked(long[] a, int idx, boolean[] mask) { long res = Long.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (long) Math.min(res, a[i]); } return res; @@ -3258,9 +3262,8 @@ public class LongMaxVectorTests extends AbstractVectorTest { static long MINReduceAllMasked(long[] a, boolean[] mask) { long res = Long.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3284,7 +3287,7 @@ public class LongMaxVectorTests extends AbstractVectorTest { ra = Long.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (long) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3294,7 +3297,7 @@ public class LongMaxVectorTests extends AbstractVectorTest { static long MAXReduce(long[] a, int idx) { long res = Long.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (long)Math.max(res, a[i]); + res = (long) Math.max(res, a[i]); } return res; @@ -3302,8 +3305,8 @@ public class LongMaxVectorTests extends AbstractVectorTest { static long MAXReduceAll(long[] a) { long res = Long.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (long)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.max(res, MAXReduce(a, i)); } return res; @@ -3325,7 +3328,7 @@ public class LongMaxVectorTests extends AbstractVectorTest { ra = Long.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (long) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3335,8 +3338,8 @@ public class LongMaxVectorTests extends AbstractVectorTest { static long MAXReduceMasked(long[] a, int idx, boolean[] mask) { long res = Long.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (long) Math.max(res, a[i]); } return res; @@ -3344,9 +3347,8 @@ public class LongMaxVectorTests extends AbstractVectorTest { static long MAXReduceAllMasked(long[] a, boolean[] mask) { long res = Long.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (long)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (long) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3370,13 +3372,98 @@ public class LongMaxVectorTests extends AbstractVectorTest { ra = Long.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { LongVector av = LongVector.fromArray(SPECIES, a, i); - ra = (long)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (long) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, LongMaxVectorTests::MAXReduceMasked, LongMaxVectorTests::MAXReduceAllMasked); } + static long FIRST_NONZEROReduce(long[] a, int idx) { + long res = (long) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static long FIRST_NONZEROReduceAll(long[] a) { + long res = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "longUnaryOpProvider") + static void FIRST_NONZEROReduceLongMaxVectorTests(IntFunction fa) { + long[] a = fa.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + long ra = (long) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + LongMaxVectorTests::FIRST_NONZEROReduce, LongMaxVectorTests::FIRST_NONZEROReduceAll); + } + static long FIRST_NONZEROReduceMasked(long[] a, int idx, boolean[] mask) { + long res = (long) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static long FIRST_NONZEROReduceAllMasked(long[] a, boolean[] mask) { + long res = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "longUnaryOpMaskProvider") + static void FIRST_NONZEROReduceLongMaxVectorTestsMasked(IntFunction fa, IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + long ra = (long) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (long) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + LongMaxVectorTests::FIRST_NONZEROReduceMasked, LongMaxVectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Short128VectorTests.java b/test/jdk/jdk/incubator/vector/Short128VectorTests.java index 2e50b940b0e..2a060c354cd 100644 --- a/test/jdk/jdk/incubator/vector/Short128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short128VectorTests.java @@ -1191,6 +1191,10 @@ public class Short128VectorTests extends AbstractVectorTest { return Short.compareUnsigned(a, b) >= 0; } + static short firstNonZero(short a, short b) { + return Short.compare(a, (short) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { ShortVector three = ShortVector.broadcast(SPECIES, (byte)-3); @@ -3206,7 +3210,7 @@ public class Short128VectorTests extends AbstractVectorTest { static short MINReduce(short[] a, int idx) { short res = Short.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (short)Math.min(res, a[i]); + res = (short) Math.min(res, a[i]); } return res; @@ -3214,8 +3218,8 @@ public class Short128VectorTests extends AbstractVectorTest { static short MINReduceAll(short[] a) { short res = Short.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (short)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.min(res, MINReduce(a, i)); } return res; @@ -3237,7 +3241,7 @@ public class Short128VectorTests extends AbstractVectorTest { ra = Short.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (short) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3247,8 +3251,8 @@ public class Short128VectorTests extends AbstractVectorTest { static short MINReduceMasked(short[] a, int idx, boolean[] mask) { short res = Short.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (short) Math.min(res, a[i]); } return res; @@ -3256,9 +3260,8 @@ public class Short128VectorTests extends AbstractVectorTest { static short MINReduceAllMasked(short[] a, boolean[] mask) { short res = Short.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3282,7 +3285,7 @@ public class Short128VectorTests extends AbstractVectorTest { ra = Short.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (short) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3292,7 +3295,7 @@ public class Short128VectorTests extends AbstractVectorTest { static short MAXReduce(short[] a, int idx) { short res = Short.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (short)Math.max(res, a[i]); + res = (short) Math.max(res, a[i]); } return res; @@ -3300,8 +3303,8 @@ public class Short128VectorTests extends AbstractVectorTest { static short MAXReduceAll(short[] a) { short res = Short.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (short)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.max(res, MAXReduce(a, i)); } return res; @@ -3323,7 +3326,7 @@ public class Short128VectorTests extends AbstractVectorTest { ra = Short.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (short) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3333,8 +3336,8 @@ public class Short128VectorTests extends AbstractVectorTest { static short MAXReduceMasked(short[] a, int idx, boolean[] mask) { short res = Short.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (short) Math.max(res, a[i]); } return res; @@ -3342,9 +3345,8 @@ public class Short128VectorTests extends AbstractVectorTest { static short MAXReduceAllMasked(short[] a, boolean[] mask) { short res = Short.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3368,13 +3370,98 @@ public class Short128VectorTests extends AbstractVectorTest { ra = Short.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (short) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Short128VectorTests::MAXReduceMasked, Short128VectorTests::MAXReduceAllMasked); } + static short FIRST_NONZEROReduce(short[] a, int idx) { + short res = (short) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static short FIRST_NONZEROReduceAll(short[] a) { + short res = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "shortUnaryOpProvider") + static void FIRST_NONZEROReduceShort128VectorTests(IntFunction fa) { + short[] a = fa.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + short ra = (short) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Short128VectorTests::FIRST_NONZEROReduce, Short128VectorTests::FIRST_NONZEROReduceAll); + } + static short FIRST_NONZEROReduceMasked(short[] a, int idx, boolean[] mask) { + short res = (short) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static short FIRST_NONZEROReduceAllMasked(short[] a, boolean[] mask) { + short res = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "shortUnaryOpMaskProvider") + static void FIRST_NONZEROReduceShort128VectorTestsMasked(IntFunction fa, IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + short ra = (short) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Short128VectorTests::FIRST_NONZEROReduceMasked, Short128VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Short256VectorTests.java b/test/jdk/jdk/incubator/vector/Short256VectorTests.java index 67fc08c6194..46626d63aaf 100644 --- a/test/jdk/jdk/incubator/vector/Short256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short256VectorTests.java @@ -1191,6 +1191,10 @@ public class Short256VectorTests extends AbstractVectorTest { return Short.compareUnsigned(a, b) >= 0; } + static short firstNonZero(short a, short b) { + return Short.compare(a, (short) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { ShortVector three = ShortVector.broadcast(SPECIES, (byte)-3); @@ -3206,7 +3210,7 @@ public class Short256VectorTests extends AbstractVectorTest { static short MINReduce(short[] a, int idx) { short res = Short.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (short)Math.min(res, a[i]); + res = (short) Math.min(res, a[i]); } return res; @@ -3214,8 +3218,8 @@ public class Short256VectorTests extends AbstractVectorTest { static short MINReduceAll(short[] a) { short res = Short.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (short)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.min(res, MINReduce(a, i)); } return res; @@ -3237,7 +3241,7 @@ public class Short256VectorTests extends AbstractVectorTest { ra = Short.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (short) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3247,8 +3251,8 @@ public class Short256VectorTests extends AbstractVectorTest { static short MINReduceMasked(short[] a, int idx, boolean[] mask) { short res = Short.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (short) Math.min(res, a[i]); } return res; @@ -3256,9 +3260,8 @@ public class Short256VectorTests extends AbstractVectorTest { static short MINReduceAllMasked(short[] a, boolean[] mask) { short res = Short.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3282,7 +3285,7 @@ public class Short256VectorTests extends AbstractVectorTest { ra = Short.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (short) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3292,7 +3295,7 @@ public class Short256VectorTests extends AbstractVectorTest { static short MAXReduce(short[] a, int idx) { short res = Short.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (short)Math.max(res, a[i]); + res = (short) Math.max(res, a[i]); } return res; @@ -3300,8 +3303,8 @@ public class Short256VectorTests extends AbstractVectorTest { static short MAXReduceAll(short[] a) { short res = Short.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (short)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.max(res, MAXReduce(a, i)); } return res; @@ -3323,7 +3326,7 @@ public class Short256VectorTests extends AbstractVectorTest { ra = Short.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (short) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3333,8 +3336,8 @@ public class Short256VectorTests extends AbstractVectorTest { static short MAXReduceMasked(short[] a, int idx, boolean[] mask) { short res = Short.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (short) Math.max(res, a[i]); } return res; @@ -3342,9 +3345,8 @@ public class Short256VectorTests extends AbstractVectorTest { static short MAXReduceAllMasked(short[] a, boolean[] mask) { short res = Short.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3368,13 +3370,98 @@ public class Short256VectorTests extends AbstractVectorTest { ra = Short.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (short) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Short256VectorTests::MAXReduceMasked, Short256VectorTests::MAXReduceAllMasked); } + static short FIRST_NONZEROReduce(short[] a, int idx) { + short res = (short) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static short FIRST_NONZEROReduceAll(short[] a) { + short res = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "shortUnaryOpProvider") + static void FIRST_NONZEROReduceShort256VectorTests(IntFunction fa) { + short[] a = fa.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + short ra = (short) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Short256VectorTests::FIRST_NONZEROReduce, Short256VectorTests::FIRST_NONZEROReduceAll); + } + static short FIRST_NONZEROReduceMasked(short[] a, int idx, boolean[] mask) { + short res = (short) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static short FIRST_NONZEROReduceAllMasked(short[] a, boolean[] mask) { + short res = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "shortUnaryOpMaskProvider") + static void FIRST_NONZEROReduceShort256VectorTestsMasked(IntFunction fa, IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + short ra = (short) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Short256VectorTests::FIRST_NONZEROReduceMasked, Short256VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Short512VectorTests.java b/test/jdk/jdk/incubator/vector/Short512VectorTests.java index 63bc3709481..2cff4a4802a 100644 --- a/test/jdk/jdk/incubator/vector/Short512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short512VectorTests.java @@ -1191,6 +1191,10 @@ public class Short512VectorTests extends AbstractVectorTest { return Short.compareUnsigned(a, b) >= 0; } + static short firstNonZero(short a, short b) { + return Short.compare(a, (short) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { ShortVector three = ShortVector.broadcast(SPECIES, (byte)-3); @@ -3206,7 +3210,7 @@ public class Short512VectorTests extends AbstractVectorTest { static short MINReduce(short[] a, int idx) { short res = Short.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (short)Math.min(res, a[i]); + res = (short) Math.min(res, a[i]); } return res; @@ -3214,8 +3218,8 @@ public class Short512VectorTests extends AbstractVectorTest { static short MINReduceAll(short[] a) { short res = Short.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (short)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.min(res, MINReduce(a, i)); } return res; @@ -3237,7 +3241,7 @@ public class Short512VectorTests extends AbstractVectorTest { ra = Short.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (short) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3247,8 +3251,8 @@ public class Short512VectorTests extends AbstractVectorTest { static short MINReduceMasked(short[] a, int idx, boolean[] mask) { short res = Short.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (short) Math.min(res, a[i]); } return res; @@ -3256,9 +3260,8 @@ public class Short512VectorTests extends AbstractVectorTest { static short MINReduceAllMasked(short[] a, boolean[] mask) { short res = Short.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3282,7 +3285,7 @@ public class Short512VectorTests extends AbstractVectorTest { ra = Short.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (short) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3292,7 +3295,7 @@ public class Short512VectorTests extends AbstractVectorTest { static short MAXReduce(short[] a, int idx) { short res = Short.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (short)Math.max(res, a[i]); + res = (short) Math.max(res, a[i]); } return res; @@ -3300,8 +3303,8 @@ public class Short512VectorTests extends AbstractVectorTest { static short MAXReduceAll(short[] a) { short res = Short.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (short)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.max(res, MAXReduce(a, i)); } return res; @@ -3323,7 +3326,7 @@ public class Short512VectorTests extends AbstractVectorTest { ra = Short.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (short) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3333,8 +3336,8 @@ public class Short512VectorTests extends AbstractVectorTest { static short MAXReduceMasked(short[] a, int idx, boolean[] mask) { short res = Short.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (short) Math.max(res, a[i]); } return res; @@ -3342,9 +3345,8 @@ public class Short512VectorTests extends AbstractVectorTest { static short MAXReduceAllMasked(short[] a, boolean[] mask) { short res = Short.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3368,13 +3370,98 @@ public class Short512VectorTests extends AbstractVectorTest { ra = Short.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (short) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Short512VectorTests::MAXReduceMasked, Short512VectorTests::MAXReduceAllMasked); } + static short FIRST_NONZEROReduce(short[] a, int idx) { + short res = (short) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static short FIRST_NONZEROReduceAll(short[] a) { + short res = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "shortUnaryOpProvider") + static void FIRST_NONZEROReduceShort512VectorTests(IntFunction fa) { + short[] a = fa.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + short ra = (short) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Short512VectorTests::FIRST_NONZEROReduce, Short512VectorTests::FIRST_NONZEROReduceAll); + } + static short FIRST_NONZEROReduceMasked(short[] a, int idx, boolean[] mask) { + short res = (short) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static short FIRST_NONZEROReduceAllMasked(short[] a, boolean[] mask) { + short res = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "shortUnaryOpMaskProvider") + static void FIRST_NONZEROReduceShort512VectorTestsMasked(IntFunction fa, IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + short ra = (short) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Short512VectorTests::FIRST_NONZEROReduceMasked, Short512VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/Short64VectorTests.java b/test/jdk/jdk/incubator/vector/Short64VectorTests.java index 8c05159737d..481081b75da 100644 --- a/test/jdk/jdk/incubator/vector/Short64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short64VectorTests.java @@ -1191,6 +1191,10 @@ public class Short64VectorTests extends AbstractVectorTest { return Short.compareUnsigned(a, b) >= 0; } + static short firstNonZero(short a, short b) { + return Short.compare(a, (short) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { ShortVector three = ShortVector.broadcast(SPECIES, (byte)-3); @@ -3206,7 +3210,7 @@ public class Short64VectorTests extends AbstractVectorTest { static short MINReduce(short[] a, int idx) { short res = Short.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (short)Math.min(res, a[i]); + res = (short) Math.min(res, a[i]); } return res; @@ -3214,8 +3218,8 @@ public class Short64VectorTests extends AbstractVectorTest { static short MINReduceAll(short[] a) { short res = Short.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (short)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.min(res, MINReduce(a, i)); } return res; @@ -3237,7 +3241,7 @@ public class Short64VectorTests extends AbstractVectorTest { ra = Short.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (short) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3247,8 +3251,8 @@ public class Short64VectorTests extends AbstractVectorTest { static short MINReduceMasked(short[] a, int idx, boolean[] mask) { short res = Short.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (short) Math.min(res, a[i]); } return res; @@ -3256,9 +3260,8 @@ public class Short64VectorTests extends AbstractVectorTest { static short MINReduceAllMasked(short[] a, boolean[] mask) { short res = Short.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3282,7 +3285,7 @@ public class Short64VectorTests extends AbstractVectorTest { ra = Short.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (short) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3292,7 +3295,7 @@ public class Short64VectorTests extends AbstractVectorTest { static short MAXReduce(short[] a, int idx) { short res = Short.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (short)Math.max(res, a[i]); + res = (short) Math.max(res, a[i]); } return res; @@ -3300,8 +3303,8 @@ public class Short64VectorTests extends AbstractVectorTest { static short MAXReduceAll(short[] a) { short res = Short.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (short)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.max(res, MAXReduce(a, i)); } return res; @@ -3323,7 +3326,7 @@ public class Short64VectorTests extends AbstractVectorTest { ra = Short.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (short) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3333,8 +3336,8 @@ public class Short64VectorTests extends AbstractVectorTest { static short MAXReduceMasked(short[] a, int idx, boolean[] mask) { short res = Short.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (short) Math.max(res, a[i]); } return res; @@ -3342,9 +3345,8 @@ public class Short64VectorTests extends AbstractVectorTest { static short MAXReduceAllMasked(short[] a, boolean[] mask) { short res = Short.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3368,13 +3370,98 @@ public class Short64VectorTests extends AbstractVectorTest { ra = Short.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (short) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, Short64VectorTests::MAXReduceMasked, Short64VectorTests::MAXReduceAllMasked); } + static short FIRST_NONZEROReduce(short[] a, int idx) { + short res = (short) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static short FIRST_NONZEROReduceAll(short[] a) { + short res = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "shortUnaryOpProvider") + static void FIRST_NONZEROReduceShort64VectorTests(IntFunction fa) { + short[] a = fa.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + short ra = (short) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + Short64VectorTests::FIRST_NONZEROReduce, Short64VectorTests::FIRST_NONZEROReduceAll); + } + static short FIRST_NONZEROReduceMasked(short[] a, int idx, boolean[] mask) { + short res = (short) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static short FIRST_NONZEROReduceAllMasked(short[] a, boolean[] mask) { + short res = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "shortUnaryOpMaskProvider") + static void FIRST_NONZEROReduceShort64VectorTestsMasked(IntFunction fa, IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + short ra = (short) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + Short64VectorTests::FIRST_NONZEROReduceMasked, Short64VectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java b/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java index b196aad5218..00d99484a13 100644 --- a/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java @@ -1196,6 +1196,10 @@ public class ShortMaxVectorTests extends AbstractVectorTest { return Short.compareUnsigned(a, b) >= 0; } + static short firstNonZero(short a, short b) { + return Short.compare(a, (short) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { ShortVector three = ShortVector.broadcast(SPECIES, (byte)-3); @@ -3211,7 +3215,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest { static short MINReduce(short[] a, int idx) { short res = Short.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (short)Math.min(res, a[i]); + res = (short) Math.min(res, a[i]); } return res; @@ -3219,8 +3223,8 @@ public class ShortMaxVectorTests extends AbstractVectorTest { static short MINReduceAll(short[] a) { short res = Short.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - res = (short)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.min(res, MINReduce(a, i)); } return res; @@ -3242,7 +3246,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest { ra = Short.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.min(ra, av.reduceLanes(VectorOperators.MIN)); + ra = (short) Math.min(ra, av.reduceLanes(VectorOperators.MIN)); } } @@ -3252,8 +3256,8 @@ public class ShortMaxVectorTests extends AbstractVectorTest { static short MINReduceMasked(short[] a, int idx, boolean[] mask) { short res = Short.MAX_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.min(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (short) Math.min(res, a[i]); } return res; @@ -3261,9 +3265,8 @@ public class ShortMaxVectorTests extends AbstractVectorTest { static short MINReduceAllMasked(short[] a, boolean[] mask) { short res = Short.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.min(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.min(res, MINReduceMasked(a, i, mask)); } return res; @@ -3287,7 +3290,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest { ra = Short.MAX_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); + ra = (short) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask)); } } @@ -3297,7 +3300,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest { static short MAXReduce(short[] a, int idx) { short res = Short.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = (short)Math.max(res, a[i]); + res = (short) Math.max(res, a[i]); } return res; @@ -3305,8 +3308,8 @@ public class ShortMaxVectorTests extends AbstractVectorTest { static short MAXReduceAll(short[] a) { short res = Short.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - res = (short)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.max(res, MAXReduce(a, i)); } return res; @@ -3328,7 +3331,7 @@ public class ShortMaxVectorTests extends AbstractVectorTest { ra = Short.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.max(ra, av.reduceLanes(VectorOperators.MAX)); + ra = (short) Math.max(ra, av.reduceLanes(VectorOperators.MAX)); } } @@ -3338,8 +3341,8 @@ public class ShortMaxVectorTests extends AbstractVectorTest { static short MAXReduceMasked(short[] a, int idx, boolean[] mask) { short res = Short.MIN_VALUE; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = (short) Math.max(res, a[i]); } return res; @@ -3347,9 +3350,8 @@ public class ShortMaxVectorTests extends AbstractVectorTest { static short MAXReduceAllMasked(short[] a, boolean[] mask) { short res = Short.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = (short)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = (short) Math.max(res, MAXReduceMasked(a, i, mask)); } return res; @@ -3373,13 +3375,98 @@ public class ShortMaxVectorTests extends AbstractVectorTest { ra = Short.MIN_VALUE; for (int i = 0; i < a.length; i += SPECIES.length()) { ShortVector av = ShortVector.fromArray(SPECIES, a, i); - ra = (short)Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); + ra = (short) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask)); } } assertReductionArraysEqualsMasked(r, ra, a, mask, ShortMaxVectorTests::MAXReduceMasked, ShortMaxVectorTests::MAXReduceAllMasked); } + static short FIRST_NONZEROReduce(short[] a, int idx) { + short res = (short) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + res = firstNonZero(res, a[i]); + } + + return res; + } + + static short FIRST_NONZEROReduceAll(short[] a) { + short res = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduce(a, i)); + } + + return res; + } + @Test(dataProvider = "shortUnaryOpProvider") + static void FIRST_NONZEROReduceShortMaxVectorTests(IntFunction fa) { + short[] a = fa.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + short ra = (short) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO)); + } + } + + assertReductionArraysEquals(r, ra, a, + ShortMaxVectorTests::FIRST_NONZEROReduce, ShortMaxVectorTests::FIRST_NONZEROReduceAll); + } + static short FIRST_NONZEROReduceMasked(short[] a, int idx, boolean[] mask) { + short res = (short) 0; + for (int i = idx; i < (idx + SPECIES.length()); i++) { + if (mask[i % SPECIES.length()]) + res = firstNonZero(res, a[i]); + } + + return res; + } + + static short FIRST_NONZEROReduceAllMasked(short[] a, boolean[] mask) { + short res = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask)); + } + + return res; + } + @Test(dataProvider = "shortUnaryOpMaskProvider") + static void FIRST_NONZEROReduceShortMaxVectorTestsMasked(IntFunction fa, IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] r = fr.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + short ra = (short) 0; + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask); + } + } + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + ra = (short) 0; + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask)); + } + } + + assertReductionArraysEqualsMasked(r, ra, a, mask, + ShortMaxVectorTests::FIRST_NONZEROReduceMasked, ShortMaxVectorTests::FIRST_NONZEROReduceAllMasked); + } static boolean anyTrue(boolean[] a, int idx) { boolean res = false; diff --git a/test/jdk/jdk/incubator/vector/gen-template.sh b/test/jdk/jdk/incubator/vector/gen-template.sh index 544cd0dc317..51fb155fd84 100644 --- a/test/jdk/jdk/incubator/vector/gen-template.sh +++ b/test/jdk/jdk/incubator/vector/gen-template.sh @@ -55,17 +55,13 @@ compare_template="Compare" compare_masked_template="Compare-Masked" compare_broadcast_template="Compare-Broadcast" reduction_scalar="Reduction-Scalar-op" -reduction_scalar_min="Reduction-Scalar-Min-op" -reduction_scalar_max="Reduction-Scalar-Max-op" +reduction_scalar_func="Reduction-Scalar-op-func" reduction_scalar_masked="Reduction-Scalar-Masked-op" -reduction_scalar_min_masked="Reduction-Scalar-Masked-Min-op" -reduction_scalar_max_masked="Reduction-Scalar-Masked-Max-op" +reduction_scalar_masked_func="Reduction-Scalar-Masked-op-func" reduction_op="Reduction-op" -reduction_op_min="Reduction-Min-op" -reduction_op_max="Reduction-Max-op" +reduction_op_func="Reduction-op-func" reduction_op_masked="Reduction-Masked-op" -reduction_op_min_masked="Reduction-Masked-Min-op" -reduction_op_max_masked="Reduction-Masked-Max-op" +reduction_op_masked_func="Reduction-Masked-op-func" unary_math_template="Unary-op-math" binary_math_template="Binary-op-math" binary_math_broadcast_template="Binary-Broadcast-op-math" @@ -337,20 +333,12 @@ function gen_reduction_op { gen_op_tmpl $reduction_op_masked "$@" } -function gen_reduction_op_min { +function gen_reduction_op_func { echo "Generating reduction op $1 ($2)..." - gen_op_tmpl $reduction_scalar_min "$@" - gen_op_tmpl $reduction_op_min "$@" - gen_op_tmpl $reduction_scalar_min_masked "$@" - gen_op_tmpl $reduction_op_min_masked "$@" -} - -function gen_reduction_op_max { - echo "Generating reduction op $1 ($2)..." - gen_op_tmpl $reduction_scalar_max "$@" - gen_op_tmpl $reduction_op_max "$@" - gen_op_tmpl $reduction_scalar_max_masked "$@" - gen_op_tmpl $reduction_op_max_masked "$@" + gen_op_tmpl $reduction_scalar_func "$@" + gen_op_tmpl $reduction_op_func "$@" + gen_op_tmpl $reduction_scalar_masked_func "$@" + gen_op_tmpl $reduction_op_masked_func "$@" } function gen_bool_reduction_op { @@ -462,9 +450,9 @@ gen_reduction_op "OR" "|" "BITWISE" "0" gen_reduction_op "XOR" "^" "BITWISE" "0" gen_reduction_op "ADD" "+" "" "0" gen_reduction_op "MUL" "*" "" "1" -gen_reduction_op_min "MIN" "" "" "\$Wideboxtype\$.\$MaxValue\$" -gen_reduction_op_max "MAX" "" "" "\$Wideboxtype\$.\$MinValue\$" -#gen_reduction_op "reduce_FIRST_NONZERO" "lanewise_FIRST_NONZERO" "{#if[FP]?Double.doubleToLongBits}(a)=0?a:b" "" "1" +gen_reduction_op_func "MIN" "(\$type\$) Math.min" "" "\$Wideboxtype\$.\$MaxValue\$" +gen_reduction_op_func "MAX" "(\$type\$) Math.max" "" "\$Wideboxtype\$.\$MinValue\$" +gen_reduction_op_func "FIRST_NONZERO" "firstNonZero" "" "(\$type\$) 0" # Boolean reductions. gen_bool_reduction_op "anyTrue" "|" "BITWISE" "false" diff --git a/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Masked-Min-op.template b/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Masked-Min-op.template deleted file mode 100644 index 041b61da0e1..00000000000 --- a/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Masked-Min-op.template +++ /dev/null @@ -1,21 +0,0 @@ - $type$[] a = fa.apply(SPECIES.length()); - $type$[] r = fr.apply(SPECIES.length()); - boolean[] mask = fm.apply(SPECIES.length()); - VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0); - $type$ ra = [[TEST_INIT]]; - - for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { - $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); - r[i] = av.reduceLanes(VectorOperators.[[TEST]], vmask); - } - } - - for (int ic = 0; ic < INVOC_COUNT; ic++) { - ra = [[TEST_INIT]]; - for (int i = 0; i < a.length; i += SPECIES.length()) { - $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); - ra = ($type$)Math.min(ra, av.reduceLanes(VectorOperators.[[TEST]], vmask)); - } - } - diff --git a/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Masked-Max-op.template b/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Masked-op-func.template similarity index 90% rename from test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Masked-Max-op.template rename to test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Masked-op-func.template index d317aaf4f8a..bf03a4d0430 100644 --- a/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Masked-Max-op.template +++ b/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Masked-op-func.template @@ -15,7 +15,7 @@ ra = [[TEST_INIT]]; for (int i = 0; i < a.length; i += SPECIES.length()) { $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); - ra = ($type$)Math.max(ra, av.reduceLanes(VectorOperators.[[TEST]], vmask)); + ra = [[TEST_OP]](ra, av.reduceLanes(VectorOperators.[[TEST]], vmask)); } } diff --git a/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Min-op.template b/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Min-op.template deleted file mode 100644 index d6d53e4ef21..00000000000 --- a/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Min-op.template +++ /dev/null @@ -1,19 +0,0 @@ - $type$[] a = fa.apply(SPECIES.length()); - $type$[] r = fr.apply(SPECIES.length()); - $type$ ra = [[TEST_INIT]]; - - for (int ic = 0; ic < INVOC_COUNT; ic++) { - for (int i = 0; i < a.length; i += SPECIES.length()) { - $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); - r[i] = av.reduceLanes(VectorOperators.[[TEST]]); - } - } - - for (int ic = 0; ic < INVOC_COUNT; ic++) { - ra = [[TEST_INIT]]; - for (int i = 0; i < a.length; i += SPECIES.length()) { - $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); - ra = ($type$)Math.min(ra, av.reduceLanes(VectorOperators.[[TEST]])); - } - } - diff --git a/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Max-op.template b/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-op-func.template similarity index 89% rename from test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Max-op.template rename to test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-op-func.template index 3af5b8cfde9..7082ff0795e 100644 --- a/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-Max-op.template +++ b/test/jdk/jdk/incubator/vector/templates/Kernel-Reduction-op-func.template @@ -13,7 +13,7 @@ ra = [[TEST_INIT]]; for (int i = 0; i < a.length; i += SPECIES.length()) { $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); - ra = ($type$)Math.max(ra, av.reduceLanes(VectorOperators.[[TEST]])); + ra = [[TEST_OP]](ra, av.reduceLanes(VectorOperators.[[TEST]])); } } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Masked-Min-op.template b/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Masked-Min-op.template deleted file mode 100644 index 70ffa79bf6f..00000000000 --- a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Masked-Min-op.template +++ /dev/null @@ -1,6 +0,0 @@ - @Test(dataProvider = "$type$UnaryOpMaskProvider") - static void [[TEST]]Reduce$vectorteststype$Masked(IntFunction<$type$[]> fa, IntFunction fm) { -[[KERNEL]] - assertReductionArraysEqualsMasked(r, ra, a, mask, - $vectorteststype$::[[TEST]]ReduceMasked, $vectorteststype$::[[TEST]]ReduceAllMasked); - } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Masked-Max-op.template b/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Masked-op-func.template similarity index 100% rename from test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Masked-Max-op.template rename to test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Masked-op-func.template diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Min-op.template b/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Min-op.template deleted file mode 100644 index b86248f3f09..00000000000 --- a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Min-op.template +++ /dev/null @@ -1,6 +0,0 @@ - @Test(dataProvider = "$type$UnaryOpProvider") - static void [[TEST]]Reduce$vectorteststype$(IntFunction<$type$[]> fa) { -[[KERNEL]] - assertReductionArraysEquals(r, ra, a, - $vectorteststype$::[[TEST]]Reduce, $vectorteststype$::[[TEST]]ReduceAll); - } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Masked-Min-op.template b/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Masked-Min-op.template deleted file mode 100644 index 6a491c05734..00000000000 --- a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Masked-Min-op.template +++ /dev/null @@ -1,19 +0,0 @@ - static $type$ [[TEST]]ReduceMasked($type$[] a, int idx, boolean[] mask) { - $type$ res = [[TEST_INIT]]; - for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = ($type$)Math.min(res, a[i]); - } - - return res; - } - - static $type$ [[TEST]]ReduceAllMasked($type$[] a, boolean[] mask) { - $type$ res = [[TEST_INIT]]; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = ($type$)Math.min(res, a[i]); - } - - return res; - } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Masked-Max-op.template b/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Masked-op-func.template similarity index 60% rename from test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Masked-Max-op.template rename to test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Masked-op-func.template index b4a2c764b84..00b8ed390bc 100644 --- a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Masked-Max-op.template +++ b/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Masked-op-func.template @@ -1,8 +1,8 @@ static $type$ [[TEST]]ReduceMasked($type$[] a, int idx, boolean[] mask) { $type$ res = [[TEST_INIT]]; for (int i = idx; i < (idx + SPECIES.length()); i++) { - if(mask[i % SPECIES.length()]) - res = ($type$)Math.max(res, a[i]); + if (mask[i % SPECIES.length()]) + res = [[TEST_OP]](res, a[i]); } return res; @@ -10,9 +10,8 @@ static $type$ [[TEST]]ReduceAllMasked($type$[] a, boolean[] mask) { $type$ res = [[TEST_INIT]]; - for (int i = 0; i < a.length; i++) { - if(mask[i % SPECIES.length()]) - res = ($type$)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = [[TEST_OP]](res, [[TEST]]ReduceMasked(a, i, mask)); } return res; diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Min-op.template b/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Min-op.template deleted file mode 100644 index 9e84bd13034..00000000000 --- a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Min-op.template +++ /dev/null @@ -1,17 +0,0 @@ - static $type$ [[TEST]]Reduce($type$[] a, int idx) { - $type$ res = [[TEST_INIT]]; - for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = ($type$)Math.min(res, a[i]); - } - - return res; - } - - static $type$ [[TEST]]ReduceAll($type$[] a) { - $type$ res = [[TEST_INIT]]; - for (int i = 0; i < a.length; i++) { - res = ($type$)Math.min(res, a[i]); - } - - return res; - } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Max-op.template b/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-op-func.template similarity index 65% rename from test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Max-op.template rename to test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-op-func.template index 528f4ddb5f3..2abdcd295b4 100644 --- a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-Max-op.template +++ b/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Scalar-op-func.template @@ -1,7 +1,7 @@ static $type$ [[TEST]]Reduce($type$[] a, int idx) { $type$ res = [[TEST_INIT]]; for (int i = idx; i < (idx + SPECIES.length()); i++) { - res = ($type$)Math.max(res, a[i]); + res = [[TEST_OP]](res, a[i]); } return res; @@ -9,8 +9,8 @@ static $type$ [[TEST]]ReduceAll($type$[] a) { $type$ res = [[TEST_INIT]]; - for (int i = 0; i < a.length; i++) { - res = ($type$)Math.max(res, a[i]); + for (int i = 0; i < a.length; i += SPECIES.length()) { + res = [[TEST_OP]](res, [[TEST]]Reduce(a, i)); } return res; diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Max-op.template b/test/jdk/jdk/incubator/vector/templates/Unit-Reduction-op-func.template similarity index 100% rename from test/jdk/jdk/incubator/vector/templates/Unit-Reduction-Max-op.template rename to test/jdk/jdk/incubator/vector/templates/Unit-Reduction-op-func.template diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-header.template b/test/jdk/jdk/incubator/vector/templates/Unit-header.template index f73d697e2a7..239596bf433 100644 --- a/test/jdk/jdk/incubator/vector/templates/Unit-header.template +++ b/test/jdk/jdk/incubator/vector/templates/Unit-header.template @@ -1451,6 +1451,10 @@ public class $vectorteststype$ extends AbstractVectorTest { } #end[!FP] + static $type$ firstNonZero($type$ a, $type$ b) { + return $Boxtype$.compare(a, ($type$) 0) != 0 ? a : b; + } + @Test static void smokeTest1() { $abstractvectortype$ three = $abstractvectortype$.broadcast(SPECIES, (byte)-3); -- GitLab From 58c2bd315836b9c4fbffa212497fd84c8f589c17 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Thu, 10 Feb 2022 22:51:39 +0000 Subject: [PATCH 202/400] 8281536: JFR: Improve jdk.jfr.ContentType documentation Reviewed-by: mgronlun --- .../share/classes/jdk/jfr/ContentType.java | 16 ++++ .../jdk/jfr/snippet-files/Snippets.java | 82 +++++++++++++++++++ 2 files changed, 98 insertions(+) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/ContentType.java b/src/jdk.jfr/share/classes/jdk/jfr/ContentType.java index 13a5ae226ba..3580997ad24 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/ContentType.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/ContentType.java @@ -33,6 +33,22 @@ import java.lang.annotation.Target; /** * Meta annotation, specifies that an annotation represents a content type, such * as a time span or a frequency. + *

    + * The following example shows how a temperature content type can be created and + * used. + *

    + * First declare a temperature annotation using the {@code ContentType} + * annotation: + * + * {@snippet class="Snippets" region="ContentTypeDeclaration"} + * + * Then declare an event, annotate a field and commit the data: + * + * {@snippet class="Snippets" region="ContentTypeEvent"} + * + * Finally, inspect the annotation when displaying event data: + * + * {@snippet class="Snippets" region="ContentTypeConsumption"} * * @since 9 */ diff --git a/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java b/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java index b2d4fff29de..ef95e2ffb35 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java @@ -32,7 +32,10 @@ import jdk.jfr.Name; import jdk.jfr.Label; import jdk.jfr.Description; import jdk.jfr.Category; +import jdk.jfr.ContentType; +import jdk.jfr.Period; import jdk.jfr.Recording; +import jdk.jfr.StackTrace; import jdk.jfr.MetadataDefinition; import jdk.jfr.Relational; import jdk.jfr.consumer.RecordingFile; @@ -40,6 +43,7 @@ import jdk.jfr.Configuration; import jdk.jfr.SettingDefinition; import jdk.jfr.SettingControl; import jdk.jfr.FlightRecorder; +import jdk.jfr.consumer.RecordedEvent; import java.io.IOException; import java.nio.file.Files; @@ -78,6 +82,84 @@ public class Snippets { // @end } + record CPU(String id, float temperature) { + } + + private static List listCPUs() { + return List.of(); + } + + // @start region="ContentTypeDeclaration" + @MetadataDefinition + @ContentType + @Name("com.example.Temperature") + @Label("Temperature") + @Target(ElementType.FIELD) + @Retention(RetentionPolicy.RUNTIME) + public @interface Temperature { + public final static String KELVIN = "KELVIN"; + public final static String CELSIUS = "CELSIUS"; + public final static String FAHRENEHIT = "FAHRENHEIT"; + + String value() default CELSIUS; + } + // @end + + // @start region="ContentTypeEvent" + @Name("com.example.CPU") + @Label("CPU") + @Category({ "Hardware", "CPU" }) + @Period("1 s") + @StackTrace(false) + static public class CPUEvent extends Event { + @Label("ID") + String id; + + @Temperature(Temperature.KELVIN) + @Label("Temperature") + float temperature; + } + + public static void main(String... args) throws InterruptedException { + FlightRecorder.addPeriodicEvent(CPUEvent.class, () -> { + for (var cpu : listCPUs()) { + CPUEvent event = new CPUEvent(); + event.id = cpu.id(); + event.temperature = cpu.temperature(); // in Kelvin + event.commit(); + } + }); + Thread.sleep(10_000); + } + // @end + + // @start region="ContentTypeConsumption" + void printTemperaturesInCelsius(Path file) throws IOException { + for (RecordedEvent event : RecordingFile.readAllEvents(file)) { + for (ValueDescriptor field : event.getEventType().getFields()) { + for (AnnotationElement ae : field.getAnnotationElements()) { + ContentType type = ae.getAnnotation(ContentType.class); + if (type != null) { + if (ae.getTypeName().equals("com.example.Temperature")) { + double value = event.getDouble(field.getName()); + String unit = (String) ae.getValue("value"); + double celsius = switch (unit) { + case "CELSIUS" -> value; + case "KELVIN" -> value - 273.15; + case "FAHRENHEIT" -> (value - 32) / 1.8; + default -> throw new IllegalStateException("Unknown temperature unit '" + unit + "'"); + }; + System.out.println(celsius + " C"); + } else { + System.err.println("Can't format content type " + ae.getTypeName() + " for field " + field.getName()); + } + } + } + } + } + } + // @end + // @start region="EventOverview" public class Example { -- GitLab From 84868e39be4522ba87e603beea0f8da9efa43b6d Mon Sep 17 00:00:00 2001 From: David Holmes Date: Thu, 10 Feb 2022 23:23:48 +0000 Subject: [PATCH 203/400] 8281275: Upgrading from 8 to 11 no longer accepts '/' as filepath separator in gc paths Reviewed-by: shade, dcubed --- .../share/logging/logConfiguration.cpp | 8 +++--- .../gtest/logging/test_logConfiguration.cpp | 25 ++++++++++++++++++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/hotspot/share/logging/logConfiguration.cpp b/src/hotspot/share/logging/logConfiguration.cpp index a46af599215..518e7979ef8 100644 --- a/src/hotspot/share/logging/logConfiguration.cpp +++ b/src/hotspot/share/logging/logConfiguration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -365,9 +365,9 @@ bool LogConfiguration::parse_command_line_arguments(const char* opts) { // Find the next colon or quote char* next = strpbrk(str, ":\""); #ifdef _WINDOWS - // Skip over Windows paths such as "C:\..." - // Handle both C:\... and file=C:\..." - if (next != NULL && next[0] == ':' && next[1] == '\\') { + // Skip over Windows paths such as "C:\..." and "C:/...". + // Handles both "C:\..." and "file=C:\...". + if (next != NULL && next[0] == ':' && (next[1] == '\\' || next[1] == '/')) { if (next == str + 1 || (strncmp(str, "file=", 5) == 0)) { next = strpbrk(next + 1, ":\""); } diff --git a/test/hotspot/gtest/logging/test_logConfiguration.cpp b/test/hotspot/gtest/logging/test_logConfiguration.cpp index 0d092dc0d75..38997af68cb 100644 --- a/test/hotspot/gtest/logging/test_logConfiguration.cpp +++ b/test/hotspot/gtest/logging/test_logConfiguration.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -359,6 +359,29 @@ TEST_VM_F(LogConfigurationTest, parse_command_line_arguments) { ret = jio_snprintf(buf, sizeof(buf), ":%s", TestLogFileName); ASSERT_NE(-1, ret); EXPECT_TRUE(LogConfiguration::parse_command_line_arguments(buf)); + +#ifdef _WINDOWS + // We need to test the special-case parsing for drive letters in + // log file paths e.g. c:\log.txt and c:/log.txt. Our temp directory + // based TestLogFileName should already be the \ format (we print it + // below to visually verify) so we only need to convert to /. + printf("Checked: %s\n", buf); + // First disable logging so the current log file will be closed and we + // can delete it, so that UL won't try to perform log file rotation. + // The rotated file would not be auto-deleted. + set_log_config(TestLogFileName, "all=off"); + delete_file(TestLogFileName); + + // now convert \ to / + char* current_pos = strchr(buf,'\\'); + while (current_pos != nullptr) { + *current_pos = '/'; + current_pos = strchr(current_pos + 1, '\\'); + } + printf("Checking: %s\n", buf); + EXPECT_TRUE(LogConfiguration::parse_command_line_arguments(buf)); +#endif + } // Test split up log configuration arguments -- GitLab From eee6a5622dca683d4d6a701daa48e09e8d17b54e Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Fri, 11 Feb 2022 05:34:27 +0000 Subject: [PATCH 204/400] 8281522: Rename ADLC classes which have the same name as hotspot variants Reviewed-by: neliasso, kvn --- .../share/adlc/{arena.cpp => adlArena.cpp} | 94 +++++++++---------- .../share/adlc/{arena.hpp => adlArena.hpp} | 56 +++++------ src/hotspot/share/adlc/adlc.hpp | 2 +- src/hotspot/share/adlc/adlparse.cpp | 16 ++-- src/hotspot/share/adlc/dfa.cpp | 6 +- src/hotspot/share/adlc/dict2.cpp | 4 +- src/hotspot/share/adlc/dict2.hpp | 6 +- src/hotspot/share/adlc/forms.cpp | 14 +-- src/hotspot/share/adlc/forms.hpp | 10 +- src/hotspot/share/adlc/formsopt.cpp | 4 +- src/hotspot/share/adlc/formssel.cpp | 6 +- 11 files changed, 109 insertions(+), 109 deletions(-) rename src/hotspot/share/adlc/{arena.cpp => adlArena.cpp} (66%) rename src/hotspot/share/adlc/{arena.hpp => adlArena.hpp} (73%) diff --git a/src/hotspot/share/adlc/arena.cpp b/src/hotspot/share/adlc/adlArena.cpp similarity index 66% rename from src/hotspot/share/adlc/arena.cpp rename to src/hotspot/share/adlc/adlArena.cpp index 60a546e7961..7c6e9419d4f 100644 --- a/src/hotspot/share/adlc/arena.cpp +++ b/src/hotspot/share/adlc/adlArena.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -24,7 +24,7 @@ #include "adlc.hpp" -void* AllocateHeap(size_t size) { +void* AdlAllocateHeap(size_t size) { unsigned char* ptr = (unsigned char*) malloc(size); if (ptr == NULL && size != 0) { fprintf(stderr, "Error: Out of memory in ADLC\n"); // logging can cause crash! @@ -34,7 +34,7 @@ void* AllocateHeap(size_t size) { return ptr; } -void* ReAllocateHeap(void* old_ptr, size_t size) { +void* AdlReAllocateHeap(void* old_ptr, size_t size) { unsigned char* ptr = (unsigned char*) realloc(old_ptr, size); if (ptr == NULL && size != 0) { fprintf(stderr, "Error: Out of memory in ADLC\n"); // logging can cause crash! @@ -44,24 +44,24 @@ void* ReAllocateHeap(void* old_ptr, size_t size) { return ptr; } -void* Chunk::operator new(size_t requested_size, size_t length) throw() { - return CHeapObj::operator new(requested_size + length); +void* AdlChunk::operator new(size_t requested_size, size_t length) throw() { + return AdlCHeapObj::operator new(requested_size + length); } -void Chunk::operator delete(void* p, size_t length) { - CHeapObj::operator delete(p); +void AdlChunk::operator delete(void* p, size_t length) { + AdlCHeapObj::operator delete(p); } -Chunk::Chunk(size_t length) { +AdlChunk::AdlChunk(size_t length) { _next = NULL; // Chain on the linked list _len = length; // Save actual size } //------------------------------chop------------------------------------------- -void Chunk::chop() { - Chunk *k = this; +void AdlChunk::chop() { + AdlChunk *k = this; while( k ) { - Chunk *tmp = k->_next; + AdlChunk *tmp = k->_next; // clear out this chunk (to detect allocation bugs) memset(k, 0xBE, k->_len); free(k); // Free chunk (was malloc'd) @@ -69,52 +69,52 @@ void Chunk::chop() { } } -void Chunk::next_chop() { +void AdlChunk::next_chop() { _next->chop(); _next = NULL; } -//------------------------------Arena------------------------------------------ -Arena::Arena( size_t init_size ) { +//------------------------------AdlArena------------------------------------------ +AdlArena::AdlArena( size_t init_size ) { init_size = (init_size+3) & ~3; - _first = _chunk = new (init_size) Chunk(init_size); + _first = _chunk = new (init_size) AdlChunk(init_size); _hwm = _chunk->bottom(); // Save the cached hwm, max _max = _chunk->top(); set_size_in_bytes(init_size); } -Arena::Arena() { - _first = _chunk = new (Chunk::init_size) Chunk(Chunk::init_size); +AdlArena::AdlArena() { + _first = _chunk = new (AdlChunk::init_size) AdlChunk(AdlChunk::init_size); _hwm = _chunk->bottom(); // Save the cached hwm, max _max = _chunk->top(); - set_size_in_bytes(Chunk::init_size); + set_size_in_bytes(AdlChunk::init_size); } -Arena::Arena( Arena *a ) +AdlArena::AdlArena( AdlArena *a ) : _chunk(a->_chunk), _hwm(a->_hwm), _max(a->_max), _first(a->_first) { set_size_in_bytes(a->size_in_bytes()); } //------------------------------used------------------------------------------- -// Total of all Chunks in arena -size_t Arena::used() const { - size_t sum = _chunk->_len - (_max-_hwm); // Size leftover in this Chunk - Chunk *k = _first; - while( k != _chunk) { // Whilst have Chunks in a row - sum += k->_len; // Total size of this Chunk - k = k->_next; // Bump along to next Chunk +// Total of all AdlChunks in arena +size_t AdlArena::used() const { + size_t sum = _chunk->_len - (_max-_hwm); // Size leftover in this AdlChunk + AdlChunk *k = _first; + while( k != _chunk) { // Whilst have AdlChunks in a row + sum += k->_len; // Total size of this AdlChunk + k = k->_next; // Bump along to next AdlChunk } return sum; // Return total consumed space. } //------------------------------grow------------------------------------------- -// Grow a new Chunk -void* Arena::grow( size_t x ) { +// Grow a new AdlChunk +void* AdlArena::grow( size_t x ) { // Get minimal required size. Either real big, or even bigger for giant objs - size_t len = max(x, Chunk::size); + size_t len = max(x, AdlChunk::size); - Chunk *k = _chunk; // Get filled-up chunk address - _chunk = new (len) Chunk(len); + AdlChunk *k = _chunk; // Get filled-up chunk address + _chunk = new (len) AdlChunk(len); if( k ) k->_next = _chunk; // Append new chunk to end of linked list else _first = _chunk; @@ -127,8 +127,8 @@ void* Arena::grow( size_t x ) { } //------------------------------calloc----------------------------------------- -// Allocate zeroed storage in Arena -void *Arena::Acalloc( size_t items, size_t x ) { +// Allocate zeroed storage in AdlArena +void *AdlArena::Acalloc( size_t items, size_t x ) { size_t z = items*x; // Total size needed void *ptr = Amalloc(z); // Get space memset( ptr, 0, z ); // Zap space @@ -136,8 +136,8 @@ void *Arena::Acalloc( size_t items, size_t x ) { } //------------------------------realloc---------------------------------------- -// Reallocate storage in Arena. -void *Arena::Arealloc( void *old_ptr, size_t old_size, size_t new_size ) { +// Reallocate storage in AdlArena. +void *AdlArena::Arealloc( void *old_ptr, size_t old_size, size_t new_size ) { char *c_old = (char*)old_ptr; // Handy name // Stupid fast special case if( new_size <= old_size ) { // Shrink in-place @@ -161,32 +161,32 @@ void *Arena::Arealloc( void *old_ptr, size_t old_size, size_t new_size ) { } //------------------------------reset------------------------------------------ -// Reset this Arena to empty, and return this Arenas guts in a new Arena. -Arena *Arena::reset(void) { - Arena *a = new Arena(this); // New empty arena +// Reset this AdlArena to empty, and return this AdlArenas guts in a new AdlArena. +AdlArena *AdlArena::reset(void) { + AdlArena *a = new AdlArena(this); // New empty arena _first = _chunk = NULL; // Normal, new-arena initialization _hwm = _max = NULL; - return a; // Return Arena with guts + return a; // Return AdlArena with guts } //------------------------------contains--------------------------------------- -// Determine if pointer belongs to this Arena or not. -bool Arena::contains( const void *ptr ) const { +// Determine if pointer belongs to this AdlArena or not. +bool AdlArena::contains( const void *ptr ) const { if( (void*)_chunk->bottom() <= ptr && ptr < (void*)_hwm ) return true; // Check for in this chunk - for( Chunk *c = _first; c; c = c->_next ) + for( AdlChunk *c = _first; c; c = c->_next ) if( (void*)c->bottom() <= ptr && ptr < (void*)c->top()) - return true; // Check for every chunk in Arena - return false; // Not in any Chunk, so not in Arena + return true; // Check for every chunk in AdlArena + return false; // Not in any AdlChunk, so not in AdlArena } //----------------------------------------------------------------------------- // CHeapObj -void* CHeapObj::operator new(size_t size) throw() { - return (void *) AllocateHeap(size); +void* AdlCHeapObj::operator new(size_t size) throw() { + return (void *) AdlAllocateHeap(size); } -void CHeapObj::operator delete(void* p){ +void AdlCHeapObj::operator delete(void* p){ free(p); } diff --git a/src/hotspot/share/adlc/arena.hpp b/src/hotspot/share/adlc/adlArena.hpp similarity index 73% rename from src/hotspot/share/adlc/arena.hpp rename to src/hotspot/share/adlc/adlArena.hpp index 1fa99ed0e24..254f414f707 100644 --- a/src/hotspot/share/adlc/arena.hpp +++ b/src/hotspot/share/adlc/adlArena.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -22,11 +22,11 @@ * */ -#ifndef SHARE_ADLC_ARENA_HPP -#define SHARE_ADLC_ARENA_HPP +#ifndef SHARE_ADLC_ADLARENA_HPP +#define SHARE_ADLC_ADLARENA_HPP -void* AllocateHeap(size_t size); -void* ReAllocateHeap(void* old_ptr, size_t size); +void* AdlAllocateHeap(size_t size); +void* AdlReAllocateHeap(void* old_ptr, size_t size); // All classes in adlc may be derived // from one of the following allocation classes: @@ -35,10 +35,10 @@ void* ReAllocateHeap(void* old_ptr, size_t size); // - CHeapObj // // For classes used as name spaces. -// - AllStatic +// - AdlAllStatic // -class CHeapObj { +class AdlCHeapObj { public: void* operator new(size_t size) throw(); void operator delete(void* p); @@ -47,16 +47,16 @@ class CHeapObj { // Base class for classes that constitute name spaces. -class AllStatic { +class AdlAllStatic { public: void* operator new(size_t size) throw(); void operator delete(void* p); }; -//------------------------------Chunk------------------------------------------ +//------------------------------AdlChunk------------------------------------------ // Linked list of raw memory chunks -class Chunk: public CHeapObj { +class AdlChunk: public AdlCHeapObj { private: // This ordinary operator delete is needed even though not used, so the // below two-argument operator delete will be treated as a placement @@ -65,41 +65,41 @@ class Chunk: public CHeapObj { public: void* operator new(size_t size, size_t length) throw(); void operator delete(void* p, size_t length); - Chunk(size_t length); + AdlChunk(size_t length); enum { init_size = 1*1024, // Size of first chunk - size = 32*1024 // Default size of an Arena chunk (following the first) + size = 32*1024 // Default size of an AdlArena chunk (following the first) }; - Chunk* _next; // Next Chunk in list - size_t _len; // Size of this Chunk + AdlChunk* _next; // Next AdlChunk in list + size_t _len; // Size of this AdlChunk void chop(); // Chop this chunk void next_chop(); // Chop next chunk // Boundaries of data area (possibly unused) - char* bottom() const { return ((char*) this) + sizeof(Chunk); } + char* bottom() const { return ((char*) this) + sizeof(AdlChunk); } char* top() const { return bottom() + _len; } }; -//------------------------------Arena------------------------------------------ +//------------------------------AdlArena------------------------------------------ // Fast allocation of memory -class Arena: public CHeapObj { +class AdlArena: public AdlCHeapObj { protected: friend class ResourceMark; friend class HandleMark; friend class NoHandleMark; - Chunk *_first; // First chunk - Chunk *_chunk; // current chunk + AdlChunk *_first; // First chunk + AdlChunk *_chunk; // current chunk char *_hwm, *_max; // High water mark and max in current chunk - void* grow(size_t x); // Get a new Chunk of at least size x + void* grow(size_t x); // Get a new AdlChunk of at least size x size_t _size_in_bytes; // Size of arena (used for memory usage tracing) public: - Arena(); - Arena(size_t init_size); - Arena(Arena *old); - ~Arena() { _first->chop(); } + AdlArena(); + AdlArena(size_t init_size); + AdlArena(AdlArena *old); + ~AdlArena() { _first->chop(); } char* hwm() const { return _hwm; } // Fast allocate in the arena. Common case is: pointer test + increment. @@ -137,10 +137,10 @@ public: void *Acalloc( size_t items, size_t x ); void *Arealloc( void *old_ptr, size_t old_size, size_t new_size ); - // Reset this Arena to empty, and return this Arenas guts in a new Arena. - Arena *reset(void); + // Reset this AdlArena to empty, and return this AdlArenas guts in a new AdlArena. + AdlArena *reset(void); - // Determine if pointer belongs to this Arena or not. + // Determine if pointer belongs to this AdlArena or not. bool contains( const void *ptr ) const; // Total of all chunks in use (not thread-safe) @@ -151,4 +151,4 @@ public: void set_size_in_bytes(size_t size) { _size_in_bytes = size; } }; -#endif // SHARE_ADLC_ARENA_HPP +#endif // SHARE_ADLC_ADLARENA_HPP diff --git a/src/hotspot/share/adlc/adlc.hpp b/src/hotspot/share/adlc/adlc.hpp index 297d5cb0133..19567f05d40 100644 --- a/src/hotspot/share/adlc/adlc.hpp +++ b/src/hotspot/share/adlc/adlc.hpp @@ -93,7 +93,7 @@ typedef unsigned int uintptr_t; #define max(a, b) (((a)>(b)) ? (a) : (b)) // ADLC components -#include "arena.hpp" +#include "adlArena.hpp" #include "opto/adlcVMDeps.hpp" #include "filebuff.hpp" #include "dict2.hpp" diff --git a/src/hotspot/share/adlc/adlparse.cpp b/src/hotspot/share/adlc/adlparse.cpp index ecb722c56b2..283713bb1f8 100644 --- a/src/hotspot/share/adlc/adlparse.cpp +++ b/src/hotspot/share/adlc/adlparse.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -211,7 +211,7 @@ void ADLParser::instr_parse(void) { return; } assert(match_rules_cnt < 100," too many match rule clones"); - char* buf = (char*) AllocateHeap(strlen(instr->_ident) + 4); + char* buf = (char*) AdlAllocateHeap(strlen(instr->_ident) + 4); sprintf(buf, "%s_%d", instr->_ident, match_rules_cnt++); rule->_result = buf; // Check for commutative operations with tree operands. @@ -2805,7 +2805,7 @@ void ADLParser::ins_encode_parse_block(InstructForm& inst) { // Create a new encoding name based on the name of the instruction // definition, which should be unique. const char* prefix = "__ins_encode_"; - char* ec_name = (char*) AllocateHeap(strlen(inst._ident) + strlen(prefix) + 1); + char* ec_name = (char*) AdlAllocateHeap(strlen(inst._ident) + strlen(prefix) + 1); sprintf(ec_name, "%s%s", prefix, inst._ident); assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); @@ -3276,7 +3276,7 @@ void ADLParser::constant_parse(InstructForm& inst) { // Create a new encoding name based on the name of the instruction // definition, which should be unique. const char* prefix = "__constant_"; - char* ec_name = (char*) AllocateHeap(strlen(inst._ident) + strlen(prefix) + 1); + char* ec_name = (char*) AdlAllocateHeap(strlen(inst._ident) + strlen(prefix) + 1); sprintf(ec_name, "%s%s", prefix, inst._ident); assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); @@ -4409,7 +4409,7 @@ char* ADLParser::find_cpp_block(const char* description) { if (_AD._adlocation_debug) { char* location = get_line_string(line); char* end_loc = end_line_marker(); - char* result = (char *)AllocateHeap(strlen(location) + strlen(cppBlock) + strlen(end_loc) + 1); + char* result = (char *)AdlAllocateHeap(strlen(location) + strlen(cppBlock) + strlen(end_loc) + 1); strcpy(result, location); strcat(result, cppBlock); strcat(result, end_loc); @@ -4498,7 +4498,7 @@ char *ADLParser::get_paren_expr(const char *description, bool include_location) // Prepend location descriptor, for debugging. char* location = get_line_string(line); char* end_loc = end_line_marker(); - char* result = (char *)AllocateHeap(strlen(location) + strlen(token2) + strlen(end_loc) + 1); + char* result = (char *)AdlAllocateHeap(strlen(location) + strlen(token2) + strlen(end_loc) + 1); strcpy(result, location); strcat(result, token2); strcat(result, end_loc); @@ -4596,7 +4596,7 @@ char *ADLParser::get_ident_or_literal_constant(const char* description) { // Grab a constant expression. param = get_paren_expr(description); if (param[0] != '(') { - char* buf = (char*) AllocateHeap(strlen(param) + 3); + char* buf = (char*) AdlAllocateHeap(strlen(param) + 3); sprintf(buf, "(%s)", param); param = buf; } @@ -5204,7 +5204,7 @@ void ADLParser::next_line() { char* ADLParser::get_line_string(int linenum) { const char* file = _AD._ADL_file._name; int line = linenum ? linenum : this->linenum(); - char* location = (char *)AllocateHeap(strlen(file) + 100); + char* location = (char *)AdlAllocateHeap(strlen(file) + 100); sprintf(location, "\n#line %d \"%s\"\n", line, file); return location; } diff --git a/src/hotspot/share/adlc/dfa.cpp b/src/hotspot/share/adlc/dfa.cpp index b1556ab5f5e..5abc4365297 100644 --- a/src/hotspot/share/adlc/dfa.cpp +++ b/src/hotspot/share/adlc/dfa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -72,7 +72,7 @@ private: public: // cmpstr does string comparisions. hashstr computes a key. - ProductionState(Arena *arena) : _production(cmpstr, hashstr, arena) { initialize(); }; + ProductionState(AdlArena *arena) : _production(cmpstr, hashstr, arena) { initialize(); }; ~ProductionState() { }; void initialize(); // reset local and dictionary state @@ -817,7 +817,7 @@ bool Expr::check_buffers() { //------------------------------ExprDict--------------------------------------- // Constructor -ExprDict::ExprDict( CmpKey cmp, Hash hash, Arena *arena ) +ExprDict::ExprDict( CmpKey cmp, Hash hash, AdlArena *arena ) : _expr(cmp, hash, arena), _defines() { } ExprDict::~ExprDict() { diff --git a/src/hotspot/share/adlc/dict2.cpp b/src/hotspot/share/adlc/dict2.cpp index 4f3e33dd626..9fd22572855 100644 --- a/src/hotspot/share/adlc/dict2.cpp +++ b/src/hotspot/share/adlc/dict2.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -56,7 +56,7 @@ Dict::Dict(CmpKey initcmp, Hash inithash) : _hash(inithash), _cmp(initcmp), _are init(); } -Dict::Dict(CmpKey initcmp, Hash inithash, Arena *arena) : _hash(inithash), _cmp(initcmp), _arena(arena) { +Dict::Dict(CmpKey initcmp, Hash inithash, AdlArena *arena) : _hash(inithash), _cmp(initcmp), _arena(arena) { init(); } diff --git a/src/hotspot/share/adlc/dict2.hpp b/src/hotspot/share/adlc/dict2.hpp index a9790088dfb..c6b7da3368a 100644 --- a/src/hotspot/share/adlc/dict2.hpp +++ b/src/hotspot/share/adlc/dict2.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -43,7 +43,7 @@ typedef void (*FuncDict)(const void *key, const void *val, Dict *d); class Dict { // Dictionary structure private: - class Arena *_arena; // Where to draw storage from + class AdlArena *_arena; // Where to draw storage from class bucket *_bin; // Hash table is array of buckets int _size; // Size (# of slots) in hash table int _cnt; // Number of key-value pairs in hash table @@ -56,7 +56,7 @@ class Dict { // Dictionary structure // cmp is a key comparision routine. hash is a routine to hash a key. Dict( CmpKey cmp, Hash hash ); - Dict( CmpKey cmp, Hash hash, Arena *arena ); + Dict( CmpKey cmp, Hash hash, AdlArena *arena ); void init(); ~Dict(); diff --git a/src/hotspot/share/adlc/forms.cpp b/src/hotspot/share/adlc/forms.cpp index 3a246285b3a..9580d81484d 100644 --- a/src/hotspot/share/adlc/forms.cpp +++ b/src/hotspot/share/adlc/forms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -27,9 +27,9 @@ //------------------------------Static Initializers---------------------------- // allocate arena used by forms -Arena *Form::arena = Form::generate_arena(); // = Form::generate_arena(); -Arena *Form::generate_arena() { - return (new Arena); +AdlArena *Form::arena = Form::generate_arena(); // = Form::generate_arena(); +AdlArena *Form::generate_arena() { + return (new AdlArena); } //------------------------------NameList--------------------------------------- @@ -40,7 +40,7 @@ const char *NameList::_signal3 = "$$SIGNAL3$$"; // Constructor and Destructor NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) { - _names = (const char**) AllocateHeap(_max*sizeof(char*)); + _names = (const char**) AdlAllocateHeap(_max*sizeof(char*)); } NameList::~NameList() { // The following free is a double-free, and crashes the program: @@ -49,7 +49,7 @@ NameList::~NameList() { void NameList::addName(const char *name) { if (_cur == _max) { - _names = (const char**) ReAllocateHeap(_names, (_max *=2)*sizeof(char*)); + _names = (const char**) AdlReAllocateHeap(_names, (_max *=2)*sizeof(char*)); } _names[_cur++] = name; } @@ -312,7 +312,7 @@ FormList::~FormList() { //------------------------------FormDict--------------------------------------- // Constructor -FormDict::FormDict( CmpKey cmp, Hash hash, Arena *arena ) +FormDict::FormDict( CmpKey cmp, Hash hash, AdlArena *arena ) : _form(cmp, hash, arena) { } FormDict::~FormDict() { diff --git a/src/hotspot/share/adlc/forms.hpp b/src/hotspot/share/adlc/forms.hpp index b4e115229c3..6586ea88311 100644 --- a/src/hotspot/share/adlc/forms.hpp +++ b/src/hotspot/share/adlc/forms.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -97,7 +97,7 @@ private: public: // cmp is a key comparision routine. hash is a routine to hash a key. // FormDict( CmpKey cmp, Hash hash ); - FormDict( CmpKey cmp, Hash hash, Arena *arena ); + FormDict( CmpKey cmp, Hash hash, AdlArena *arena ); FormDict( const FormDict & fd ); // Deep-copy guts ~FormDict(); @@ -119,9 +119,9 @@ public: //------------------------------Form------------------------------------------- class Form { public: - static Arena *arena; // arena used by forms + static AdlArena *arena; // arena used by forms private: - static Arena *generate_arena(); // allocate arena used by forms + static AdlArena *generate_arena(); // allocate arena used by forms protected: int _ftype; // Indicator for derived class type @@ -573,7 +573,7 @@ private: public: // cmp is a key comparision routine. hash is a routine to hash a key. - ExprDict( CmpKey cmp, Hash hash, Arena *arena ); + ExprDict( CmpKey cmp, Hash hash, AdlArena *arena ); ~ExprDict(); // Return # of key-value pairs in dict diff --git a/src/hotspot/share/adlc/formsopt.cpp b/src/hotspot/share/adlc/formsopt.cpp index 351904bbb29..6f1a5997511 100644 --- a/src/hotspot/share/adlc/formsopt.cpp +++ b/src/hotspot/share/adlc/formsopt.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 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 @@ -206,7 +206,7 @@ RegDef::RegDef(char *regname, char *callconv, char *c_conv, char * idealtype, ch _concrete(concrete), _register_num(0) { - // Chunk and register mask are determined by the register number + // AdlChunk and register mask are determined by the register number // _register_num is set when registers are added to an allocation class } RegDef::~RegDef() { // Destructor diff --git a/src/hotspot/share/adlc/formssel.cpp b/src/hotspot/share/adlc/formssel.cpp index f7ff8ccf40b..67c49459db9 100644 --- a/src/hotspot/share/adlc/formssel.cpp +++ b/src/hotspot/share/adlc/formssel.cpp @@ -1366,7 +1366,7 @@ void InstructForm::set_unique_opnds() { // component back to an index and any DEF always goes at 0 so the // length of the array has to be the number of components + 1. _uniq_idx_length = _components.count() + 1; - uniq_idx = (uint*) AllocateHeap(sizeof(uint) * _uniq_idx_length); + uniq_idx = (uint*) AdlAllocateHeap(sizeof(uint) * _uniq_idx_length); for (i = 0; i < _uniq_idx_length; i++) { uniq_idx[i] = i; } @@ -3476,7 +3476,7 @@ void MatchNode::build_internalop( ) { rstr = (_rChild) ? ((_rChild->_internalop) ? _rChild->_internalop : _rChild->_opType) : ""; len += (int)strlen(lstr) + (int)strlen(rstr); - subtree = (char *)AllocateHeap(len); + subtree = (char *)AdlAllocateHeap(len); sprintf(subtree,"_%s_%s_%s", _opType, lstr, rstr); // Hash the subtree string in _internalOps; if a name exists, use it iop = (char *)_AD._internalOps[subtree]; @@ -3926,7 +3926,7 @@ void MatchRule::matchrule_swap_commutative_op(const char* instr_ident, int count MatchRule* clone = new MatchRule(_AD, this); // Swap operands of commutative operation ((MatchNode*)clone)->swap_commutative_op(true, count); - char* buf = (char*) AllocateHeap(strlen(instr_ident) + 4); + char* buf = (char*) AdlAllocateHeap(strlen(instr_ident) + 4); sprintf(buf, "%s_%d", instr_ident, match_rules_cnt++); clone->_result = buf; -- GitLab From 65831eb294b6f1f5f99988836c00005d41c27fd3 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Fri, 11 Feb 2022 06:45:13 +0000 Subject: [PATCH 205/400] 8281318: Improve jfr/event/allocation tests reliability Reviewed-by: mgronlun --- .../TestObjectAllocationInNewTLABEvent.java | 30 +++++++++++++------ .../TestObjectAllocationOutsideTLABEvent.java | 28 ++++++++++++----- ...ObjectAllocationSampleEventThrottling.java | 17 ++++++++--- 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationInNewTLABEvent.java b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationInNewTLABEvent.java index d4078a65ecd..cb70c0ba324 100644 --- a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationInNewTLABEvent.java +++ b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationInNewTLABEvent.java @@ -30,6 +30,8 @@ import jdk.jfr.consumer.RecordedEvent; import jdk.test.lib.jfr.EventNames; import jdk.test.lib.jfr.Events; import jdk.test.lib.Asserts; +import jdk.test.lib.Platform; +import sun.hotspot.WhiteBox; /** * @test @@ -37,8 +39,16 @@ import jdk.test.lib.Asserts; * @key jfr * @requires vm.hasJFR * @library /test/lib - * @run main/othervm -XX:+UseTLAB -XX:TLABSize=100k -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=1 jdk.jfr.event.allocation.TestObjectAllocationInNewTLABEvent - * @run main/othervm -XX:+UseTLAB -XX:TLABSize=100k -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=1 -Xint jdk.jfr.event.allocation.TestObjectAllocationInNewTLABEvent + * @build sun.hotspot.WhiteBox + * + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * -XX:+UseTLAB -XX:TLABSize=100k -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=1 + * jdk.jfr.event.allocation.TestObjectAllocationInNewTLABEvent + * @run main/othervm -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * -XX:+UseTLAB -XX:TLABSize=100k -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=1 + * -Xint + * jdk.jfr.event.allocation.TestObjectAllocationInNewTLABEvent */ /** @@ -46,17 +56,19 @@ import jdk.test.lib.Asserts; * an event will be triggered. The test is done for default and interpreted mode (-Xint). * * To force objects to be allocated in a new TLAB: - * the size of TLAB is set to 100k (-XX:TLABSize=100k); - * the size of allocated objects is set to 100k minus 16 bytes overhead; + * the initial size of TLAB is set to 100k (-XX:TLABSize=100k); + * the size of allocated objects is set to 128k; * max TLAB waste at refill is set to minimum (-XX:TLABRefillWasteFraction=1), * to provoke a new TLAB creation. */ public class TestObjectAllocationInNewTLABEvent { private final static String EVENT_NAME = EventNames.ObjectAllocationInNewTLAB; - private static final int BYTE_ARRAY_OVERHEAD = 16; // Extra bytes used by a byte array. - private static final int OBJECT_SIZE = 100 * 1024; - private static final int OBJECT_SIZE_ALT = OBJECT_SIZE + 8; // Object size in case of disabled CompressedOops. + private static final Boolean COMPRESSED_CLASS_PTRS = WhiteBox.getWhiteBox().getBooleanVMFlag("UseCompressedClassPointers"); + + private static final int BYTE_ARRAY_OVERHEAD = (Platform.is64bit() && !COMPRESSED_CLASS_PTRS) ? 24 : 16; + private static final int OBJECT_SIZE = 128 * 1024; + private static final int OBJECTS_TO_ALLOCATE = 100; private static final String BYTE_ARRAY_CLASS_NAME = new byte[0].getClass().getName(); private static final int INITIAL_TLAB_SIZE = 100 * 1024; @@ -112,9 +124,9 @@ public class TestObjectAllocationInNewTLABEvent { long allocationSize = Events.assertField(event, "allocationSize").atLeast(1L).getValue(); long tlabSize = Events.assertField(event, "tlabSize").atLeast(allocationSize).getValue(); String className = Events.assertField(event, "objectClass.name").notEmpty().getValue(); - if (className.equals(BYTE_ARRAY_CLASS_NAME) && (allocationSize == OBJECT_SIZE || allocationSize == OBJECT_SIZE_ALT)) { + if (className.equals(BYTE_ARRAY_CLASS_NAME) && (allocationSize == OBJECT_SIZE)) { countAllTlabs++; - if (tlabSize == INITIAL_TLAB_SIZE + OBJECT_SIZE || tlabSize == INITIAL_TLAB_SIZE + OBJECT_SIZE_ALT) { + if (tlabSize == INITIAL_TLAB_SIZE + OBJECT_SIZE) { countFullTlabs++; } } diff --git a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationOutsideTLABEvent.java b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationOutsideTLABEvent.java index 466a0062ac9..70bf4518f08 100644 --- a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationOutsideTLABEvent.java +++ b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationOutsideTLABEvent.java @@ -30,6 +30,8 @@ import jdk.jfr.consumer.RecordedEvent; import jdk.test.lib.jfr.EventNames; import jdk.test.lib.jfr.Events; import jdk.test.lib.Asserts; +import jdk.test.lib.Platform; +import sun.hotspot.WhiteBox; /** * @test @@ -37,8 +39,16 @@ import jdk.test.lib.Asserts; * @key jfr * @requires vm.hasJFR * @library /test/lib - * @run main/othervm -XX:+UseTLAB -XX:TLABSize=90k -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=256 jdk.jfr.event.allocation.TestObjectAllocationOutsideTLABEvent - * @run main/othervm -XX:+UseTLAB -XX:TLABSize=90k -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=256 -Xint jdk.jfr.event.allocation.TestObjectAllocationOutsideTLABEvent + * @build sun.hotspot.WhiteBox + * + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * -XX:+UseTLAB -XX:TLABSize=90k -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=256 + * jdk.jfr.event.allocation.TestObjectAllocationOutsideTLABEvent + * @run main/othervm -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * -XX:+UseTLAB -XX:TLABSize=90k -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=256 + * -Xint + * jdk.jfr.event.allocation.TestObjectAllocationOutsideTLABEvent */ /** @@ -46,17 +56,19 @@ import jdk.test.lib.Asserts; * Thread Local Allocation Buffer (TLAB). The test is done for default interpreted mode (-Xint). * * To force objects to be allocated outside TLAB: - * the size of TLAB is set to 90k (-XX:TLABSize=90k); - * the size of allocated objects is set to 100k. + * the initial size of TLAB is set to 90k (-XX:TLABSize=90k); + * the size of allocated objects is set to 128k; * max TLAB waste at refill is set to 256 (-XX:TLABRefillWasteFraction=256), * to prevent a new TLAB creation. */ public class TestObjectAllocationOutsideTLABEvent { private static final String EVENT_NAME = EventNames.ObjectAllocationOutsideTLAB; - private static final int BYTE_ARRAY_OVERHEAD = 16; // Extra bytes used by a byte array - private static final int OBJECT_SIZE = 100 * 1024; - private static final int OBJECT_SIZE_ALT = OBJECT_SIZE + 8; // Object size in case of disabled CompressedOops + private static final Boolean COMPRESSED_CLASS_PTRS = WhiteBox.getWhiteBox().getBooleanVMFlag("UseCompressedClassPointers"); + + private static final int BYTE_ARRAY_OVERHEAD = (Platform.is64bit() && !COMPRESSED_CLASS_PTRS) ? 24 : 16; + private static final int OBJECT_SIZE = 128 * 1024; + private static final int OBJECTS_TO_ALLOCATE = 100; private static final String BYTE_ARRAY_CLASS_NAME = new byte[0].getClass().getName(); private static int eventCount; @@ -94,7 +106,7 @@ public class TestObjectAllocationOutsideTLABEvent { } long allocationSize = Events.assertField(event, "allocationSize").atLeast(1L).getValue(); String className = Events.assertField(event, "objectClass.name").notEmpty().getValue(); - if (className.equals(BYTE_ARRAY_CLASS_NAME) && (allocationSize == OBJECT_SIZE || allocationSize == OBJECT_SIZE_ALT)) { + if (className.equals(BYTE_ARRAY_CLASS_NAME) && (allocationSize == OBJECT_SIZE)) { ++eventCount; } } diff --git a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEventThrottling.java b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEventThrottling.java index 22d03ce57ba..a10b6e2b56a 100644 --- a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEventThrottling.java +++ b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEventThrottling.java @@ -32,6 +32,8 @@ import jdk.jfr.consumer.RecordedEvent; import jdk.test.lib.jfr.EventNames; import jdk.test.lib.jfr.Events; import jdk.test.lib.Asserts; +import jdk.test.lib.Platform; +import sun.hotspot.WhiteBox; /** * @test @@ -39,15 +41,22 @@ import jdk.test.lib.Asserts; * @key jfr * @requires vm.hasJFR * @library /test/lib -* @run main/othervm -XX:+UseTLAB -XX:TLABSize=2k -XX:-ResizeTLAB jdk.jfr.event.allocation.TestObjectAllocationSampleEventThrottling + * @build sun.hotspot.WhiteBox + * + * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * -XX:+UseTLAB -XX:TLABSize=2k -XX:-ResizeTLAB + * jdk.jfr.event.allocation.TestObjectAllocationSampleEventThrottling */ public class TestObjectAllocationSampleEventThrottling { private static final String EVENT_NAME = EventNames.ObjectAllocationSample; - private static final int BYTE_ARRAY_OVERHEAD = 16; // Extra bytes used by a byte array - private static final int OBJECT_SIZE = 100 * 1024; - private static final int OBJECT_SIZE_ALT = OBJECT_SIZE + 8; // Object size in case of disabled CompressedOops + private static final Boolean COMPRESSED_CLASS_PTRS = WhiteBox.getWhiteBox().getBooleanVMFlag("UseCompressedClassPointers"); + + private static final int BYTE_ARRAY_OVERHEAD = (Platform.is64bit() && !COMPRESSED_CLASS_PTRS) ? 24 : 16; + private static final int OBJECT_SIZE = 128 * 1024; + private static final int OBJECTS_TO_ALLOCATE = 100; private static final String BYTE_ARRAY_CLASS_NAME = new byte[0].getClass().getName(); private static int eventCount; -- GitLab From a037b3c35831f029d23a88bdd49e7f2c2d951631 Mon Sep 17 00:00:00 2001 From: Thomas Stuefe Date: Fri, 11 Feb 2022 07:21:04 +0000 Subject: [PATCH 206/400] 8281460: Let ObjectMonitor have its own NMT category Reviewed-by: dholmes, dcubed, shade --- src/hotspot/share/memory/allocation.hpp | 1 + src/hotspot/share/runtime/objectMonitor.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/memory/allocation.hpp b/src/hotspot/share/memory/allocation.hpp index 8503942f21f..ec7f78b9fa4 100644 --- a/src/hotspot/share/memory/allocation.hpp +++ b/src/hotspot/share/memory/allocation.hpp @@ -146,6 +146,7 @@ class AllocatedObj { f(mtServiceability, "Serviceability") \ f(mtMetaspace, "Metaspace") \ f(mtStringDedup, "String Deduplication") \ + f(mtObjectMonitor, "Object Monitors") \ f(mtNone, "Unknown") \ //end diff --git a/src/hotspot/share/runtime/objectMonitor.hpp b/src/hotspot/share/runtime/objectMonitor.hpp index 4ca4cc28c86..889a844fa50 100644 --- a/src/hotspot/share/runtime/objectMonitor.hpp +++ b/src/hotspot/share/runtime/objectMonitor.hpp @@ -127,7 +127,7 @@ class ObjectWaiter : public StackObj { #define OM_CACHE_LINE_SIZE DEFAULT_CACHE_LINE_SIZE #endif -class ObjectMonitor : public CHeapObj { +class ObjectMonitor : public CHeapObj { friend class ObjectSynchronizer; friend class ObjectWaiter; friend class VMStructs; -- GitLab From 8441d51e71e143250b44eea74114a624cf00cc3e Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Fri, 11 Feb 2022 07:41:18 +0000 Subject: [PATCH 207/400] 8281419: The source data for the color conversion can be discarded Reviewed-by: prr, aivanov --- src/java.desktop/share/native/liblcms/LCMS.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/java.desktop/share/native/liblcms/LCMS.c b/src/java.desktop/share/native/liblcms/LCMS.c index 4bbd6e100c3..27c23c6d92f 100644 --- a/src/java.desktop/share/native/liblcms/LCMS.c +++ b/src/java.desktop/share/native/liblcms/LCMS.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -496,19 +496,20 @@ static void *getILData(JNIEnv *env, jobject data, jint type) { } } -static void releaseILData(JNIEnv *env, void *pData, jint type, jobject data) { +static void releaseILData(JNIEnv *env, void *pData, jint type, jobject data, + jint mode) { switch (type) { case DT_BYTE: - (*env)->ReleaseByteArrayElements(env, data, (jbyte *) pData, 0); + (*env)->ReleaseByteArrayElements(env, data, (jbyte *) pData, mode); break; case DT_SHORT: - (*env)->ReleaseShortArrayElements(env, data, (jshort *) pData, 0); + (*env)->ReleaseShortArrayElements(env, data, (jshort *) pData, mode); break; case DT_INT: - (*env)->ReleaseIntArrayElements(env, data, (jint *) pData, 0); + (*env)->ReleaseIntArrayElements(env, data, (jint *) pData, mode); break; case DT_DOUBLE: - (*env)->ReleaseDoubleArrayElements(env, data, (jdouble *) pData, 0); + (*env)->ReleaseDoubleArrayElements(env, data, (jdouble *) pData, mode); break; } } @@ -542,7 +543,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert void *outputBuffer = getILData(env, dstData, dstDType); if (outputBuffer == NULL) { - releaseILData(env, inputBuffer, srcDType, srcData); + releaseILData(env, inputBuffer, srcDType, srcData, JNI_ABORT); // An exception should have already been thrown. return; } @@ -560,8 +561,8 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert } } - releaseILData(env, inputBuffer, srcDType, srcData); - releaseILData(env, outputBuffer, dstDType, dstData); + releaseILData(env, inputBuffer, srcDType, srcData, JNI_ABORT); + releaseILData(env, outputBuffer, dstDType, dstData, 0); } /* -- GitLab From 3a13425bc9088cbb6d95e1a46248d7eba27fb1a6 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Fri, 11 Feb 2022 08:46:55 +0000 Subject: [PATCH 208/400] 8072070: Improve interpreter stack banging Reviewed-by: xliu, coleenp, mdoerr --- .../x86/templateInterpreterGenerator_x86.cpp | 56 ++++++-- src/hotspot/share/runtime/javaCalls.cpp | 4 +- src/hotspot/share/runtime/os.cpp | 6 +- src/hotspot/share/runtime/stackOverflow.hpp | 123 +++++++++++++++++- src/hotspot/share/runtime/thread.hpp | 6 + 5 files changed, 173 insertions(+), 22 deletions(-) diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp index a4e86ff4202..cc365f70426 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -713,23 +713,59 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) { } void TemplateInterpreterGenerator::bang_stack_shadow_pages(bool native_call) { - // Quick & dirty stack overflow checking: bang the stack & handle trap. + // See more discussion in stackOverflow.hpp. + // Note that we do the banging after the frame is setup, since the exception // handling code expects to find a valid interpreter frame on the stack. // Doing the banging earlier fails if the caller frame is not an interpreter // frame. // (Also, the exception throwing code expects to unlock any synchronized - // method receiever, so do the banging after locking the receiver.) + // method receiver, so do the banging after locking the receiver.) - // Bang each page in the shadow zone. We can't assume it's been done for - // an interpreter frame with greater than a page of locals, so each page - // needs to be checked. Only true for non-native. + const int shadow_zone_size = checked_cast(StackOverflow::stack_shadow_zone_size()); const int page_size = os::vm_page_size(); - const int n_shadow_pages = ((int)StackOverflow::stack_shadow_zone_size()) / page_size; - const int start_page = native_call ? n_shadow_pages : 1; - for (int pages = start_page; pages <= n_shadow_pages; pages++) { - __ bang_stack_with_offset(pages*page_size); + const int n_shadow_pages = shadow_zone_size / page_size; + + const Register thread = NOT_LP64(rsi) LP64_ONLY(r15_thread); +#ifndef _LP64 + __ push(thread); + __ get_thread(thread); +#endif + +#ifdef ASSERT + Label L_good_limit; + __ cmpptr(Address(thread, JavaThread::shadow_zone_safe_limit()), (int32_t)NULL_WORD); + __ jcc(Assembler::notEqual, L_good_limit); + __ stop("shadow zone safe limit is not initialized"); + __ bind(L_good_limit); + + Label L_good_watermark; + __ cmpptr(Address(thread, JavaThread::shadow_zone_growth_watermark()), (int32_t)NULL_WORD); + __ jcc(Assembler::notEqual, L_good_watermark); + __ stop("shadow zone growth watermark is not initialized"); + __ bind(L_good_watermark); +#endif + + Label L_done; + + __ cmpptr(rsp, Address(thread, JavaThread::shadow_zone_growth_watermark())); + __ jcc(Assembler::above, L_done); + + for (int p = 1; p <= n_shadow_pages; p++) { + __ bang_stack_with_offset(p*page_size); } + + // Record a new watermark, unless the update is above the safe limit. + // Otherwise, the next time around a check above would pass the safe limit. + __ cmpptr(rsp, Address(thread, JavaThread::shadow_zone_safe_limit())); + __ jccb(Assembler::belowEqual, L_done); + __ movptr(Address(thread, JavaThread::shadow_zone_growth_watermark()), rsp); + + __ bind(L_done); + +#ifndef _LP64 + __ pop(thread); +#endif } // Interpreter stub for calling a native method. (asm interpreter) diff --git a/src/hotspot/share/runtime/javaCalls.cpp b/src/hotspot/share/runtime/javaCalls.cpp index 5390c5f6eaf..978fd20e0dd 100644 --- a/src/hotspot/share/runtime/javaCalls.cpp +++ b/src/hotspot/share/runtime/javaCalls.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -380,7 +380,7 @@ void JavaCalls::call_helper(JavaValue* result, const methodHandle& method, JavaC // Check that there are shadow pages available before changing thread state // to Java. Calculate current_stack_pointer here to make sure - // stack_shadow_pages_available() and bang_stack_shadow_pages() use the same sp. + // stack_shadow_pages_available() and map_stack_shadow_pages() use the same sp. address sp = os::current_stack_pointer(); if (!os::stack_shadow_pages_available(THREAD, method, sp)) { // Throw stack overflow exception with preinitialized exception. diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index a85be30ec48..f86396beada 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -1384,7 +1384,7 @@ char** os::split_path(const char* path, size_t* elements, size_t file_name_lengt // pages, false otherwise. bool os::stack_shadow_pages_available(Thread *thread, const methodHandle& method, address sp) { if (!thread->is_Java_thread()) return false; - // Check if we have StackShadowPages above the yellow zone. This parameter + // Check if we have StackShadowPages above the guard zone. This parameter // is dependent on the depth of the maximum VM call stack possible from // the handler for stack overflow. 'instanceof' in the stack overflow // handler or a println uses at least 8k stack of VM and native code @@ -1392,9 +1392,7 @@ bool os::stack_shadow_pages_available(Thread *thread, const methodHandle& method const int framesize_in_bytes = Interpreter::size_top_interpreter_activation(method()) * wordSize; - address limit = JavaThread::cast(thread)->stack_end() + - (StackOverflow::stack_guard_zone_size() + StackOverflow::stack_shadow_zone_size()); - + address limit = JavaThread::cast(thread)->stack_overflow_state()->shadow_zone_safe_limit(); return sp > (limit + framesize_in_bytes); } diff --git a/src/hotspot/share/runtime/stackOverflow.hpp b/src/hotspot/share/runtime/stackOverflow.hpp index c8e4249ab25..5a8a88c4fcd 100644 --- a/src/hotspot/share/runtime/stackOverflow.hpp +++ b/src/hotspot/share/runtime/stackOverflow.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -51,6 +51,8 @@ class StackOverflow { _stack_guard_state(stack_guard_unused), _stack_overflow_limit(nullptr), _reserved_stack_activation(nullptr), // stack base not known yet + _shadow_zone_safe_limit(nullptr), + _shadow_zone_growth_watermark(nullptr), _stack_base(nullptr), _stack_end(nullptr) {} // Initialization after thread is started. @@ -58,6 +60,7 @@ class StackOverflow { _stack_base = base; _stack_end = end; set_stack_overflow_limit(); + set_shadow_zone_limits(); set_reserved_stack_activation(base); } private: @@ -68,6 +71,8 @@ class StackOverflow { // We load it from here to simplify the stack overflow check in assembly. address _stack_overflow_limit; address _reserved_stack_activation; + address _shadow_zone_safe_limit; + address _shadow_zone_growth_watermark; // Support for stack overflow handling, copied down from thread. address _stack_base; @@ -77,6 +82,9 @@ class StackOverflow { address stack_base() const { assert(_stack_base != nullptr, "Sanity check"); return _stack_base; } // Stack overflow support + // -------------------------------------------------------------------------------- + // + // The Java thread stack is structured as follows: // // (low addresses) // @@ -95,11 +103,24 @@ class StackOverflow { // | | // | reserved zone | // | | - // -- <-- stack_reserved_zone_base() --- --- - // /|\ shadow <-- stack_overflow_limit() (somewhere in here) - // | zone - // \|/ size - // some untouched memory --- + // -- <-- stack_reserved_zone_base() --- --- + // ^ + // | <-- stack_overflow_limit() [somewhere in here] + // | shadow + // | zone + // | size + // v + // --- <-- shadow_zone_safe_limit() + // (Here and below: not yet touched stack) + // + // + // (Here and below: touched at least once) --- + // ^ + // | shadow + // | zone + // | size + // v + // --- <-- shadow_zone_growth_watermark() // // // -- @@ -120,6 +141,84 @@ class StackOverflow { // // (high addresses) // + // + // The stack overflow mechanism detects overflows by touching ("banging") the stack + // ahead of current stack pointer (SP). The entirety of guard zone is memory protected, + // therefore such access would trap when touching the guard zone, and one of the following + // things would happen. + // + // Access in the red zone: unrecoverable stack overflow. Crash the VM, generate a report, + // crash dump, and other diagnostics. + // + // Access in the yellow zone: recoverable, reportable stack overflow. Create and throw + // a StackOverflowError, remove the protection of yellow zone temporarily to let exception + // handlers run. If exception handlers themselves run out of stack, they will crash VM due + // to access to red zone. + // + // Access in the reserved zone: recoverable, reportable, transparent for privileged methods + // stack overflow. Perform a stack walk to check if there's a method annotated with + // @ReservedStackAccess on the call stack. If such method is found, remove the protection of + // reserved zone temporarily, and let the method run. If not, handle the access like a yellow + // zone trap. + // + // The banging itself happens within the "shadow zone" that extends from the current SP. + // + // The goals for properly implemented shadow zone banging are: + // + // a) Allow native/VM methods to run without stack overflow checks within some reasonable + // headroom. Default shadow zone size should accommodate the largest normally expected + // native/VM stack use. + // b) Guarantee the stack overflow checks work even if SP is dangerously close to guard zone. + // If SP is very low, banging at the edge of shadow zone (SP+shadow-zone-size) can slip + // into adjacent thread stack, or even into other readable memory. This would potentially + // pass the check by accident. + // c) Allow for incremental stack growth on some OSes. This is enabled by handling traps + // from not yet committed thread stacks, even outside the guard zone. The banging should + // not allow uncommitted "gaps" on thread stack. See for example the uses of + // os::map_stack_shadow_pages(). + // d) Make sure the stack overflow trap happens in the code that is known to runtime, so + // the traps can be reasonably handled: handling a spurious trap from executing Java code + // is hard, while properly handling the trap from VM/native code is nearly impossible. + // + // The simplest code that satisfies all these requirements is banging the shadow zone + // page by page at every Java/native method entry. + // + // While that code is sufficient, it comes with the large performance cost. This performance + // cost can be reduced by several *optional* techniques: + // + // 1. Guarantee that stack would not take another page. If so, the current bang was + // enough to verify we are not near the guard zone. This kind of insight is usually only + // available for compilers that can know the size of the frame exactly. + // + // Examples: PhaseOutput::need_stack_bang. + // + // 2. Check the current SP in relation to shadow zone safe limit. + // + // Define "safe limit" as the highest SP where banging would not touch the guard zone. + // Then, do the page-by-page bang only if current SP is above that safe limit, OR some + // OS-es need it to get the stack mapped. + // + // Examples: AbstractAssembler::generate_stack_overflow_check, JavaCalls::call_helper, + // os::stack_shadow_pages_available, os::map_stack_shadow_pages and their uses. + // + // 3. Check the current SP in relation to the shadow zone growth watermark. + // + // Define "shadow zone growth watermark" as the highest SP where we banged already. + // Invariant: growth watermark is always above the safe limit, which allows testing + // for watermark and safe limit at the same time in the most frequent case. + // + // Easy and overwhelmingly frequent case: SP is above the growth watermark, and + // by extension above the safe limit. In this case, we know that the guard zone is far away + // (safe limit), and that the stack was banged before for stack growth (growth watermark). + // Therefore, we can skip the banging altogether. + // + // Harder cases: SP is below the growth watermark. In might be due to two things: + // we have not banged the stack for growth (below growth watermark only), or we are + // close to guard zone (also below safe limit). Do the full banging. Once done, we + // can adjust the growth watermark, thus recording the bang for stack growth had + // happened. + // + // Examples: TemplateInterpreterGenerator::bang_stack_shadow_pages on x86 and others. private: // These values are derived from flags StackRedPages, StackYellowPages, @@ -189,6 +288,11 @@ class StackOverflow { return _stack_shadow_zone_size; } + address shadow_zone_safe_limit() const { + assert(_shadow_zone_safe_limit != nullptr, "Don't call this before the field is initialized."); + return _shadow_zone_safe_limit; + } + void create_stack_guard_pages(); void remove_stack_guard_pages(); @@ -242,6 +346,13 @@ class StackOverflow { _stack_overflow_limit = stack_end() + MAX2(stack_guard_zone_size(), stack_shadow_zone_size()); } + + void set_shadow_zone_limits() { + _shadow_zone_safe_limit = + stack_end() + stack_guard_zone_size() + stack_shadow_zone_size(); + _shadow_zone_growth_watermark = + stack_base(); + } }; #endif // SHARE_RUNTIME_STACKOVERFLOW_HPP diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp index 9ceb17f7af1..151d487355a 100644 --- a/src/hotspot/share/runtime/thread.hpp +++ b/src/hotspot/share/runtime/thread.hpp @@ -1299,6 +1299,12 @@ class JavaThread: public Thread { static ByteSize reserved_stack_activation_offset() { return byte_offset_of(JavaThread, _stack_overflow_state._reserved_stack_activation); } + static ByteSize shadow_zone_safe_limit() { + return byte_offset_of(JavaThread, _stack_overflow_state._shadow_zone_safe_limit); + } + static ByteSize shadow_zone_growth_watermark() { + return byte_offset_of(JavaThread, _stack_overflow_state._shadow_zone_growth_watermark); + } static ByteSize suspend_flags_offset() { return byte_offset_of(JavaThread, _suspend_flags); } -- GitLab From 90939cb80193c671cae635b7a4e41bd2e6bcdbd5 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Fri, 11 Feb 2022 09:05:50 +0000 Subject: [PATCH 209/400] 8281626: NonblockingQueue should use nullptr Reviewed-by: shade, dholmes --- .../share/utilities/nonblockingQueue.hpp | 10 +-- .../utilities/nonblockingQueue.inline.hpp | 68 +++++++++---------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/hotspot/share/utilities/nonblockingQueue.hpp b/src/hotspot/share/utilities/nonblockingQueue.hpp index a271aaa38d8..7ba4c80cfd6 100644 --- a/src/hotspot/share/utilities/nonblockingQueue.hpp +++ b/src/hotspot/share/utilities/nonblockingQueue.hpp @@ -45,7 +45,7 @@ // // A queue may temporarily appear to be empty even though elements have been // added and not removed. For example, after running the following program, -// the value of r may be NULL. +// the value of r may be nullptr. // // thread1: q.push(a); r = q.pop(); // thread2: q.push(b); @@ -105,15 +105,15 @@ public: // Thread-safe attempt to remove and return the first object in the queue. // Returns true if successful. If successful then *node_ptr is the former - // first object, or NULL if the queue was empty. If unsuccessful, because + // first object, or nullptr if the queue was empty. If unsuccessful, because // of contention with a concurrent modification, then returns false with // the value of *node_ptr unspecified. Subject to ABA behavior; callers // must ensure usage is safe. inline bool try_pop(T** node_ptr); - // Thread-safe remove and return the first object in the queue, or NULL if - // the queue was empty. This just iterates on try_pop() until it - // succeeds, returning the (possibly NULL) element obtained from that. + // Thread-safe remove and return the first object in the queue, or nullptr + // if the queue was empty. This just iterates on try_pop() until it + // succeeds, returning the (possibly nullptr) element obtained from that. // Subject to ABA behavior; callers must ensure usage is safe. inline T* pop(); diff --git a/src/hotspot/share/utilities/nonblockingQueue.inline.hpp b/src/hotspot/share/utilities/nonblockingQueue.inline.hpp index 2ecb1663e45..f4e86c6fe65 100644 --- a/src/hotspot/share/utilities/nonblockingQueue.inline.hpp +++ b/src/hotspot/share/utilities/nonblockingQueue.inline.hpp @@ -40,13 +40,13 @@ void NonblockingQueue::set_next(T& node, T* new_next) { } template -NonblockingQueue::NonblockingQueue() : _head(NULL), _tail(NULL) {} +NonblockingQueue::NonblockingQueue() : _head(nullptr), _tail(nullptr) {} #ifdef ASSERT template NonblockingQueue::~NonblockingQueue() { - assert(_head == NULL, "precondition"); - assert(_tail == NULL, "precondition"); + assert(_head == nullptr, "precondition"); + assert(_tail == nullptr, "precondition"); } #endif @@ -61,7 +61,7 @@ T* NonblockingQueue::end_marker() const { template T* NonblockingQueue::first() const { T* head = Atomic::load(&_head); - return head == NULL ? end_marker() : head; + return head == nullptr ? end_marker() : head; } template @@ -71,7 +71,7 @@ bool NonblockingQueue::is_end(const T* entry) const { template bool NonblockingQueue::empty() const { - return Atomic::load(&_head) == NULL; + return Atomic::load(&_head) == nullptr; } template @@ -85,8 +85,8 @@ size_t NonblockingQueue::length() const { // An append operation atomically exchanges the new tail with the queue tail. // It then sets the "next" value of the old tail to the head of the list being -// appended. If the old tail is NULL then the queue was empty, then the head -// of the list being appended is instead stored in the queue head. +// appended. If the old tail is nullptr then the queue was empty, then the +// head of the list being appended is instead stored in the queue head. // // This means there is a period between the exchange and the old tail update // where the queue sequence is split into two parts, the list from the queue @@ -100,17 +100,17 @@ size_t NonblockingQueue::length() const { // is both the head and the tail of the list being appended. template void NonblockingQueue::append(T& first, T& last) { - assert(next(last) == NULL, "precondition"); + assert(next(last) == nullptr, "precondition"); // Make last the new end of the queue. Any further push/appends will // extend after last. We will try to extend from the previous end of // queue. set_next(last, end_marker()); T* old_tail = Atomic::xchg(&_tail, &last); - if (old_tail == NULL) { - // If old_tail is NULL then the queue was empty, and _head must also be - // NULL. The correctness of this assertion depends on try_pop clearing + if (old_tail == nullptr) { + // If old_tail is nullptr then the queue was empty, and _head must also be + // nullptr. The correctness of this assertion depends on try_pop clearing // first _head then _tail when taking the last entry. - assert(Atomic::load(&_head) == NULL, "invariant"); + assert(Atomic::load(&_head) == nullptr, "invariant"); // Fall through to common update of _head. } else if (is_end(Atomic::cmpxchg(next_ptr(*old_tail), end_marker(), &first))) { // Successfully extended the queue list from old_tail to first. No @@ -126,10 +126,10 @@ void NonblockingQueue::append(T& first, T& last) { return; } else { // A concurrent try_pop has claimed old_tail, so it is no longer in the - // list. The queue was logically empty. _head is either NULL or + // list. The queue was logically empty. _head is either nullptr or // old_tail, depending on how far try_pop operations have progressed. DEBUG_ONLY(T* old_head = Atomic::load(&_head);) - assert((old_head == NULL) || (old_head == old_tail), "invariant"); + assert((old_head == nullptr) || (old_head == old_tail), "invariant"); // Fall through to common update of _head. } // The queue was empty, and first should become the new _head. The queue @@ -142,8 +142,8 @@ bool NonblockingQueue::try_pop(T** node_ptr) { // We only need memory_order_consume. Upgrade it to "load_acquire" // as the memory_order_consume API is not ready for use yet. T* old_head = Atomic::load_acquire(&_head); - if (old_head == NULL) { - *node_ptr = NULL; + if (old_head == nullptr) { + *node_ptr = nullptr; return true; // Queue is empty. } @@ -152,7 +152,7 @@ bool NonblockingQueue::try_pop(T** node_ptr) { // [Clause 1] // There are several cases for next_node. // (1) next_node is the extension of the queue's list. - // (2) next_node is NULL, because a competing try_pop took old_head. + // (2) next_node is nullptr, because a competing try_pop took old_head. // (3) next_node is the extension of some unrelated list, because a // competing try_pop took old_head and put it in some other list. // @@ -166,16 +166,16 @@ bool NonblockingQueue::try_pop(T** node_ptr) { // the race and claimed old_head. This can happen for any of the // next_node cases. return false; - } else if (next_node == NULL) { + } else if (next_node == nullptr) { // [Clause 1b] // The cmpxchg to advance the list succeeded, but a concurrent try_pop // has already claimed old_head (see [Clause 2] - old_head was the last // entry in the list) by nulling old_head's next field. The advance set - // _head to NULL, "helping" the competing try_pop. _head will remain - // NULL until a subsequent push/append. This is a lost race, and we + // _head to nullptr, "helping" the competing try_pop. _head will remain + // nullptr until a subsequent push/append. This is a lost race, and we // report it as such for consistency, though we could report the queue // was empty. We don't attempt to further help [Clause 2] by also - // trying to set _tail to NULL, as that would just ensure that one or + // trying to set _tail to nullptr, as that would just ensure that one or // the other cmpxchg is a wasted failure. return false; } else { @@ -183,15 +183,15 @@ bool NonblockingQueue::try_pop(T** node_ptr) { // Successfully advanced the list and claimed old_head. next_node was // in the extension of the queue's list. Return old_head after // unlinking it from next_node. - set_next(*old_head, NULL); + set_next(*old_head, nullptr); *node_ptr = old_head; return true; } - } else if (is_end(Atomic::cmpxchg(next_ptr(*old_head), next_node, (T*)NULL))) { + } else if (is_end(Atomic::cmpxchg(next_ptr(*old_head), next_node, (T*)nullptr))) { // [Clause 2] // Old_head was the last entry and we've claimed it by setting its next - // value to NULL. However, this leaves the queue in disarray. Fix up + // value to nullptr. However, this leaves the queue in disarray. Fix up // the queue, possibly in conjunction with other concurrent operations. // Any further try_pops will consider the queue empty until a // push/append completes by installing a new head. @@ -200,16 +200,16 @@ bool NonblockingQueue::try_pop(T** node_ptr) { // dealing with _head first gives a stronger invariant in append, and is // also consistent with [Clause 1b]. - // Attempt to change the queue head from old_head to NULL. Failure of the - // cmpxchg indicates a concurrent operation updated _head first. That + // Attempt to change the queue head from old_head to nullptr. Failure of + // the cmpxchg indicates a concurrent operation updated _head first. That // could be either a push/append or a try_pop in [Clause 1b]. - Atomic::cmpxchg(&_head, old_head, (T*)NULL); + Atomic::cmpxchg(&_head, old_head, (T*)nullptr); - // Attempt to change the queue tail from old_head to NULL. Failure of the - // cmpxchg indicates that a concurrent push/append updated _tail first. + // Attempt to change the queue tail from old_head to nullptr. Failure of + // the cmpxchg indicates that a concurrent push/append updated _tail first. // That operation will eventually recognize the old tail (our old_head) is // no longer in the list and update _head from the list being appended. - Atomic::cmpxchg(&_tail, old_head, (T*)NULL); + Atomic::cmpxchg(&_tail, old_head, (T*)nullptr); // The queue has been restored to order, and we can return old_head. *node_ptr = old_head; @@ -226,7 +226,7 @@ bool NonblockingQueue::try_pop(T** node_ptr) { template T* NonblockingQueue::pop() { - T* result = NULL; + T* result = nullptr; // Typically try_pop() will succeed without retrying many times, thus we // omit SpinPause in the loop body. SpinPause or yield may be worthwhile // in rare, highly contended cases, and client code could implement such @@ -238,10 +238,10 @@ T* NonblockingQueue::pop() { template Pair NonblockingQueue::take_all() { T* tail = Atomic::load(&_tail); - if (tail != NULL) set_next(*tail, NULL); // Clear end marker. + if (tail != nullptr) set_next(*tail, nullptr); // Clear end marker. Pair result(Atomic::load(&_head), tail); - Atomic::store(&_head, (T*)NULL); - Atomic::store(&_tail, (T*)NULL); + Atomic::store(&_head, (T*)nullptr); + Atomic::store(&_tail, (T*)nullptr); return result; } -- GitLab From 4d64076058a4ec5df101b06572195ed5fdee6f64 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Fri, 11 Feb 2022 09:39:10 +0000 Subject: [PATCH 210/400] 8047749: javadoc for getPathBounds() in TreeUI and BasicTreeUI is incorrect Reviewed-by: aivanov --- src/java.desktop/share/classes/javax/swing/plaf/TreeUI.java | 2 +- .../share/classes/javax/swing/plaf/basic/BasicTreeUI.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/TreeUI.java b/src/java.desktop/share/classes/javax/swing/plaf/TreeUI.java index 22e8a10052b..40b575f1b2c 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/TreeUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/TreeUI.java @@ -45,7 +45,7 @@ public abstract class TreeUI extends ComponentUI /** * Returns the Rectangle enclosing the label portion that the * last item in path will be drawn into. Will return null if - * any component in path is currently valid. + * any component in path is currently invalid. * * @param tree the {@code JTree} for {@code path} * @param path the {@code TreePath} identifying the node diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTreeUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTreeUI.java index 2626b1c9585..d02a53315af 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTreeUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTreeUI.java @@ -665,7 +665,7 @@ public class BasicTreeUI extends TreeUI /** * Returns the Rectangle enclosing the label portion that the * last item in path will be drawn into. Will return null if - * any component in path is currently valid. + * any component in path is currently invalid. */ public Rectangle getPathBounds(JTree tree, TreePath path) { if(tree != null && treeState != null) { -- GitLab From d254cf28c5e72bd9b8de863b831015237640ca25 Mon Sep 17 00:00:00 2001 From: Jie Fu Date: Fri, 11 Feb 2022 11:39:54 +0000 Subject: [PATCH 211/400] 8281638: jfr/event/allocation tests fail with release VMs after JDK-8281318 due to lack of -XX:+UnlockDiagnosticVMOptions Reviewed-by: shade --- .../allocation/TestObjectAllocationInNewTLABEvent.java | 6 +++--- .../allocation/TestObjectAllocationOutsideTLABEvent.java | 6 +++--- .../TestObjectAllocationSampleEventThrottling.java | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationInNewTLABEvent.java b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationInNewTLABEvent.java index cb70c0ba324..6dbd51b1386 100644 --- a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationInNewTLABEvent.java +++ b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationInNewTLABEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -42,10 +42,10 @@ import sun.hotspot.WhiteBox; * @build sun.hotspot.WhiteBox * * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. * -XX:+UseTLAB -XX:TLABSize=100k -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=1 * jdk.jfr.event.allocation.TestObjectAllocationInNewTLABEvent - * @run main/othervm -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. * -XX:+UseTLAB -XX:TLABSize=100k -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=1 * -Xint * jdk.jfr.event.allocation.TestObjectAllocationInNewTLABEvent diff --git a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationOutsideTLABEvent.java b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationOutsideTLABEvent.java index 70bf4518f08..87c3b29af42 100644 --- a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationOutsideTLABEvent.java +++ b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationOutsideTLABEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -42,10 +42,10 @@ import sun.hotspot.WhiteBox; * @build sun.hotspot.WhiteBox * * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. * -XX:+UseTLAB -XX:TLABSize=90k -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=256 * jdk.jfr.event.allocation.TestObjectAllocationOutsideTLABEvent - * @run main/othervm -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. * -XX:+UseTLAB -XX:TLABSize=90k -XX:-ResizeTLAB -XX:TLABRefillWasteFraction=256 * -Xint * jdk.jfr.event.allocation.TestObjectAllocationOutsideTLABEvent diff --git a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEventThrottling.java b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEventThrottling.java index a10b6e2b56a..5049acc229c 100644 --- a/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEventThrottling.java +++ b/test/jdk/jdk/jfr/event/allocation/TestObjectAllocationSampleEventThrottling.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -44,7 +44,7 @@ import sun.hotspot.WhiteBox; * @build sun.hotspot.WhiteBox * * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox - * @run main/othervm -XX:+WhiteBoxAPI -Xbootclasspath/a:. + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. * -XX:+UseTLAB -XX:TLABSize=2k -XX:-ResizeTLAB * jdk.jfr.event.allocation.TestObjectAllocationSampleEventThrottling */ -- GitLab From 4ff5824f5bc13826d2eae1c83094acfcccdb7b8f Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Fri, 11 Feb 2022 12:11:29 +0000 Subject: [PATCH 212/400] 8281100: Spurious "variable might not have been initialized" with sealed class switch Reviewed-by: vromero --- .../com/sun/tools/javac/comp/Flow.java | 32 ++++---- .../com/sun/tools/javac/tree/JCTree.java | 2 + .../com/sun/tools/javac/tree/TreeInfo.java | 6 ++ .../tools/javac/patterns/Exhaustiveness.java | 81 ++++++++++++++++++- 4 files changed, 104 insertions(+), 17 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java index 1346d141bb7..db64097c02d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java @@ -664,10 +664,7 @@ public class Flow { ListBuffer prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); scan(tree.selector); - boolean exhaustiveSwitch = tree.patternSwitch || - tree.cases.stream() - .flatMap(c -> c.labels.stream()) - .anyMatch(l -> TreeInfo.isNull(l)); + boolean exhaustiveSwitch = TreeInfo.expectedExhaustive(tree); Set constants = exhaustiveSwitch ? new HashSet<>() : null; for (List l = tree.cases; l.nonEmpty(); l = l.tail) { alive = Liveness.ALIVE; @@ -689,10 +686,13 @@ public class Flow { l.tail.head.pos(), Warnings.PossibleFallThroughIntoCase); } - if (!tree.hasTotalPattern && exhaustiveSwitch && - !TreeInfo.isErrorEnumSwitch(tree.selector, tree.cases) && - (constants == null || !isExhaustive(tree.selector.pos(), tree.selector.type, constants))) { - log.error(tree, Errors.NotExhaustiveStatement); + tree.isExhaustive = tree.hasTotalPattern || + TreeInfo.isErrorEnumSwitch(tree.selector, tree.cases); + if (exhaustiveSwitch) { + tree.isExhaustive |= isExhaustive(tree.selector.pos(), tree.selector.type, constants); + if (!tree.isExhaustive) { + log.error(tree, Errors.NotExhaustiveStatement); + } } if (!tree.hasTotalPattern) { alive = Liveness.ALIVE; @@ -725,8 +725,10 @@ public class Flow { } } } - if (!tree.hasTotalPattern && !TreeInfo.isErrorEnumSwitch(tree.selector, tree.cases) && - !isExhaustive(tree.selector.pos(), tree.selector.type, constants)) { + tree.isExhaustive = tree.hasTotalPattern || + TreeInfo.isErrorEnumSwitch(tree.selector, tree.cases) || + isExhaustive(tree.selector.pos(), tree.selector.type, constants); + if (!tree.isExhaustive) { log.error(tree, Errors.NotExhaustive); } alive = prevAlive; @@ -2432,15 +2434,15 @@ public class Flow { } public void visitSwitch(JCSwitch tree) { - handleSwitch(tree, tree.selector, tree.cases, tree.hasTotalPattern); + handleSwitch(tree, tree.selector, tree.cases, tree.isExhaustive); } public void visitSwitchExpression(JCSwitchExpression tree) { - handleSwitch(tree, tree.selector, tree.cases, tree.hasTotalPattern); + handleSwitch(tree, tree.selector, tree.cases, tree.isExhaustive); } private void handleSwitch(JCTree tree, JCExpression selector, - List cases, boolean hasTotalPattern) { + List cases, boolean isExhaustive) { ListBuffer prevPendingExits = pendingExits; pendingExits = new ListBuffer<>(); int nextadrPrev = nextadr; @@ -2478,10 +2480,10 @@ public class Flow { addVars(c.stats, initsSwitch, uninitsSwitch); // Warn about fall-through if lint switch fallthrough enabled. } - if (!hasTotalPattern) { + if (!isExhaustive) { if (tree.hasTag(SWITCH_EXPRESSION)) { markDead(); - } else { + } else if (tree.hasTag(SWITCH) && !TreeInfo.expectedExhaustive((JCSwitch) tree)) { inits.assign(initsSwitch); uninits.assign(uninits.andSet(uninitsSwitch)); } diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java index a6d3de24e3c..cc66127baa4 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -1285,6 +1285,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { /** Position of closing brace, optional. */ public int endpos = Position.NOPOS; public boolean hasTotalPattern; + public boolean isExhaustive; public boolean patternSwitch; protected JCSwitch(JCExpression selector, List cases) { this.selector = selector; @@ -1371,6 +1372,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { /** Position of closing brace, optional. */ public int endpos = Position.NOPOS; public boolean hasTotalPattern; + public boolean isExhaustive; public boolean patternSwitch; protected JCSwitchExpression(JCExpression selector, List cases) { this.selector = selector; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java index ee25802ca86..355e19c8826 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java @@ -1384,4 +1384,10 @@ public class TreeInfo { public record PatternPrimaryType(Type type, boolean unconditional) {} + public static boolean expectedExhaustive(JCSwitch tree) { + return tree.patternSwitch || + tree.cases.stream() + .flatMap(c -> c.labels.stream()) + .anyMatch(l -> TreeInfo.isNull(l)); + } } diff --git a/test/langtools/tools/javac/patterns/Exhaustiveness.java b/test/langtools/tools/javac/patterns/Exhaustiveness.java index b7db66c3231..75121a97eca 100644 --- a/test/langtools/tools/javac/patterns/Exhaustiveness.java +++ b/test/langtools/tools/javac/patterns/Exhaustiveness.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8262891 8268871 8274363 + * @bug 8262891 8268871 8274363 8281100 * @summary Check exhaustiveness of switches over sealed types. * @library /tools/lib * @modules jdk.compiler/com.sun.tools.javac.api @@ -791,6 +791,82 @@ public class Exhaustiveness extends TestRunner { } } + @Test + public void testDefiniteAssignment(Path base) throws Exception { + doTest(base, + new String[]{""" + package lib; + public sealed interface S permits A, B {} + """, + """ + package lib; + public final class A implements S {} + """, + """ + package lib; + public final class B implements S {} + """}, + """ + package test; + import lib.*; + public class Test { + private void testStatement(S obj) { + int data; + switch (obj) { + case A a -> data = 0; + case B b -> data = 0; + }; + System.err.println(data); + } + private void testExpression(S obj) { + int data; + int v = switch (obj) { + case A a -> data = 0; + case B b -> data = 0; + }; + System.err.println(data); + } + private void testStatementNotExhaustive(S obj) { + int data; + switch (obj) { + case A a -> data = 0; + }; + System.err.println(data); + } + private void testExpressionNotExhaustive(S obj) { + int data; + int v = switch (obj) { + case A a -> data = 0; + }; + System.err.println(data); + } + private void testStatementErrorEnum(E e) { //"E" is intentionally unresolvable + int data; + switch (e) { + case A -> data = 0; + case B -> data = 0; + }; + System.err.println(data); + } + private void testExpressionErrorEnum(E e) { //"E" is intentionally unresolvable + int data; + int v = switch (e) { + case A -> data = 0; + case B -> data = 0; + }; + System.err.println(data); + } + } + """, + "Test.java:34:41: compiler.err.cant.resolve.location: kindname.class, E, , , (compiler.misc.location: kindname.class, test.Test, null)", + "Test.java:42:42: compiler.err.cant.resolve.location: kindname.class, E, , , (compiler.misc.location: kindname.class, test.Test, null)", + "Test.java:22:9: compiler.err.not.exhaustive.statement", + "Test.java:29:17: compiler.err.not.exhaustive", + "- compiler.note.preview.filename: Test.java, DEFAULT", + "- compiler.note.preview.recompile", + "4 errors"); + } + private void doTest(Path base, String[] libraryCode, String testCode, String... expectedErrors) throws IOException { Path current = base.resolve("."); Path libClasses = current.resolve("libClasses"); @@ -825,7 +901,8 @@ public class Exhaustiveness extends TestRunner { "-source", JAVA_VERSION, "-XDrawDiagnostics", "-Xlint:-preview", - "--class-path", libClasses.toString()) + "--class-path", libClasses.toString(), + "-XDshould-stop.at=FLOW") .outdir(classes) .files(tb.findJavaFiles(src)) .run(expectedErrors.length > 0 ? Task.Expect.FAIL : Task.Expect.SUCCESS) -- GitLab From f399ae558eabdce8960d339ef0758c023aeb89cc Mon Sep 17 00:00:00 2001 From: "lawrence.andrews" Date: Fri, 11 Feb 2022 15:33:17 +0000 Subject: [PATCH 213/400] 8202836: [macosx] test java/awt/Graphics/TextAAHintsTest.java fails Reviewed-by: prr, aivanov --- .../java/awt/Graphics/TextAAHintsTest.java | 132 +++++++++++++++--- 1 file changed, 110 insertions(+), 22 deletions(-) diff --git a/test/jdk/java/awt/Graphics/TextAAHintsTest.java b/test/jdk/java/awt/Graphics/TextAAHintsTest.java index 46fa6c28c9b..15fd5a63464 100644 --- a/test/jdk/java/awt/Graphics/TextAAHintsTest.java +++ b/test/jdk/java/awt/Graphics/TextAAHintsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -21,21 +21,44 @@ * questions. */ -/** +/* * @test * @bug 6263951 * @summary Text should be B&W, grayscale, and LCD. - * @run main/manual=yesno TextAAHintsTest + * @requires (os.family != "mac") + * @run main/manual TextAAHintsTest */ -import java.awt.*; -import java.awt.geom.*; -import java.awt.image.*; + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.ImageCapabilities; +import java.awt.Panel; +import java.awt.RenderingHints; +import java.awt.TextArea; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; public class TextAAHintsTest extends Component { - String black = "This text should be solid black"; - String gray = "This text should be gray scale anti-aliased"; - String lcd = "This text should be LCD sub-pixel text (coloured)."; + private static final String black = "This text should be solid black"; + private static final String gray = "This text should be gray scale anti-aliased"; + private static final String lcd = "This text should be LCD sub-pixel text (coloured)."; + private static final CountDownLatch countDownLatch = new CountDownLatch(1); + private static volatile String failureReason; + private static volatile boolean testPassed = false; + private static Frame frame; public void paint(Graphics g) { @@ -63,28 +86,24 @@ public class TextAAHintsTest extends Component { RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); g2d.drawString(black, 10, 20); - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); - g2d.drawString(black, 10, 35); - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); - g2d.drawString(gray, 10, 50); + g2d.drawString(gray, 10, 35); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - g2d.drawString(gray, 10, 65); + g2d.drawString(gray, 10, 50); /* For visual comparison, render grayscale with graphics AA off */ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - g2d.drawString(gray, 10, 80); + g2d.drawString(gray, 10, 65); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); - g2d.drawString(lcd, 10, 95); + g2d.drawString(lcd, 10, 80); } public void bufferedImageText(Graphics g) { @@ -139,11 +158,80 @@ public class TextAAHintsTest extends Component { return new Dimension(500,300); } - public static void main(String[] args) throws Exception { + public static void createTestUI() { + frame = new Frame("Composite and Text Test"); + TextAAHintsTest textAAHintsTestObject = new TextAAHintsTest(); + frame.add(textAAHintsTestObject, BorderLayout.NORTH); + + String instructions = """ + Note: Texts are rendered with different TEXT_ANTIALIASING & + VALUE_TEXT_ANTIALIAS. Text should be B&W, grayscale, and LCD. + Note: The results may be visually the same. + 1. Verify that first set of text are rendered correctly. + 2. Second set of text are created using BufferedImage of the first text. + 3. Third set of text are created using VolatileImage of the first text. + """; + TextArea instructionTextArea = new TextArea(instructions, 8, 50); + instructionTextArea.setEditable(false); + frame.add(instructionTextArea, BorderLayout.CENTER); + + Panel controlPanel = new Panel(); + Button passButton = new Button("Pass"); + passButton.addActionListener(e -> { + testPassed = true; + countDownLatch.countDown(); + frame.dispose(); + }); + Button failButton = new Button("Fail"); + failButton.addActionListener(e -> { + getFailureReason(); + testPassed = false; + countDownLatch.countDown(); + frame.dispose(); + }); + controlPanel.add(passButton); + controlPanel.add(failButton); + frame.add(controlPanel, BorderLayout.SOUTH); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + public static void getFailureReason() { + // Show dialog to read why the testcase was failed and append the + // testcase failure reason to the output + final Dialog dialog = new Dialog(frame, "TestCase" + + " failure reason", true); + TextArea textArea = new TextArea("", 5, 60, TextArea.SCROLLBARS_BOTH); + dialog.add(textArea, BorderLayout.CENTER); + + Button okButton = new Button("OK"); + okButton.addActionListener(e1 -> { + failureReason = textArea.getText(); + dialog.dispose(); + }); + Panel ctlPanel = new Panel(); + ctlPanel.add(okButton); + dialog.add(ctlPanel, BorderLayout.SOUTH); + dialog.setLocationRelativeTo(null); + dialog.pack(); + dialog.setVisible(true); + } + + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + EventQueue.invokeAndWait(TextAAHintsTest::createTestUI); + if (!countDownLatch.await(2, TimeUnit.MINUTES)) { + EventQueue.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + throw new RuntimeException("Timeout : No action was taken on the test."); + } - Frame f = new Frame("Composite and Text Test"); - f.add(new TextAAHintsTest(), BorderLayout.CENTER); - f.pack(); - f.setVisible(true); + if (!testPassed) { + throw new RuntimeException("Test failed : Reason : " + failureReason); + } } } + -- GitLab From e73ee0ca10b644600ee3747b901e5f69104d03df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jeli=C5=84ski?= Date: Fri, 11 Feb 2022 16:24:43 +0000 Subject: [PATCH 214/400] 8281259: MutableBigInteger subtraction could be simplified Reviewed-by: bpb --- .../share/classes/java/math/MutableBigInteger.java | 10 +++++----- .../org/openjdk/bench/java/math/BigIntegers.java | 11 +++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/java/math/MutableBigInteger.java b/src/java.base/share/classes/java/math/MutableBigInteger.java index 7d0ccbf1e09..91f710d67b8 100644 --- a/src/java.base/share/classes/java/math/MutableBigInteger.java +++ b/src/java.base/share/classes/java/math/MutableBigInteger.java @@ -945,13 +945,13 @@ class MutableBigInteger { x--; y--; diff = (a.value[x+a.offset] & LONG_MASK) - - (b.value[y+b.offset] & LONG_MASK) - ((int)-(diff>>32)); + (b.value[y+b.offset] & LONG_MASK) + (diff >> 32); result[rstart--] = (int)diff; } // Subtract remainder of longer number while (x > 0) { x--; - diff = (a.value[x+a.offset] & LONG_MASK) - ((int)-(diff>>32)); + diff = (a.value[x+a.offset] & LONG_MASK) + (diff >> 32); result[rstart--] = (int)diff; } @@ -986,13 +986,13 @@ class MutableBigInteger { while (y > 0) { x--; y--; diff = (a.value[a.offset+ x] & LONG_MASK) - - (b.value[b.offset+ y] & LONG_MASK) - ((int)-(diff>>32)); + (b.value[b.offset+ y] & LONG_MASK) + (diff >> 32); a.value[a.offset+x] = (int)diff; } // Subtract remainder of longer number - while (x > 0) { + while (diff < 0 && x > 0) { x--; - diff = (a.value[a.offset+ x] & LONG_MASK) - ((int)-(diff>>32)); + diff = (a.value[a.offset+ x] & LONG_MASK) + (diff >> 32); a.value[a.offset+x] = (int)diff; } diff --git a/test/micro/org/openjdk/bench/java/math/BigIntegers.java b/test/micro/org/openjdk/bench/java/math/BigIntegers.java index e2d563d8306..54056e2c5d4 100644 --- a/test/micro/org/openjdk/bench/java/math/BigIntegers.java +++ b/test/micro/org/openjdk/bench/java/math/BigIntegers.java @@ -207,4 +207,15 @@ public class BigIntegers { bh.consume(tmp); } } + + /** Invokes the gcd method of BigInteger with different values. */ + @Benchmark + @OperationsPerInvocation(TESTSIZE) + public void testGcd(Blackhole bh) { + for (int i = 0; i < TESTSIZE; i++) { + BigInteger i1 = shiftArray[TESTSIZE - i - 1]; + BigInteger i2 = shiftArray[i]; + bh.consume(i2.gcd(i1)); + } + } } -- GitLab From e75e8cd708ed478eda08c4a5c724e7e82f57d36e Mon Sep 17 00:00:00 2001 From: Yumin Qi Date: Fri, 11 Feb 2022 16:42:07 +0000 Subject: [PATCH 215/400] 8279997: check_for_dynamic_dump should not exit vm Reviewed-by: ccheung, iklam --- src/hotspot/share/cds/dynamicArchive.cpp | 5 +- src/hotspot/share/runtime/arguments.cpp | 4 ++ .../dynamicArchive/ArchiveConsistency.java | 27 ++++++++++- .../SharedArchiveFileOption.java | 48 ++++++++----------- 4 files changed, 54 insertions(+), 30 deletions(-) diff --git a/src/hotspot/share/cds/dynamicArchive.cpp b/src/hotspot/share/cds/dynamicArchive.cpp index 0ff6a017fed..00d586ffc4f 100644 --- a/src/hotspot/share/cds/dynamicArchive.cpp +++ b/src/hotspot/share/cds/dynamicArchive.cpp @@ -375,9 +375,10 @@ void DynamicArchive::check_for_dynamic_dump() { vm_exit_during_initialization("-XX:+RecordDynamicDumpInfo" __THEMSG, NULL); } else { assert(ArchiveClassesAtExit != nullptr, "sanity"); - vm_exit_during_initialization("-XX:ArchiveClassesAtExit" __THEMSG, NULL); -#undef __THEMSG + warning("-XX:ArchiveClassesAtExit" __THEMSG); } +#undef __THEMSG + DynamicDumpSharedSpaces = false; } } diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index c0f78eaaccf..7d0f1ddd4d3 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -3576,6 +3576,10 @@ void Arguments::init_shared_archive_paths() { SharedArchivePath = get_default_shared_archive_path(); SharedArchiveFile = nullptr; } else { + if (AutoCreateSharedArchive) { + warning("-XX:+AutoCreateSharedArchive is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info."); + AutoCreateSharedArchive = false; + } no_shared_spaces("invalid archive"); } } else if (base_archive_path == NULL) { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java index 33bfc2ef99e..0dcc0e3d7b0 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -202,5 +202,30 @@ public class ArchiveConsistency extends DynamicArchiveTestBase { runTwo(nonExistBase, nonExistTop, appJar, mainClass, isAuto ? 0 : 1, "Specified shared archive not found (" + nonExistBase + ")"); + + // following two tests: + // -Xshare:auto -XX:SharedArchiveFile=top.jsa, but base does not exist. + + new File(baseArchiveName).delete(); + + startTest("10. -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=" + topArchiveName); + run(topArchiveName, + "-Xshare:auto", + "-XX:+AutoCreateSharedArchive", + "-cp", + appJar, mainClass) + .assertNormalExit(output -> { + output.shouldContain("warning: -XX:+AutoCreateSharedArchive is unsupported when base CDS archive is not loaded"); + }); + + startTest("11. -XX:SharedArchiveFile=" + topArchiveName + " -XX:ArchiveClassesAtExit=" + getNewArchiveName("top3")); + run(topArchiveName, + "-Xshare:auto", + "-XX:ArchiveClassesAtExit=" + getNewArchiveName("top3"), + "-cp", + appJar, mainClass) + .assertNormalExit(output -> { + output.shouldContain("VM warning: -XX:ArchiveClassesAtExit is unsupported when base CDS archive is not loaded"); + }); } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/SharedArchiveFileOption.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/SharedArchiveFileOption.java index 1dd12b2b55d..d06bb8ef106 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/SharedArchiveFileOption.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/SharedArchiveFileOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -64,17 +64,6 @@ public class SharedArchiveFileOption extends DynamicArchiveTestBase { public void run() throws Exception; } - private static void mustSkipWith(String expectedMsg, MyRunnable r) throws Exception { - try { - r.run(); - } catch (SkippedException e) { - System.out.println("Got SkippedException: " + e); - Asserts.assertTrue(e.getMessage().contains(expectedMsg), "SkippedException must have message " + expectedMsg); - return; - } - Asserts.fail("SkippedException should have been thrown"); - } - private static void doTest(String baseArchiveName, String topArchiveName) throws Exception { String appJar = ClassFileInstaller.getJarPath("hello.jar"); String mainClass = "Hello"; @@ -205,25 +194,30 @@ public class SharedArchiveFileOption extends DynamicArchiveTestBase { output.shouldNotMatch("\\[cds,dynamic"); }); - { + { String ERROR = "-XX:ArchiveClassesAtExit is unsupported when base CDS archive is not loaded"; testcase("-XX:ArchiveClassesAtExit with CDS disabled (-Xshare:off)"); - mustSkipWith(ERROR, () -> { - dump2(baseArchiveName, - topArchiveName, - "-Xshare:off", - "-cp", appJar, mainClass); - }); + dump2(baseArchiveName, + topArchiveName, + "-Xshare:off", + "-Xlog:cds", + "-cp", appJar, mainClass) + .assertNormalExit(output -> { + output.shouldNotMatch("\\[cds,dynamic"); + output.shouldContain(ERROR); + }); testcase("-XX:ArchiveClassesAtExit with CDS disabled (Base archive cannot be mapped -- doesn't exist"); - mustSkipWith(ERROR, () -> { - dump2(baseArchiveName + ".notExist", - topArchiveName, - "-Xlog:cds", - "-Xshare:auto", - "-cp", appJar, mainClass); - }); + dump2(baseArchiveName + ".notExist", + topArchiveName, + "-Xlog:cds", + "-Xshare:auto", + "-cp", appJar, mainClass) + .assertNormalExit(output -> { + output.shouldNotMatch("\\[cds,dynamic"); + output.shouldContain(ERROR); + }); testcase("-XX:ArchiveClassesAtExit with CDS disabled (incompatible VM options)"); dump2(baseArchiveName, @@ -233,7 +227,7 @@ public class SharedArchiveFileOption extends DynamicArchiveTestBase { "-Xshare:auto", "-Xlog:cds", "-cp", appJar, mainClass) - .assertAbnormalExit("Cannot use the following option when dumping the shared archive: --patch-module"); + .assertAbnormalExit("Cannot use the following option when dumping the shared archive: --patch-module"); } { -- GitLab From 8886839779094f8a13c16be79f88052b2c79eeea Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Fri, 11 Feb 2022 17:15:04 +0000 Subject: [PATCH 216/400] 8281622: JFR: Improve documentation of jdk.jfr.Relational Reviewed-by: jbachorik --- .../share/classes/jdk/jfr/Relational.java | 9 ++++- .../jdk/jfr/snippet-files/Snippets.java | 40 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/Relational.java b/src/jdk.jfr/share/classes/jdk/jfr/Relational.java index f195d6ac67b..153346a19ac 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/Relational.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/Relational.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -32,6 +32,13 @@ import java.lang.annotation.Target; /** * Meta annotation for relational annotations, to be used on an annotation. + *

    + * The following example shows how a relational annotation can be created and + * used. The {@code Orderid} annotation indicates there is a relation between + * {@code OrderEvent} and {@code OrderLineEvent}. if they have the same ID, + * the order line belongs to the order. + * + * {@snippet class="Snippets" region="RelationalOverview"} * * @since 9 */ diff --git a/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java b/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java index ef95e2ffb35..ef2ff2f3670 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java @@ -42,6 +42,7 @@ import jdk.jfr.consumer.RecordingFile; import jdk.jfr.Configuration; import jdk.jfr.SettingDefinition; import jdk.jfr.SettingControl; +import jdk.jfr.Timestamp; import jdk.jfr.FlightRecorder; import jdk.jfr.consumer.RecordedEvent; @@ -260,6 +261,45 @@ public class Snippets { } // @end + // @start region="RelationalOverview" + @MetadataDefinition + @Relational + @Name("com.example.OrderId") + @Label("Order ID") + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface OrderId { + } + + @Name("com.example.Order") + @Label("Order") + @Category("Orders") + class OrderEvent extends Event { + @Label("Order ID") + @OrderId + long orderId; + + @Label("Order Date") + @Timestamp + long orderDate; + } + + @Name("com.example.OrderLine") + @Label("Order Line") + @Category("Orders") + class OrderLineEvent extends Event { + @Label("Order ID") + @OrderId + long orderId; + + @Label("Quantity") + long quantity; + + @Label("Product") + String product; + } + // @end + void RecordingnOverview() throws Exception { // @start region="RecordingOverview" Configuration c = Configuration.getConfiguration("default"); -- GitLab From c5ff6e45dee41b5703138d323a04c2c7973a08b9 Mon Sep 17 00:00:00 2001 From: Calvin Cheung Date: Fri, 11 Feb 2022 17:39:20 +0000 Subject: [PATCH 217/400] 8223077: module path support for dynamic CDS archive Reviewed-by: iklam, minqi --- src/hotspot/share/cds/filemap.cpp | 19 ++- src/hotspot/share/cds/filemap.hpp | 1 + src/hotspot/share/runtime/arguments.hpp | 2 +- .../jtreg/runtime/cds/appcds/TestCommon.java | 15 +- .../cds/appcds/dynamicArchive/ModulePath.java | 131 ++++++++++++++++++ .../UnsupportedBaseArchive.java | 23 +-- 6 files changed, 175 insertions(+), 16 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ModulePath.java diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 5128565803b..63ba7fb2893 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -963,6 +963,17 @@ void FileMapInfo::log_paths(const char* msg, int start_idx, int end_idx) { } } +bool FileMapInfo::check_module_paths() { + const char* rp = Arguments::get_property("jdk.module.path"); + int num_paths = Arguments::num_archives(rp); + if (num_paths != header()->num_module_paths()) { + return false; + } + ResourceMark rm; + GrowableArray* rp_array = create_path_array(rp); + return check_paths(header()->app_module_paths_start_index(), num_paths, rp_array); +} + bool FileMapInfo::validate_shared_path_table() { assert(UseSharedSpaces, "runtime only"); @@ -985,9 +996,11 @@ bool FileMapInfo::validate_shared_path_table() { "Dynamic archiving is disabled because base layer archive has appended boot classpath"); } if (header()->num_module_paths() > 0) { - DynamicDumpSharedSpaces = false; - warning( - "Dynamic archiving is disabled because base layer archive has module path"); + if (!check_module_paths()) { + DynamicDumpSharedSpaces = false; + warning( + "Dynamic archiving is disabled because base layer archive has a different module path"); + } } } diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp index e6655858187..f34fb4d7211 100644 --- a/src/hotspot/share/cds/filemap.hpp +++ b/src/hotspot/share/cds/filemap.hpp @@ -491,6 +491,7 @@ public: static void clone_shared_path_table(TRAPS); static int add_shared_classpaths(int i, const char* which, ClassPathEntry *cpe, TRAPS); static void check_nonempty_dir_in_shared_path_table(); + bool check_module_paths(); bool validate_shared_path_table(); void validate_non_existent_class_paths(); static void set_shared_path_table(FileMapInfo* info) { diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index 19bb12196e3..de6cf1a4d23 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp @@ -470,12 +470,12 @@ class Arguments : AllStatic { static char* SharedArchivePath; static char* SharedDynamicArchivePath; static size_t _default_SharedBaseAddress; // The default value specified in globals.hpp - static int num_archives(const char* archive_path) NOT_CDS_RETURN_(0); static void extract_shared_archive_paths(const char* archive_path, char** base_archive_path, char** top_archive_path) NOT_CDS_RETURN; public: + static int num_archives(const char* archive_path) NOT_CDS_RETURN_(0); // Parses the arguments, first phase static jint parse(const JavaVMInitArgs* args); // Parse a string for a unsigned integer. Returns true if value diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestCommon.java b/test/hotspot/jtreg/runtime/cds/appcds/TestCommon.java index a90512f73fb..959d43173d0 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/TestCommon.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/TestCommon.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -153,6 +153,19 @@ public class TestCommon extends CDSTestUtils { return out; } + public static OutputAnalyzer dumpBaseArchive(String baseArchiveName, String classList[], String ... cmdLineSuffix) + throws Exception + { + CDSOptions opts = new CDSOptions(); + opts.setArchiveName(baseArchiveName); + opts.setClassList(classList); + opts.addSuffix(cmdLineSuffix); + opts.addSuffix("-Djava.class.path="); + OutputAnalyzer out = CDSTestUtils.createArchive(opts); + CDSTestUtils.checkBaseDump(out); + return out; + } + // Create AppCDS archive using most common args - convenience method public static OutputAnalyzer createArchive(String appJar, String classList[], String... suffix) throws Exception { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ModulePath.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ModulePath.java new file mode 100644 index 00000000000..2672225ee05 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ModulePath.java @@ -0,0 +1,131 @@ +/* + * 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. + * + * 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.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import jdk.test.lib.cds.CDSTestUtils; + +/* + * @test + * @summary Dyanmic archive with module path + * @requires vm.cds + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes + * @compile ../test-classes/Hello.java + * @build sun.hotspot.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar sun.hotspot.WhiteBox + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:./WhiteBox.jar ModulePath + */ + +public class ModulePath extends DynamicArchiveTestBase { + private static final Path USER_DIR = Paths.get(CDSTestUtils.getOutputDir()); + + private static final String FS = File.separator; + private static final String TEST_SRC = System.getProperty("test.src") + + FS + ".." + FS + "jigsaw" + FS + "modulepath"; + + private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); + private static final Path MODS_DIR = Paths.get("mods"); + + // the module name of the test module + private static final String TEST_MODULE = "com.simple"; + + // the module main class + private static final String MAIN_CLASS = "com.simple.Main"; + + private static Path moduleDir = null; + private static Path srcJar = null; + + public static void buildTestModule() throws Exception { + + // javac -d mods/$TESTMODULE --module-path MOD_DIR src/$TESTMODULE/** + JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE), + MODS_DIR.resolve(TEST_MODULE), + MODS_DIR.toString()); + + + moduleDir = Files.createTempDirectory(USER_DIR, "mlib"); + srcJar = moduleDir.resolve(TEST_MODULE + ".jar"); + String classes = MODS_DIR.resolve(TEST_MODULE).toString(); + JarBuilder.createModularJar(srcJar.toString(), classes, MAIN_CLASS); + } + + public static void main(String[] args) throws Exception { + runTest(ModulePath::test); + } + + static void test(String args[]) throws Exception { + String topArchiveName = getNewArchiveName("top"); + String baseArchiveName = getNewArchiveName("base"); + + String appJar = JarBuilder.getOrCreateHelloJar(); + String mainClass = "Hello"; + + // create a base archive with the --module-path option + buildTestModule(); + baseArchiveName = getNewArchiveName("base-with-module"); + String appClasses[] = {mainClass}; + TestCommon.dumpBaseArchive(baseArchiveName, + appClasses, + "-Xlog:class+load", + "-cp", appJar, + "--module-path", moduleDir.toString(), + "-m", TEST_MODULE); + + // Dumping of dynamic archive should be successful if the specified + // --module-path is the same as for the base archive. + topArchiveName = getNewArchiveName("top-with-module"); + dump2(baseArchiveName, topArchiveName, + "-Xlog:cds*", + "-Xlog:cds+dynamic=debug", + "-Xlog:class+path=info,class+load", + "-cp", appJar, + "--module-path", moduleDir.toString(), + "-m", TEST_MODULE, MAIN_CLASS) + .assertNormalExit(); + + // Load the Hello class from the base archive. + run2(baseArchiveName, topArchiveName, + "-Xlog:class+load", + "-Xlog:cds+dynamic=debug,cds=debug", + "-cp", appJar, mainClass) + .assertNormalExit(output -> { + output.shouldContain("Hello source: shared objects file") + .shouldHaveExitValue(0); + }); + + // Load the com.simple.Main class from the dynamic archive. + run2(baseArchiveName, topArchiveName, + "-Xlog:class+load", + "-Xlog:cds+dynamic=debug,cds=debug", + "-cp", appJar, + "--module-path", moduleDir.toString(), + "-m", TEST_MODULE, MAIN_CLASS) + .assertNormalExit(output -> { + output.shouldContain("com.simple.Main source: shared objects file (top)") + .shouldHaveExitValue(0); + }); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/UnsupportedBaseArchive.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/UnsupportedBaseArchive.java index a6027354e25..6a34bcc3192 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/UnsupportedBaseArchive.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/UnsupportedBaseArchive.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -62,7 +62,7 @@ public class UnsupportedBaseArchive extends DynamicArchiveTestBase { "Dynamic archiving is disabled because base layer archive has appended boot classpath"; private static final String warningModulePath = - "Dynamic archiving is disabled because base layer archive has module path"; + "Dynamic archiving is disabled because base layer archive has a different module path"; public static void buildTestModule() throws Exception { @@ -104,22 +104,23 @@ public class UnsupportedBaseArchive extends DynamicArchiveTestBase { // create a base archive with the --module-path option buildTestModule(); baseArchiveName = getNewArchiveName("base-with-module"); + String appClasses[] = {mainClass}; TestCommon.dumpBaseArchive(baseArchiveName, - "-cp", srcJar.toString(), + appClasses, + "-Xlog:class+load", + "-cp", appJar, "--module-path", moduleDir.toString(), "-m", TEST_MODULE); - // dumping of dynamic archive should be disabled with a warning message - // if the base archive contains --module-path entries. - topArchiveName = getNewArchiveName("top-with-module"); + // Try to create a dynamic archive without specifying module path, + // dumping should fail. + topArchiveName = getNewArchiveName("top-with-module-failed"); dump2(baseArchiveName, topArchiveName, "-Xlog:cds*", "-Xlog:cds+dynamic=debug", - "-Xlog:class+path=info", - "-cp", srcJar.toString(), - "--module-path", moduleDir.toString(), - "-m", TEST_MODULE) + "-Xlog:class+path=info,class+load", + "-cp", appJar, + mainClass) .assertNormalExit(warningModulePath); - } } -- GitLab From 0786ddb4712296c90df2c9e97c76c203a4de4612 Mon Sep 17 00:00:00 2001 From: Manukumar V S Date: Fri, 11 Feb 2022 17:40:25 +0000 Subject: [PATCH 218/400] 8281535: Create a regression test for JDK-4670051 Reviewed-by: aivanov --- .../4670051/DateFieldUnderCursorTest.java | 282 ++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 test/jdk/javax/swing/JSpinner/4670051/DateFieldUnderCursorTest.java diff --git a/test/jdk/javax/swing/JSpinner/4670051/DateFieldUnderCursorTest.java b/test/jdk/javax/swing/JSpinner/4670051/DateFieldUnderCursorTest.java new file mode 100644 index 00000000000..c0346700699 --- /dev/null +++ b/test/jdk/javax/swing/JSpinner/4670051/DateFieldUnderCursorTest.java @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2002, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.ComponentOrientation; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.SpinnerDateModel; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +import static javax.swing.UIManager.getInstalledLookAndFeels; + +/* + * @test + * @key headful + * @bug 4670051 + * @summary Checks whether JSpinner with a SpinnerDateModel + * spins the field where cursor is located. + * @run main DateFieldUnderCursorTest + */ +public class DateFieldUnderCursorTest { + + private static final Calendar expected = Calendar.getInstance(); + private static final Calendar actual = Calendar.getInstance(); + private static Robot robot; + private static JSpinner spinner; + private static Date initValue; + private static Date upValue; + private static Date downValue; + private static JFrame frame; + private static boolean passed = true; + private static volatile Point spinnerUpButtonCenter; + private static volatile Point spinnerDownButtonCenter; + private static volatile Date spinnerValue; + + public static void main(String[] s) throws Exception { + runTest(); + } + + public static void runTest() throws Exception { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); + List lafs = Arrays.stream(getInstalledLookAndFeels()) + .map(UIManager.LookAndFeelInfo::getClassName) + .collect(Collectors.toList()); + for (final String laf : lafs) { + try { + SwingUtilities.invokeAndWait(() -> { + setLookAndFeel(laf); + createUI(); + }); + SwingUtilities.invokeAndWait(() -> { + Point loc = spinner.getLocationOnScreen(); + int editorWidth = spinner.getEditor().getWidth(); + int buttonWidth = spinner.getWidth() - editorWidth; + int quarterHeight = spinner.getHeight() / 4; + + spinnerUpButtonCenter = new Point(loc.x + editorWidth + + (buttonWidth / 2), + loc.y + quarterHeight); + spinnerDownButtonCenter = new Point(spinnerUpButtonCenter.x, + loc.y + (3 * quarterHeight)); + }); + + // Cursor at Day field. + // Increment Day + initValue = getSpinnerValue(); + mousePressOnUpButton(); + upValue = getSpinnerValue(); + verifyDayIncrement(); + // Decrement Day + initValue = getSpinnerValue(); + mousePressOnDownButton(); + downValue = getSpinnerValue(); + verifyDayDecrement(); + + // Cursor at Month Field + pressRightArrowKey(); + // Increment Month + initValue = getSpinnerValue(); + mousePressOnUpButton(); + upValue = getSpinnerValue(); + verifyMonthIncrement(); + // Decrement Month + initValue = getSpinnerValue(); + mousePressOnDownButton(); + downValue = getSpinnerValue(); + verifyMonthDecrement(); + + // Cursor at Year Field + pressRightArrowKey(); + // Increment Year + initValue = getSpinnerValue(); + mousePressOnUpButton(); + upValue = getSpinnerValue(); + verifyYearIncrement(); + // Decrement Year + initValue = getSpinnerValue(); + mousePressOnDownButton(); + downValue = getSpinnerValue(); + verifyYearDecrement(); + + if (passed) { + System.out.println("Test Passed"); + } else { + throw new RuntimeException("Test Failed as one or more cases failed"); + } + } finally { + SwingUtilities.invokeAndWait(DateFieldUnderCursorTest::disposeFrame); + } + } + } + + private static Date getSpinnerValue() throws Exception { + SwingUtilities.invokeAndWait(() -> spinnerValue = (Date) spinner.getValue()); + return spinnerValue; + } + + public static void pressRightArrowKey() { + robot.keyPress(KeyEvent.VK_RIGHT); + robot.keyRelease(KeyEvent.VK_RIGHT); + } + + public static void mousePressOnUpButton() { + robot.mouseMove(spinnerUpButtonCenter.x, spinnerUpButtonCenter.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + + public static void mousePressOnDownButton() { + robot.mouseMove(spinnerDownButtonCenter.x, spinnerDownButtonCenter.y); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + } + + + public static boolean compareDates() { + return (expected.get(Calendar.DATE) == actual.get(Calendar.DATE)) + && (expected.get(Calendar.MONTH) == actual.get(Calendar.MONTH)) + && (expected.get(Calendar.YEAR) == actual.get(Calendar.YEAR)); + } + + private static void checkResult() { + if (compareDates()) { + System.out.println(" Case Passed"); + } else { + passed = false; + System.out.println(" Case Failed because the expected: " + expected.getTime() + + " and actual: " + actual.getTime() + " outputs do not match."); + } + } + + private static void updateCalendarObjects(Date finalValue) { + expected.setTime(initValue); + actual.setTime(finalValue); + } + + /** + * Verifying that JSpinner increments the date field when cursor is on date field + */ + private static void verifyDayIncrement() { + System.out.print("verifyDateIncrement"); + updateCalendarObjects(upValue); + expected.add(Calendar.DATE, 1); + checkResult(); + } + + /** + * Verifying that JSpinner decrements the date field when cursor is on date field + */ + private static void verifyDayDecrement() { + System.out.print("verifyDateDecrement"); + updateCalendarObjects(downValue); + expected.add(Calendar.DATE, -1); + checkResult(); + } + + /** + * Verifying that JSpinner increments the month field when cursor is on month field + */ + private static void verifyMonthIncrement() { + System.out.print("verifyMonthIncrement"); + updateCalendarObjects(upValue); + expected.add(Calendar.MONTH, 1); + checkResult(); + } + + /** + * Verifying that JSpinner decrements the month field when cursor is on month field + */ + private static void verifyMonthDecrement() { + System.out.print("verifyMonthDecrement"); + updateCalendarObjects(downValue); + expected.add(Calendar.MONTH, -1); + checkResult(); + } + + /** + * Verifying that, JSpinner decrements the year field when the cursor is on year field. + */ + private static void verifyYearDecrement() { + System.out.print("verifyYearDecrement"); + updateCalendarObjects(downValue); + expected.add(Calendar.YEAR, -1); + checkResult(); + } + + /** + * Verifying that JSpinner increments the year field when cursor is on year field + */ + private static void verifyYearIncrement() { + System.out.print("verifyYearIncrement"); + updateCalendarObjects(upValue); + expected.add(Calendar.YEAR, 1); + checkResult(); + } + + private static void createUI() { + frame = new JFrame(); + JPanel panel = new JPanel(); + spinner = new JSpinner(new SpinnerDateModel()); + JSpinner.DateEditor editor = new JSpinner.DateEditor(spinner, " dd/MM/yy "); + spinner.setEditor(editor); + spinner.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); + panel.add(spinner); + + frame.add(panel); + frame.setUndecorated(true); + frame.pack(); + frame.setAlwaysOnTop(true); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + private static void setLookAndFeel(final String laf) { + try { + UIManager.setLookAndFeel(laf); + System.out.println("LookAndFeel: " + laf); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static void disposeFrame() { + if (frame != null) { + frame.dispose(); + frame = null; + } + } + +} -- GitLab From 83ffbd2e7aed8a9c788395ccbe920ddff221ae16 Mon Sep 17 00:00:00 2001 From: "Dr Heinz M. Kabutz" Date: Fri, 11 Feb 2022 18:49:04 +0000 Subject: [PATCH 219/400] 8277175: Add a parallel multiply method to BigInteger Reviewed-by: psandoz --- .../share/classes/java/math/BigInteger.java | 155 +++++++-- .../BigIntegerParallelMultiplyTest.java | 82 +++++ .../math/BigIntegerMersennePrimeMultiply.java | 322 ++++++++++++++++++ .../java/math/BigIntegerParallelMultiply.java | 61 ++++ 4 files changed, 601 insertions(+), 19 deletions(-) create mode 100644 test/jdk/java/math/BigInteger/BigIntegerParallelMultiplyTest.java create mode 100644 test/micro/org/openjdk/bench/java/math/BigIntegerMersennePrimeMultiply.java create mode 100644 test/micro/org/openjdk/bench/java/math/BigIntegerParallelMultiply.java diff --git a/src/java.base/share/classes/java/math/BigInteger.java b/src/java.base/share/classes/java/math/BigInteger.java index 34f1953d003..81d9a9cf248 100644 --- a/src/java.base/share/classes/java/math/BigInteger.java +++ b/src/java.base/share/classes/java/math/BigInteger.java @@ -36,6 +36,9 @@ import java.io.ObjectStreamField; import java.util.Arrays; import java.util.Objects; import java.util.Random; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinWorkerThread; +import java.util.concurrent.RecursiveTask; import java.util.concurrent.ThreadLocalRandom; import jdk.internal.math.DoubleConsts; @@ -1581,7 +1584,30 @@ public class BigInteger extends Number implements Comparable { * @return {@code this * val} */ public BigInteger multiply(BigInteger val) { - return multiply(val, false); + return multiply(val, false, false, 0); + } + + /** + * Returns a BigInteger whose value is {@code (this * val)}. + * When both {@code this} and {@code val} are large, typically + * in the thousands of bits, parallel multiply might be used. + * This method returns the exact same mathematical result as + * {@link #multiply}. + * + * @implNote This implementation may offer better algorithmic + * performance when {@code val == this}. + * + * @implNote Compared to {@link #multiply}, an implementation's + * parallel multiplication algorithm would typically use more + * CPU resources to compute the result faster, and may do so + * with a slight increase in memory consumption. + * + * @param val value to be multiplied by this BigInteger. + * @return {@code this * val} + * @see #multiply + */ + public BigInteger parallelMultiply(BigInteger val) { + return multiply(val, false, true, 0); } /** @@ -1590,16 +1616,17 @@ public class BigInteger extends Number implements Comparable { * * @param val value to be multiplied by this BigInteger. * @param isRecursion whether this is a recursive invocation + * @param parallel whether the multiply should be done in parallel * @return {@code this * val} */ - private BigInteger multiply(BigInteger val, boolean isRecursion) { + private BigInteger multiply(BigInteger val, boolean isRecursion, boolean parallel, int depth) { if (val.signum == 0 || signum == 0) return ZERO; int xlen = mag.length; if (val == this && xlen > MULTIPLY_SQUARE_THRESHOLD) { - return square(); + return square(true, parallel, depth); } int ylen = val.mag.length; @@ -1677,7 +1704,7 @@ public class BigInteger extends Number implements Comparable { } } - return multiplyToomCook3(this, val); + return multiplyToomCook3(this, val, parallel, depth); } } } @@ -1844,6 +1871,88 @@ public class BigInteger extends Number implements Comparable { } } + @SuppressWarnings("serial") + private abstract static sealed class RecursiveOp extends RecursiveTask { + /** + * The threshold until when we should continue forking recursive ops + * if parallel is true. This threshold is only relevant for Toom Cook 3 + * multiply and square. + */ + private static final int PARALLEL_FORK_DEPTH_THRESHOLD = + calculateMaximumDepth(ForkJoinPool.getCommonPoolParallelism()); + + private static final int calculateMaximumDepth(int parallelism) { + return 32 - Integer.numberOfLeadingZeros(parallelism); + } + + final boolean parallel; + /** + * The current recursing depth. Since it is a logarithmic algorithm, + * we do not need an int to hold the number. + */ + final byte depth; + + private RecursiveOp(boolean parallel, int depth) { + this.parallel = parallel; + this.depth = (byte) depth; + } + + private static int getParallelForkDepthThreshold() { + if (Thread.currentThread() instanceof ForkJoinWorkerThread fjwt) { + return calculateMaximumDepth(fjwt.getPool().getParallelism()); + } + else { + return PARALLEL_FORK_DEPTH_THRESHOLD; + } + } + + protected RecursiveTask forkOrInvoke() { + if (parallel && depth <= getParallelForkDepthThreshold()) fork(); + else invoke(); + return this; + } + + @SuppressWarnings("serial") + private static final class RecursiveMultiply extends RecursiveOp { + private final BigInteger a; + private final BigInteger b; + + public RecursiveMultiply(BigInteger a, BigInteger b, boolean parallel, int depth) { + super(parallel, depth); + this.a = a; + this.b = b; + } + + @Override + public BigInteger compute() { + return a.multiply(b, true, parallel, depth); + } + } + + @SuppressWarnings("serial") + private static final class RecursiveSquare extends RecursiveOp { + private final BigInteger a; + + public RecursiveSquare(BigInteger a, boolean parallel, int depth) { + super(parallel, depth); + this.a = a; + } + + @Override + public BigInteger compute() { + return a.square(true, parallel, depth); + } + } + + private static RecursiveTask multiply(BigInteger a, BigInteger b, boolean parallel, int depth) { + return new RecursiveMultiply(a, b, parallel, depth).forkOrInvoke(); + } + + private static RecursiveTask square(BigInteger a, boolean parallel, int depth) { + return new RecursiveSquare(a, parallel, depth).forkOrInvoke(); + } + } + /** * Multiplies two BigIntegers using a 3-way Toom-Cook multiplication * algorithm. This is a recursive divide-and-conquer algorithm which is @@ -1872,7 +1981,7 @@ public class BigInteger extends Number implements Comparable { * LNCS #4547. Springer, Madrid, Spain, June 21-22, 2007. * */ - private static BigInteger multiplyToomCook3(BigInteger a, BigInteger b) { + private static BigInteger multiplyToomCook3(BigInteger a, BigInteger b, boolean parallel, int depth) { int alen = a.mag.length; int blen = b.mag.length; @@ -1896,16 +2005,20 @@ public class BigInteger extends Number implements Comparable { BigInteger v0, v1, v2, vm1, vinf, t1, t2, tm1, da1, db1; - v0 = a0.multiply(b0, true); + depth++; + var v0_task = RecursiveOp.multiply(a0, b0, parallel, depth); da1 = a2.add(a0); db1 = b2.add(b0); - vm1 = da1.subtract(a1).multiply(db1.subtract(b1), true); + var vm1_task = RecursiveOp.multiply(da1.subtract(a1), db1.subtract(b1), parallel, depth); da1 = da1.add(a1); db1 = db1.add(b1); - v1 = da1.multiply(db1, true); + var v1_task = RecursiveOp.multiply(da1, db1, parallel, depth); v2 = da1.add(a2).shiftLeft(1).subtract(a0).multiply( - db1.add(b2).shiftLeft(1).subtract(b0), true); - vinf = a2.multiply(b2, true); + db1.add(b2).shiftLeft(1).subtract(b0), true, parallel, depth); + vinf = a2.multiply(b2, true, parallel, depth); + v0 = v0_task.join(); + vm1 = vm1_task.join(); + v1 = v1_task.join(); // The algorithm requires two divisions by 2 and one by 3. // All divisions are known to be exact, that is, they do not produce @@ -2071,7 +2184,7 @@ public class BigInteger extends Number implements Comparable { * @return this2 */ private BigInteger square() { - return square(false); + return square(false, false, 0); } /** @@ -2081,7 +2194,7 @@ public class BigInteger extends Number implements Comparable { * @param isRecursion whether this is a recursive invocation * @return this2 */ - private BigInteger square(boolean isRecursion) { + private BigInteger square(boolean isRecursion, boolean parallel, int depth) { if (signum == 0) { return ZERO; } @@ -2103,7 +2216,7 @@ public class BigInteger extends Number implements Comparable { } } - return squareToomCook3(); + return squareToomCook3(parallel, depth); } } } @@ -2237,7 +2350,7 @@ public class BigInteger extends Number implements Comparable { * that has better asymptotic performance than the algorithm used in * squareToLen or squareKaratsuba. */ - private BigInteger squareToomCook3() { + private BigInteger squareToomCook3(boolean parallel, int depth) { int len = mag.length; // k is the size (in ints) of the lower-order slices. @@ -2254,13 +2367,17 @@ public class BigInteger extends Number implements Comparable { a0 = getToomSlice(k, r, 2, len); BigInteger v0, v1, v2, vm1, vinf, t1, t2, tm1, da1; - v0 = a0.square(true); + depth++; + var v0_fork = RecursiveOp.square(a0, parallel, depth); da1 = a2.add(a0); - vm1 = da1.subtract(a1).square(true); + var vm1_fork = RecursiveOp.square(da1.subtract(a1), parallel, depth); da1 = da1.add(a1); - v1 = da1.square(true); - vinf = a2.square(true); - v2 = da1.add(a2).shiftLeft(1).subtract(a0).square(true); + var v1_fork = RecursiveOp.square(da1, parallel, depth); + vinf = a2.square(true, parallel, depth); + v2 = da1.add(a2).shiftLeft(1).subtract(a0).square(true, parallel, depth); + v0 = v0_fork.join(); + vm1 = vm1_fork.join(); + v1 = v1_fork.join(); // The algorithm requires two divisions by 2 and one by 3. // All divisions are known to be exact, that is, they do not produce diff --git a/test/jdk/java/math/BigInteger/BigIntegerParallelMultiplyTest.java b/test/jdk/java/math/BigInteger/BigIntegerParallelMultiplyTest.java new file mode 100644 index 00000000000..1396ae06d96 --- /dev/null +++ b/test/jdk/java/math/BigInteger/BigIntegerParallelMultiplyTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. + * 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 + * @run main BigIntegerParallelMultiplyTest + * @summary tests parallelMultiply() method in BigInteger + * @author Heinz Kabutz heinz@javaspecialists.eu + */ + +import java.math.BigInteger; +import java.util.function.BinaryOperator; + +/** + * This is a simple test class created to ensure that the results + * of multiply() are the same as multiplyParallel(). We calculate + * the Fibonacci numbers using Dijkstra's sum of squares to get + * very large numbers (hundreds of thousands of bits). + * + * @author Heinz Kabutz, heinz@javaspecialists.eu + */ +public class BigIntegerParallelMultiplyTest { + public static BigInteger fibonacci(int n, BinaryOperator multiplyOperator) { + if (n == 0) return BigInteger.ZERO; + if (n == 1) return BigInteger.ONE; + + int half = (n + 1) / 2; + BigInteger f0 = fibonacci(half - 1, multiplyOperator); + BigInteger f1 = fibonacci(half, multiplyOperator); + if (n % 2 == 1) { + BigInteger b0 = multiplyOperator.apply(f0, f0); + BigInteger b1 = multiplyOperator.apply(f1, f1); + return b0.add(b1); + } else { + BigInteger b0 = f0.shiftLeft(1).add(f1); + return multiplyOperator.apply(b0, f1); + } + } + + public static void main(String[] args) throws Exception { + compare(1000, 324); + compare(10_000, 3473); + compare(100_000, 34883); + compare(1_000_000, 347084); + } + + private static void compare(int n, int expectedBitCount) { + BigInteger multiplyResult = fibonacci(n, BigInteger::multiply); + BigInteger parallelMultiplyResult = fibonacci(n, BigInteger::parallelMultiply); + checkBitCount(n, expectedBitCount, multiplyResult); + checkBitCount(n, expectedBitCount, parallelMultiplyResult); + if (!multiplyResult.equals(parallelMultiplyResult)) + throw new AssertionError("multiply() and parallelMultiply() give different results"); + } + + private static void checkBitCount(int n, int expectedBitCount, BigInteger number) { + if (number.bitCount() != expectedBitCount) + throw new AssertionError( + "bitCount of fibonacci(" + n + ") was expected to be " + expectedBitCount + + " but was " + number.bitCount()); + } +} diff --git a/test/micro/org/openjdk/bench/java/math/BigIntegerMersennePrimeMultiply.java b/test/micro/org/openjdk/bench/java/math/BigIntegerMersennePrimeMultiply.java new file mode 100644 index 00000000000..7ac4cf54dc2 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/math/BigIntegerMersennePrimeMultiply.java @@ -0,0 +1,322 @@ +package org.openjdk.bench.java.math; + +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadMXBean; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Locale; +import java.util.LongSummaryStatistics; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinWorkerThread; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.BinaryOperator; +import java.util.function.LongUnaryOperator; +import java.util.stream.Collectors; + +import static java.util.concurrent.ForkJoinPool.defaultForkJoinWorkerThreadFactory; + +/** + * Benchmark for checking performance difference between sequential and parallel + * multiply of very large Mersenne primes using BigInteger. We want to measure + * real time, user time, system time and the amount of memory allocated. To + * calculate this, we create our own thread factory for the common ForkJoinPool + * and then use that to measure user time, cpu time and bytes allocated. + *

    + * We use reflection to discover all methods that match "*ultiply", and use them + * to multiply two very large Mersenne primes together. + *

    + *

    Results on a 1-6-2 machine running Ubuntu linux

    + *

    + * Memory allocation increased from 83.9GB to 84GB, for both the sequential and + * parallel versions. This is an increase of just 0.1%. On this machine, the + * parallel version was 3.8x faster in latency (real time), but it used 2.7x + * more CPU resources. + *

    + * Testing multiplying Mersenne primes of 2^57885161-1 and 2^82589933-1 + *

    + *

    + * openjdk version "18-internal" 2022-03-15
    + * BigInteger.parallelMultiply()
    + * real  0m6.288s
    + * user  1m3.010s
    + * sys   0m0.027s
    + * mem   84.0GB
    + * BigInteger.multiply()
    + * real  0m23.682s
    + * user  0m23.530s
    + * sys   0m0.004s
    + * mem   84.0GB
    + *
    + * openjdk version "1.8.0_302"
    + * BigInteger.multiply()
    + * real  0m25.657s
    + * user  0m25.390s
    + * sys   0m0.001s
    + * mem   83.9GB
    + *
    + * openjdk version "9.0.7.1"
    + * BigInteger.multiply()
    + * real  0m24.907s
    + * user  0m24.700s
    + * sys   0m0.001s
    + * mem   83.9GB
    + *
    + * openjdk version "10.0.2" 2018-07-17
    + * BigInteger.multiply()
    + * real  0m24.632s
    + * user  0m24.380s
    + * sys   0m0.004s
    + * mem   83.9GB
    + *
    + * openjdk version "11.0.12" 2021-07-20 LTS
    + * BigInteger.multiply()
    + * real  0m22.114s
    + * user  0m21.930s
    + * sys   0m0.001s
    + * mem   83.9GB
    + *
    + * openjdk version "12.0.2" 2019-07-16
    + * BigInteger.multiply()
    + * real  0m23.015s
    + * user  0m22.830s
    + * sys   0m0.000s
    + * mem   83.9GB
    + *
    + * openjdk version "13.0.9" 2021-10-19
    + * BigInteger.multiply()
    + * real  0m23.548s
    + * user  0m23.350s
    + * sys   0m0.005s
    + * mem   83.9GB
    + *
    + * openjdk version "14.0.2" 2020-07-14
    + * BigInteger.multiply()
    + * real  0m22.918s
    + * user  0m22.530s
    + * sys   0m0.131s
    + * mem   83.9GB
    + *
    + * openjdk version "15.0.5" 2021-10-19
    + * BigInteger.multiply()
    + * real  0m22.038s
    + * user  0m21.750s
    + * sys   0m0.003s
    + * mem   83.9GB
    + *
    + * openjdk version "16.0.2" 2021-07-20
    + * BigInteger.multiply()
    + * real  0m23.049s
    + * user  0m22.760s
    + * sys   0m0.006s
    + * mem   83.9GB
    + *
    + * openjdk version "17" 2021-09-14
    + * BigInteger.multiply()
    + * real  0m22.580s
    + * user  0m22.310s
    + * sys   0m0.001s
    + * mem   83.9GB
    + *
    + * + * @author Heinz Kabutz, heinz@javaspecialists.eu + */ +public class BigIntegerMersennePrimeMultiply implements ForkJoinPool.ForkJoinWorkerThreadFactory { + // Large Mersenne prime discovered by Curtis Cooper in 2013 + private static final int EXPONENT_1 = 57885161; + private static final BigInteger MERSENNE_1 = + BigInteger.ONE.shiftLeft(EXPONENT_1).subtract(BigInteger.ONE); + // Largest Mersenne prime number discovered by Patrick Laroche in 2018 + private static final int EXPONENT_2 = 82589933; + private static final BigInteger MERSENNE_2 = + BigInteger.ONE.shiftLeft(EXPONENT_2).subtract(BigInteger.ONE); + private static boolean DEBUG = false; + + public static void main(String... args) { + System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory", + BigIntegerMersennePrimeMultiply.class.getName()); + System.out.println("Testing multiplying Mersenne primes of " + + "2^" + EXPONENT_1 + "-1 and 2^" + EXPONENT_2 + "-1"); + addCounters(Thread.currentThread()); + System.out.println("Using the following multiply methods:"); + List methods = Arrays.stream(BigInteger.class.getMethods()) + .filter(method -> method.getName().endsWith("ultiply") && + method.getParameterCount() == 1 && + method.getParameterTypes()[0] == BigInteger.class) + .peek(method -> System.out.println(" " + method)) + .collect(Collectors.toList()); + + for (int i = 0; i < 3; i++) { + System.out.println(); + methods.forEach(BigIntegerMersennePrimeMultiply::test); + } + } + + private static void test(Method method) { + BinaryOperator multiplyOperator = (a, b) -> { + try { + return (BigInteger) method.invoke(a, b); + } catch (IllegalAccessException e) { + throw new AssertionError(e); + } catch (InvocationTargetException e) { + throw new AssertionError(e.getCause()); + } + }; + test(method.getName(), multiplyOperator); + } + + private static void test(String description, + BinaryOperator multiplyOperator) { + System.out.println("BigInteger." + description + "()"); + resetAllCounters(); + long elapsedTimeInNanos = System.nanoTime(); + try { + BigInteger result1 = multiplyOperator.apply(MERSENNE_1, MERSENNE_2); + BigInteger result2 = multiplyOperator.apply(MERSENNE_2, MERSENNE_1); + if (result1.bitLength() != 140475094) + throw new AssertionError("Expected bitLength: 140475094, " + + "but was " + result1.bitLength()); + if (result2.bitLength() != 140475094) + throw new AssertionError("Expected bitLength: 140475094, " + + "but was " + result1.bitLength()); + } finally { + elapsedTimeInNanos = System.nanoTime() - elapsedTimeInNanos; + } + + LongSummaryStatistics userTimeStatistics = getStatistics(userTime); + LongSummaryStatistics cpuTimeStatistics = getStatistics(cpuTime); + LongSummaryStatistics memoryAllocationStatistics = getStatistics(bytes); + System.out.println("real " + formatTime(elapsedTimeInNanos)); + System.out.println("user " + formatTime(userTimeStatistics.getSum())); + System.out.println("sys " + + formatTime(cpuTimeStatistics.getSum() - userTimeStatistics.getSum())); + System.out.println("mem " + formatMemory(memoryAllocationStatistics.getSum(), 1)); + } + + private static LongSummaryStatistics getStatistics(Map timeMap) { + return timeMap.entrySet() + .stream() + .peek(entry -> { + long timeInMs = (counterExtractorMap.get(timeMap) + .applyAsLong(entry.getKey().getId()) + - entry.getValue().get()); + entry.getValue().set(timeInMs); + }) + .peek(BigIntegerMersennePrimeMultiply::printTime) + .map(Map.Entry::getValue) + .mapToLong(AtomicLong::get) + .summaryStatistics(); + } + + private static void printTime(Map.Entry threadCounter) { + if (DEBUG) + System.out.printf("%s %d%n", threadCounter.getKey(), threadCounter.getValue() + .get()); + } + + private static void addCounters(Thread thread) { + counterExtractorMap.forEach((map, timeExtractor) -> add(map, thread, timeExtractor)); + } + + private static void add(Map time, Thread thread, + LongUnaryOperator timeExtractor) { + time.put(thread, new AtomicLong(timeExtractor.applyAsLong(thread.getId()))); + } + + private static void resetAllCounters() { + counterExtractorMap.forEach(BigIntegerMersennePrimeMultiply::resetTimes); + } + + private static void resetTimes(Map timeMap, LongUnaryOperator timeMethod) { + timeMap.forEach((thread, time) -> + time.set(timeMethod.applyAsLong(thread.getId()))); + } + + private static final Map userTime = + new ConcurrentHashMap<>(); + private static final Map cpuTime = + new ConcurrentHashMap<>(); + private static final Map bytes = + new ConcurrentHashMap<>(); + private static final ThreadMXBean tmb = ManagementFactory.getThreadMXBean(); + + private static final Map, LongUnaryOperator> counterExtractorMap = + new IdentityHashMap<>(); + + static { + counterExtractorMap.put(userTime, tmb::getThreadUserTime); + counterExtractorMap.put(cpuTime, tmb::getThreadCpuTime); + counterExtractorMap.put(bytes, BigIntegerMersennePrimeMultiply::threadAllocatedBytes); + } + + public final ForkJoinWorkerThread newThread(ForkJoinPool pool) { + ForkJoinWorkerThread thread = defaultForkJoinWorkerThreadFactory.newThread(pool); + addCounters(thread); + return thread; + } + + private static final String[] SIGNATURE = new String[]{long.class.getName()}; + private static final MBeanServer mBeanServer; + private static final ObjectName name; + + static { + try { + name = new ObjectName(ManagementFactory.THREAD_MXBEAN_NAME); + mBeanServer = ManagementFactory.getPlatformMBeanServer(); + } catch (MalformedObjectNameException e) { + throw new ExceptionInInitializerError(e); + } + } + + public static long threadAllocatedBytes(long threadId) { + try { + return (long) mBeanServer.invoke( + name, + "getThreadAllocatedBytes", + new Object[]{threadId}, + SIGNATURE + ); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + public static String formatMemory(double bytes, int decimals) { + double val; + String unitStr; + if (bytes < 1024) { + val = bytes; + unitStr = "B"; + } else if (bytes < 1024 * 1024) { + val = bytes / 1024; + unitStr = "KB"; + } else if (bytes < 1024 * 1024 * 1024) { + val = bytes / (1024 * 1024); + unitStr = "MB"; + } else if (bytes < 1024 * 1024 * 1024 * 1024L) { + val = bytes / (1024 * 1024 * 1024L); + unitStr = "GB"; + } else { + val = bytes / (1024 * 1024 * 1024 * 1024L); + unitStr = "TB"; + } + return String.format(Locale.US, "%." + decimals + "f%s", val, unitStr); + } + + public static String formatTime(long nanos) { + if (nanos < 0) nanos = 0; + long timeInMs = TimeUnit.NANOSECONDS.toMillis(nanos); + long minutes = timeInMs / 60_000; + double remainingMs = (timeInMs % 60_000) / 1000.0; + return String.format(Locale.US, "%dm%.3fs", minutes, remainingMs); + } +} \ No newline at end of file diff --git a/test/micro/org/openjdk/bench/java/math/BigIntegerParallelMultiply.java b/test/micro/org/openjdk/bench/java/math/BigIntegerParallelMultiply.java new file mode 100644 index 00000000000..92a1c5a8237 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/math/BigIntegerParallelMultiply.java @@ -0,0 +1,61 @@ +package org.openjdk.bench.java.math; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.math.BigInteger; +import java.util.concurrent.TimeUnit; +import java.util.function.BinaryOperator; + +/** + * Benchmark for checking performance difference between + * sequential and parallel multiply methods in BigInteger, + * using a large Fibonacci calculation of up to n = 100 million. + * + * @author Heinz Kabutz, heinz@javaspecialists.eu + */ +@BenchmarkMode(Mode.SingleShotTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Fork(value = 2) +@Warmup(iterations = 2) +@Measurement(iterations = 2) // only 2 iterations because each one takes very long +@State(Scope.Thread) +public class BigIntegerParallelMultiply { + private static BigInteger fibonacci(int n, BinaryOperator multiplyOperator) { + if (n == 0) return BigInteger.ZERO; + if (n == 1) return BigInteger.ONE; + + int half = (n + 1) / 2; + BigInteger f0 = fibonacci(half - 1, multiplyOperator); + BigInteger f1 = fibonacci(half, multiplyOperator); + if (n % 2 == 1) { + BigInteger b0 = multiplyOperator.apply(f0, f0); + BigInteger b1 = multiplyOperator.apply(f1, f1); + return b0.add(b1); + } else { + BigInteger b0 = f0.shiftLeft(1).add(f1); + return multiplyOperator.apply(b0, f1); + } + } + + @Param({"1000000", "10000000", "100000000"}) + private int n; + + @Benchmark + public void multiply() { + fibonacci(n, BigInteger::multiply); + } + + @Benchmark + public void parallelMultiply() { + fibonacci(n, BigInteger::parallelMultiply); + } +} \ No newline at end of file -- GitLab From 4032fe76dccb6da85927361aee7ceedcdb758e89 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Fri, 11 Feb 2022 21:52:16 +0000 Subject: [PATCH 220/400] 8281238: TYPE_USE annotations not printed in correct position in toString output Reviewed-by: vromero --- .../share/classes/com/sun/tools/javac/code/Type.java | 12 ++++++++++-- test/langtools/tools/javac/patterns/Annotations.java | 10 +++++----- .../tools/javac/tree/ArrayTypeToString.java | 6 +++--- .../langtools/tools/javac/tree/ArrayTypeToString.out | 2 +- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java index 3cf34052300..86851fa8cb6 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java @@ -1038,8 +1038,16 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons appendAnnotationsString(buf); buf.append(className(tsym, false)); } else { - appendAnnotationsString(buf); - buf.append(className(tsym, true)); + if (isAnnotated()) { + if (!tsym.packge().isUnnamed()) { + buf.append(tsym.packge()); + buf.append("."); + } + appendAnnotationsString(buf); + buf.append(tsym.name); + } else { + buf.append(className(tsym, true)); + } } if (getTypeArguments().nonEmpty()) { diff --git a/test/langtools/tools/javac/patterns/Annotations.java b/test/langtools/tools/javac/patterns/Annotations.java index 8c9062fa427..324f07945dd 100644 --- a/test/langtools/tools/javac/patterns/Annotations.java +++ b/test/langtools/tools/javac/patterns/Annotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8256266 + * @bug 8256266 8281238 * @summary Verify annotations work correctly on binding variables * @library /tools/javac/lib * @modules java.compiler @@ -114,11 +114,11 @@ public class Annotations extends JavacTestingAbstractProcessor { } case "dta" -> { expectedDeclAnnos = "@Annotations.DTA"; - expectedType = "@Annotations.DTA java.lang.String"; + expectedType = "java.lang.@Annotations.DTA String"; } case "ta" -> { expectedDeclAnnos = ""; - expectedType = "@Annotations.TA java.lang.String"; + expectedType = "java.lang.@Annotations.TA String"; } default -> { throw new AssertionError("Unexpected variable: " + var); @@ -133,7 +133,7 @@ public class Annotations extends JavacTestingAbstractProcessor { String type = varType.toString(); if (!expectedType.equals(type)) { throw new AssertionError("Unexpected type: " + type + - " for: " + var.getName()); + " for: " + var.getName() + " expected " + expectedType); } return super.visitInstanceOf(node, p); } diff --git a/test/langtools/tools/javac/tree/ArrayTypeToString.java b/test/langtools/tools/javac/tree/ArrayTypeToString.java index 9d2275ab26f..eac8f345bef 100644 --- a/test/langtools/tools/javac/tree/ArrayTypeToString.java +++ b/test/langtools/tools/javac/tree/ArrayTypeToString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8068737 + * @bug 8068737 8281238 * @summary Tests ArrayType.toString with type annotations present * @modules jdk.compiler/com.sun.tools.javac.code * @library /tools/javac/lib @@ -66,7 +66,7 @@ public class ArrayTypeToString extends JavacTestingAbstractProcessor { // Normalize output by removing whitespace s = s.replaceAll("\\s", ""); - // Expected: "@Foo(0)java.lang.String@Foo(3)[]@Foo(2)[]@Foo(1)[]" + // Expected: "java.lang.@Foo(0)String@Foo(1)[]@Foo(2)[]@Foo(3)[]" processingEnv.getMessager().printNote(s); } } diff --git a/test/langtools/tools/javac/tree/ArrayTypeToString.out b/test/langtools/tools/javac/tree/ArrayTypeToString.out index 375a6f28949..ca3db541c2d 100644 --- a/test/langtools/tools/javac/tree/ArrayTypeToString.out +++ b/test/langtools/tools/javac/tree/ArrayTypeToString.out @@ -1 +1 @@ -- compiler.note.proc.messager: @Foo(0)java.lang.String@Foo(1)[]@Foo(2)[]@Foo(3)[] +- compiler.note.proc.messager: java.lang.@Foo(0)String@Foo(1)[]@Foo(2)[]@Foo(3)[] -- GitLab From c3179a8760019b5954e344bf0d2775e1e1968f32 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Fri, 11 Feb 2022 23:24:08 +0000 Subject: [PATCH 221/400] 8281462: Annotation toString output for enum not reusable for source input Reviewed-by: mchung --- .../AnnotationInvocationHandler.java | 30 ++++++++++------ .../annotation/AnnotationToStringTest.java | 21 +++++++++--- .../EnumTypeMismatchTest.java | 4 +-- .../TestConstructorParameterAnnotations.java | 34 +++++++++---------- .../GetAnnotatedNestedSuperclass.java | 12 +++---- ...stConstructorParameterTypeAnnotations.java | 18 +++++----- .../typeAnnotations/TestObjectMethods.java | 4 +-- .../reflect/records/RecordReflectionTest.java | 6 ++-- 8 files changed, 74 insertions(+), 55 deletions(-) diff --git a/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java b/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java index c4cc4ccdec7..74eec629b3e 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java +++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -145,7 +145,9 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { private String toStringImpl() { StringBuilder result = new StringBuilder(128); result.append('@'); - result.append(type.getName()); + // Guard against null canonical name; shouldn't happen + result.append(Objects.toString(type.getCanonicalName(), + "")); result.append('('); boolean firstMember = true; Set> entries = memberValues.entrySet(); @@ -189,6 +191,10 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { return toSourceString((long) value); else if (type == Byte.class) return toSourceString((byte) value); + else if (value instanceof Enum v) + // Predicate above covers enum constants, including + // those with specialized class bodies. + return toSourceString(v); else return value.toString(); } else { @@ -219,6 +225,10 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { stringStream = Arrays.stream((String[])value). map(AnnotationInvocationHandler::toSourceString); + else if (type.getComponentType().isEnum()) + stringStream = + Arrays.stream((Enum[])value). + map(AnnotationInvocationHandler::toSourceString); else stringStream = Arrays.stream((Object[])value).map(Objects::toString); @@ -231,15 +241,9 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { * string representation of an annotation. */ private static String toSourceString(Class clazz) { - Class finalComponent = clazz; - StringBuilder arrayBrackets = new StringBuilder(); - - while(finalComponent.isArray()) { - finalComponent = finalComponent.getComponentType(); - arrayBrackets.append("[]"); - } - - return finalComponent.getName() + arrayBrackets.toString() + ".class"; + // Guard against null canonical name; shouldn't happen + return Objects.toString(clazz.getCanonicalName(), + "") + ".class"; } private static String toSourceString(float f) { @@ -307,6 +311,10 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable { return String.valueOf(ell) + "L"; } + private static String toSourceString(Enum enumConstant) { + return enumConstant.name(); + } + /** * Return a string suitable for use in the string representation * of an annotation. diff --git a/test/jdk/java/lang/annotation/AnnotationToStringTest.java b/test/jdk/java/lang/annotation/AnnotationToStringTest.java index e9fcf57014e..71551193a3f 100644 --- a/test/jdk/java/lang/annotation/AnnotationToStringTest.java +++ b/test/jdk/java/lang/annotation/AnnotationToStringTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -31,7 +31,8 @@ // test/langtools/tools/javac/processing/model/element/AnnotationToStringTest.java import java.lang.annotation.*; -import java.lang.reflect.*; +import java.lang.reflect.Field; +import javax.lang.model.element.Modifier; import java.util.*; /** @@ -160,6 +161,11 @@ public class AnnotationToStringTest { } static class ArrayAnnotationHost { + @ExpectedString( + "@EnumValue(NON_SEALED)") // toString and name differ + @EnumValue(Modifier.NON_SEALED) + public int f00; + @ExpectedString( "@BooleanArray({true, false, true})") @BooleanArray({true, false, true}) @@ -213,8 +219,8 @@ public class AnnotationToStringTest { public Class[] f9; @ExpectedString( - "@EnumArray({SOURCE})") - @EnumArray({RetentionPolicy.SOURCE}) + "@EnumArray({SEALED, NON_SEALED, PUBLIC})") + @EnumArray({Modifier.SEALED, Modifier.NON_SEALED, Modifier.PUBLIC}) public RetentionPolicy[] f10; } } @@ -223,6 +229,11 @@ public class AnnotationToStringTest { class Obj {} +@Retention(RetentionPolicy.RUNTIME) +@interface EnumValue { + Modifier value(); +} + @Retention(RetentionPolicy.RUNTIME) @interface ExpectedString { String value(); @@ -285,7 +296,7 @@ class Obj {} @Retention(RetentionPolicy.RUNTIME) @interface EnumArray { - RetentionPolicy[] value(); + Modifier[] value(); } @Retention(RetentionPolicy.RUNTIME) diff --git a/test/jdk/java/lang/annotation/AnnotationTypeMismatchException/EnumTypeMismatchTest.java b/test/jdk/java/lang/annotation/AnnotationTypeMismatchException/EnumTypeMismatchTest.java index dd787e727b4..5000aa0ee65 100644 --- a/test/jdk/java/lang/annotation/AnnotationTypeMismatchException/EnumTypeMismatchTest.java +++ b/test/jdk/java/lang/annotation/AnnotationTypeMismatchException/EnumTypeMismatchTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -61,7 +61,7 @@ public class EnumTypeMismatchTest { } catch (AnnotationTypeMismatchException e) { if (!e.element().getName().equals("value")) { throw new IllegalStateException("Unexpected element: " + e.element()); - } else if (!e.foundType().equals("@" + AnAnnotation.class.getName() + "(" + AnEnum.VALUE.name() + ")")) { + } else if (!e.foundType().equals("@" + AnAnnotation.class.getCanonicalName() + "(" + AnEnum.VALUE.name() + ")")) { throw new IllegalStateException("Unexpected type: " + e.foundType()); } } diff --git a/test/jdk/java/lang/annotation/TestConstructorParameterAnnotations.java b/test/jdk/java/lang/annotation/TestConstructorParameterAnnotations.java index f36474ef3b7..3e39cdb6e8d 100644 --- a/test/jdk/java/lang/annotation/TestConstructorParameterAnnotations.java +++ b/test/jdk/java/lang/annotation/TestConstructorParameterAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -129,21 +129,21 @@ public class TestConstructorParameterAnnotations { @ExpectedGetParameterAnnotations( "[[], " + - "[@TestConstructorParameterAnnotations$MarkerAnnotation(1)]]") + "[@TestConstructorParameterAnnotations.MarkerAnnotation(1)]]") @ExpectedParameterAnnotations({ "null", - "@TestConstructorParameterAnnotations$MarkerAnnotation(1)"}) + "@TestConstructorParameterAnnotations.MarkerAnnotation(1)"}) public class NestedClass1 { public NestedClass1(@MarkerAnnotation(1) int parameter) {} } @ExpectedGetParameterAnnotations( "[[], " + - "[@TestConstructorParameterAnnotations$MarkerAnnotation(2)], " + + "[@TestConstructorParameterAnnotations.MarkerAnnotation(2)], " + "[]]") @ExpectedParameterAnnotations({ "null", - "@TestConstructorParameterAnnotations$MarkerAnnotation(2)", + "@TestConstructorParameterAnnotations.MarkerAnnotation(2)", "null"}) public class NestedClass2 { public NestedClass2(@MarkerAnnotation(2) int parameter1, @@ -152,11 +152,11 @@ public class TestConstructorParameterAnnotations { @ExpectedGetParameterAnnotations( "[[], " + - "[@TestConstructorParameterAnnotations$MarkerAnnotation(3)], " + + "[@TestConstructorParameterAnnotations.MarkerAnnotation(3)], " + "[]]") @ExpectedParameterAnnotations({ "null", - "@TestConstructorParameterAnnotations$MarkerAnnotation(3)", + "@TestConstructorParameterAnnotations.MarkerAnnotation(3)", "null"}) public class NestedClass3 { public

    NestedClass3(@MarkerAnnotation(3) P parameter1, @@ -165,11 +165,11 @@ public class TestConstructorParameterAnnotations { @ExpectedGetParameterAnnotations( "[[], " + - "[@TestConstructorParameterAnnotations$MarkerAnnotation(4)], " + + "[@TestConstructorParameterAnnotations.MarkerAnnotation(4)], " + "[]]") @ExpectedParameterAnnotations({ "null", - "@TestConstructorParameterAnnotations$MarkerAnnotation(4)", + "@TestConstructorParameterAnnotations.MarkerAnnotation(4)", "null"}) public class NestedClass4 { public NestedClass4(@MarkerAnnotation(4) P parameter1, @@ -183,18 +183,18 @@ public class TestConstructorParameterAnnotations { } @ExpectedGetParameterAnnotations( - "[[@TestConstructorParameterAnnotations$MarkerAnnotation(1)]]") + "[[@TestConstructorParameterAnnotations.MarkerAnnotation(1)]]") @ExpectedParameterAnnotations({ - "@TestConstructorParameterAnnotations$MarkerAnnotation(1)"}) + "@TestConstructorParameterAnnotations.MarkerAnnotation(1)"}) public static class StaticNestedClass1 { public StaticNestedClass1(@MarkerAnnotation(1) int parameter) {} } @ExpectedGetParameterAnnotations( - "[[@TestConstructorParameterAnnotations$MarkerAnnotation(2)], " + + "[[@TestConstructorParameterAnnotations.MarkerAnnotation(2)], " + "[]]") @ExpectedParameterAnnotations({ - "@TestConstructorParameterAnnotations$MarkerAnnotation(2)", + "@TestConstructorParameterAnnotations.MarkerAnnotation(2)", "null"}) public static class StaticNestedClass2 { public StaticNestedClass2(@MarkerAnnotation(2) int parameter1, @@ -202,10 +202,10 @@ public class TestConstructorParameterAnnotations { } @ExpectedGetParameterAnnotations( - "[[@TestConstructorParameterAnnotations$MarkerAnnotation(3)], " + + "[[@TestConstructorParameterAnnotations.MarkerAnnotation(3)], " + "[]]") @ExpectedParameterAnnotations({ - "@TestConstructorParameterAnnotations$MarkerAnnotation(3)", + "@TestConstructorParameterAnnotations.MarkerAnnotation(3)", "null"}) public static class StaticNestedClass3 { public

    StaticNestedClass3(@MarkerAnnotation(3) P parameter1, @@ -213,10 +213,10 @@ public class TestConstructorParameterAnnotations { } @ExpectedGetParameterAnnotations( - "[[@TestConstructorParameterAnnotations$MarkerAnnotation(4)], " + + "[[@TestConstructorParameterAnnotations.MarkerAnnotation(4)], " + "[]]") @ExpectedParameterAnnotations({ - "@TestConstructorParameterAnnotations$MarkerAnnotation(4)", + "@TestConstructorParameterAnnotations.MarkerAnnotation(4)", "null"}) public static class StaticNestedClass4 { public StaticNestedClass4(@MarkerAnnotation(4) P parameter1, diff --git a/test/jdk/java/lang/annotation/typeAnnotations/GetAnnotatedNestedSuperclass.java b/test/jdk/java/lang/annotation/typeAnnotations/GetAnnotatedNestedSuperclass.java index a667a2e2c23..8603b7f9f19 100644 --- a/test/jdk/java/lang/annotation/typeAnnotations/GetAnnotatedNestedSuperclass.java +++ b/test/jdk/java/lang/annotation/typeAnnotations/GetAnnotatedNestedSuperclass.java @@ -64,31 +64,31 @@ public class GetAnnotatedNestedSuperclass { public static void main(String[] args) throws Exception { AnnotatedType x = Y.class.getAnnotatedSuperclass(); - assertEquals(Arrays.toString(x.getAnnotations()), "[@GetAnnotatedNestedSuperclass$A()]"); + assertEquals(Arrays.toString(x.getAnnotations()), "[@GetAnnotatedNestedSuperclass.A()]"); AnnotatedParameterizedType xpt = (AnnotatedParameterizedType) x; { AnnotatedType arg = xpt.getAnnotatedActualTypeArguments()[0]; assertEquals( - Arrays.toString(arg.getAnnotations()), "[@GetAnnotatedNestedSuperclass$B()]"); + Arrays.toString(arg.getAnnotations()), "[@GetAnnotatedNestedSuperclass.B()]"); } { AnnotatedType arg = xpt.getAnnotatedActualTypeArguments()[1]; assertEquals( - Arrays.toString(arg.getAnnotations()), "[@GetAnnotatedNestedSuperclass$C()]"); + Arrays.toString(arg.getAnnotations()), "[@GetAnnotatedNestedSuperclass.C()]"); } { AnnotatedType arg = xpt.getAnnotatedActualTypeArguments()[2]; assertEquals( - Arrays.toString(arg.getAnnotations()), "[@GetAnnotatedNestedSuperclass$D()]"); + Arrays.toString(arg.getAnnotations()), "[@GetAnnotatedNestedSuperclass.D()]"); AnnotatedType nestedArg = ((AnnotatedParameterizedType) arg).getAnnotatedActualTypeArguments()[0]; assertEquals( Arrays.toString(nestedArg.getAnnotations()), - "[@GetAnnotatedNestedSuperclass$E()]"); + "[@GetAnnotatedNestedSuperclass.E()]"); } } - private static void assertEquals(Object expected, Object actual) { + private static void assertEquals(Object actual, Object expected) { if (!Objects.equals(expected, actual)) { throw new AssertionError("expected: " + expected + "; actual=" + actual); } diff --git a/test/jdk/java/lang/annotation/typeAnnotations/TestConstructorParameterTypeAnnotations.java b/test/jdk/java/lang/annotation/typeAnnotations/TestConstructorParameterTypeAnnotations.java index 21934b3247d..a90aa36ba09 100644 --- a/test/jdk/java/lang/annotation/typeAnnotations/TestConstructorParameterTypeAnnotations.java +++ b/test/jdk/java/lang/annotation/typeAnnotations/TestConstructorParameterTypeAnnotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -128,7 +128,7 @@ public class TestConstructorParameterTypeAnnotations { @ExpectedGetParameterAnnotations("[[], []]") @ExpectedParameterTypeAnnotations({ "null", - "@TestConstructorParameterTypeAnnotations$MarkerTypeAnnotation(1)"}) + "@TestConstructorParameterTypeAnnotations.MarkerTypeAnnotation(1)"}) public class NestedClass1 { public NestedClass1(@MarkerTypeAnnotation(1) int parameter) {} } @@ -136,7 +136,7 @@ public class TestConstructorParameterTypeAnnotations { @ExpectedGetParameterAnnotations("[[], [], []]") @ExpectedParameterTypeAnnotations({ "null", - "@TestConstructorParameterTypeAnnotations$MarkerTypeAnnotation(2)", + "@TestConstructorParameterTypeAnnotations.MarkerTypeAnnotation(2)", "null"}) public class NestedClass2 { public NestedClass2(@MarkerTypeAnnotation(2) int parameter1, @@ -146,7 +146,7 @@ public class TestConstructorParameterTypeAnnotations { @ExpectedGetParameterAnnotations("[[], [], []]") @ExpectedParameterTypeAnnotations({ "null", - "@TestConstructorParameterTypeAnnotations$MarkerTypeAnnotation(3)", + "@TestConstructorParameterTypeAnnotations.MarkerTypeAnnotation(3)", "null"}) public class NestedClass3 { public

    NestedClass3(@MarkerTypeAnnotation(3) P parameter1, @@ -156,7 +156,7 @@ public class TestConstructorParameterTypeAnnotations { @ExpectedGetParameterAnnotations("[[], [], []]") @ExpectedParameterTypeAnnotations({ "null", - "@TestConstructorParameterTypeAnnotations$MarkerTypeAnnotation(4)", + "@TestConstructorParameterTypeAnnotations.MarkerTypeAnnotation(4)", "null"}) public class NestedClass4 { public NestedClass4(@MarkerTypeAnnotation(4) P parameter1, @@ -171,14 +171,14 @@ public class TestConstructorParameterTypeAnnotations { @ExpectedGetParameterAnnotations("[[]]") @ExpectedParameterTypeAnnotations({ - "@TestConstructorParameterTypeAnnotations$MarkerTypeAnnotation(1)"}) + "@TestConstructorParameterTypeAnnotations.MarkerTypeAnnotation(1)"}) public static class StaticNestedClass1 { public StaticNestedClass1(@MarkerTypeAnnotation(1) int parameter) {} } @ExpectedGetParameterAnnotations("[[], []]") @ExpectedParameterTypeAnnotations({ - "@TestConstructorParameterTypeAnnotations$MarkerTypeAnnotation(2)", + "@TestConstructorParameterTypeAnnotations.MarkerTypeAnnotation(2)", "null"}) public static class StaticNestedClass2 { public StaticNestedClass2(@MarkerTypeAnnotation(2) int parameter1, @@ -187,7 +187,7 @@ public class TestConstructorParameterTypeAnnotations { @ExpectedGetParameterAnnotations("[[], []]") @ExpectedParameterTypeAnnotations({ - "@TestConstructorParameterTypeAnnotations$MarkerTypeAnnotation(3)", + "@TestConstructorParameterTypeAnnotations.MarkerTypeAnnotation(3)", "null"}) public static class StaticNestedClass3 { public

    StaticNestedClass3(@MarkerTypeAnnotation(3) P parameter1, @@ -196,7 +196,7 @@ public class TestConstructorParameterTypeAnnotations { @ExpectedGetParameterAnnotations("[[], []]") @ExpectedParameterTypeAnnotations({ - "@TestConstructorParameterTypeAnnotations$MarkerTypeAnnotation(4)", + "@TestConstructorParameterTypeAnnotations.MarkerTypeAnnotation(4)", "null"}) public static class StaticNestedClass4 { public StaticNestedClass4(@MarkerTypeAnnotation(4) P parameter1, diff --git a/test/jdk/java/lang/annotation/typeAnnotations/TestObjectMethods.java b/test/jdk/java/lang/annotation/typeAnnotations/TestObjectMethods.java index dea8f42db6a..8349d48af72 100644 --- a/test/jdk/java/lang/annotation/typeAnnotations/TestObjectMethods.java +++ b/test/jdk/java/lang/annotation/typeAnnotations/TestObjectMethods.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -177,7 +177,7 @@ public class TestObjectMethods { } } - private static final Pattern annotationRegex = Pattern.compile("@TestObjectMethods\\$AnnotType\\((\\p{Digit})+\\)"); + private static final Pattern annotationRegex = Pattern.compile("@TestObjectMethods\\.AnnotType\\((\\p{Digit})+\\)"); static void testGetAnnotations(Class clazz, boolean annotationsExpectedOnMethods) { System.err.println("Testing getAnnotations on methods of class " + clazz.getName()); diff --git a/test/jdk/java/lang/reflect/records/RecordReflectionTest.java b/test/jdk/java/lang/reflect/records/RecordReflectionTest.java index 5968b4813ea..23b707663a9 100644 --- a/test/jdk/java/lang/reflect/records/RecordReflectionTest.java +++ b/test/jdk/java/lang/reflect/records/RecordReflectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -162,7 +162,7 @@ public class RecordReflectionTest { RecordComponent rc = recordClass.getRecordComponents()[0]; Annotation[] annos = rc.getAnnotations(); assertEquals(annos.length, 1); - assertEquals(annos[0].toString(), "@RecordReflectionTest$RCA()"); + assertEquals(annos[0].toString(), "@RecordReflectionTest.RCA()"); Field f = recordClass.getDeclaredField("i"); assertEquals(f.getAnnotations().length, 1); @@ -181,7 +181,7 @@ public class RecordReflectionTest { AnnotatedType at = rc.getAnnotatedType(); Annotation[] annos = at.getAnnotations(); assertEquals(annos.length, 1); - assertEquals(annos[0].toString(), "@RecordReflectionTest$TYPE_USE()"); + assertEquals(annos[0].toString(), "@RecordReflectionTest.TYPE_USE()"); Field f = recordClass.getDeclaredField("i"); assertEquals(f.getAnnotatedType().getAnnotations().length, 1); -- GitLab From 6fdfe0458df989a7946b4f52a3023e8a39fb3bbb Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Sat, 12 Feb 2022 01:33:41 +0000 Subject: [PATCH 222/400] 8281674: tools/javac/annotations/typeAnnotations/classfile/AnonymousExtendsTest.java fails with AssertionError Reviewed-by: vromero --- .../typeAnnotations/classfile/AnonymousExtendsTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/AnonymousExtendsTest.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/AnonymousExtendsTest.java index 063afbf43f3..0a99008c643 100644 --- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/AnonymousExtendsTest.java +++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/AnonymousExtendsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 8146167 + * @bug 8146167 8281674 * @summary Anonymous type declarations drop supertype type parameter annotations * @run main AnonymousExtendsTest */ @@ -52,10 +52,10 @@ public class AnonymousExtendsTest { public void testIt() { checkAnnotations(TestClass.class.getAnnotatedSuperclass(), - "[@AnonymousExtendsTest$TA(1)],[@AnonymousExtendsTest$TA(2)]"); + "[@AnonymousExtendsTest.TA(1)],[@AnonymousExtendsTest.TA(2)]"); checkAnnotations(new @TA(3) ArrayList<@TA(4) List>() { }.getClass().getAnnotatedSuperclass(), - "[@AnonymousExtendsTest$TA(3)],[@AnonymousExtendsTest$TA(4)]"); + "[@AnonymousExtendsTest.TA(3)],[@AnonymousExtendsTest.TA(4)]"); } public void checkAnnotations(AnnotatedType type, String expected) { -- GitLab From aa918a6ec4cd1356efd481c6f6fa94959f94f7b3 Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Sat, 12 Feb 2022 09:26:47 +0000 Subject: [PATCH 223/400] 8281033: Improve ImageCheckboxTest to test all available LaF Reviewed-by: serb --- .../ImageCheckboxFocus/ImageCheckboxTest.java | 59 +++++++++++++++---- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/test/jdk/javax/swing/JCheckBox/ImageCheckboxFocus/ImageCheckboxTest.java b/test/jdk/javax/swing/JCheckBox/ImageCheckboxFocus/ImageCheckboxTest.java index c93715d8087..844692bf454 100644 --- a/test/jdk/javax/swing/JCheckBox/ImageCheckboxFocus/ImageCheckboxTest.java +++ b/test/jdk/javax/swing/JCheckBox/ImageCheckboxFocus/ImageCheckboxTest.java @@ -23,13 +23,14 @@ import java.awt.Color; import java.awt.Component; -import java.awt.Dimension; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import javax.swing.Icon; import javax.swing.JCheckBox; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; /* * @test @@ -43,18 +44,43 @@ import javax.swing.JCheckBox; public class ImageCheckboxTest { public static void main(String[] args) throws Exception { - new ImageCheckboxTest().performTest(); + ImageCheckboxTest test = new ImageCheckboxTest(); + boolean passed = true; + // There are bugs found in various LaFs that needs to be fixed + // to enable testing there + String[] skip = { + "GTK+", // JDK-8281580 + "Nimbus" // JDK-8281581 + }; + testloop: + for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) { + for (String s : skip) { + if (s.equals(laf.getName())) { + continue testloop; + } + } + passed = passed && test.performTest(laf); + } + + if(!passed) { + throw new RuntimeException("Test failed"); + } } - public void performTest() throws Exception { + public boolean performTest(UIManager.LookAndFeelInfo laf) throws Exception { BufferedImage imageNoFocus = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB); BufferedImage imageFocus = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB); BufferedImage imageFocusNotPainted = new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB); + boolean success = true; - + try { + UIManager.setLookAndFeel(laf.getClassName()); + } catch (UnsupportedLookAndFeelException ulaf) { + return true; + } CustomCheckBox checkbox = new CustomCheckBox("Test", new MyIcon(Color.GREEN)); checkbox.setFocusPainted(true); checkbox.setSize(100, 50); @@ -64,21 +90,32 @@ public class ImageCheckboxTest { checkbox.paint(imageFocus.createGraphics()); if (Util.compareBufferedImages(imageFocus, imageNoFocus)) { - ImageIO.write(imageFocus, "png", new File("imageFocus.png")); - ImageIO.write(imageNoFocus, "png", new File("imageNoFocus.png")); - throw new Exception("Changing focus is not visualized"); + File folder = new File(laf.getName()); + if (!folder.exists()) { + folder.mkdir(); + } + ImageIO.write(imageFocus, "png", new File(folder, "/imageFocus.png")); + ImageIO.write(imageNoFocus, "png", new File(folder, "/imageNoFocus.png")); + System.err.println(laf.getName() + ": Changing of focus is not visualized"); + success = false; } checkbox.setFocusPainted(false); checkbox.paint(imageFocusNotPainted.createGraphics()); if (!Util.compareBufferedImages(imageFocusNotPainted, imageNoFocus)) { + File folder = new File(laf.getName()); + if (!folder.exists()) { + folder.mkdir(); + } ImageIO.write(imageFocusNotPainted, "png", - new File("imageFocusNotPainted.png")); - ImageIO.write(imageFocus, "png", new File("imageFocus.png")); - ImageIO.write(imageNoFocus, "png", new File("imageNoFocus.png")); - throw new Exception("setFocusPainted(false) is ignored"); + new File(folder,"imageFocusNotPainted.png")); + ImageIO.write(imageFocus, "png", new File(folder, "imageFocus.png")); + ImageIO.write(imageNoFocus, "png", new File(folder, "imageNoFocus.png")); + System.err.println(laf.getName() + ": setFocusPainted(false) is ignored"); + success = false; } + return success; } class MyIcon implements Icon { -- GitLab From 58dae60da0711c4ae0cb23f8ce2328e051d603b2 Mon Sep 17 00:00:00 2001 From: Alexey Bakhtin Date: Sat, 12 Feb 2022 11:54:22 +0000 Subject: [PATCH 224/400] 8274524: SSLSocket.close() hangs if it is called during the ssl handshake Reviewed-by: xuelei --- .../sun/security/ssl/SSLSocketImpl.java | 17 +++ .../SSLSocketImpl/ClientSocketCloseHang.java | 134 ++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 test/jdk/sun/security/ssl/SSLSocketImpl/ClientSocketCloseHang.java diff --git a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java index e55419d70ee..842cef11911 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java @@ -107,6 +107,11 @@ public final class SSLSocketImpl private static final boolean trustNameService = Utilities.getBooleanProperty("jdk.tls.trustNameService", false); + /* + * Default timeout to skip bytes from the open socket + */ + private static final int DEFAULT_SKIP_TIMEOUT = 1; + /** * Package-private constructor used to instantiate an unconnected * socket. @@ -1781,9 +1786,21 @@ public final class SSLSocketImpl if (conContext.inputRecord instanceof SSLSocketInputRecord inputRecord && isConnected) { if (appInput.readLock.tryLock()) { + int soTimeout = getSoTimeout(); try { + // deplete could hang on the skip operation + // in case of infinite socket read timeout. + // Change read timeout to avoid deadlock. + // This workaround could be replaced later + // with the right synchronization + if (soTimeout == 0) + setSoTimeout(DEFAULT_SKIP_TIMEOUT); inputRecord.deplete(false); + } catch (java.net.SocketTimeoutException stEx) { + // skip timeout exception during deplete } finally { + if (soTimeout == 0) + setSoTimeout(soTimeout); appInput.readLock.unlock(); } } diff --git a/test/jdk/sun/security/ssl/SSLSocketImpl/ClientSocketCloseHang.java b/test/jdk/sun/security/ssl/SSLSocketImpl/ClientSocketCloseHang.java new file mode 100644 index 00000000000..249aab13291 --- /dev/null +++ b/test/jdk/sun/security/ssl/SSLSocketImpl/ClientSocketCloseHang.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8274524 + * @summary 8274524: SSLSocket.close() hangs if it is called during the ssl handshake + * @library /javax/net/ssl/templates + * @run main/othervm ClientSocketCloseHang TLSv1.2 + * @run main/othervm ClientSocketCloseHang TLSv1.3 + */ + + +import javax.net.ssl.*; +import java.net.InetAddress; + +public class ClientSocketCloseHang implements SSLContextTemplate { + + public static void main(String[] args) throws Exception { + System.setProperty("jdk.tls.client.protocols", args[0]); + for (int i = 0; i<= 20; i++) { + System.err.println("==================================="); + System.err.println("loop " + i); + System.err.println("==================================="); + new ClientSocketCloseHang().test(); + } + } + + private void test() throws Exception { + SSLServerSocket listenSocket = null; + SSLSocket serverSocket = null; + ClientSocket clientSocket = null; + try { + SSLServerSocketFactory serversocketfactory = + createServerSSLContext().getServerSocketFactory(); + listenSocket = + (SSLServerSocket)serversocketfactory.createServerSocket(0); + listenSocket.setNeedClientAuth(false); + listenSocket.setEnableSessionCreation(true); + listenSocket.setUseClientMode(false); + + + System.err.println("Starting client"); + clientSocket = new ClientSocket(listenSocket.getLocalPort()); + clientSocket.start(); + + System.err.println("Accepting client requests"); + serverSocket = (SSLSocket) listenSocket.accept(); + + serverSocket.startHandshake(); + } finally { + if (clientSocket != null) { + clientSocket.close(); + } + if (listenSocket != null) { + listenSocket.close(); + } + + if (serverSocket != null) { + serverSocket.close(); + } + } + } + + private class ClientSocket extends Thread{ + int serverPort = 0; + SSLSocket clientSocket = null; + + public ClientSocket(int serverPort) { + this.serverPort = serverPort; + } + + @Override + public void run() { + try { + System.err.println( + "Connecting to server at port " + serverPort); + SSLSocketFactory sslSocketFactory = + createClientSSLContext().getSocketFactory(); + clientSocket = (SSLSocket)sslSocketFactory.createSocket( + InetAddress.getLocalHost(), serverPort); + clientSocket.setSoLinger(true, 3); + clientSocket.startHandshake(); + } catch (Exception e) { + } + } + + public void close() { + Thread t = new Thread() { + @Override + public void run() { + try { + if (clientSocket != null) { + clientSocket.close(); + } + } catch (Exception ex) { + } + } + }; + try { + // Close client connection + t.start(); + t.join(2000); // 2 sec + } catch (InterruptedException ex) { + return; + } + + if (t.isAlive()) { + throw new RuntimeException("SSL Client hangs on close"); + } + } + } +} + -- GitLab From 67077a04307b512219a46b6c4c274ce308ee46de Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Sat, 12 Feb 2022 13:08:39 +0000 Subject: [PATCH 225/400] 8278423: ExtendedDTraceProbes should be deprecated Reviewed-by: dholmes, hseigel, kvn, thartmann --- src/hotspot/share/runtime/arguments.cpp | 3 ++ src/hotspot/share/runtime/globals.hpp | 10 ++++--- src/java.base/share/man/java.1 | 28 +++++++++++++++---- .../CommandLine/VMDeprecatedOptions.java | 1 + .../7170638/SDTProbesGNULinuxTest.java | 4 ++- 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 7d0f1ddd4d3..952b96f537e 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -537,6 +537,7 @@ static SpecialFlag const special_jvm_flags[] = { #ifdef PRODUCT { "UseHeavyMonitors", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::jdk(20) }, #endif + { "ExtendedDTraceProbes", JDK_Version::jdk(19), JDK_Version::jdk(20), JDK_Version::jdk(21) }, // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in: { "DefaultMaxRAMFraction", JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() }, @@ -2886,6 +2887,8 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m } } else if (match_option(option, "-XX:+ExtendedDTraceProbes")) { #if defined(DTRACE_ENABLED) + warning("Option ExtendedDTraceProbes was deprecated in version 19 and will likely be removed in a future release."); + warning("Use the combination of -XX:+DTraceMethodProbes, -XX:+DTraceAllocProbes and -XX:+DTraceMonitorProbes instead."); if (FLAG_SET_CMDLINE(ExtendedDTraceProbes, true) != JVMFlag::SUCCESS) { return JNI_EINVAL; } diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index bc80a2eb45f..f45d259fd21 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -1858,16 +1858,18 @@ const intx ObjectAlignmentInBytes = 8; "Pause and wait for keypress on exit if a debugger is attached") \ \ product(bool, ExtendedDTraceProbes, false, \ - "Enable performance-impacting dtrace probes") \ + "(Deprecated) Enable performance-impacting dtrace probes. " \ + "Use the combination of -XX:+DTraceMethodProbes, " \ + "-XX:+DTraceAllocProbes and -XX:+DTraceMonitorProbes instead.") \ \ product(bool, DTraceMethodProbes, false, \ - "Enable dtrace probes for method-entry and method-exit") \ + "Enable dtrace tool probes for method-entry and method-exit") \ \ product(bool, DTraceAllocProbes, false, \ - "Enable dtrace probes for object allocation") \ + "Enable dtrace tool probes for object allocation") \ \ product(bool, DTraceMonitorProbes, false, \ - "Enable dtrace probes for monitor events") \ + "Enable dtrace tool probes for monitor events") \ \ product(bool, RelaxAccessControlCheck, false, \ "Relax the access control checks in the verifier") \ diff --git a/src/java.base/share/man/java.1 b/src/java.base/share/man/java.1 index 6a1532a8981..ea7edb8ef99 100644 --- a/src/java.base/share/man/java.1 +++ b/src/java.base/share/man/java.1 @@ -2977,11 +2977,19 @@ different JDK version. .RE .RE .TP -.B \f[CB]\-XX:+ExtendedDTraceProbes\f[R] -\f[B]Linux and macOS:\f[R] Enables additional \f[CB]dtrace\f[R] tool probes -that affect the performance. -By default, this option is disabled and \f[CB]dtrace\f[R] performs only -standard probes. +.B \f[CB]\-XX:+DTraceAllocProbes\f[R] +\f[B]Linux and macOS:\f[R] Enable \f[CB]dtrace\f[R] tool probes for object allocation. +.RS +.RE +.TP +.B \f[CB]\-XX:+DTraceMethodProbes\f[R] +\f[B]Linux and macOS:\f[R] Enable \f[CB]dtrace\f[R] tool probes for method-entry +and method-exit. +.RS +.RE +.TP +.B \f[CB]\-XX:+DTraceMonitorProbes\f[R] +\f[B]Linux and macOS:\f[R] Enable \f[CB]dtrace\f[R] tool probes for monitor events. .RS .RE .TP @@ -4008,6 +4016,16 @@ Example: \f[CB]\-Xlog:gc:garbage\-collection.log\f[R] .RE .TP +.B \f[CB]\-XX:+ExtendedDTraceProbes\f[R] +\f[B]Linux and macOS:\f[R] Enables additional \f[CB]dtrace\f[R] tool probes +that affect performance. +By default, this option is disabled and \f[CB]dtrace\f[R] performs only +standard probes. +Use the combination of these flags instead: \f[CB]\-XX:+DTraceMethodProbes\f[R], +\f[CB]\-XX:+DTraceAllocProbes\f[R], \f[CB]\-XX:+DTraceMonitorProbes\f[R]. +.RS +.RE +.TP .B \f[CB]\-XX:+FlightRecorder\f[R] Enables the use of Java Flight Recorder (JFR) during the runtime of the application. diff --git a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java index e9ccac08793..86bd3e9d2e2 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java +++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java @@ -54,6 +54,7 @@ public class VMDeprecatedOptions { {"InitialRAMFraction", "64"}, {"TLABStats", "false"}, {"AllowRedefinitionToAddDeleteMethods", "true"}, + {"ExtendedDTraceProbes", "true"}, // deprecated alias flags (see also aliased_jvm_flags): {"DefaultMaxRAMFraction", "4"}, diff --git a/test/hotspot/jtreg/serviceability/7170638/SDTProbesGNULinuxTest.java b/test/hotspot/jtreg/serviceability/7170638/SDTProbesGNULinuxTest.java index 9ad10282d1b..36759433112 100644 --- a/test/hotspot/jtreg/serviceability/7170638/SDTProbesGNULinuxTest.java +++ b/test/hotspot/jtreg/serviceability/7170638/SDTProbesGNULinuxTest.java @@ -46,7 +46,9 @@ public class SDTProbesGNULinuxTest { public static void main(String[] args) throws Throwable { { var pb = ProcessTools.createJavaProcessBuilder( - "-XX:+ExtendedDTraceProbes", + "-XX:+DTraceMethodProbes", + "-XX:+DTraceAllocProbes", + "-XX:+DTraceMonitorProbes", "-version"); var oa = new OutputAnalyzer(pb.start()); // This test only matters when build with DTRACE_ENABLED. -- GitLab From 8acfbc2e21063c3dc088c25c1574bcefa94e5a24 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Sat, 12 Feb 2022 14:12:42 +0000 Subject: [PATCH 226/400] 8281675: VMDeprecatedOptions test fails after JDK-8278423 Reviewed-by: dcubed --- .../hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java index 86bd3e9d2e2..a8b5bb31194 100644 --- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java +++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -54,7 +54,6 @@ public class VMDeprecatedOptions { {"InitialRAMFraction", "64"}, {"TLABStats", "false"}, {"AllowRedefinitionToAddDeleteMethods", "true"}, - {"ExtendedDTraceProbes", "true"}, // deprecated alias flags (see also aliased_jvm_flags): {"DefaultMaxRAMFraction", "4"}, -- GitLab From eff5dafba9f72bd0612357712ffa472ce1c9166a Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Sat, 12 Feb 2022 22:10:11 +0000 Subject: [PATCH 227/400] 8274939: Incorrect size of the pixel storage is used by the robot on macOS Reviewed-by: aivanov, prr --- .../macosx/classes/sun/lwawt/macosx/CRobot.java | 8 ++++---- src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m | 7 ++++++- .../awt/Robot/CheckCommonColors/CheckCommonColors.java | 2 ++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CRobot.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CRobot.java index 49125443b2e..5dba06cb612 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CRobot.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CRobot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -168,9 +168,9 @@ final class CRobot implements RobotPeer { */ @Override public int getRGBPixel(int x, int y) { - int[] c = new int[1]; - double scale = fDevice.getScaleFactor(); - getScreenPixels(new Rectangle(x, y, (int) scale, (int) scale), c); + int scale = fDevice.getScaleFactor(); + int[] c = new int[scale * scale]; + getScreenPixels(new Rectangle(x, y, scale, scale), c); return c[0]; } diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m index 9d90086677d..55df129960f 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -321,6 +321,11 @@ Java_sun_lwawt_macosx_CRobot_nativeGetScreenPixels jint picY = y; jint picWidth = width; jint picHeight = height; + jsize size = (*env)->GetArrayLength(env, pixels); + if (size < (long) picWidth * picHeight || picWidth < 0 || picHeight < 0) { + JNU_ThrowInternalError(env, "Invalid arguments to get screen pixels"); + return; + } CGRect screenRect = CGRectMake(picX / scale, picY / scale, picWidth / scale, picHeight / scale); diff --git a/test/jdk/java/awt/Robot/CheckCommonColors/CheckCommonColors.java b/test/jdk/java/awt/Robot/CheckCommonColors/CheckCommonColors.java index 57419b0ac5a..55d9b4358af 100644 --- a/test/jdk/java/awt/Robot/CheckCommonColors/CheckCommonColors.java +++ b/test/jdk/java/awt/Robot/CheckCommonColors/CheckCommonColors.java @@ -42,6 +42,8 @@ import javax.imageio.ImageIO; * @key headful * @bug 8215105 8211999 * @summary tests that Robot can capture the common colors without artifacts + * @run main/othervm CheckCommonColors + * @run main/othervm -Xcheck:jni CheckCommonColors */ public final class CheckCommonColors { -- GitLab From adbe0661029f12a36a44af52b83b189384d33a27 Mon Sep 17 00:00:00 2001 From: Bhavana Kilambi Date: Mon, 14 Feb 2022 01:33:20 +0000 Subject: [PATCH 228/400] 8239927: Product variable PrefetchFieldsAhead is unused and should be removed Reviewed-by: njian, dholmes --- src/hotspot/cpu/x86/vm_version_x86.cpp | 8 +------- src/hotspot/share/gc/shared/gc_globals.hpp | 6 +----- src/hotspot/share/runtime/arguments.cpp | 1 + 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp index 93613850a5e..c09785b969a 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.cpp +++ b/src/hotspot/cpu/x86/vm_version_x86.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -1818,9 +1818,6 @@ void VM_Version::get_processor_features() { if (FLAG_IS_DEFAULT(PrefetchScanIntervalInBytes)) { FLAG_SET_DEFAULT(PrefetchScanIntervalInBytes, 576); } - if (FLAG_IS_DEFAULT(PrefetchFieldsAhead)) { - FLAG_SET_DEFAULT(PrefetchFieldsAhead, 1); - } #endif if (FLAG_IS_DEFAULT(ContendedPaddingWidth) && @@ -1883,9 +1880,6 @@ void VM_Version::get_processor_features() { if (PrefetchScanIntervalInBytes > 0) { log->print_cr("PrefetchScanIntervalInBytes %d", (int) PrefetchScanIntervalInBytes); } - if (PrefetchFieldsAhead > 0) { - log->print_cr("PrefetchFieldsAhead %d", (int) PrefetchFieldsAhead); - } if (ContendedPaddingWidth > 0) { log->print_cr("ContendedPaddingWidth %d", (int) ContendedPaddingWidth); } diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp index 555170a091a..d9380b2af71 100644 --- a/src/hotspot/share/gc/shared/gc_globals.hpp +++ b/src/hotspot/share/gc/shared/gc_globals.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -503,10 +503,6 @@ "How far ahead to prefetch scan area (<= 0 means off)") \ range(-1, max_jint) \ \ - product(intx, PrefetchFieldsAhead, -1, \ - "How many fields ahead to prefetch in oop scan (<= 0 means off)") \ - range(-1, max_jint) \ - \ product(bool, VerifyDuringStartup, false, DIAGNOSTIC, \ "Verify memory system before executing any Java code " \ "during VM initialization") \ diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 952b96f537e..fed6faa0ccd 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -548,6 +548,7 @@ static SpecialFlag const special_jvm_flags[] = { { "FilterSpuriousWakeups", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::jdk(20) }, { "MinInliningThreshold", JDK_Version::jdk(18), JDK_Version::jdk(19), JDK_Version::jdk(20) }, + { "PrefetchFieldsAhead", JDK_Version::undefined(), JDK_Version::jdk(19), JDK_Version::jdk(20) }, #ifdef ASSERT { "DummyObsoleteTestFlag", JDK_Version::undefined(), JDK_Version::jdk(18), JDK_Version::undefined() }, #endif -- GitLab From 483d4b97e0ae4ab7b0d87058901f57688a0f0811 Mon Sep 17 00:00:00 2001 From: Nils Eliasson Date: Mon, 14 Feb 2022 08:27:21 +0000 Subject: [PATCH 229/400] 8281505: Add CompileCommand PrintIdealPhase Reviewed-by: kvn, thartmann, chagedorn --- src/hotspot/share/compiler/compileBroker.cpp | 3 +- .../share/compiler/compilerDirectives.cpp | 20 ++ .../share/compiler/compilerDirectives.hpp | 6 +- src/hotspot/share/compiler/compilerOracle.cpp | 16 ++ src/hotspot/share/compiler/compilerOracle.hpp | 7 +- .../share/compiler/directivesParser.cpp | 10 + src/hotspot/share/opto/compile.cpp | 15 +- src/hotspot/share/opto/compile.hpp | 1 + src/hotspot/share/opto/phasetype.hpp | 248 +++++++++++------- .../compiler/oracle/PrintIdealPhaseTest.java | 153 +++++++++++ 10 files changed, 377 insertions(+), 102 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index 4ae7bc21ce6..1c8656044b5 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -614,9 +614,8 @@ void register_jfr_phasetype_serializer(CompilerType compiler_type) { #ifdef COMPILER2 } else if (compiler_type == compiler_c2) { assert(first_registration, "invariant"); // c2 must be registered first. - GrowableArray* c2_phase_names = new GrowableArray(PHASE_NUM_TYPES); for (int i = 0; i < PHASE_NUM_TYPES; i++) { - const char* phase_name = CompilerPhaseTypeHelper::to_string((CompilerPhaseType) i); + const char* phase_name = CompilerPhaseTypeHelper::to_description((CompilerPhaseType) i); CompilerEvent::PhaseEvent::get_phase_id(phase_name, false, false, false); } first_registration = false; diff --git a/src/hotspot/share/compiler/compilerDirectives.cpp b/src/hotspot/share/compiler/compilerDirectives.cpp index 6d864072d1b..5fe84827195 100644 --- a/src/hotspot/share/compiler/compilerDirectives.cpp +++ b/src/hotspot/share/compiler/compilerDirectives.cpp @@ -30,6 +30,7 @@ #include "compiler/compilerOracle.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" +#include "opto/phasetype.hpp" #include "runtime/globals_extension.hpp" CompilerDirectives::CompilerDirectives() : _next(NULL), _match(NULL), _ref_count(0) { @@ -262,6 +263,7 @@ void DirectiveSet::init_control_intrinsic() { DirectiveSet::DirectiveSet(CompilerDirectives* d) :_inlinematchers(NULL), _directive(d) { #define init_defaults_definition(name, type, dvalue, compiler) this->name##Option = dvalue; + _ideal_phase_name_mask = 0; compilerdirectives_common_flags(init_defaults_definition) compilerdirectives_c2_flags(init_defaults_definition) compilerdirectives_c1_flags(init_defaults_definition) @@ -381,6 +383,24 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle compilerdirectives_c2_flags(init_default_cc) compilerdirectives_c1_flags(init_default_cc) + // Parse PrintIdealPhaseName and create an efficient lookup mask +#ifndef PRODUCT +#ifdef COMPILER2 + if (!_modified[PrintIdealPhaseIndex]) { + // Parse ccstr and create mask + ccstrlist option; + if (CompilerOracle::has_option_value(method, CompileCommand::PrintIdealPhase, option)) { + uint64_t mask = 0; + PhaseNameValidator validator(option, mask); + if (validator.is_valid()) { + assert(mask != 0, "Must be set"); + set.cloned()->_ideal_phase_name_mask = mask; + } + } + } +#endif +#endif + // Canonicalize DisableIntrinsic to contain only ',' as a separator. ccstrlist option_value; bool need_reset = true; // if Control/DisableIntrinsic redefined, only need to reset control_words once diff --git a/src/hotspot/share/compiler/compilerDirectives.hpp b/src/hotspot/share/compiler/compilerDirectives.hpp index 7daa034a8d0..8e3ba2db005 100644 --- a/src/hotspot/share/compiler/compilerDirectives.hpp +++ b/src/hotspot/share/compiler/compilerDirectives.hpp @@ -67,6 +67,7 @@ NOT_PRODUCT(cflags(TraceOptoPipelining, bool, TraceOptoPipelining, TraceOptoPipelining)) \ NOT_PRODUCT(cflags(TraceOptoOutput, bool, TraceOptoOutput, TraceOptoOutput)) \ NOT_PRODUCT(cflags(PrintIdeal, bool, PrintIdeal, PrintIdeal)) \ +NOT_PRODUCT(cflags(PrintIdealPhase, ccstrlist, "", PrintIdealPhase)) \ NOT_PRODUCT(cflags(PrintIdealLevel, uintx, PrintIdealLevel, PrintIdealLevel)) \ cflags(TraceSpilling, bool, TraceSpilling, TraceSpilling) \ cflags(Vectorize, bool, false, Vectorize) \ @@ -108,6 +109,7 @@ private: InlineMatcher* _inlinematchers; CompilerDirectives* _directive; TriBoolArray<(size_t)vmIntrinsics::number_of_intrinsics(), int> _intrinsic_control_words; + uint64_t _ideal_phase_name_mask; public: DirectiveSet(CompilerDirectives* directive); @@ -137,7 +139,6 @@ public: private: bool _modified[number_of_flags]; // Records what options where set by a directive - public: #define flag_store_definition(name, type, dvalue, cc_flag) type name##Option; compilerdirectives_common_flags(flag_store_definition) @@ -150,6 +151,9 @@ public: compilerdirectives_c2_flags(set_function_definition) compilerdirectives_c1_flags(set_function_definition) + void set_ideal_phase_mask(uint64_t mask) { _ideal_phase_name_mask = mask; }; + uint64_t ideal_phase_mask() { return _ideal_phase_name_mask; }; + void print_intx(outputStream* st, ccstr n, intx v, bool mod) { if (mod) { st->print("%s:" INTX_FORMAT " ", n, v); } } void print_uintx(outputStream* st, ccstr n, intx v, bool mod) { if (mod) { st->print("%s:" UINTX_FORMAT " ", n, v); } } void print_bool(outputStream* st, ccstr n, bool v, bool mod) { if (mod) { st->print("%s:%s ", n, v ? "true" : "false"); } } diff --git a/src/hotspot/share/compiler/compilerOracle.cpp b/src/hotspot/share/compiler/compilerOracle.cpp index 7d58a28d272..7d8b7179d0c 100644 --- a/src/hotspot/share/compiler/compilerOracle.cpp +++ b/src/hotspot/share/compiler/compilerOracle.cpp @@ -34,6 +34,7 @@ #include "oops/klass.hpp" #include "oops/method.inline.hpp" #include "oops/symbol.hpp" +#include "opto/phasetype.hpp" #include "runtime/globals_extension.hpp" #include "runtime/handles.inline.hpp" #include "runtime/jniHandles.hpp" @@ -683,6 +684,21 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read, jio_snprintf(errorbuf, buf_size, "Unrecognized intrinsic detected in %s: %s", option2name(option), validator.what()); } } +#ifndef PRODUCT + else if (option == CompileCommand::PrintIdealPhase) { + uint64_t mask = 0; + PhaseNameValidator validator(value, mask); + + if (!validator.is_valid()) { + jio_snprintf(errorbuf, buf_size, "Unrecognized phase name in %s: %s", option2name(option), validator.what()); + } + } else if (option == CompileCommand::TestOptionList) { + // all values are ok + } +#endif + else { + assert(false, "Ccstrlist type option missing validator"); + } register_command(matcher, option, (ccstr) value); return; diff --git a/src/hotspot/share/compiler/compilerOracle.hpp b/src/hotspot/share/compiler/compilerOracle.hpp index f2fc0e8251d..24ed40b7ef2 100644 --- a/src/hotspot/share/compiler/compilerOracle.hpp +++ b/src/hotspot/share/compiler/compilerOracle.hpp @@ -79,9 +79,10 @@ class methodHandle; option(TraceOptoPipelining, "TraceOptoPipelining", Bool) \ option(TraceOptoOutput, "TraceOptoOutput", Bool) \ option(TraceSpilling, "TraceSpilling", Bool) \ - option(PrintIdeal, "PrintIdeal", Bool) \ - option(PrintIdealLevel, "PrintIdealLevel", Uintx) \ - option(IGVPrintLevel, "IGVPrintLevel", Intx) \ +NOT_PRODUCT(option(PrintIdeal, "PrintIdeal", Bool)) \ +NOT_PRODUCT(option(PrintIdealLevel, "PrintIdealLevel", Uintx)) \ +NOT_PRODUCT(option(PrintIdealPhase, "PrintIdealPhase", Ccstrlist)) \ +NOT_PRODUCT(option(IGVPrintLevel, "IGVPrintLevel", Intx)) \ option(Vectorize, "Vectorize", Bool) \ option(VectorizeDebug, "VectorizeDebug", Uintx) \ option(CloneMapDebug, "CloneMapDebug", Bool) \ diff --git a/src/hotspot/share/compiler/directivesParser.cpp b/src/hotspot/share/compiler/directivesParser.cpp index b4ce9a3877c..e48ac58b31c 100644 --- a/src/hotspot/share/compiler/directivesParser.cpp +++ b/src/hotspot/share/compiler/directivesParser.cpp @@ -27,6 +27,7 @@ #include "compiler/directivesParser.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" +#include "opto/phasetype.hpp" #include "runtime/os.hpp" #include @@ -334,6 +335,15 @@ bool DirectivesParser::set_option_flag(JSON_TYPE t, JSON_VAL* v, const key* opti error(VALUE_ERROR, "Unrecognized intrinsic detected in DisableIntrinsic: %s", validator.what()); return false; } + } else if (strncmp(option_key->name, "PrintIdealPhase", 15) == 0) { + uint64_t mask = 0; + PhaseNameValidator validator(s, mask); + + if (!validator.is_valid()) { + error(VALUE_ERROR, "Unrecognized phase name detected in PrintIdealPhase: %s", validator.what()); + return false; + } + set->set_ideal_phase_mask(mask); } } break; diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 1296a3ff8b8..44456772321 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -4833,7 +4833,7 @@ void Compile::print_method(CompilerPhaseType cpt, int level, Node* n) { #ifndef PRODUCT ResourceMark rm; stringStream ss; - ss.print_raw(CompilerPhaseTypeHelper::to_string(cpt)); + ss.print_raw(CompilerPhaseTypeHelper::to_name(cpt)); if (n != nullptr) { ss.print(": %d %s ", n->_idx, NodeClassNames[n->Opcode()]); } @@ -4842,8 +4842,8 @@ void Compile::print_method(CompilerPhaseType cpt, int level, Node* n) { if (should_print_igv(level)) { _igv_printer->print_method(name, level); } - if (should_print_ideal(level)) { - print_ideal_ir(name); + if (should_print_ideal(level) || should_print_phase(cpt)) { + print_ideal_ir(CompilerPhaseTypeHelper::to_name(cpt)); } #endif C->_latest_stage_start_counter.stamp(); @@ -4873,6 +4873,15 @@ void Compile::end_method() { #endif } +bool Compile::should_print_phase(CompilerPhaseType cpt) { +#ifndef PRODUCT + if ((_directive->ideal_phase_mask() & CompilerPhaseTypeHelper::to_bitmask(cpt)) != 0) { + return true; + } +#endif + return false; +} + bool Compile::should_print_igv(int level) { #ifndef PRODUCT if (PrintIdealGraphLevel < 0) { // disabled by the user diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp index 70480b0d06e..0d74c9e5f9a 100644 --- a/src/hotspot/share/opto/compile.hpp +++ b/src/hotspot/share/opto/compile.hpp @@ -654,6 +654,7 @@ class Compile : public Phase { void begin_method(); void end_method(); bool should_print_igv(int level); + bool should_print_phase(CompilerPhaseType cpt); void print_method(CompilerPhaseType cpt, int level, Node* n = nullptr); diff --git a/src/hotspot/share/opto/phasetype.hpp b/src/hotspot/share/opto/phasetype.hpp index 2aa55a65553..d56a7b13197 100644 --- a/src/hotspot/share/opto/phasetype.hpp +++ b/src/hotspot/share/opto/phasetype.hpp @@ -25,105 +25,167 @@ #ifndef SHARE_OPTO_PHASETYPE_HPP #define SHARE_OPTO_PHASETYPE_HPP +#define COMPILER_PHASES(flags) \ + flags(BEFORE_STRINGOPTS, "Before StringOpts") \ + flags(AFTER_STRINGOPTS, "After StringOpts") \ + flags(BEFORE_REMOVEUSELESS, "Before RemoveUseless") \ + flags(AFTER_PARSING, "After Parsing") \ + flags(ITER_GVN1, "Iter GVN 1") \ + flags(EXPAND_VUNBOX, "Expand VectorUnbox") \ + flags(SCALARIZE_VBOX, "Scalarize VectorBox") \ + flags(INLINE_VECTOR_REBOX, "Inline Vector Rebox Calls") \ + flags(EXPAND_VBOX, "Expand VectorBox") \ + flags(ELIMINATE_VBOX_ALLOC, "Eliminate VectorBoxAllocate") \ + flags(PHASEIDEAL_BEFORE_EA, "PhaseIdealLoop before EA") \ + flags(ITER_GVN_AFTER_VECTOR, "Iter GVN after vector box elimination") \ + flags(ITER_GVN_BEFORE_EA, "Iter GVN before EA") \ + flags(ITER_GVN_AFTER_EA, "Iter GVN after EA") \ + flags(ITER_GVN_AFTER_ELIMINATION, "Iter GVN after eliminating allocations and locks") \ + flags(PHASEIDEALLOOP1, "PhaseIdealLoop 1") \ + flags(PHASEIDEALLOOP2, "PhaseIdealLoop 2") \ + flags(PHASEIDEALLOOP3, "PhaseIdealLoop 3") \ + flags(CCP1, "PhaseCCP 1") \ + flags(ITER_GVN2, "Iter GVN 2") \ + flags(PHASEIDEALLOOP_ITERATIONS, "PhaseIdealLoop iterations") \ + flags(OPTIMIZE_FINISHED, "Optimize finished") \ + flags(GLOBAL_CODE_MOTION, "Global code motion") \ + flags(FINAL_CODE, "Final Code") \ + flags(AFTER_EA, "After Escape Analysis") \ + flags(BEFORE_CLOOPS, "Before CountedLoop") \ + flags(AFTER_CLOOPS, "After CountedLoop") \ + flags(BEFORE_BEAUTIFY_LOOPS, "Before beautify loops") \ + flags(AFTER_BEAUTIFY_LOOPS, "After beautify loops") \ + flags(BEFORE_MATCHING, "Before matching") \ + flags(MATCHING, "After matching") \ + flags(INCREMENTAL_INLINE, "Incremental Inline") \ + flags(INCREMENTAL_INLINE_STEP, "Incremental Inline Step") \ + flags(INCREMENTAL_INLINE_CLEANUP, "Incremental Inline Cleanup") \ + flags(INCREMENTAL_BOXING_INLINE, "Incremental Boxing Inline") \ + flags(CALL_CATCH_CLEANUP, "Call catch cleanup") \ + flags(MACRO_EXPANSION, "Macro expand") \ + flags(BARRIER_EXPANSION, "Barrier expand") \ + flags(END, "End") \ + flags(FAILURE, "Failure") \ + flags(DEBUG, "Debug") + +#define table_entry(name, description) PHASE_##name, enum CompilerPhaseType { - PHASE_BEFORE_STRINGOPTS, - PHASE_AFTER_STRINGOPTS, - PHASE_BEFORE_REMOVEUSELESS, - PHASE_AFTER_PARSING, - PHASE_ITER_GVN1, - PHASE_EXPAND_VUNBOX, - PHASE_SCALARIZE_VBOX, - PHASE_INLINE_VECTOR_REBOX, - PHASE_EXPAND_VBOX, - PHASE_ELIMINATE_VBOX_ALLOC, - PHASE_PHASEIDEAL_BEFORE_EA, - PHASE_ITER_GVN_AFTER_VECTOR, - PHASE_ITER_GVN_BEFORE_EA, - PHASE_ITER_GVN_AFTER_EA, - PHASE_ITER_GVN_AFTER_ELIMINATION, - PHASE_PHASEIDEALLOOP1, - PHASE_PHASEIDEALLOOP2, - PHASE_PHASEIDEALLOOP3, - PHASE_CCP1, - PHASE_ITER_GVN2, - PHASE_PHASEIDEALLOOP_ITERATIONS, - PHASE_OPTIMIZE_FINISHED, - PHASE_GLOBAL_CODE_MOTION, - PHASE_FINAL_CODE, - PHASE_AFTER_EA, - PHASE_BEFORE_CLOOPS, - PHASE_AFTER_CLOOPS, - PHASE_BEFORE_BEAUTIFY_LOOPS, - PHASE_AFTER_BEAUTIFY_LOOPS, - PHASE_BEFORE_MATCHING, - PHASE_MATCHING, - PHASE_INCREMENTAL_INLINE, - PHASE_INCREMENTAL_INLINE_STEP, - PHASE_INCREMENTAL_INLINE_CLEANUP, - PHASE_INCREMENTAL_BOXING_INLINE, - PHASE_CALL_CATCH_CLEANUP, - PHASE_INSERT_BARRIER, - PHASE_MACRO_EXPANSION, - PHASE_BARRIER_EXPANSION, - PHASE_ADD_UNSAFE_BARRIER, - PHASE_END, - PHASE_FAILURE, - PHASE_DEBUG, - - PHASE_NUM_TYPES + COMPILER_PHASES(table_entry) + PHASE_NUM_TYPES, + PHASE_NONE +}; +#undef table_entry + +static const char* phase_descriptions[] = { +#define array_of_labels(name, description) description, + COMPILER_PHASES(array_of_labels) +#undef array_of_labels +}; + +static const char* phase_names[] = { +#define array_of_labels(name, description) #name, + COMPILER_PHASES(array_of_labels) +#undef array_of_labels }; class CompilerPhaseTypeHelper { public: - static const char* to_string(CompilerPhaseType cpt) { - switch (cpt) { - case PHASE_BEFORE_STRINGOPTS: return "Before StringOpts"; - case PHASE_AFTER_STRINGOPTS: return "After StringOpts"; - case PHASE_BEFORE_REMOVEUSELESS: return "Before RemoveUseless"; - case PHASE_AFTER_PARSING: return "After Parsing"; - case PHASE_ITER_GVN1: return "Iter GVN 1"; - case PHASE_EXPAND_VUNBOX: return "Expand VectorUnbox"; - case PHASE_SCALARIZE_VBOX: return "Scalarize VectorBox"; - case PHASE_INLINE_VECTOR_REBOX: return "Inline Vector Rebox Calls"; - case PHASE_EXPAND_VBOX: return "Expand VectorBox"; - case PHASE_ELIMINATE_VBOX_ALLOC: return "Eliminate VectorBoxAllocate"; - case PHASE_PHASEIDEAL_BEFORE_EA: return "PhaseIdealLoop before EA"; - case PHASE_ITER_GVN_AFTER_VECTOR: return "Iter GVN after vector box elimination"; - case PHASE_ITER_GVN_BEFORE_EA: return "Iter GVN before EA"; - case PHASE_ITER_GVN_AFTER_EA: return "Iter GVN after EA"; - case PHASE_ITER_GVN_AFTER_ELIMINATION: return "Iter GVN after eliminating allocations and locks"; - case PHASE_PHASEIDEALLOOP1: return "PhaseIdealLoop 1"; - case PHASE_PHASEIDEALLOOP2: return "PhaseIdealLoop 2"; - case PHASE_PHASEIDEALLOOP3: return "PhaseIdealLoop 3"; - case PHASE_CCP1: return "PhaseCCP 1"; - case PHASE_ITER_GVN2: return "Iter GVN 2"; - case PHASE_PHASEIDEALLOOP_ITERATIONS: return "PhaseIdealLoop iterations"; - case PHASE_OPTIMIZE_FINISHED: return "Optimize finished"; - case PHASE_GLOBAL_CODE_MOTION: return "Global code motion"; - case PHASE_FINAL_CODE: return "Final Code"; - case PHASE_AFTER_EA: return "After Escape Analysis"; - case PHASE_BEFORE_CLOOPS: return "Before CountedLoop"; - case PHASE_AFTER_CLOOPS: return "After CountedLoop"; - case PHASE_BEFORE_BEAUTIFY_LOOPS: return "Before beautify loops"; - case PHASE_AFTER_BEAUTIFY_LOOPS: return "After beautify loops"; - case PHASE_BEFORE_MATCHING: return "Before matching"; - case PHASE_MATCHING: return "After matching"; - case PHASE_INCREMENTAL_INLINE: return "Incremental Inline"; - case PHASE_INCREMENTAL_INLINE_STEP: return "Incremental Inline Step"; - case PHASE_INCREMENTAL_INLINE_CLEANUP: return "Incremental Inline Cleanup"; - case PHASE_INCREMENTAL_BOXING_INLINE: return "Incremental Boxing Inline"; - case PHASE_CALL_CATCH_CLEANUP: return "Call catch cleanup"; - case PHASE_INSERT_BARRIER: return "Insert barrier"; - case PHASE_MACRO_EXPANSION: return "Macro expand"; - case PHASE_BARRIER_EXPANSION: return "Barrier expand"; - case PHASE_ADD_UNSAFE_BARRIER: return "Add barrier to unsafe op"; - case PHASE_END: return "End"; - case PHASE_FAILURE: return "Failure"; - case PHASE_DEBUG: return "Debug"; - default: - ShouldNotReachHere(); - return NULL; + static const char* to_name(CompilerPhaseType cpt) { + return phase_names[cpt]; + } + static const char* to_description(CompilerPhaseType cpt) { + return phase_descriptions[cpt]; + } + static int to_bitmask(CompilerPhaseType cpt) { + return (1 << cpt); + } +}; + +static CompilerPhaseType find_phase(const char* str) { + for (int i = 0; i < PHASE_NUM_TYPES; i++) { + if (strcmp(phase_names[i], str) == 0) { + return (CompilerPhaseType)i; + } + } + return PHASE_NONE; +} + +class PhaseNameIter { + private: + char* _token; + char* _saved_ptr; + char* _list; + + public: + PhaseNameIter(ccstrlist option) { + _list = (char*) canonicalize(option); + _saved_ptr = _list; + _token = strtok_r(_saved_ptr, ",", &_saved_ptr); + } + + ~PhaseNameIter() { + FREE_C_HEAP_ARRAY(char, _list); + } + + const char* operator*() const { return _token; } + + PhaseNameIter& operator++() { + _token = strtok_r(NULL, ",", &_saved_ptr); + return *this; + } + + ccstrlist canonicalize(ccstrlist option_value) { + char* canonicalized_list = NEW_C_HEAP_ARRAY(char, strlen(option_value) + 1, mtCompiler); + int i = 0; + char current; + while ((current = option_value[i]) != '\0') { + if (current == '\n' || current == ' ') { + canonicalized_list[i] = ','; + } else { + canonicalized_list[i] = current; + } + i++; } + canonicalized_list[i] = '\0'; + return canonicalized_list; + } +}; + +class PhaseNameValidator { + private: + bool _valid; + char* _bad; + + public: + PhaseNameValidator(ccstrlist option, uint64_t& mask) : _valid(true), _bad(nullptr) { + for (PhaseNameIter iter(option); *iter != NULL && _valid; ++iter) { + + CompilerPhaseType cpt = find_phase(*iter); + if (PHASE_NONE == cpt) { + const size_t len = MIN2(strlen(*iter), 63) + 1; // cap len to a value we know is enough for all phase descriptions + _bad = NEW_C_HEAP_ARRAY(char, len, mtCompiler); + // strncpy always writes len characters. If the source string is shorter, the function fills the remaining bytes with NULLs. + strncpy(_bad, *iter, len); + _valid = false; + } else { + assert(cpt < 64, "out of bounds"); + mask |= CompilerPhaseTypeHelper::to_bitmask(cpt); + } + } + } + + ~PhaseNameValidator() { + if (_bad != NULL) { + FREE_C_HEAP_ARRAY(char, _bad); + } + } + + bool is_valid() const { + return _valid; + } + + const char* what() const { + return _bad; } }; diff --git a/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java b/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java new file mode 100644 index 00000000000..f07d7264482 --- /dev/null +++ b/test/hotspot/jtreg/compiler/oracle/PrintIdealPhaseTest.java @@ -0,0 +1,153 @@ +/* + * 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. + * + * 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 PrintIdealPhaseTest + * @summary Checks that -XX:CompileCommand=PrintIdealPhase,... works + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.management + * @requires vm.debug == true & vm.compiler2.enabled + * @run driver compiler.oracle.PrintIdealPhaseTest + */ + +package compiler.oracle; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import jdk.test.lib.Asserts; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class PrintIdealPhaseTest { + + public static void main(String[] args) throws Exception { + new PrintIdealPhaseTest(); + } + + PrintIdealPhaseTest() throws Exception { + // The Phases specified here will be exchanged for the enum Phase in compiler.lib.ir_framework when it's done + + // Test -XX:CompileCommand=PrintIdealPhase,*::test,CCP1 + List expectedPhases = new ArrayList(); + expectedPhases.add("CCP1"); + runTest("CCP1", expectedPhases, "hotspot_log_1.log", true); + runTest("FISH", expectedPhases, "hotspot_log_1f.log", false); + + // Test -XX:CompileCommand=PrintIdealPhase,*::test,MATCHING + expectedPhases.clear(); + expectedPhases.add("MATCHING"); + runTest("MATCHING", expectedPhases, "hotspot_log_2.log", true); + + // Test -XX:CompileCommand=PrintIdealPhase,*::test,CCP_1,AFTER_MATCHING + expectedPhases.add("CCP1"); + runTest("MATCHING,CCP1", expectedPhases, "hotspot_log_3.log", true); + } + + private void runTest(String cmdPhases, List expectedPhases, String logFile, boolean valid) throws Exception { + List options = new ArrayList(); + options.add("-Xbatch"); + options.add("-XX:+PrintCompilation"); + options.add("-XX:LogFile="+logFile); + options.add("-XX:+IgnoreUnrecognizedVMOptions"); + options.add("-XX:CompileCommand=PrintIdealPhase," + getTestClass() + "::test," + cmdPhases); + options.add(getTestClass()); + + OutputAnalyzer oa = ProcessTools.executeTestJvm(options); + if (valid) { + oa.shouldHaveExitValue(0) + .shouldContain("CompileCommand: PrintIdealPhase compiler/oracle/PrintIdealPhaseTest$TestMain.test const char* PrintIdealPhase = '"+cmdPhases.replace(',', ' ')+"'") + .shouldNotContain("CompileCommand: An error occurred during parsing") + .shouldNotContain("Error: Unrecognized phase name in PrintIdealPhase:") + .shouldNotContain("# A fatal error has been detected by the Java Runtime Environment"); + + // Check that all the expected phases matches what can be found in the compilation log file + HashSet loggedPhases = parseLogFile(logFile); + System.out.println("Logged phases:"); + for (String loggedPhase : loggedPhases) { + System.out.println("loggedPhase: "+ loggedPhase); + } + for (String expectedPhase : expectedPhases) { + System.out.println("Looking for phase: " + expectedPhase); + + Asserts.assertTrue(loggedPhases.contains(expectedPhase), "Must find specified phase: " + expectedPhase); + loggedPhases.remove(expectedPhase); + } + Asserts.assertTrue(loggedPhases.isEmpty(), "Expect no other phases"); + } else { + // Check that we don't pass even though bad phase names where given + oa.shouldHaveExitValue(0) + .shouldContain("CompileCommand: An error occurred during parsing") + .shouldContain("Error: Unrecognized phase name in PrintIdealPhase:"); + } + } + + private HashSet parseLogFile(String logFile) { + String printIdealTag = " phasesFound = new HashSet<>(); + + try (var br = Files.newBufferedReader(Paths.get(logFile))) { + String line; + while ((line = br.readLine()) != null) { + if (line.startsWith(printIdealTag)) { + Matcher matcher = compilePhasePattern.matcher(line); + if (matcher.find()) { + phasesFound.add(matcher.group(1)); + } else { + throw new Error("Failed to match compile_phase in file: " + logFile); + } + } + } + } catch (IOException e) { + throw new Error("Failed to read " + logFile + " data: " + e, e); + } + return phasesFound; + } + + // Test class that is invoked by the sub process + public String getTestClass() { + return TestMain.class.getName(); + } + + public static class TestMain { + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(i); + } + } + + static void test(int i) { + if ((i % 1000) == 0) { + System.out.println("Hello World!"); + } + } + } +} -- GitLab From 1ef45c5bbdeb4e1ca65c6d8f3ac1568a6951f3a7 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Mon, 14 Feb 2022 08:35:53 +0000 Subject: [PATCH 230/400] =?UTF-8?q?8280799:=20=D0=A12:=20assert(false)=20f?= =?UTF-8?q?ailed:=20cyclic=20dependency=20prevents=20range=20check=20elimi?= =?UTF-8?q?nation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: thartmann, kvn --- src/hotspot/share/opto/loopnode.cpp | 59 ++-- src/hotspot/share/opto/split_if.cpp | 18 ++ .../TestPredicateInputBelowLoopPredicate.java | 268 ++++++++++++++++++ 3 files changed, 319 insertions(+), 26 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/loopopts/TestPredicateInputBelowLoopPredicate.java diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp index e2b01f61d49..ceb2327edb5 100644 --- a/src/hotspot/share/opto/loopnode.cpp +++ b/src/hotspot/share/opto/loopnode.cpp @@ -5725,38 +5725,45 @@ void PhaseIdealLoop::build_loop_late_post_work(Node *n, bool pinned) { } assert(early == legal || legal != C->root(), "bad dominance of inputs"); + if (least != early) { + // Move the node above predicates as far up as possible so a + // following pass of loop predication doesn't hoist a predicate + // that depends on it above that node. + Node* new_ctrl = least; + for (;;) { + if (!new_ctrl->is_Proj()) { + break; + } + CallStaticJavaNode* call = new_ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none); + if (call == NULL) { + break; + } + int req = call->uncommon_trap_request(); + Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req); + if (trap_reason != Deoptimization::Reason_loop_limit_check && + trap_reason != Deoptimization::Reason_predicate && + trap_reason != Deoptimization::Reason_profile_predicate) { + break; + } + Node* c = new_ctrl->in(0)->in(0); + if (is_dominator(c, early) && c != early) { + break; + } + new_ctrl = c; + } + least = new_ctrl; + } // Try not to place code on a loop entry projection // which can inhibit range check elimination. if (least != early) { Node* ctrl_out = least->unique_ctrl_out(); if (ctrl_out && ctrl_out->is_Loop() && - least == ctrl_out->in(LoopNode::EntryControl)) { - // Move the node above predicates as far up as possible so a - // following pass of loop predication doesn't hoist a predicate - // that depends on it above that node. - Node* new_ctrl = least; - for (;;) { - if (!new_ctrl->is_Proj()) { - break; - } - CallStaticJavaNode* call = new_ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none); - if (call == NULL) { - break; - } - int req = call->uncommon_trap_request(); - Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req); - if (trap_reason != Deoptimization::Reason_loop_limit_check && - trap_reason != Deoptimization::Reason_predicate && - trap_reason != Deoptimization::Reason_profile_predicate) { - break; - } - Node* c = new_ctrl->in(0)->in(0); - if (is_dominator(c, early) && c != early) { - break; - } - new_ctrl = c; + least == ctrl_out->in(LoopNode::EntryControl) && + (ctrl_out->is_CountedLoop() || ctrl_out->is_OuterStripMinedLoop())) { + Node* least_dom = idom(least); + if (get_loop(least_dom)->is_member(get_loop(least))) { + least = least_dom; } - least = new_ctrl; } } diff --git a/src/hotspot/share/opto/split_if.cpp b/src/hotspot/share/opto/split_if.cpp index 05babc625c6..f85f3996ca5 100644 --- a/src/hotspot/share/opto/split_if.cpp +++ b/src/hotspot/share/opto/split_if.cpp @@ -201,6 +201,24 @@ bool PhaseIdealLoop::split_up( Node *n, Node *blk1, Node *blk2 ) { return true; } } + if (n->Opcode() == Op_OpaqueLoopStride || n->Opcode() == Op_OpaqueLoopInit) { + Unique_Node_List wq; + wq.push(n); + for (uint i = 0; i < wq.size(); i++) { + Node* m = wq.at(i); + if (m->is_If()) { + assert(skeleton_predicate_has_opaque(m->as_If()), "opaque node not reachable from if?"); + Node* bol = clone_skeleton_predicate_bool(m, NULL, NULL, m->in(0)); + _igvn.replace_input_of(m, 1, bol); + } else { + assert(!m->is_CFG(), "not CFG expected"); + for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax; j++) { + Node* u = m->fast_out(j); + wq.push(u); + } + } + } + } // See if splitting-up a Store. Any anti-dep loads must go up as // well. An anti-dep load might be in the wrong block, because in diff --git a/test/hotspot/jtreg/compiler/loopopts/TestPredicateInputBelowLoopPredicate.java b/test/hotspot/jtreg/compiler/loopopts/TestPredicateInputBelowLoopPredicate.java new file mode 100644 index 00000000000..8ffa476ff26 --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/TestPredicateInputBelowLoopPredicate.java @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2022, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * bug 8280799 + * @summary С2: assert(false) failed: cyclic dependency prevents range check elimination + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseCountedLoopSafepoints TestPredicateInputBelowLoopPredicate + */ + +public class TestPredicateInputBelowLoopPredicate { + private static final Object object = new Object(); + private static int fieldStop = 100; + private static int[] array = new int[200]; + private static int[] array2 = new int[200]; + private static int fieldStart = 0; + + public static void main(String[] args) { + for (int i = 0; i < 20_000; i++) { + test(true); + test(false); + } + } + + private static void test(boolean flag) { + if (array == null) { + } + int start = fieldStart; + int i = start; + for(;;) { + int j; + for (j = -10; j < 0; j++) { + } + int stop = fieldStop; + // bound check becomes candidate for predication once + // loop above is optimized out + array[stop - i + j] = 0; + + // A bunch of stuff to grow loop body size and prevent peeling: + array2[0] = 0; + array2[1] = 0; + array2[2] = 0; + array2[3] = 0; + array2[4] = 0; + array2[5] = 0; + array2[6] = 0; + array2[7] = 0; + array2[8] = 0; + array2[9] = 0; + array2[10] = 0; + array2[11] = 0; + array2[12] = 0; + array2[13] = 0; + array2[14] = 0; + array2[15] = 0; + array2[16] = 0; + array2[17] = 0; + array2[18] = 0; + array2[19] = 0; + array2[20] = 0; + array2[21] = 0; + array2[22] = 0; + array2[23] = 0; + array2[24] = 0; + array2[25] = 0; + array2[26] = 0; + array2[27] = 0; + array2[28] = 0; + array2[29] = 0; + array2[30] = 0; + array2[31] = 0; + array2[32] = 0; + array2[33] = 0; + array2[34] = 0; + array2[35] = 0; + array2[36] = 0; + array2[37] = 0; + array2[38] = 0; + array2[39] = 0; + array2[40] = 0; + array2[41] = 0; + array2[42] = 0; + array2[43] = 0; + array2[44] = 0; + array2[45] = 0; + array2[46] = 0; + array2[47] = 0; + array2[48] = 0; + array2[49] = 0; + array2[50] = 0; + array2[51] = 0; + array2[52] = 0; + array2[53] = 0; + array2[54] = 0; + array2[55] = 0; + array2[56] = 0; + array2[57] = 0; + array2[58] = 0; + array2[59] = 0; + array2[60] = 0; + array2[61] = 0; + array2[62] = 0; + array2[63] = 0; + array2[64] = 0; + array2[65] = 0; + array2[66] = 0; + array2[67] = 0; + array2[68] = 0; + array2[69] = 0; + array2[70] = 0; + array2[71] = 0; + array2[72] = 0; + array2[73] = 0; + array2[74] = 0; + array2[75] = 0; + array2[76] = 0; + array2[77] = 0; + array2[78] = 0; + array2[79] = 0; + array2[80] = 0; + array2[81] = 0; + array2[82] = 0; + array2[83] = 0; + array2[84] = 0; + array2[85] = 0; + array2[86] = 0; + array2[87] = 0; + array2[88] = 0; + array2[89] = 0; + array2[90] = 0; + array2[91] = 0; + array2[92] = 0; + array2[93] = 0; + array2[94] = 0; + array2[95] = 0; + array2[96] = 0; + array2[97] = 0; + array2[98] = 0; + array2[99] = 0; + + array2[100] = 0; + array2[101] = 0; + array2[102] = 0; + array2[103] = 0; + array2[104] = 0; + array2[105] = 0; + array2[106] = 0; + array2[107] = 0; + array2[108] = 0; + array2[109] = 0; + array2[110] = 0; + array2[111] = 0; + array2[112] = 0; + array2[113] = 0; + array2[114] = 0; + array2[115] = 0; + array2[116] = 0; + array2[117] = 0; + array2[118] = 0; + array2[119] = 0; + array2[120] = 0; + array2[121] = 0; + array2[122] = 0; + array2[123] = 0; + array2[124] = 0; + array2[125] = 0; + array2[126] = 0; + array2[127] = 0; + array2[128] = 0; + array2[129] = 0; + array2[130] = 0; + array2[131] = 0; + array2[132] = 0; + array2[133] = 0; + array2[134] = 0; + array2[135] = 0; + array2[136] = 0; + array2[137] = 0; + array2[138] = 0; + array2[139] = 0; + array2[140] = 0; + array2[141] = 0; + array2[142] = 0; + array2[143] = 0; + array2[144] = 0; + array2[145] = 0; + array2[146] = 0; + array2[147] = 0; + array2[148] = 0; + array2[149] = 0; + array2[150] = 0; + array2[151] = 0; + array2[152] = 0; + array2[153] = 0; + array2[154] = 0; + array2[155] = 0; + array2[156] = 0; + array2[157] = 0; + array2[158] = 0; + array2[159] = 0; + array2[160] = 0; + array2[161] = 0; + array2[162] = 0; + array2[163] = 0; + array2[164] = 0; + array2[165] = 0; + array2[166] = 0; + array2[167] = 0; + array2[168] = 0; + array2[169] = 0; + array2[170] = 0; + array2[171] = 0; + array2[172] = 0; + array2[173] = 0; + array2[174] = 0; + array2[175] = 0; + array2[176] = 0; + array2[177] = 0; + array2[178] = 0; + array2[179] = 0; + array2[180] = 0; + array2[181] = 0; + array2[182] = 0; + array2[183] = 0; + array2[184] = 0; + array2[185] = 0; + array2[186] = 0; + array2[187] = 0; + array2[188] = 0; + array2[189] = 0; + array2[190] = 0; + array2[191] = 0; + array2[192] = 0; + array2[193] = 0; + array2[194] = 0; + array2[195] = 0; + array2[196] = 0; + array2[197] = 0; + array2[198] = 0; + array2[199] = 0; + i++; + + if (i == stop) { // requires a loop limit predicate + break; + } + } + } +} -- GitLab From 46f522962f1b2bbb2513823821e332db1093994b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 14 Feb 2022 08:37:31 +0000 Subject: [PATCH 231/400] 8281539: IGV: schedule approximation computes immediate dominators wrongly Replace custom dominator computation with one from the WALA libraries. Reviewed-by: neliasso, chagedorn --- .../ServerCompiler/pom.xml | 7 +- .../ServerCompilerScheduler.java | 173 ++---------------- src/utils/IdealGraphVisualizer/pom.xml | 3 +- 3 files changed, 26 insertions(+), 157 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/pom.xml b/src/utils/IdealGraphVisualizer/ServerCompiler/pom.xml index b43145fa974..79209514ebc 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/pom.xml +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/pom.xml @@ -1,6 +1,6 @@ server // client <--- 401 ---- server try (Socket s = ss.accept()) { - new MessageHeader().parseHeader(s.getInputStream()); + new HttpHeaderParser().parse(s.getInputStream()); s.getOutputStream().write(reply.getBytes("US-ASCII")); } @@ -171,10 +171,10 @@ public class NoNTLM { // client <--- 200 ---- server String auth; try (Socket s = ss.accept()) { - MessageHeader mh = new MessageHeader(); - mh.parseHeader(s.getInputStream()); + HttpHeaderParser mh = new HttpHeaderParser(); + mh.parse(s.getInputStream()); s.getOutputStream().write(OKAY.getBytes("US-ASCII")); - auth = mh.findValue("Authorization"); + auth = mh.getHeaderValue("Authorization").get(0); } // check Authorization header @@ -208,7 +208,7 @@ public class NoNTLM { // client ---- GET ---> server // client <--- 401 ---- client try (Socket s = ss.accept()) { - new MessageHeader().parseHeader(s.getInputStream()); + new HttpHeaderParser().parse(s.getInputStream()); s.getOutputStream().write(reply.getBytes("US-ASCII")); } diff --git a/test/jdk/sun/net/www/protocol/http/RetryUponTimeout.java b/test/jdk/sun/net/www/protocol/http/RetryUponTimeout.java index bfda1663259..b2214780c2e 100644 --- a/test/jdk/sun/net/www/protocol/http/RetryUponTimeout.java +++ b/test/jdk/sun/net/www/protocol/http/RetryUponTimeout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -26,13 +26,13 @@ * @bug 4772077 * @library /test/lib * @summary using defaultReadTimeout appear to retry request upon timeout - * @modules java.base/sun.net.www */ import java.net.*; import java.io.*; + +import jdk.test.lib.net.HttpHeaderParser; import jdk.test.lib.net.URIBuilder; -import sun.net.www.*; public class RetryUponTimeout implements Runnable { // run server @@ -42,7 +42,7 @@ public class RetryUponTimeout implements Runnable { for (int i = 0; i < 2; i++) { socket = server.accept(); InputStream is = socket.getInputStream (); - MessageHeader header = new MessageHeader (is); + HttpHeaderParser header = new HttpHeaderParser (is); count++; } } catch (Exception ex) { diff --git a/test/jdk/sun/net/www/protocol/http/UserAgent.java b/test/jdk/sun/net/www/protocol/http/UserAgent.java index 7db84882488..40ff5d3106f 100644 --- a/test/jdk/sun/net/www/protocol/http/UserAgent.java +++ b/test/jdk/sun/net/www/protocol/http/UserAgent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -25,7 +25,6 @@ * @test * @bug 4512200 * @library /test/lib - * @modules java.base/sun.net.www * @run main/othervm -Dhttp.agent=foo UserAgent * @run main/othervm -Dhttp.agent=foo -Djava.net.preferIPv6Addresses=true UserAgent * @summary HTTP header "User-Agent" format incorrect @@ -34,8 +33,9 @@ import java.io.*; import java.util.*; import java.net.*; + +import jdk.test.lib.net.HttpHeaderParser; import jdk.test.lib.net.URIBuilder; -import sun.net.www.MessageHeader; class Server extends Thread { Server (ServerSocket server) { @@ -46,8 +46,8 @@ class Server extends Thread { String version = System.getProperty ("java.version"); String expected = "foo Java/"+version; Socket s = server.accept (); - MessageHeader header = new MessageHeader (s.getInputStream()); - String v = header.findValue ("User-Agent"); + HttpHeaderParser header = new HttpHeaderParser (s.getInputStream()); + String v = header.getHeaderValue ("User-Agent").get(0); if (!expected.equals (v)) { error ("Got unexpected User-Agent: " + v); } else { diff --git a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/B6226610.java b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/B6226610.java index ec75bcc3e11..9fca12c9958 100644 --- a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/B6226610.java +++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/B6226610.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,7 +25,7 @@ * @test * @bug 6226610 6973030 * @summary HTTP tunnel connections send user headers to proxy - * @modules java.base/sun.net.www + * @library /test/lib * @run main/othervm B6226610 */ @@ -37,7 +37,9 @@ import java.io.*; import java.net.*; -import sun.net.www.MessageHeader; + +import jdk.test.lib.net.HttpHeaderParser; + public class B6226610 { static HeaderCheckerProxyTunnelServer proxy; @@ -138,21 +140,21 @@ class HeaderCheckerProxyTunnelServer extends Thread private void processRequests() throws IOException { InputStream in = clientSocket.getInputStream(); - MessageHeader mheader = new MessageHeader(in); - String statusLine = mheader.getValue(0); + HttpHeaderParser mheader = new HttpHeaderParser(in); + String statusLine = mheader.getRequestDetails(); if (statusLine.startsWith("CONNECT")) { // retrieve the host and port info from the status-line retrieveConnectInfo(statusLine); - if (mheader.findValue("X-TestHeader") != null) { + if (mheader.getHeaderValue("X-TestHeader") != null) { System.out.println("Proxy should not receive user defined headers for tunneled requests"); failed = true; } // 6973030 String value; - if ((value = mheader.findValue("Proxy-Connection")) == null || + if ((value = mheader.getHeaderValue("Proxy-Connection").get(0)) == null || !value.equals("keep-alive")) { System.out.println("Proxy-Connection:keep-alive not being sent"); failed = true; diff --git a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/TunnelProxy.java b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/TunnelProxy.java index 9573543fde1..979e8be9acd 100644 --- a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/TunnelProxy.java +++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/TunnelProxy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -45,7 +45,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Set; -import sun.net.www.MessageHeader; +import jdk.test.lib.net.HttpHeaderParser; + public class TunnelProxy { @@ -261,7 +262,7 @@ public class TunnelProxy { try { InputStream is = new BufferedInputStream (new NioInputStream (chan)); String requestline = readLine (is); - MessageHeader mhead = new MessageHeader (is); + HttpHeaderParser mhead = new HttpHeaderParser (is); String[] req = requestline.split (" "); if (req.length < 2) { /* invalid request line */ diff --git a/test/lib/jdk/test/lib/net/HttpHeaderParser.java b/test/lib/jdk/test/lib/net/HttpHeaderParser.java new file mode 100644 index 00000000000..71b3a84fdaa --- /dev/null +++ b/test/lib/jdk/test/lib/net/HttpHeaderParser.java @@ -0,0 +1,390 @@ +/* + * 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. + * + * 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.test.lib.net; + +import java.io.IOException; +import java.io.InputStream; +import java.net.ProtocolException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import static java.util.Objects.requireNonNull; + +public class HttpHeaderParser { + private static final char CR = '\r'; + private static final char LF = '\n'; + private static final char HT = '\t'; + private static final char SP = ' '; + // ABNF primitives defined in RFC 7230 + private static boolean[] tchar = new boolean[256]; + private static boolean[] fieldvchar = new boolean[256]; + + static { + char[] allowedTokenChars = + ("!#$%&'*+-.^_`|~0123456789" + + "abcdefghijklmnopqrstuvwxyz" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray(); + for (char c : allowedTokenChars) { + tchar[c] = true; + } + for (char c = 0x21; c <= 0xFF; c++) { + fieldvchar[c] = true; + } + fieldvchar[0x7F] = false; // a little hole (DEL) in the range + } + + private StringBuilder sb = new StringBuilder(); + + private Map > headerMap = new LinkedHashMap<>(); + private List keyList = new ArrayList<>(); + private String requestOrStatusLine; + private int responseCode; + private boolean eof; + + + + enum State { INITIAL, + STATUS_OR_REQUEST_LINE, + STATUS_OR_REQUEST_LINE_FOUND_CR, + STATUS_OR_REQUEST_LINE_FOUND_LF, + STATUS_OR_REQUEST_LINE_END, + STATUS_OR_REQUEST_LINE_END_CR, + STATUS_OR_REQUEST_LINE_END_LF, + HEADER, + HEADER_FOUND_CR, + HEADER_FOUND_LF, + HEADER_FOUND_CR_LF, + HEADER_FOUND_CR_LF_CR, + FINISHED } + + private HttpHeaderParser.State state = HttpHeaderParser.State.INITIAL; + + public HttpHeaderParser() { + } + + + public HttpHeaderParser(InputStream is) throws IOException, ProtocolException { + parse(is); + } + + public Map> getHeaderMap() { + return headerMap; + } + + public List getHeaderValue(String key) { + if(headerMap.containsKey(key.toLowerCase(Locale.ROOT))) { + return headerMap.get(key.toLowerCase(Locale.ROOT)); + } + return null; + } + public List getValue(int id) { + String key = keyList.get(id); + return headerMap.get(key); + } + + public String getRequestDetails() { + return requestOrStatusLine; + } + + /** + * Parses HTTP/1.X status-line or request-line and headers from the given input stream. + * @param input Containing the input stream of bytes representing request or response header data + * @return true if the end of the headers block has been reached + */ + public boolean parse(InputStream input) throws IOException { + requireNonNull(input, "null input"); + while (canContinueParsing()) { + switch (state) { + case INITIAL -> state = HttpHeaderParser.State.STATUS_OR_REQUEST_LINE; + case STATUS_OR_REQUEST_LINE -> readResumeStatusLine(input); + case STATUS_OR_REQUEST_LINE_FOUND_CR, STATUS_OR_REQUEST_LINE_FOUND_LF -> readStatusLineFeed(input); + case STATUS_OR_REQUEST_LINE_END -> maybeStartHeaders(input); + case STATUS_OR_REQUEST_LINE_END_CR, STATUS_OR_REQUEST_LINE_END_LF -> maybeEndHeaders(input); + case HEADER -> readResumeHeader(input); + case HEADER_FOUND_CR, HEADER_FOUND_LF -> resumeOrLF(input); + case HEADER_FOUND_CR_LF -> resumeOrSecondCR(input); + case HEADER_FOUND_CR_LF_CR -> resumeOrEndHeaders(input); + default -> throw new InternalError("Unexpected state: " + state); + } + } + return state == HttpHeaderParser.State.FINISHED; + } + + private boolean canContinueParsing() { + // some states don't require any input to transition + // to the next state. + return switch (state) { + case FINISHED -> false; + case STATUS_OR_REQUEST_LINE_FOUND_LF, STATUS_OR_REQUEST_LINE_END_LF, HEADER_FOUND_LF -> true; + default -> !eof; + }; + } + + /** + * Returns a character (char) corresponding to the next byte in the + * input, interpreted as an ISO-8859-1 encoded character. + *

    + * The ISO-8859-1 encoding is a 8-bit character coding that + * corresponds to the first 256 Unicode characters - from U+0000 to + * U+00FF. UTF-16 is backward compatible with ISO-8859-1 - which + * means each byte in the input should be interpreted as an unsigned + * value from [0, 255] representing the character code. + * + * @param input a {@code InputStream} containing input stream of Bytes. + * @return the next byte in the input, interpreted as an ISO-8859-1 + * encoded char + * @throws IOException + * if an I/O error occurs. + */ + private char get(InputStream input) throws IOException { + int c = input.read(); + if(c < 0) + eof = true; + return (char)(c & 0xFF); + } + + private void readResumeStatusLine(InputStream input) throws IOException { + char c; + while ((c = get(input)) != CR && !eof) { + if (c == LF) break; + sb.append(c); + } + if (c == CR) { + state = HttpHeaderParser.State.STATUS_OR_REQUEST_LINE_FOUND_CR; + } else if (c == LF) { + state = HttpHeaderParser.State.STATUS_OR_REQUEST_LINE_FOUND_LF; + } + } + + private void readStatusLineFeed(InputStream input) throws IOException { + char c = state == HttpHeaderParser.State.STATUS_OR_REQUEST_LINE_FOUND_LF ? LF : get(input); + if (c != LF) { + throw protocolException("Bad trailing char, \"%s\", when parsing status line, \"%s\"", + c, sb.toString()); + } + requestOrStatusLine = sb.toString(); + sb = new StringBuilder(); + if (!requestOrStatusLine.startsWith("HTTP/1.")) { + if(!requestOrStatusLine.startsWith("GET") && !requestOrStatusLine.startsWith("POST") && + !requestOrStatusLine.startsWith("PUT") && !requestOrStatusLine.startsWith("DELETE") && + !requestOrStatusLine.startsWith("OPTIONS") && !requestOrStatusLine.startsWith("HEAD") && + !requestOrStatusLine.startsWith("PATCH") && !requestOrStatusLine.startsWith("CONNECT")) { + throw protocolException("Invalid request Or Status line: \"%s\"", requestOrStatusLine); + } else { //This is request + System.out.println("Request is :"+requestOrStatusLine); + } + } else { //This is response + if (requestOrStatusLine.length() < 12) { + throw protocolException("Invalid status line: \"%s\"", requestOrStatusLine); + } + try { + responseCode = Integer.parseInt(requestOrStatusLine.substring(9, 12)); + } catch (NumberFormatException nfe) { + throw protocolException("Invalid status line: \"%s\"", requestOrStatusLine); + } + // response code expected to be a 3-digit integer (RFC-2616, section 6.1.1) + if (responseCode < 100) { + throw protocolException("Invalid status line: \"%s\"", requestOrStatusLine); + } + } + state = HttpHeaderParser.State.STATUS_OR_REQUEST_LINE_END; + } + + private void maybeStartHeaders(InputStream input) throws IOException { + assert state == HttpHeaderParser.State.STATUS_OR_REQUEST_LINE_END; + assert sb.length() == 0; + char c = get(input); + if(!eof) { + if (c == CR) { + state = HttpHeaderParser.State.STATUS_OR_REQUEST_LINE_END_CR; + } else if (c == LF) { + state = HttpHeaderParser.State.STATUS_OR_REQUEST_LINE_END_LF; + } else { + sb.append(c); + state = HttpHeaderParser.State.HEADER; + } + } + } + + private void maybeEndHeaders(InputStream input) throws IOException { + assert state == HttpHeaderParser.State.STATUS_OR_REQUEST_LINE_END_CR || state == HttpHeaderParser.State.STATUS_OR_REQUEST_LINE_END_LF; + assert sb.length() == 0; + char c = state == HttpHeaderParser.State.STATUS_OR_REQUEST_LINE_END_LF ? LF : get(input); + if (c == LF) { + state = HttpHeaderParser.State.FINISHED; // no headers + } else { + throw protocolException("Unexpected \"%s\", after status line CR", c); + } + } + + private void readResumeHeader(InputStream input) throws IOException { + assert state == HttpHeaderParser.State.HEADER; + assert !eof; + char c = get(input); + while (!eof) { + if (c == CR) { + state = HttpHeaderParser.State.HEADER_FOUND_CR; + break; + } else if (c == LF) { + state = HttpHeaderParser.State.HEADER_FOUND_LF; + break; + } + if (c == HT) + c = SP; + sb.append(c); + c = get(input); + } + } + + private void addHeaderFromString(String headerString) throws ProtocolException { + assert sb.length() == 0; + int idx = headerString.indexOf(':'); + if (idx == -1) + return; + String name = headerString.substring(0, idx); + + // compatibility with HttpURLConnection; + if (name.isEmpty()) return; + + if (!isValidName(name)) { + throw protocolException("Invalid header name \"%s\"", name); + } + String value = headerString.substring(idx + 1).trim(); + if (!isValidValue(value)) { + throw protocolException("Invalid header value \"%s: %s\"", name, value); + } + + keyList.add(name); + headerMap.computeIfAbsent(name.toLowerCase(Locale.US), + k -> new ArrayList<>()).add(value); + } + + private void resumeOrLF(InputStream input) throws IOException { + assert state == HttpHeaderParser.State.HEADER_FOUND_CR || state == HttpHeaderParser.State.HEADER_FOUND_LF; + char c = state == HttpHeaderParser.State.HEADER_FOUND_LF ? LF : get(input); + if (!eof) { + if (c == LF) { + state = HttpHeaderParser.State.HEADER_FOUND_CR_LF; + } else if (c == SP || c == HT) { + sb.append(SP); // parity with MessageHeaders + state = HttpHeaderParser.State.HEADER; + } else { + sb = new StringBuilder(); + sb.append(c); + state = HttpHeaderParser.State.HEADER; + } + } + } + + private void resumeOrSecondCR(InputStream input) throws IOException { + assert state == HttpHeaderParser.State.HEADER_FOUND_CR_LF; + char c = get(input); + if (!eof) { + if (c == CR || c == LF) { + if (sb.length() > 0) { + // no continuation line - flush + // previous header value. + String headerString = sb.toString(); + sb = new StringBuilder(); + addHeaderFromString(headerString); + } + if (c == CR) { + state = HttpHeaderParser.State.HEADER_FOUND_CR_LF_CR; + } else { + state = HttpHeaderParser.State.FINISHED; + } + } else if (c == SP || c == HT) { + assert sb.length() != 0; + sb.append(SP); // continuation line + state = HttpHeaderParser.State.HEADER; + } else { + if (sb.length() > 0) { + // no continuation line - flush + // previous header value. + String headerString = sb.toString(); + sb = new StringBuilder(); + addHeaderFromString(headerString); + } + sb.append(c); + state = HttpHeaderParser.State.HEADER; + } + } + } + + private void resumeOrEndHeaders(InputStream input) throws IOException { + assert state == HttpHeaderParser.State.HEADER_FOUND_CR_LF_CR; + char c = get(input); + if (!eof) { + if (c == LF) { + state = HttpHeaderParser.State.FINISHED; + } else { + throw protocolException("Unexpected \"%s\", after CR LF CR", c); + } + } + } + + private ProtocolException protocolException(String format, Object ... args) { + return new ProtocolException(String.format(format, args)); + } + + /* + * Validates a RFC 7230 field-name. + */ + public boolean isValidName(String token) { + for (int i = 0; i < token.length(); i++) { + char c = token.charAt(i); + if (c > 255 || !tchar[c]) { + return false; + } + } + return !token.isEmpty(); + } + + /* + * Validates a RFC 7230 field-value. + * + * "Obsolete line folding" rule + * + * obs-fold = CRLF 1*( SP / HTAB ) + * + * is not permitted! + */ + public boolean isValidValue(String token) { + for (int i = 0; i < token.length(); i++) { + char c = token.charAt(i); + if (c > 255) { + return false; + } + if (c == ' ' || c == '\t') { + continue; + } else if (!fieldvchar[c]) { + return false; // forbidden byte + } + } + return true; + } +} -- GitLab From 9b74c3f2e74a4efdec1c1488e96ab5939a408df0 Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Wed, 16 Feb 2022 16:54:53 +0000 Subject: [PATCH 269/400] 8176706: Additional Date-Time Formats Reviewed-by: joehw, rriggs --- .../build/tools/cldrconverter/Bundle.java | 82 ++++-- .../tools/cldrconverter/CLDRConverter.java | 20 +- .../tools/cldrconverter/LDMLParseHandler.java | 12 +- .../SupplementDataParseHandler.java | 52 ++-- .../java/time/format/DateTimeFormatter.java | 54 +++- .../time/format/DateTimeFormatterBuilder.java | 204 ++++++++++++--- .../spi/JavaTimeDateTimePatternProvider.java | 27 +- .../provider/JavaTimeDateTimePatternImpl.java | 22 +- .../util/locale/provider/LocaleResources.java | 233 +++++++++++++++++- .../time/format/Skeletons_en_US.properties | 51 ++++ .../java/time/format/Skeletons_ja.properties | 43 ++++ .../time/format/TestLocalizedPattern.java | 105 ++++++++ 12 files changed, 809 insertions(+), 96 deletions(-) create mode 100644 test/jdk/java/time/test/java/time/format/Skeletons_en_US.properties create mode 100644 test/jdk/java/time/test/java/time/format/Skeletons_ja.properties create mode 100644 test/jdk/java/time/test/java/time/format/TestLocalizedPattern.java diff --git a/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java b/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java index 9f262fa0106..952e28fd43b 100644 --- a/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java +++ b/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -25,6 +25,9 @@ package build.tools.cldrconverter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; @@ -34,6 +37,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; import java.util.stream.IntStream; class Bundle { @@ -47,21 +51,21 @@ class Bundle { FORMATDATA); } - private final static Map bundles = new HashMap<>(); + private static final Map bundles = new HashMap<>(); - private final static String[] NUMBER_PATTERN_KEYS = { + private static final String[] NUMBER_PATTERN_KEYS = { "NumberPatterns/decimal", "NumberPatterns/currency", "NumberPatterns/percent", "NumberPatterns/accounting" }; - private final static String[] COMPACT_NUMBER_PATTERN_KEYS = { - "short.CompactNumberPatterns", - "long.CompactNumberPatterns" + private static final String[] COMPACT_NUMBER_PATTERN_KEYS = { + "short.CompactNumberPatterns", + "long.CompactNumberPatterns" }; - private final static String[] NUMBER_ELEMENT_KEYS = { + private static final String[] NUMBER_ELEMENT_KEYS = { "NumberElements/decimal", "NumberElements/group", "NumberElements/list", @@ -77,41 +81,45 @@ class Bundle { "NumberElements/currencyGroup", }; - private final static String[] TIME_PATTERN_KEYS = { + private static final String[] TIME_PATTERN_KEYS = { "DateTimePatterns/full-time", "DateTimePatterns/long-time", "DateTimePatterns/medium-time", "DateTimePatterns/short-time", }; - private final static String[] DATE_PATTERN_KEYS = { + private static final String[] DATE_PATTERN_KEYS = { "DateTimePatterns/full-date", "DateTimePatterns/long-date", "DateTimePatterns/medium-date", "DateTimePatterns/short-date", }; - private final static String[] DATETIME_PATTERN_KEYS = { + private static final String[] DATETIME_PATTERN_KEYS = { "DateTimePatterns/full-dateTime", "DateTimePatterns/long-dateTime", "DateTimePatterns/medium-dateTime", "DateTimePatterns/short-dateTime", }; - private final static String[] ERA_KEYS = { + private static final String[] ERA_KEYS = { "long.Eras", "Eras", "narrow.Eras" }; + // DateFormatItem prefix + static final String DATEFORMATITEM_KEY_PREFIX = "DateFormatItem."; + static final String DATEFORMATITEM_INPUT_REGIONS_PREFIX = "DateFormatItemInputRegions."; + // Keys for individual time zone names - private final static String TZ_GEN_LONG_KEY = "timezone.displayname.generic.long"; - private final static String TZ_GEN_SHORT_KEY = "timezone.displayname.generic.short"; - private final static String TZ_STD_LONG_KEY = "timezone.displayname.standard.long"; - private final static String TZ_STD_SHORT_KEY = "timezone.displayname.standard.short"; - private final static String TZ_DST_LONG_KEY = "timezone.displayname.daylight.long"; - private final static String TZ_DST_SHORT_KEY = "timezone.displayname.daylight.short"; - private final static String[] ZONE_NAME_KEYS = { + private static final String TZ_GEN_LONG_KEY = "timezone.displayname.generic.long"; + private static final String TZ_GEN_SHORT_KEY = "timezone.displayname.generic.short"; + private static final String TZ_STD_LONG_KEY = "timezone.displayname.standard.long"; + private static final String TZ_STD_SHORT_KEY = "timezone.displayname.standard.short"; + private static final String TZ_DST_LONG_KEY = "timezone.displayname.daylight.long"; + private static final String TZ_DST_SHORT_KEY = "timezone.displayname.daylight.short"; + private static final String[] ZONE_NAME_KEYS = { TZ_STD_LONG_KEY, TZ_STD_SHORT_KEY, TZ_DST_LONG_KEY, @@ -262,7 +270,7 @@ class Bundle { CLDRConverter.handleAliases(myMap); // another hack: parentsMap is not used for date-time resources. - if ("root".equals(id)) { + if (isRoot()) { parentsMap = null; } @@ -287,6 +295,14 @@ class Bundle { handleDateTimeFormatPatterns(TIME_PATTERN_KEYS, myMap, parentsMap, calendarType, "TimePatterns"); handleDateTimeFormatPatterns(DATE_PATTERN_KEYS, myMap, parentsMap, calendarType, "DatePatterns"); handleDateTimeFormatPatterns(DATETIME_PATTERN_KEYS, myMap, parentsMap, calendarType, "DateTimePatterns"); + + // Skeleton + handleSkeletonPatterns(myMap, calendarType); + } + + // Skeleton input regions + if (isRoot()) { + skeletonInputRegions(myMap); } // First, weed out any empty timezone or metazone names from myMap. @@ -647,8 +663,9 @@ class Bundle { private void convertDateTimePatternLetter(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb) { switch (cldrLetter) { case 'u': - // Change cldr letter 'u' to 'y', as 'u' is interpreted as - // "Extended year (numeric)" in CLDR/LDML, + case 'U': + // Change cldr letter 'u'/'U' to 'y', as 'u' is interpreted as + // "Extended year (numeric)", and 'U' as "Cyclic year" in CLDR/LDML, // which is not supported in SimpleDateFormat and // j.t.f.DateTimeFormatter, so it is replaced with 'y' // as the best approximation @@ -742,6 +759,19 @@ class Bundle { return false; } + private void handleSkeletonPatterns(Map myMap, CalendarType calendarType) { + String calendarPrefix = calendarType.keyElementName(); + myMap.putAll(myMap.entrySet().stream() + .filter(e -> e.getKey().startsWith(Bundle.DATEFORMATITEM_KEY_PREFIX)) + .collect(Collectors.toMap( + e -> calendarPrefix + e.getKey(), + e -> translateDateFormatLetters(calendarType, + (String)e.getValue(), + this::convertDateTimePatternLetter) + )) + ); + } + @FunctionalInterface private interface ConvertDateTimeLetters { void convert(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb); @@ -790,4 +820,14 @@ class Bundle { } return numArray; } + + private static void skeletonInputRegions(Map myMap) { + myMap.putAll(myMap.entrySet().stream() + .filter(e -> e.getKey().startsWith(Bundle.DATEFORMATITEM_INPUT_REGIONS_PREFIX)) + .collect(Collectors.toMap( + e -> e.getKey(), + e -> ((String)e.getValue()).trim() + )) + ); + } } diff --git a/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java b/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java index 267f93e733b..abf1be64306 100644 --- a/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java +++ b/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -847,20 +847,19 @@ public class CLDRConverter { "DateTimePatternChars", "PluralRules", "DayPeriodRules", + "DateFormatItem", }; private static Map extractFormatData(Map map, String id) { Map formatData = new LinkedHashMap<>(); for (CalendarType calendarType : CalendarType.values()) { - if (calendarType == CalendarType.GENERIC) { - continue; - } String prefix = calendarType.keyElementName(); - for (String element : FORMAT_DATA_ELEMENTS) { - String key = prefix + element; - copyIfPresent(map, "java.time." + key, formatData); - copyIfPresent(map, key, formatData); - } + Arrays.stream(FORMAT_DATA_ELEMENTS) + .flatMap(elem -> map.keySet().stream().filter(k -> k.startsWith(prefix + elem))) + .forEach(key -> { + copyIfPresent(map, "java.time." + key, formatData); + copyIfPresent(map, key, formatData); + }); } for (String key : map.keySet()) { @@ -868,9 +867,6 @@ public class CLDRConverter { if (key.startsWith(CLDRConverter.LOCALE_TYPE_PREFIX_CA)) { String type = key.substring(CLDRConverter.LOCALE_TYPE_PREFIX_CA.length()); for (CalendarType calendarType : CalendarType.values()) { - if (calendarType == CalendarType.GENERIC) { - continue; - } if (type.equals(calendarType.lname())) { Object value = map.get(key); String dataKey = key.replace(LOCALE_TYPE_PREFIX_CA, diff --git a/make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java b/make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java index 745796d96cf..668c187c383 100644 --- a/make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java +++ b/make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -756,6 +756,14 @@ class LDMLParseHandler extends AbstractLDMLHandler { pushStringEntry(qName, attributes, prefix + "DateTimePatterns/" + attributes.getValue("type") + "-dateTime"); } break; + case "dateFormatItem": + { + // for FormatData + String prefix = (currentCalendarType == null) ? "" : currentCalendarType.keyElementName(); + pushStringEntry(qName, attributes, + prefix + Bundle.DATEFORMATITEM_KEY_PREFIX + attributes.getValue("id")); + } + break; case "localizedPatternChars": { // for FormatData @@ -1113,7 +1121,7 @@ class LDMLParseHandler extends AbstractLDMLHandler { if (id.equals("root") && key.startsWith("MonthNames")) { value = new DateFormatSymbols(Locale.US).getShortMonths(); } - return put(entry.getKey(), value); + return put(key, value); } } return null; diff --git a/make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java b/make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java index fdc8a977766..11547ccb38e 100644 --- a/make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java +++ b/make/jdk/src/classes/build/tools/cldrconverter/SupplementDataParseHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -27,8 +27,12 @@ package build.tools.cldrconverter; import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.stream.Collectors; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -62,10 +66,15 @@ class SupplementDataParseHandler extends AbstractLDMLHandler { // parentLocale.=(" ")+ private final Map parentLocalesMap; + // Input Skeleton map for "preferred" and "allowed" + // Map<"preferred"/"allowed", Map<"skeleton", SortedSet<"regions">>> + private final Map>> inputSkeletonMap; + SupplementDataParseHandler() { firstDayMap = new HashMap<>(); minDaysMap = new HashMap<>(); parentLocalesMap = new HashMap<>(); + inputSkeletonMap = new HashMap<>(); } /** @@ -76,22 +85,25 @@ class SupplementDataParseHandler extends AbstractLDMLHandler { * It returns null when there is no firstDay and minDays for the country * although this should not happen because supplementalData.xml includes * default value for the world ("001") for firstDay and minDays. + * + * This method also returns Maps for "preferred" and "allowed" skeletons, + * which are grouped by regions. E.g, "h:XX YY ZZ;" which means 'h' pattern + * is "preferred"/"allowed" in "XX", "YY", and "ZZ" regions. */ Map getData(String id) { Map values = new HashMap<>(); if ("root".equals(id)) { - parentLocalesMap.keySet().forEach(key -> { - values.put(CLDRConverter.PARENT_LOCALE_PREFIX+key, - parentLocalesMap.get(key)); - }); - firstDayMap.keySet().forEach(key -> { - values.put(CLDRConverter.CALENDAR_FIRSTDAY_PREFIX+firstDayMap.get(key), - key); - }); - minDaysMap.keySet().forEach(key -> { - values.put(CLDRConverter.CALENDAR_MINDAYS_PREFIX+minDaysMap.get(key), - key); - }); + parentLocalesMap.forEach((k, v) -> values.put(CLDRConverter.PARENT_LOCALE_PREFIX + k, v)); + firstDayMap.forEach((k, v) -> values.put(CLDRConverter.CALENDAR_FIRSTDAY_PREFIX + v, k)); + minDaysMap.forEach((k, v) -> values.put(CLDRConverter.CALENDAR_MINDAYS_PREFIX + v, k)); + inputSkeletonMap.get("preferred").forEach((k, v) -> + values.merge(Bundle.DATEFORMATITEM_INPUT_REGIONS_PREFIX + "preferred", + k + ":" + v.stream().collect(Collectors.joining(" ")) + ";", + (old, newVal) -> old + (String)newVal)); + inputSkeletonMap.get("allowed").forEach((k, v) -> + values.merge(Bundle.DATEFORMATITEM_INPUT_REGIONS_PREFIX + "allowed", + k + ":" + v.stream().collect(Collectors.joining(" ")) + ";", + (old, newVal) -> old + (String)newVal)); } return values.isEmpty() ? null : values; } @@ -158,11 +170,23 @@ class SupplementDataParseHandler extends AbstractLDMLHandler { attributes.getValue("locales").replaceAll("_", "-")); } break; + case "hours": + if (!isIgnored(attributes)) { + var preferred = attributes.getValue("preferred"); + var allowed = attributes.getValue("allowed").replaceFirst(" .*", "").replaceFirst("b", "B"); // take only the first one, "b" -> "B" + var regions = Arrays.stream(attributes.getValue("regions").split(" ")) + .map(r -> r.replaceAll("_", "-")) + .collect(Collectors.toSet()); + var pmap = inputSkeletonMap.computeIfAbsent("preferred", k -> new HashMap<>()); + var amap = inputSkeletonMap.computeIfAbsent("allowed", k -> new HashMap<>()); + pmap.computeIfAbsent(preferred, k -> new TreeSet<>()).addAll(regions); + amap.computeIfAbsent(allowed, k -> new TreeSet<>()).addAll(regions); + } + break; default: // treat anything else as a container pushContainer(qName, attributes); break; } } - } diff --git a/src/java.base/share/classes/java/time/format/DateTimeFormatter.java b/src/java.base/share/classes/java/time/format/DateTimeFormatter.java index 063b6e14a00..0a67e22c0f3 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeFormatter.java +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -81,7 +81,6 @@ import java.time.Period; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.chrono.ChronoLocalDateTime; -import java.time.chrono.ChronoZonedDateTime; import java.time.chrono.Chronology; import java.time.chrono.IsoChronology; import java.time.format.DateTimeFormatterBuilder.CompositePrinterParser; @@ -718,6 +717,57 @@ public final class DateTimeFormatter { .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE); } + //----------------------------------------------------------------------- + /** + * Creates a locale specific formatter derived from the requested template for + * the ISO chronology. The requested template is a series of typical pattern + * symbols in canonical order from the largest date or time unit to the smallest, + * which can be expressed with the following regular expression: + * {@snippet : + * "G{0,5}" + // Era + * "y*" + // Year + * "Q{0,5}" + // Quarter + * "M{0,5}" + // Month + * "w*" + // Week of Week Based Year + * "E{0,5}" + // Day of Week + * "d{0,2}" + // Day of Month + * "B{0,5}" + // Period/AmPm of Day + * "[hHjC]{0,2}" + // Hour of Day/AmPm (refer to LDML for 'j' and 'C') + * "m{0,2}" + // Minute of Hour + * "s{0,2}" + // Second of Minute + * "[vz]{0,4}" // Zone + * } + * All pattern symbols are optional, and each pattern symbol represents a field, + * for example, 'M' represents the Month field. The number of the pattern symbol letters follows the + * same presentation, such as "number" or "text" as in the Patterns for + * Formatting and Parsing section. Other pattern symbols in the requested template are + * invalid. + *

    + * The mapping of the requested template to the closest of the available localized formats + * is defined by the + * + * Unicode LDML specification. For example, the formatter created from the requested template + * {@code yMMM} will format the date '2020-06-16' to 'Jun 2020' in the {@link Locale#US US locale}. + *

    + * The locale is determined from the formatter. The formatter returned directly by + * this method uses the {@link Locale#getDefault() default FORMAT locale}. + * The locale can be controlled using {@link DateTimeFormatter#withLocale(Locale) withLocale(Locale)} + * on the result of this method. + *

    + * The returned formatter has no override zone. + * It uses {@link ResolverStyle#SMART SMART} resolver style. + * + * @param requestedTemplate the requested template, not null + * @return the formatter based on the {@code requestedTemplate} pattern, not null + * @throws IllegalArgumentException if {@code requestedTemplate} is invalid + * @see #ofPattern(String) + * @since 19 + */ + public static DateTimeFormatter ofLocalizedPattern(String requestedTemplate) { + return new DateTimeFormatterBuilder().appendLocalized(requestedTemplate) + .toFormatter(ResolverStyle.SMART, IsoChronology.INSTANCE); + } + //----------------------------------------------------------------------- /** * The ISO date formatter that formats or parses a date without an diff --git a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java index 40c0de53d3f..62ea488ede7 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java +++ b/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -227,6 +227,42 @@ public final class DateTimeFormatterBuilder { CalendarDataUtility.findRegionOverride(locale)); } + /** + * Returns the formatting pattern for the requested template for a locale and chronology. + * The locale and chronology are used to lookup the locale specific format + * for the requested template. + *

    + * If the locale contains the "rg" (region override) + * Unicode extensions, + * the formatting pattern is overridden with the one appropriate for the region. + *

    + * Refer to {@link #appendLocalized(String)} for the detail of {@code requestedTemplate} + * argument. + * + * @param requestedTemplate the requested template, not null + * @param chrono the Chronology, non-null + * @param locale the locale, non-null + * @return the locale and Chronology specific formatting pattern + * @throws IllegalArgumentException if {@code requestedTemplate} does not match + * the regular expression syntax described in {@link #appendLocalized(String)}. + * @throws DateTimeException if a match for the localized pattern for + * {@code requestedTemplate} is not available + * @see #appendLocalized(String) + * @since 19 + */ + public static String getLocalizedDateTimePattern(String requestedTemplate, + Chronology chrono, Locale locale) { + Objects.requireNonNull(requestedTemplate, "requestedTemplate"); + Objects.requireNonNull(chrono, "chrono"); + Objects.requireNonNull(locale, "locale"); + Locale override = CalendarDataUtility.findRegionOverride(locale); + LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(JavaTimeDateTimePatternProvider.class, override); + JavaTimeDateTimePatternProvider provider = adapter.getJavaTimeDateTimePatternProvider(); + return provider.getJavaTimeDateTimePattern(requestedTemplate, + chrono.getCalendarType(), + override); + } + /** * Converts the given FormatStyle to the java.text.DateFormat style. * @@ -1423,6 +1459,84 @@ public final class DateTimeFormatterBuilder { return this; } + //----------------------------------------------------------------------- + // RegEx pattern for skeleton validity checking + private static final Pattern VALID_TEMPLATE_PATTERN = Pattern.compile( + "G{0,5}" + // Era + "y*" + // Year + "Q{0,5}" + // Quarter + "M{0,5}" + // Month + "w*" + // Week of Week Based Year + "E{0,5}" + // Day of Week + "d{0,2}" + // Day of Month + "B{0,5}" + // Period/AmPm of Day + "[hHjC]{0,2}" + // Hour of Day/AmPm + "m{0,2}" + // Minute of Hour + "s{0,2}" + // Second of Minute + "[vz]{0,4}"); // Zone + /** + * Appends a localized pattern to the formatter using the requested template. + *

    + * This appends a localized section to the builder, suitable for outputting + * a date, time or date-time combination. The format of the localized + * section is lazily looked up based on three items: + *

      + *
    • the {@code requestedTemplate} specified to this method + *
    • the {@code Locale} of the {@code DateTimeFormatter} + *
    • the {@code Chronology} of the {@code DateTimeFormatter} unless overridden + *
    + * During formatting, the chronology is obtained from the temporal object + * being formatted, which may have been overridden by + * {@link DateTimeFormatter#withChronology(Chronology)}. + *

    + * During parsing, if a chronology has already been parsed, then it is used. + * Otherwise the default from {@code DateTimeFormatter.withChronology(Chronology)} + * is used, with {@code IsoChronology} as the fallback. + *

    + * The requested template is a series of typical pattern + * symbols in canonical order from the largest date or time unit to the smallest, + * which can be expressed with the following regular expression: + * {@snippet : + * "G{0,5}" + // Era + * "y*" + // Year + * "Q{0,5}" + // Quarter + * "M{0,5}" + // Month + * "w*" + // Week of Week Based Year + * "E{0,5}" + // Day of Week + * "d{0,2}" + // Day of Month + * "B{0,5}" + // Period/AmPm of Day + * "[hHjC]{0,2}" + // Hour of Day/AmPm (refer to LDML for 'j' and 'C') + * "m{0,2}" + // Minute of Hour + * "s{0,2}" + // Second of Minute + * "[vz]{0,4}" // Zone + * } + * All pattern symbols are optional, and each pattern symbol represents a field, + * for example, 'M' represents the Month field. The number of the pattern symbol letters follows the + * same presentation, such as "number" or "text" as in the + * Patterns for Formatting and Parsing section. + * Other pattern symbols in the requested template are invalid. + *

    + * The mapping of the requested template to the closest of the available localized formats + * is defined by the + * + * Unicode LDML specification. For example, the formatter created from the requested template + * {@code yMMM} will format the date '2020-06-16' to 'Jun 2020' in the {@link Locale#US US locale}. + * + * @param requestedTemplate the requested template to use, not null + * @return this, for chaining, not null + * @throws IllegalArgumentException if {@code requestedTemplate} is invalid + * @see #appendPattern(String) + * @since 19 + */ + public DateTimeFormatterBuilder appendLocalized(String requestedTemplate) { + Objects.requireNonNull(requestedTemplate, "requestedTemplate"); + if (!VALID_TEMPLATE_PATTERN.matcher(requestedTemplate).matches()) { + throw new IllegalArgumentException("Requested template is invalid: " + requestedTemplate); + } + appendInternal(new LocalizedPrinterParser(requestedTemplate)); + return this; + } + //----------------------------------------------------------------------- /** * Appends a character literal to the formatter. @@ -2378,11 +2492,11 @@ public final class DateTimeFormatterBuilder { private final DateTimePrinterParser[] printerParsers; private final boolean optional; - CompositePrinterParser(List printerParsers, boolean optional) { + private CompositePrinterParser(List printerParsers, boolean optional) { this(printerParsers.toArray(new DateTimePrinterParser[0]), optional); } - CompositePrinterParser(DateTimePrinterParser[] printerParsers, boolean optional) { + private CompositePrinterParser(DateTimePrinterParser[] printerParsers, boolean optional) { this.printerParsers = printerParsers; this.optional = optional; } @@ -2476,7 +2590,7 @@ public final class DateTimeFormatterBuilder { * @param padWidth the width to pad to, 1 or greater * @param padChar the pad character */ - PadPrinterParserDecorator(DateTimePrinterParser printerParser, int padWidth, char padChar) { + private PadPrinterParserDecorator(DateTimePrinterParser printerParser, int padWidth, char padChar) { // input checked by DateTimeFormatterBuilder this.printerParser = printerParser; this.padWidth = padWidth; @@ -2584,7 +2698,7 @@ public final class DateTimeFormatterBuilder { private final TemporalField field; private final long value; - DefaultValueParser(TemporalField field, long value) { + private DefaultValueParser(TemporalField field, long value) { this.field = field; this.value = value; } @@ -2608,7 +2722,7 @@ public final class DateTimeFormatterBuilder { static final class CharLiteralPrinterParser implements DateTimePrinterParser { private final char literal; - CharLiteralPrinterParser(char literal) { + private CharLiteralPrinterParser(char literal) { this.literal = literal; } @@ -2651,7 +2765,7 @@ public final class DateTimeFormatterBuilder { static final class StringLiteralPrinterParser implements DateTimePrinterParser { private final String literal; - StringLiteralPrinterParser(String literal) { + private StringLiteralPrinterParser(String literal) { this.literal = literal; // validated by caller } @@ -2717,7 +2831,7 @@ public final class DateTimeFormatterBuilder { * @param maxWidth the maximum field width, from minWidth to 19 * @param signStyle the positive/negative sign style, not null */ - NumberPrinterParser(TemporalField field, int minWidth, int maxWidth, SignStyle signStyle) { + private NumberPrinterParser(TemporalField field, int minWidth, int maxWidth, SignStyle signStyle) { // validated by caller this.field = field; this.minWidth = minWidth; @@ -3008,7 +3122,7 @@ public final class DateTimeFormatterBuilder { * @param baseValue the base value * @param baseDate the base date */ - ReducedPrinterParser(TemporalField field, int minWidth, int maxWidth, + private ReducedPrinterParser(TemporalField field, int minWidth, int maxWidth, int baseValue, ChronoLocalDate baseDate) { this(field, minWidth, maxWidth, baseValue, baseDate, 0); if (minWidth < 1 || minWidth > 10) { @@ -3161,7 +3275,7 @@ public final class DateTimeFormatterBuilder { * @param maxWidth the maximum width to output, from 0 to 9 * @param decimalPoint whether to output the localized decimal point symbol */ - NanosPrinterParser(int minWidth, int maxWidth, boolean decimalPoint) { + private NanosPrinterParser(int minWidth, int maxWidth, boolean decimalPoint) { this(minWidth, maxWidth, decimalPoint, 0); if (minWidth < 0 || minWidth > 9) { throw new IllegalArgumentException("Minimum width must be from 0 to 9 inclusive but was " + minWidth); @@ -3183,7 +3297,7 @@ public final class DateTimeFormatterBuilder { * @param decimalPoint whether to output the localized decimal point symbol * @param subsequentWidth the subsequentWidth for this instance */ - NanosPrinterParser(int minWidth, int maxWidth, boolean decimalPoint, int subsequentWidth) { + private NanosPrinterParser(int minWidth, int maxWidth, boolean decimalPoint, int subsequentWidth) { super(NANO_OF_SECOND, minWidth, maxWidth, SignStyle.NOT_NEGATIVE, subsequentWidth); this.decimalPoint = decimalPoint; } @@ -3366,7 +3480,7 @@ public final class DateTimeFormatterBuilder { * @param maxWidth the maximum width to output, from 0 to 9 * @param decimalPoint whether to output the localized decimal point symbol */ - FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) { + private FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint) { this(field, minWidth, maxWidth, decimalPoint, 0); Objects.requireNonNull(field, "field"); if (field.range().isFixed() == false) { @@ -3393,7 +3507,7 @@ public final class DateTimeFormatterBuilder { * @param decimalPoint whether to output the localized decimal point symbol * @param subsequentWidth the subsequentWidth for this instance */ - FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint, int subsequentWidth) { + private FractionPrinterParser(TemporalField field, int minWidth, int maxWidth, boolean decimalPoint, int subsequentWidth) { super(field, minWidth, maxWidth, SignStyle.NOT_NEGATIVE, subsequentWidth); this.decimalPoint = decimalPoint; ValueRange range = field.range(); @@ -3583,7 +3697,7 @@ public final class DateTimeFormatterBuilder { * @param textStyle the text style, not null * @param provider the text provider, not null */ - TextPrinterParser(TemporalField field, TextStyle textStyle, DateTimeTextProvider provider) { + private TextPrinterParser(TemporalField field, TextStyle textStyle, DateTimeTextProvider provider) { // validated by caller this.field = field; this.textStyle = textStyle; @@ -3681,7 +3795,7 @@ public final class DateTimeFormatterBuilder { private static final long SECONDS_0000_TO_1970 = ((146097L * 5L) - (30L * 365L + 7L)) * 86400L; private final int fractionalDigits; - InstantPrinterParser(int fractionalDigits) { + private InstantPrinterParser(int fractionalDigits) { this.fractionalDigits = fractionalDigits; } @@ -3830,7 +3944,7 @@ public final class DateTimeFormatterBuilder { * @param pattern the pattern * @param noOffsetText the text to use for UTC, not null */ - OffsetIdPrinterParser(String pattern, String noOffsetText) { + private OffsetIdPrinterParser(String pattern, String noOffsetText) { Objects.requireNonNull(pattern, "pattern"); Objects.requireNonNull(noOffsetText, "noOffsetText"); this.type = checkPattern(pattern); @@ -4312,7 +4426,7 @@ public final class DateTimeFormatterBuilder { /** Display in generic time-zone format. True in case of pattern letter 'v' */ private final boolean isGeneric; - ZoneTextPrinterParser(TextStyle textStyle, Set preferredZones, boolean isGeneric) { + private ZoneTextPrinterParser(TextStyle textStyle, Set preferredZones, boolean isGeneric) { super(TemporalQueries.zone(), "ZoneText(" + textStyle + ")"); this.textStyle = Objects.requireNonNull(textStyle, "textStyle"); this.isGeneric = isGeneric; @@ -4484,7 +4598,7 @@ public final class DateTimeFormatterBuilder { private final TemporalQuery query; private final String description; - ZoneIdPrinterParser(TemporalQuery query, String description) { + private ZoneIdPrinterParser(TemporalQuery query, String description) { this.query = query; this.description = description; } @@ -4903,7 +5017,7 @@ public final class DateTimeFormatterBuilder { /** The text style to output, null means the ID. */ private final TextStyle textStyle; - ChronoPrinterParser(TextStyle textStyle) { + private ChronoPrinterParser(TextStyle textStyle) { // validated by caller this.textStyle = textStyle; } @@ -4978,6 +5092,7 @@ public final class DateTimeFormatterBuilder { private final FormatStyle dateStyle; private final FormatStyle timeStyle; + private final String requestedTemplate; /** * Constructor. @@ -4985,10 +5100,23 @@ public final class DateTimeFormatterBuilder { * @param dateStyle the date style to use, may be null * @param timeStyle the time style to use, may be null */ - LocalizedPrinterParser(FormatStyle dateStyle, FormatStyle timeStyle) { - // validated by caller + private LocalizedPrinterParser(FormatStyle dateStyle, FormatStyle timeStyle) { + // params validated by caller this.dateStyle = dateStyle; this.timeStyle = timeStyle; + this.requestedTemplate = null; + } + + /** + * Constructor. + * + * @param requestedTemplate the requested template to use, not null + */ + private LocalizedPrinterParser(String requestedTemplate) { + // param validated by caller + this.dateStyle = null; + this.timeStyle = null; + this.requestedTemplate = requestedTemplate; } @Override @@ -5006,7 +5134,8 @@ public final class DateTimeFormatterBuilder { /** * Gets the formatter to use. *

    - * The formatter will be the most appropriate to use for the date and time style in the locale. + * The formatter will be the most appropriate to use for the date and time style, or + * the requested template for the locale. * For example, some locales will use the month name while others will use the number. * * @param locale the locale to use, not null @@ -5015,23 +5144,22 @@ public final class DateTimeFormatterBuilder { * @throws IllegalArgumentException if the formatter cannot be found */ private DateTimeFormatter formatter(Locale locale, Chronology chrono) { - String key = chrono.getId() + '|' + locale.toString() + '|' + dateStyle + timeStyle; - DateTimeFormatter formatter = FORMATTER_CACHE.get(key); - if (formatter == null) { - String pattern = getLocalizedDateTimePattern(dateStyle, timeStyle, chrono, locale); - formatter = new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(locale); - DateTimeFormatter old = FORMATTER_CACHE.putIfAbsent(key, formatter); - if (old != null) { - formatter = old; - } - } - return formatter; + String key = chrono.getId() + '|' + locale.toString() + '|' + + (requestedTemplate != null ? requestedTemplate : Objects.toString(dateStyle) + timeStyle); + + return FORMATTER_CACHE.computeIfAbsent(key, k -> + new DateTimeFormatterBuilder() + .appendPattern(requestedTemplate != null ? + getLocalizedDateTimePattern(requestedTemplate, chrono, locale) : + getLocalizedDateTimePattern(dateStyle, timeStyle, chrono, locale)) + .toFormatter(locale)); } @Override public String toString() { - return "Localized(" + (dateStyle != null ? dateStyle : "") + "," + - (timeStyle != null ? timeStyle : "") + ")"; + return "Localized(" + (requestedTemplate != null ? requestedTemplate : + (dateStyle != null ? dateStyle : "") + "," + + (timeStyle != null ? timeStyle : "")) + ")"; } } @@ -5056,7 +5184,7 @@ public final class DateTimeFormatterBuilder { * @param minWidth the minimum field width, from 1 to 19 * @param maxWidth the maximum field width, from minWidth to 19 */ - WeekBasedFieldPrinterParser(char chr, int count, int minWidth, int maxWidth) { + private WeekBasedFieldPrinterParser(char chr, int count, int minWidth, int maxWidth) { this(chr, count, minWidth, maxWidth, 0); } @@ -5070,7 +5198,7 @@ public final class DateTimeFormatterBuilder { * @param subsequentWidth the width of subsequent non-negative numbers, 0 or greater, * -1 if fixed width due to active adjacent parsing */ - WeekBasedFieldPrinterParser(char chr, int count, int minWidth, int maxWidth, + private WeekBasedFieldPrinterParser(char chr, int count, int minWidth, int maxWidth, int subsequentWidth) { super(null, minWidth, maxWidth, SignStyle.NOT_NEGATIVE, subsequentWidth); this.chr = chr; @@ -5201,7 +5329,7 @@ public final class DateTimeFormatterBuilder { * * @param textStyle the text style, not null */ - DayPeriodPrinterParser(TextStyle textStyle) { + private DayPeriodPrinterParser(TextStyle textStyle) { // validated by caller this.textStyle = textStyle; } diff --git a/src/java.base/share/classes/sun/text/spi/JavaTimeDateTimePatternProvider.java b/src/java.base/share/classes/sun/text/spi/JavaTimeDateTimePatternProvider.java index a3835c6ac82..58235c9dff0 100644 --- a/src/java.base/share/classes/sun/text/spi/JavaTimeDateTimePatternProvider.java +++ b/src/java.base/share/classes/sun/text/spi/JavaTimeDateTimePatternProvider.java @@ -27,6 +27,7 @@ package sun.text.spi; +import java.time.DateTimeException; import java.util.Locale; import java.util.spi.LocaleServiceProvider; @@ -41,10 +42,10 @@ public abstract class JavaTimeDateTimePatternProvider extends LocaleServiceProvi } /** - * Gets the formatting pattern for a timeStyle + * Returns the formatting pattern for a timeStyle * dateStyle, calendarType and locale. * Concrete implementation of this method will retrieve - * a java.time specific dateTime Pattern from selected Locale Provider. + * a java.time specific dateTime Pattern from the selected Locale Provider. * * @param timeStyle an {@code int} value, representing FormatStyle constant, -1 * for date-only pattern @@ -58,4 +59,26 @@ public abstract class JavaTimeDateTimePatternProvider extends LocaleServiceProvi * @since 9 */ public abstract String getJavaTimeDateTimePattern(int timeStyle, int dateStyle, String calType, Locale locale); + + /** + * Returns the formatting pattern for the requested template, calendarType, and locale. + * Concrete implementation of this method will retrieve + * a java.time specific pattern from selected Locale Provider. + * + * @param requestedTemplate the requested template, not null + * @param calType a {@code String}, non-null representing CalendarType such as "japanese", + * "iso8601" + * @param locale {@code locale}, non-null + * @throws IllegalArgumentException if {@code requestedTemplate} does not match + * the regular expression syntax described in + * {@link java.time.format.DateTimeFormatterBuilder#appendLocalized(String)}. + * @throws DateTimeException if a match for the formatting pattern for + * {@code requestedTemplate} is not available + * @return formatting pattern {@code String} + * @since 19 + */ + public String getJavaTimeDateTimePattern(String requestedTemplate, String calType, Locale locale) { + // default implementation throws exception + throw new DateTimeException("Formatting pattern is not available for the requested template: " + requestedTemplate); + } } diff --git a/src/java.base/share/classes/sun/util/locale/provider/JavaTimeDateTimePatternImpl.java b/src/java.base/share/classes/sun/util/locale/provider/JavaTimeDateTimePatternImpl.java index 41de2dd7f65..c39cea799b3 100644 --- a/src/java.base/share/classes/sun/util/locale/provider/JavaTimeDateTimePatternImpl.java +++ b/src/java.base/share/classes/sun/util/locale/provider/JavaTimeDateTimePatternImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -24,7 +24,10 @@ */ package sun.util.locale.provider; +import java.time.DateTimeException; import java.util.Locale; +import java.util.Objects; +import java.util.Optional; import java.util.Set; import sun.text.spi.JavaTimeDateTimePatternProvider; @@ -63,10 +66,21 @@ public class JavaTimeDateTimePatternImpl extends JavaTimeDateTimePatternProvider @Override public String getJavaTimeDateTimePattern(int timeStyle, int dateStyle, String calType, Locale locale) { LocaleResources lr = LocaleProviderAdapter.getResourceBundleBased().getLocaleResources(locale); - String pattern = lr.getJavaTimeDateTimePattern( - timeStyle, dateStyle, calType); - return pattern; + return lr.getJavaTimeDateTimePattern(timeStyle, dateStyle, calType); + } + @Override + public String getJavaTimeDateTimePattern(String requestedTemplate, String calType, Locale locale) { + LocaleProviderAdapter lpa = LocaleProviderAdapter.getResourceBundleBased(); + return ((ResourceBundleBasedAdapter)lpa).getCandidateLocales("", locale).stream() + .map(lpa::getLocaleResources) + .map(lr -> lr.getLocalizedPattern(requestedTemplate, calType)) + .filter(Objects::nonNull) + .findFirst() + .or(() -> calType.equals("generic") ? Optional.empty(): + Optional.of(getJavaTimeDateTimePattern(requestedTemplate, "generic", locale))) + .orElseThrow(() -> new DateTimeException("Requested template \"" + requestedTemplate + + "\" cannot be resolved in the locale \"" + locale + "\"")); } @Override diff --git a/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java b/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java index fe84b66b167..aa991359c68 100644 --- a/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java +++ b/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -46,15 +46,21 @@ import java.text.MessageFormat; import java.text.NumberFormat; import java.util.Arrays; import java.util.Calendar; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.Objects; import java.util.ResourceBundle; import java.util.Set; import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.regex.Pattern; +import java.util.stream.Stream; + import sun.security.action.GetPropertyAction; import sun.util.resources.LocaleData; import sun.util.resources.OpenListResourceBundle; @@ -91,6 +97,10 @@ public class LocaleResources { private static final String COMPACT_NUMBER_PATTERNS_CACHEKEY = "CNP"; private static final String DATE_TIME_PATTERN = "DTP."; private static final String RULES_CACHEKEY = "RULE"; + private static final String SKELETON_PATTERN = "SP."; + + // ResourceBundle key names for skeletons + private static final String SKELETON_INPUT_REGIONS_KEY = "DateFormatItemInputRegions"; // TimeZoneNamesBundle exemplar city prefix private static final String TZNB_EXCITY_PREFIX = "timezone.excity."; @@ -98,6 +108,31 @@ public class LocaleResources { // null singleton cache value private static final Object NULLOBJECT = new Object(); + // RegEx pattern for skeleton validity checking + private static final Pattern VALID_SKELETON_PATTERN = Pattern.compile( + "(?" + + "G{0,5}" + // Era + "y*" + // Year + "Q{0,5}" + // Quarter + "M{0,5}" + // Month + "w*" + // Week of Week Based Year + "E{0,5}" + // Day of Week + "d{0,2})" + // Day of Month + "(?

    * This method is caller sensitive, which means that it may return different * values to different callers. + * In cases where {@code MethodHandles.lookup} is called from a context where + * there is no caller frame on the stack (e.g. when called directly + * from a JNI attached thread), {@code IllegalCallerException} is thrown. + * To obtain a {@link Lookup lookup object} in such a context, use an auxiliary class that will + * implicitly be identified as the caller, or use {@link MethodHandles#publicLookup()} + * to obtain a low-privileged lookup instead. * @return a lookup object for the caller of this method, with * {@linkplain Lookup#ORIGINAL original} and * {@linkplain Lookup#hasFullPrivilegeAccess() full privilege access}. + * @throws IllegalCallerException if there is no caller frame on the stack. */ @CallerSensitive @ForceInline // to ensure Reflection.getCallerClass optimization public static Lookup lookup() { - return new Lookup(Reflection.getCallerClass()); + final Class c = Reflection.getCallerClass(); + if (c == null) { + throw new IllegalCallerException("no caller frame"); + } + return new Lookup(c); } /** diff --git a/test/jdk/java/lang/invoke/MethodHandles/exeNullCallerLookup/NullCallerLookupTest.java b/test/jdk/java/lang/invoke/MethodHandles/exeNullCallerLookup/NullCallerLookupTest.java new file mode 100644 index 00000000000..cda0b2bc7af --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandles/exeNullCallerLookup/NullCallerLookupTest.java @@ -0,0 +1,69 @@ +/* + * 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. + * + * 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 8281003 + * @summary Test uses custom launcher that starts VM using JNI that verifies + * MethodHandles::lookup with null caller class throws an IllegalCallerException. + * @library /test/lib + * @requires os.family != "aix" + * @run main/native NullCallerLookupTest + */ + +// Test disabled on AIX since we cannot invoke the JVM on the primordial thread. + +import java.io.File; +import java.util.Map; +import jdk.test.lib.Platform; +import jdk.test.lib.process.OutputAnalyzer; + +import java.io.IOException; +import java.nio.file.Path; + +public class NullCallerLookupTest { + public static void main(String[] args) throws IOException { + Path launcher = Path.of(System.getProperty("test.nativepath"), "NullCallerLookupTest"); + ProcessBuilder pb = new ProcessBuilder(launcher.toString()); + Map env = pb.environment(); + + String libDir = Platform.libDir().toString(); + String vmDir = Platform.jvmLibDir().toString(); + + // set up shared library path + String sharedLibraryPathEnvName = Platform.sharedLibraryPathVariableName(); + env.compute(sharedLibraryPathEnvName, + (k, v) -> (v == null) ? libDir : v + File.pathSeparator + libDir); + env.compute(sharedLibraryPathEnvName, + (k, v) -> (v == null) ? vmDir : v + File.pathSeparator + vmDir); + + System.out.println("Launching: " + launcher + " shared library path: " + + env.get(sharedLibraryPathEnvName)); + new OutputAnalyzer(pb.start()) + .outputTo(System.out) + .errorTo(System.err) + .shouldHaveExitValue(0); + } +} + diff --git a/test/jdk/java/lang/invoke/MethodHandles/exeNullCallerLookup/exeNullCallerLookupTest.c b/test/jdk/java/lang/invoke/MethodHandles/exeNullCallerLookup/exeNullCallerLookupTest.c new file mode 100644 index 00000000000..3abe15ce96c --- /dev/null +++ b/test/jdk/java/lang/invoke/MethodHandles/exeNullCallerLookup/exeNullCallerLookupTest.c @@ -0,0 +1,76 @@ +/* + * 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. + * + * 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 +#include + +#include "jni.h" +#include "assert.h" + +static jclass class_IllegalCallerException; + +int checkAndClearIllegalCallerExceptionThrown(JNIEnv *env) { + jthrowable t = (*env)->ExceptionOccurred(env); + if ((*env)->IsInstanceOf(env, t, class_IllegalCallerException) == JNI_TRUE) { + (*env)->ExceptionClear(env); + return JNI_TRUE; + } + return JNI_FALSE; +} + +int main(int argc, char** args) { + JavaVM *jvm; + JNIEnv *env; + JavaVMInitArgs vm_args; + JavaVMOption options[1]; + jint rc; + + + vm_args.version = JNI_VERSION_1_2; + vm_args.nOptions = 0; + vm_args.options = options; + + if ((rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)) != JNI_OK) { + printf("ERROR: cannot create VM.\n"); + exit(-1); + } + class_IllegalCallerException = (*env)->FindClass(env, "java/lang/IllegalCallerException"); + assert (class_IllegalCallerException != NULL); + + // call MethodHandles.lookup() + jclass methodHandlesClass = (*env)->FindClass(env, "java/lang/invoke/MethodHandles"); + assert(methodHandlesClass != NULL); + jmethodID mid_MethodHandles_lookup = (*env)->GetStaticMethodID(env, methodHandlesClass, "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;" ); + assert(mid_MethodHandles_lookup != NULL); + jobject l = (*env)->CallStaticObjectMethod(env, methodHandlesClass, mid_MethodHandles_lookup ); + if ((rc = checkAndClearIllegalCallerExceptionThrown(env)) != JNI_TRUE) { + printf("ERROR: Didn't get the expected IllegalCallerException.\n"); + exit(-1); + } + + printf("Expected IllegalCallerException was thrown\n"); + + (*jvm)->DestroyJavaVM(jvm); + return 0; +} + -- GitLab From 48f6e93079f377a621ca769b820fa221062ceab1 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 16 Feb 2022 21:38:48 +0000 Subject: [PATCH 275/400] 8282020: ProblemList sun/net/www/protocol/https/HttpsURLConnection/B6216082.java until JDK-8282017 is fixed Reviewed-by: michaelm, naoto --- test/jdk/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 6b54c726277..8e00e12f1ba 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -597,6 +597,7 @@ java/net/MulticastSocket/SetGetNetworkInterfaceTest.java 8219083 windows- java/net/ServerSocket/AcceptInheritHandle.java 8211854 aix-ppc64 +sun/net/www/protocol/https/HttpsURLConnection/B6216082.java 8282017 generic-all ############################################################################ -- GitLab From 9ba0760cf85f9e843f3383b725017c9ffac350df Mon Sep 17 00:00:00 2001 From: Martin Desruisseaux Date: Wed, 16 Feb 2022 22:01:01 +0000 Subject: [PATCH 276/400] 8275345: RasterFormatException when drawing a tiled image made of non-writable rasters Reviewed-by: prr, aivanov --- .../classes/sun/java2d/SunGraphics2D.java | 18 +- .../java/awt/image/DrawImage/TiledImage.java | 225 ++++++++++++++++++ 2 files changed, 234 insertions(+), 9 deletions(-) create mode 100644 test/jdk/java/awt/image/DrawImage/TiledImage.java diff --git a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java index b5b5225938b..193a8a38587 100644 --- a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java +++ b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java @@ -2838,23 +2838,23 @@ public final class SunGraphics2D WritableRaster wRaster = null; if (raster instanceof WritableRaster) { wRaster = (WritableRaster)raster; + + // Translate wRaster to start at (0, 0) and to contain + // only the relevent portion of the tile + wRaster = wRaster.createWritableChild(tileRect.x, tileRect.y, + tileRect.width, + tileRect.height, + 0, 0, + null); } else { // Create a WritableRaster in the same coordinate system - // as the original raster. + // as the original raster, except origin which is (0,0). wRaster = Raster.createWritableRaster(raster.getSampleModel(), raster.getDataBuffer(), null); } - // Translate wRaster to start at (0, 0) and to contain - // only the relevent portion of the tile - wRaster = wRaster.createWritableChild(tileRect.x, tileRect.y, - tileRect.width, - tileRect.height, - 0, 0, - null); - // Wrap wRaster in a BufferedImage BufferedImage bufImg = new BufferedImage(colorModel, diff --git a/test/jdk/java/awt/image/DrawImage/TiledImage.java b/test/jdk/java/awt/image/DrawImage/TiledImage.java new file mode 100644 index 00000000000..8faca3aec6a --- /dev/null +++ b/test/jdk/java/awt/image/DrawImage/TiledImage.java @@ -0,0 +1,225 @@ +/* + * 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import java.awt.image.BandedSampleModel; +import java.awt.image.BufferedImage; +import java.awt.image.Raster; +import java.awt.image.ColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferByte; +import java.awt.image.RenderedImage; +import java.awt.image.SampleModel; +import java.awt.image.WritableRaster; +import java.util.Objects; +import java.util.Vector; + + +/** + * @test + * @bug 8275345 + * @summary RasterFormatException when drawing a tiled image made of non-writable rasters. + * + * Test drawing a tiled image made of non-writable {@link Raster} tiles. + * Drawing works when tiles are instances of {@link WritableRaster}. + * But if tiles are instances of {@link Raster} only, then the following + * exception is thrown: + * + * Exception in thread "main" java.awt.image.RasterFormatException: (parentX + width) is outside raster + * at java.desktop/java.awt.image.WritableRaster.createWritableChild(WritableRaster.java:228) + * at java.desktop/sun.java2d.SunGraphics2D.drawTranslatedRenderedImage(SunGraphics2D.java:2852) + * at java.desktop/sun.java2d.SunGraphics2D.drawRenderedImage(SunGraphics2D.java:2711) + * + * The bug is demonstrated by drawing the same image twice: + * once with {@link WritableRaster} tiles (which succeed), + * then the same operation but with {@link Raster} tiles. + * + * The bug is caused by the following code in {@code SunGraphics2D}: + * + * // Create a WritableRaster containing the tile + * WritableRaster wRaster = null; + * if (raster instanceof WritableRaster) { + * wRaster = (WritableRaster)raster; + * } else { + * // Create a WritableRaster in the same coordinate system + * // as the original raster. + * wRaster = + * Raster.createWritableRaster(raster.getSampleModel(), + * raster.getDataBuffer(), + * null); + * } + * // Translate wRaster to start at (0, 0) and to contain + * // only the relevant portion of the tile + * wRaster = wRaster.createWritableChild(tileRect.x, tileRect.y, + * tileRect.width, + * tileRect.height, + * 0, 0, + * null); + * + * If {@code raster} is not an instance of {@link WritableRaster}, + * then a new {@link WritableRaster} is created wrapping the same + * buffer but with a location of (0,0), because + * the {@code location} argument of {@code createWritableRaster} + * is null. Consequently the call to {@code createWritableChild} + * shall not be done in that case, because the raster is already + * translated. The current code applies translation twice. + * + * This bug is largely unnoticed because most {@code Raster.create} + * methods actually create {@link WritableRaster} instances, even + * when the user did not asked for writable raster. To make this + * bug apparent, we need to invoke {@code Raster.createRaster(…)} + * with a sample model for which no optimization is provided. + */ +public class TiledImage implements RenderedImage { + /** + * Run the test using writable tiles first, then read-only tiles. + */ + public static void main(String[] args) { + draw(true); // Pass. + draw(false); // Fail if 8275345 is not fixed. + } + + private static final int NUM_X_TILES = 2, NUM_Y_TILES = 3; + + private static final int TILE_WIDTH = 16, TILE_HEIGHT = 12; + + /** + * Tests rendering a tiled image. + * + * @param writable whether the image shall use writable raster. + */ + private static void draw(final boolean writable) { + final BufferedImage target = new BufferedImage( + TILE_WIDTH * NUM_X_TILES, + TILE_HEIGHT * NUM_Y_TILES, + BufferedImage.TYPE_BYTE_GRAY); + + final RenderedImage source = new TiledImage(writable, + target.getColorModel()); + + Graphics2D g = target.createGraphics(); + g.drawRenderedImage(source, new AffineTransform()); + g.dispose(); + } + + private final ColorModel colorModel; + + private final Raster[] tiles; + + /** + * Creates a tiled image. The image is empty, + * but pixel values are not the purpose of this test. + * + * @param writable whether the image shall use writable raster. + */ + private TiledImage(boolean writable, ColorModel cm) { + /* + * We need a sample model class for which Raster.createRaster + * do not provide a special case. That method has optimizations + * for most SampleModel sub-types, except BandedSampleModel. + */ + SampleModel sm = new BandedSampleModel(DataBuffer.TYPE_BYTE, TILE_WIDTH, TILE_HEIGHT, 1); + tiles = new Raster[NUM_X_TILES * NUM_Y_TILES]; + final Point location = new Point(); + for (int tileY = 0; tileY < NUM_Y_TILES; tileY++) { + for (int tileX = 0; tileX < NUM_X_TILES; tileX++) { + location.x = tileX * TILE_WIDTH; + location.y = tileY * TILE_HEIGHT; + DataBufferByte db = new DataBufferByte(TILE_WIDTH * TILE_HEIGHT); + Raster r; + if (writable) { + r = Raster.createWritableRaster(sm, db, location); + } else { + // Case causing RasterFormatException later. + r = Raster.createRaster(sm, db, location); + } + tiles[tileX + tileY * NUM_X_TILES] = r; + } + } + colorModel = cm; + } + + @Override + public ColorModel getColorModel() { + return colorModel; + } + + @Override + public SampleModel getSampleModel() { + return tiles[0].getSampleModel(); + } + + @Override + public Vector getSources() { + return new Vector<>(); + } + + @Override + public Object getProperty(String key) { + return Image.UndefinedProperty; + } + + @Override + public String[] getPropertyNames() { + return null; + } + + @Override public int getMinX() {return 0;} + @Override public int getMinY() {return 0;} + @Override public int getMinTileX() {return 0;} + @Override public int getMinTileY() {return 0;} + @Override public int getTileGridXOffset() {return 0;} + @Override public int getTileGridYOffset() {return 0;} + @Override public int getNumXTiles() {return NUM_X_TILES;} + @Override public int getNumYTiles() {return NUM_Y_TILES;} + @Override public int getTileWidth() {return TILE_WIDTH;} + @Override public int getTileHeight() {return TILE_HEIGHT;} + @Override public int getWidth() {return TILE_WIDTH * NUM_X_TILES;} + @Override public int getHeight() {return TILE_HEIGHT * NUM_Y_TILES;} + + @Override + public Raster getTile(final int tileX, final int tileY) { + Objects.checkIndex(tileX, NUM_X_TILES); + Objects.checkIndex(tileY, NUM_Y_TILES); + return tiles[tileX + tileY * NUM_X_TILES]; + } + + @Override + public Raster getData() { + throw new UnsupportedOperationException("Not needed for this test."); + } + + @Override + public Raster getData(Rectangle rect) { + throw new UnsupportedOperationException("Not needed for this test."); + } + + @Override + public WritableRaster copyData(WritableRaster raster) { + throw new UnsupportedOperationException("Not needed for this test."); + } +} -- GitLab From 5ec7898dbf1ebe261e5e25939cad42134611ff12 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Wed, 16 Feb 2022 22:02:55 +0000 Subject: [PATCH 277/400] 8281671: Class.getCanonicalName spec should explicitly cover array classes Reviewed-by: mchung --- .../share/classes/java/lang/Class.java | 10 ++ test/jdk/java/lang/Class/NameTest.java | 101 ++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 test/jdk/java/lang/Class/NameTest.java diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index fb936b14989..fce7793fbcf 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -1732,8 +1732,18 @@ public final class Class implements java.io.Serializable, *

  • an array whose component type does not have a canonical name
  • * * + * The canonical name for a primitive class is the keyword for the + * corresponding primitive type ({@code byte}, {@code short}, + * {@code char}, {@code int}, and so on). + * + *

    An array type has a canonical name if and only if its + * component type has a canonical name. When an array type has a + * canonical name, it is equal to the canonical name of the + * component type followed by "{@code []}". + * * @return the canonical name of the underlying class if it exists, and * {@code null} otherwise. + * @jls 6.7 Fully Qualified Names and Canonical Names * @since 1.5 */ public String getCanonicalName() { diff --git a/test/jdk/java/lang/Class/NameTest.java b/test/jdk/java/lang/Class/NameTest.java new file mode 100644 index 00000000000..b8d6e2125b8 --- /dev/null +++ b/test/jdk/java/lang/Class/NameTest.java @@ -0,0 +1,101 @@ +/* + * 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. + * + * 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 8281671 + * @summary Checks on various "getFooName" methods of java.lang.Class + */ + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class NameTest { + public static void main(String... args) { + testCanonicalName(); + testSimpleName(); + } + + private static void testCanonicalName() { + class LocalClass {} // Local class; no canonical name + Object o = new Object() {}; // Anonymous class; no canonical name + Object[] objectArray = {}; + + Map, String> expectedCanonicalName = new HashMap<>(); + + expectedCanonicalName.put(LocalClass.class, null); + expectedCanonicalName.put(o.getClass(), null); + + // If a component type doesn't have a canonical name, neither + // does an array of that type. + expectedCanonicalName.put(LocalClass.class.arrayType(), null); + expectedCanonicalName.put(o.getClass().arrayType(), null); + + expectedCanonicalName.put(int.class, "int"); + expectedCanonicalName.put(Object.class, "java.lang.Object"); + expectedCanonicalName.put(objectArray.getClass(), "java.lang.Object[]"); + + for (var entry : expectedCanonicalName.entrySet()) { + var key = entry.getKey(); + var expectedName = entry.getValue(); + String canonicalName = key.getCanonicalName(); + if (!Objects.equals(canonicalName, expectedName)) { + System.err.println("Unexpected canonical name '" + + canonicalName + "' found for " + + key + ", expected " + expectedName); + throw new RuntimeException(); + } + } + } + + private static void testSimpleName() { + class ALocalClass {} // Local class + Object o = new Object() {}; // Anonymous class, empty simple name + Object[] objectArray = {}; + + Map, String> expectedSimpleName = new HashMap<>(); + + expectedSimpleName.put(ALocalClass.class, "ALocalClass"); + expectedSimpleName.put(o.getClass(), ""); + + expectedSimpleName.put(ALocalClass.class.arrayType(), "ALocalClass[]"); + expectedSimpleName.put(o.getClass().arrayType(), "[]"); + + expectedSimpleName.put(int.class, "int"); + expectedSimpleName.put(Object.class, "Object"); + expectedSimpleName.put(objectArray.getClass(), "Object[]"); + + for (var entry : expectedSimpleName.entrySet()) { + var key = entry.getKey(); + var expectedName = entry.getValue(); + String simpleName = key.getSimpleName(); + if (!Objects.equals(simpleName, expectedName)) { + System.err.println("Unexpected simple name '" + + simpleName + "' found for " + + key + ", expected " + expectedName); + throw new RuntimeException(); + } + } + } +} -- GitLab From 0b00ce17cd6b530d9394e79ac8b07208cd4b92f5 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Wed, 16 Feb 2022 23:23:57 +0000 Subject: [PATCH 278/400] 8282011: test/jdk/tools/jpackage/windows/WinL10nTest.java test fails if light.exe is not in %PATH% Reviewed-by: almatvee --- test/jdk/tools/jpackage/windows/WinL10nTest.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/jdk/tools/jpackage/windows/WinL10nTest.java b/test/jdk/tools/jpackage/windows/WinL10nTest.java index 4171da208a4..4f7e726a3af 100644 --- a/test/jdk/tools/jpackage/windows/WinL10nTest.java +++ b/test/jdk/tools/jpackage/windows/WinL10nTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -94,8 +94,11 @@ public class WinL10nTest { private final static Stream getLightCommandLine( Executor.Result result) { - return result.getOutput().stream() - .filter(s -> s.trim().startsWith("light.exe")); + return result.getOutput().stream().filter(s -> { + s = s.trim(); + return s.startsWith("light.exe") || ((s.contains("\\light.exe ") + && s.contains(" -out "))); + }); } @Test -- GitLab From cd234f5dbebd18ebf0c78dfdf533318cdc627971 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Thu, 17 Feb 2022 05:27:41 +0000 Subject: [PATCH 279/400] 8282007: Assorted enhancements to jpackage testing framework Reviewed-by: almatvee --- test/jdk/tools/jpackage/apps/Hello.java | 19 +- .../jdk/jpackage/test/AdditionalLauncher.java | 137 ++++++++++--- .../helpers/jdk/jpackage/test/CfgFile.java | 6 +- .../helpers/jdk/jpackage/test/Executor.java | 8 +- .../helpers/jdk/jpackage/test/HelloApp.java | 21 +- .../jdk/jpackage/test/JPackageCommand.java | 67 +++++- .../helpers/jdk/jpackage/test/JavaTool.java | 6 +- .../jdk/jpackage/test/LinuxHelper.java | 44 ++-- .../helpers/jdk/jpackage/test/MacHelper.java | 93 +++++---- .../jdk/jpackage/test/PackageTest.java | 190 ++++++++++++------ .../jpackage/test/RunnablePackageTest.java | 16 +- .../helpers/jdk/jpackage/test/TKit.java | 2 +- .../jdk/jpackage/test/WindowsHelper.java | 109 ++++++---- test/jdk/tools/jpackage/run_tests.sh | 62 ++++-- .../share/MultiLauncherTwoPhaseTest.java | 4 +- test/jdk/tools/jpackage/test_jpackage.sh | 100 --------- .../jpackage/windows/WinUpgradeUUIDTest.java | 4 +- 17 files changed, 562 insertions(+), 326 deletions(-) delete mode 100644 test/jdk/tools/jpackage/test_jpackage.sh diff --git a/test/jdk/tools/jpackage/apps/Hello.java b/test/jdk/tools/jpackage/apps/Hello.java index dd6f114a421..000573c933f 100644 --- a/test/jdk/tools/jpackage/apps/Hello.java +++ b/test/jdk/tools/jpackage/apps/Hello.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -37,6 +37,7 @@ import java.util.List; import java.util.ArrayList; import java.util.stream.Stream; import java.util.Collections; +import java.util.Optional; public class Hello implements OpenFilesHandler { @@ -60,6 +61,15 @@ public class Hello implements OpenFilesHandler { var outputFile = getOutputFile(args); trace(String.format("Output file: [%s]", outputFile)); Files.write(outputFile, lines); + + if (Optional.ofNullable(System.getProperty("jpackage.test.noexit")).map( + Boolean::parseBoolean).orElse(false)) { + trace("noexit"); + var lock = new Object(); + synchronized (lock) { + lock.wait(); + } + } } private static List printArgs(String[] args) { @@ -87,7 +97,8 @@ public class Hello implements OpenFilesHandler { } private static Path getOutputFile(String[] args) { - Path outputFilePath = Path.of("appOutput.txt"); + Path outputFilePath = Path.of(Optional.ofNullable(System.getProperty( + "jpackage.test.appOutput")).orElse("appOutput.txt")); // If first arg is a file (most likely from fa), then put output in the same folder as // the file from fa. @@ -101,7 +112,7 @@ public class Hello implements OpenFilesHandler { try { // Try writing in the default output file. Files.write(outputFilePath, Collections.emptyList()); - return outputFilePath; + return outputFilePath.toAbsolutePath(); } catch (IOException ex) { // Log reason of a failure. StringWriter errors = new StringWriter(); @@ -109,7 +120,7 @@ public class Hello implements OpenFilesHandler { Stream.of(errors.toString().split("\\R")).forEachOrdered(Hello::trace); } - return Path.of(System.getProperty("user.home")).resolve(outputFilePath); + return Path.of(System.getProperty("user.home")).resolve(outputFilePath).toAbsolutePath(); } @Override diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java index 10033db4802..44d75d98ec9 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -29,13 +29,17 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.function.BiConsumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.test.Functional.ThrowingBiConsumer; +import static jdk.jpackage.test.Functional.ThrowingFunction.toFunction; -public final class AdditionalLauncher { +public class AdditionalLauncher { public AdditionalLauncher(String name) { this.name = name; @@ -43,12 +47,12 @@ public final class AdditionalLauncher { setPersistenceHandler(null); } - public AdditionalLauncher setDefaultArguments(String... v) { + final public AdditionalLauncher setDefaultArguments(String... v) { defaultArguments = new ArrayList<>(List.of(v)); return this; } - public AdditionalLauncher addDefaultArguments(String... v) { + final public AdditionalLauncher addDefaultArguments(String... v) { if (defaultArguments == null) { return setDefaultArguments(v); } @@ -57,12 +61,12 @@ public final class AdditionalLauncher { return this; } - public AdditionalLauncher setJavaOptions(String... v) { + final public AdditionalLauncher setJavaOptions(String... v) { javaOptions = new ArrayList<>(List.of(v)); return this; } - public AdditionalLauncher addJavaOptions(String... v) { + final public AdditionalLauncher addJavaOptions(String... v) { if (javaOptions == null) { return setJavaOptions(v); } @@ -71,23 +75,24 @@ public final class AdditionalLauncher { return this; } - public AdditionalLauncher addRawProperties(Map.Entry... v) { + final public AdditionalLauncher addRawProperties( + Map.Entry... v) { return addRawProperties(List.of(v)); } - public AdditionalLauncher addRawProperties( + final public AdditionalLauncher addRawProperties( Collection> v) { rawProperties.addAll(v); return this; } - public AdditionalLauncher setShortcuts(boolean menu, boolean shortcut) { + final public AdditionalLauncher setShortcuts(boolean menu, boolean shortcut) { withMenuShortcut = menu; withShortcut = shortcut; return this; } - public AdditionalLauncher setIcon(Path iconPath) { + final public AdditionalLauncher setIcon(Path iconPath) { if (iconPath == NO_ICON) { throw new IllegalArgumentException(); } @@ -96,12 +101,12 @@ public final class AdditionalLauncher { return this; } - public AdditionalLauncher setNoIcon() { + final public AdditionalLauncher setNoIcon() { icon = NO_ICON; return this; } - public AdditionalLauncher setPersistenceHandler( + final public AdditionalLauncher setPersistenceHandler( ThrowingBiConsumer>> handler) { if (handler != null) { createFileHandler = ThrowingBiConsumer.toBiConsumer(handler); @@ -111,19 +116,53 @@ public final class AdditionalLauncher { return this; } - public void applyTo(JPackageCommand cmd) { + final public void applyTo(JPackageCommand cmd) { cmd.addPrerequisiteAction(this::initialize); cmd.addVerifyAction(this::verify); } - public void applyTo(PackageTest test) { - test.addLauncherName(name); + final public void applyTo(PackageTest test) { test.addInitializer(this::initialize); test.addInstallVerifier(this::verify); } + static void forEachAdditionalLauncher(JPackageCommand cmd, + BiConsumer consumer) { + var argIt = cmd.getAllArguments().iterator(); + while (argIt.hasNext()) { + if ("--add-launcher".equals(argIt.next())) { + // = + var arg = argIt.next(); + var items = arg.split("=", 2); + consumer.accept(items[0], Path.of(items[1])); + } + } + } + + static PropertyFile getAdditionalLauncherProperties( + JPackageCommand cmd, String launcherName) { + PropertyFile shell[] = new PropertyFile[1]; + forEachAdditionalLauncher(cmd, (name, propertiesFilePath) -> { + if (name.equals(launcherName)) { + shell[0] = toFunction(PropertyFile::new).apply( + propertiesFilePath); + } + }); + return Optional.of(shell[0]).get(); + } + private void initialize(JPackageCommand cmd) { - final Path propsFile = TKit.workDir().resolve(name + ".properties"); + Path propsFile = TKit.workDir().resolve(name + ".properties"); + if (Files.exists(propsFile)) { + // File with the given name exists, pick another name that + // will not reference existing file. + try { + propsFile = TKit.createTempFile(propsFile); + TKit.deleteIfExists(propsFile); + } catch (IOException ex) { + Functional.rethrowUnchecked(ex); + } + } cmd.addArguments("--add-launcher", String.format("%s=%s", name, propsFile)); @@ -242,7 +281,7 @@ public final class AdditionalLauncher { } } - private void verify(JPackageCommand cmd) throws IOException { + protected void verify(JPackageCommand cmd) throws IOException { verifyIcon(cmd); verifyShortcuts(cmd); @@ -255,14 +294,60 @@ public final class AdditionalLauncher { return; } - HelloApp.assertApp(launcherPath) - .addDefaultArguments(Optional - .ofNullable(defaultArguments) - .orElseGet(() -> List.of(cmd.getAllArgumentValues("--arguments")))) - .addJavaOptions(Optional - .ofNullable(javaOptions) - .orElseGet(() -> List.of(cmd.getAllArgumentValues("--java-options")))) - .executeAndVerifyOutput(); + var appVerifier = HelloApp.assertApp(launcherPath) + .addDefaultArguments(Optional + .ofNullable(defaultArguments) + .orElseGet(() -> List.of(cmd.getAllArgumentValues("--arguments")))) + .addJavaOptions(Optional + .ofNullable(javaOptions) + .orElseGet(() -> List.of(cmd.getAllArgumentValues( + "--java-options"))).stream().map( + str -> resolveVariables(cmd, str)).toList()); + + appVerifier.executeAndVerifyOutput(); + } + + public static final class PropertyFile { + + PropertyFile(Path path) throws IOException { + data = Files.readAllLines(path).stream().map(str -> { + return str.split("=", 2); + }).collect( + Collectors.toMap(tokens -> tokens[0], tokens -> tokens[1], + (oldValue, newValue) -> { + return newValue; + })); + } + + public boolean isPropertySet(String name) { + Objects.requireNonNull(name); + return data.containsKey(name); + } + + public Optional getPropertyValue(String name) { + Objects.requireNonNull(name); + return Optional.of(data.get(name)); + } + + public Optional getPropertyBooleanValue(String name) { + Objects.requireNonNull(name); + return Optional.ofNullable(data.get(name)).map(Boolean::parseBoolean); + } + + private final Map data; + } + + private static String resolveVariables(JPackageCommand cmd, String str) { + var map = Map.of( + "$APPDIR", cmd.appLayout().appDirectory(), + "$ROOTDIR", + cmd.isImagePackageType() ? cmd.outputBundle() : cmd.appInstallationDirectory(), + "$BINDIR", cmd.appLayout().launchersDirectory()); + for (var e : map.entrySet()) { + str = str.replaceAll(Pattern.quote(e.getKey()), + Matcher.quoteReplacement(e.getValue().toString())); + } + return str; } private List javaOptions; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CfgFile.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CfgFile.java index e2a380366e8..31bf0520a31 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CfgFile.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CfgFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -29,6 +29,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -85,7 +86,8 @@ public final class CfgFile { } if (!currentSection.isEmpty()) { - result.put("", Collections.unmodifiableMap(currentSection)); + result.put(Optional.ofNullable(currentSectionName).orElse(""), + Collections.unmodifiableMap(currentSection)); } return new CfgFile(Collections.unmodifiableMap(result), path.toString()); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java index d65fe4e667b..3fed83ddb36 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -90,8 +90,10 @@ public final class Executor extends CommandArguments { } public Executor setWindowsTmpDir(String tmp) { - TKit.assertTrue(TKit.isWindows(), - "setWindowsTmpDir is only valid on Windows platform"); + if (!TKit.isWindows()) { + throw new UnsupportedOperationException( + "setWindowsTmpDir is only valid on Windows platform"); + } winTmpDir = tmp; return this; } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java index 71561a51cf3..2d0d23dae26 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -351,6 +351,7 @@ public final class HelloApp { public final static class AppOutputVerifier { AppOutputVerifier(Path helloAppLauncher) { this.launcherPath = helloAppLauncher; + this.outputFilePath = TKit.workDir().resolve(OUTPUT_FILENAME); this.params = new HashMap<>(); this.defaultLauncherArgs = new ArrayList<>(); } @@ -367,6 +368,8 @@ public final class HelloApp { public AppOutputVerifier addParam(String name, String value) { if (name.startsWith("param")) { params.put(name, value); + } else if ("jpackage.test.appOutput".equals(name)) { + outputFilePath = Path.of(value); } return this; } @@ -397,6 +400,18 @@ public final class HelloApp { .collect(Collectors.toList())); } + public void verifyOutput(String... args) { + final List launcherArgs = List.of(args); + final List appArgs; + if (launcherArgs.isEmpty()) { + appArgs = defaultLauncherArgs; + } else { + appArgs = launcherArgs; + } + + verifyOutputFile(outputFilePath, appArgs, params); + } + public void executeAndVerifyOutput(String... args) { executeAndVerifyOutput(false, args); } @@ -408,8 +423,7 @@ public final class HelloApp { getExecutor(launcherArgs.toArray(new String[0])).dumpOutput().setRemovePath( removePath).executeAndRepeatUntilExitCode(0, attempts, waitBetweenAttemptsSeconds); - Path outputFile = TKit.workDir().resolve(OUTPUT_FILENAME); - verifyOutputFile(outputFile, appArgs, params); + verifyOutputFile(outputFilePath, appArgs, params); } public void executeAndVerifyOutput(boolean removePath, String... args) { @@ -453,6 +467,7 @@ public final class HelloApp { } private final Path launcherPath; + private Path outputFilePath; private final List defaultLauncherArgs; private final Map params; } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index b68fe08bd1e..d30f96ff786 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -47,6 +47,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.jpackage.internal.AppImageFile; import jdk.jpackage.internal.ApplicationLayout; +import static jdk.jpackage.test.AdditionalLauncher.forEachAdditionalLauncher; import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.Functional.ThrowingFunction; import jdk.jpackage.test.Functional.ThrowingSupplier; @@ -242,6 +243,17 @@ public final class JPackageCommand extends CommandArguments { return this; } + public JPackageCommand setInputToEmptyDirectory() { + if (Files.exists(inputDir())) { + try { + setArgumentValue("--input", TKit.createTempDirectory("input")); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + return this; + } + public JPackageCommand setFakeRuntime() { verifyMutable(); @@ -414,6 +426,28 @@ public final class JPackageCommand extends CommandArguments { return unpackDir.resolve(TKit.removeRootFromAbsolutePath(path)); } + /** + * Returns path to package file from the path in unpacked package directory + * or the given path if the package is not unpacked. + */ + public Path pathToPackageFile(Path path) { + Path unpackDir = unpackedPackageDirectory(); + if (unpackDir == null) { + if (!path.isAbsolute()) { + throw new IllegalArgumentException(String.format( + "Path [%s] is not absolute", path)); + } + return path; + } + + if (!path.startsWith(unpackDir)) { + throw new IllegalArgumentException(String.format( + "Path [%s] doesn't start with [%s] path", path, unpackDir)); + } + + return Path.of("/").resolve(unpackDir.relativize(path)); + } + Path unpackedPackageDirectory() { verifyIsOfType(PackageType.NATIVE); return getArgumentValue(UNPACKED_PATH_ARGNAME, () -> null, Path::of); @@ -497,6 +531,18 @@ public final class JPackageCommand extends CommandArguments { return appLauncherPath(null); } + /** + * Returns names of all additional launchers or empty list if none + * configured. + */ + public List addLauncherNames() { + List names = new ArrayList<>(); + forEachAdditionalLauncher(this, (launcherName, propFile) -> { + names.add(launcherName); + }); + return names; + } + private void verifyNotRuntime() { if (isRuntime()) { throw new IllegalArgumentException("Java runtime packaging"); @@ -537,9 +583,9 @@ public final class JPackageCommand extends CommandArguments { throw TKit.throwUnknownPlatformError(); } - if (criticalRuntimeFiles.stream().filter( - v -> runtimeDir.resolve(v).toFile().exists()).findFirst().orElse( - null) == null) { + if (!criticalRuntimeFiles.stream().anyMatch(v -> { + return runtimeDir.resolve(v).toFile().exists(); + })) { // Fake runtime TKit.trace(String.format( "%s because application runtime directory [%s] is incomplete", @@ -738,7 +784,7 @@ public final class JPackageCommand extends CommandArguments { appImageFileName)); } } - } else if (TKit.isOSX()) { + } else if (TKit.isOSX() && !isRuntime()) { TKit.assertFileExists(AppImageFile.getPathInAppImage( appInstallationDirectory())); } else { @@ -763,7 +809,11 @@ public final class JPackageCommand extends CommandArguments { JPackageCommand setUnpackedPackageLocation(Path path) { verifyIsOfType(PackageType.NATIVE); - setArgumentValue(UNPACKED_PATH_ARGNAME, path); + if (path != null) { + setArgumentValue(UNPACKED_PATH_ARGNAME, path); + } else { + removeArgumentWithValue(UNPACKED_PATH_ARGNAME); + } return this; } @@ -788,6 +838,11 @@ public final class JPackageCommand extends CommandArguments { return createExecutor().getPrintableCommandLine(); } + @Override + public String toString() { + return getPrintableCommandLine(); + } + public void verifyIsOfType(Collection types) { verifyIsOfType(types.toArray(PackageType[]::new)); } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaTool.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaTool.java index de5a4e4d8e4..7b217b2431c 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaTool.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JavaTool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -40,7 +40,7 @@ public enum JavaTool { } } - Path getPath() { + public Path getPath() { return path; } @@ -48,7 +48,7 @@ public enum JavaTool { return ToolProvider.findFirst(toolName()).orElse(null); } - Path relativePathInJavaHome() { + private Path relativePathInJavaHome() { Path path = Path.of("bin", toolName()); if (TKit.isWindows()) { path = path.getParent().resolve(path.getFileName().toString() + ".exe"); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java index 5b91b829457..4d096198c9d 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -42,8 +42,7 @@ import jdk.jpackage.internal.IOUtils; import jdk.jpackage.test.PackageTest.PackageHandlers; - -public class LinuxHelper { +public final class LinuxHelper { private static String getReleaseSuffix(JPackageCommand cmd) { String value = null; final PackageType packageType = cmd.packageType(); @@ -183,7 +182,10 @@ public class LinuxHelper { }; deb.uninstallHandler = cmd -> { cmd.verifyIsOfType(PackageType.LINUX_DEB); - Executor.of("sudo", "dpkg", "-r", getPackageName(cmd)).execute(); + var packageName = getPackageName(cmd); + String script = String.format("! dpkg -s %s || sudo dpkg -r %s", + packageName, packageName); + Executor.of("sh", "-c", script).execute(); }; deb.unpackHandler = (cmd, destinationDir) -> { cmd.verifyIsOfType(PackageType.LINUX_DEB); @@ -200,13 +202,16 @@ public class LinuxHelper { PackageHandlers rpm = new PackageHandlers(); rpm.installHandler = cmd -> { cmd.verifyIsOfType(PackageType.LINUX_RPM); - Executor.of("sudo", "rpm", "-i") + Executor.of("sudo", "rpm", "-U") .addArgument(cmd.outputBundle()) .execute(); }; rpm.uninstallHandler = cmd -> { cmd.verifyIsOfType(PackageType.LINUX_RPM); - Executor.of("sudo", "rpm", "-e", getPackageName(cmd)).execute(); + var packageName = getPackageName(cmd); + String script = String.format("! rpm -q %s || sudo rpm -e %s", + packageName, packageName); + Executor.of("sh", "-c", script).execute(); }; rpm.unpackHandler = (cmd, destinationDir) -> { cmd.verifyIsOfType(PackageType.LINUX_RPM); @@ -363,10 +368,10 @@ public class LinuxHelper { test.addInstallVerifier(cmd -> { // Verify .desktop files. - try (var files = Files.walk(cmd.appLayout().destktopIntegrationDirectory(), 1)) { + try (var files = Files.list(cmd.appLayout().destktopIntegrationDirectory())) { List desktopFiles = files .filter(path -> path.getFileName().toString().endsWith(".desktop")) - .collect(Collectors.toList()); + .toList(); if (!integrated) { TKit.assertStringListEquals(List.of(), desktopFiles.stream().map(Path::toString).collect( @@ -470,23 +475,18 @@ public class LinuxHelper { String desktopFileName = queryMimeTypeDefaultHandler(mimeType); - Path desktopFile = getSystemDesktopFilesFolder().resolve( + Path systemDesktopFile = getSystemDesktopFilesFolder().resolve( + desktopFileName); + Path appDesktopFile = cmd.appLayout().destktopIntegrationDirectory().resolve( desktopFileName); - TKit.assertFileExists(desktopFile); - - TKit.trace(String.format("Reading [%s] file...", desktopFile)); - String mimeHandler = Files.readAllLines(desktopFile).stream().peek( - v -> TKit.trace(v)).filter( - v -> v.startsWith("Exec=")).map( - v -> v.split("=", 2)[1]).findFirst().orElseThrow(); - - TKit.trace(String.format("Done")); - - TKit.assertEquals(cmd.appLauncherPath().toString(), - mimeHandler, String.format( - "Check mime type handler is the main application launcher")); + TKit.assertFileExists(systemDesktopFile); + TKit.assertFileExists(appDesktopFile); + TKit.assertStringListEquals(Files.readAllLines(appDesktopFile), + Files.readAllLines(systemDesktopFile), String.format( + "Check [%s] file is a copy of [%s] file", + systemDesktopFile, appDesktopFile)); }); }); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java index 9b6457ccc58..7f5887f0ac3 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -39,6 +39,7 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; +import jdk.jpackage.internal.IOUtils; import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.Functional.ThrowingSupplier; import jdk.jpackage.test.PackageTest.PackageHandlers; @@ -46,7 +47,7 @@ import jdk.jpackage.internal.RetryExecutor; import org.xml.sax.SAXException; import org.w3c.dom.NodeList; -public class MacHelper { +public final class MacHelper { public static void withExplodedDmg(JPackageCommand cmd, ThrowingConsumer consumer) { @@ -172,41 +173,62 @@ public class MacHelper { pkg.installHandler = cmd -> { cmd.verifyIsOfType(PackageType.MAC_PKG); Executor.of("sudo", "/usr/sbin/installer", "-allowUntrusted", "-pkg") - .addArgument(cmd.outputBundle()) - .addArguments("-target", "/") - .execute(); + .addArgument(cmd.outputBundle()) + .addArguments("-target", "/") + .execute(); }; pkg.unpackHandler = (cmd, destinationDir) -> { cmd.verifyIsOfType(PackageType.MAC_PKG); + + var dataDir = destinationDir.resolve("data"); + Executor.of("pkgutil", "--expand") - .addArgument(cmd.outputBundle()) - .addArgument(destinationDir.resolve("data")) // We need non-existing folder - .execute(); + .addArgument(cmd.outputBundle()) + .addArgument(dataDir) // We need non-existing folder + .execute(); final Path unpackRoot = destinationDir.resolve("unpacked"); - Path installDir = TKit.removeRootFromAbsolutePath( - getInstallationDirectory(cmd)).getParent(); - final Path unpackDir = unpackRoot.resolve(installDir); - try { - Files.createDirectories(unpackDir); + // Unpack all ".pkg" files from $dataDir folder in $unpackDir folder + try (var dataListing = Files.list(dataDir)) { + dataListing.filter(file -> { + return ".pkg".equals(IOUtils.getSuffix(file.getFileName())); + }).forEach(ThrowingConsumer.toConsumer(pkgDir -> { + // Installation root of the package is stored in + // /pkg-info@install-location attribute in $pkgDir/PackageInfo xml file + var doc = createDocumentBuilder().parse( + new ByteArrayInputStream(Files.readAllBytes( + pkgDir.resolve("PackageInfo")))); + var xPath = XPathFactory.newInstance().newXPath(); + + final String installRoot = (String) xPath.evaluate( + "/pkg-info/@install-location", doc, + XPathConstants.STRING); + + final Path unpackDir = unpackRoot.resolve( + TKit.removeRootFromAbsolutePath(Path.of(installRoot))); + + Files.createDirectories(unpackDir); + + Executor.of("tar", "-C") + .addArgument(unpackDir) + .addArgument("-xvf") + .addArgument(pkgDir.resolve("Payload")) + .execute(); + })); } catch (IOException ex) { throw new RuntimeException(ex); } - Executor.of("tar", "-C") - .addArgument(unpackDir) - .addArgument("-xvf") - .addArgument(Path.of(destinationDir.toString(), "data", - cmd.name() + "-app.pkg", "Payload")) - .execute(); return unpackRoot; }; pkg.uninstallHandler = cmd -> { cmd.verifyIsOfType(PackageType.MAC_PKG); + Executor.of("sudo", "rm", "-rf") - .addArgument(cmd.appInstallationDirectory()) - .execute(); + .addArgument(cmd.appInstallationDirectory()) + .execute(); + }; return pkg; @@ -220,13 +242,13 @@ public class MacHelper { static Path getInstallationDirectory(JPackageCommand cmd) { cmd.verifyIsOfType(PackageType.MAC); - return Path.of(cmd.getArgumentValue("--install-dir", () -> "/Applications")) - .resolve(cmd.name() + (cmd.isRuntime() ? "" : ".app")); + return Path.of(cmd.getArgumentValue("--install-dir", + () -> cmd.isRuntime() ? "/Library/Java/JavaVirtualMachines" : "/Applications")).resolve( + cmd.name() + (cmd.isRuntime() ? "" : ".app")); } private static String getPackageName(JPackageCommand cmd) { - return cmd.getArgumentValue("--mac-package-name", - () -> cmd.installerName()); + return cmd.getArgumentValue("--mac-package-name", cmd::installerName); } public static final class PListWrapper { @@ -274,25 +296,24 @@ public class MacHelper { return values; } - PListWrapper(String xml) throws ParserConfigurationException, + private PListWrapper(String xml) throws ParserConfigurationException, SAXException, IOException { doc = createDocumentBuilder().parse(new ByteArrayInputStream( xml.getBytes(StandardCharsets.UTF_8))); } - private static DocumentBuilder createDocumentBuilder() throws - ParserConfigurationException { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance(); - dbf.setFeature( - "http://apache.org/xml/features/nonvalidating/load-external-dtd", - false); - return dbf.newDocumentBuilder(); - } - private final org.w3c.dom.Document doc; } + private static DocumentBuilder createDocumentBuilder() throws + ParserConfigurationException { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance(); + dbf.setFeature( + "http://apache.org/xml/features/nonvalidating/load-external-dtd", + false); + return dbf.newDocumentBuilder(); + } + static final Set CRITICAL_RUNTIME_FILES = Set.of(Path.of( "Contents/Home/lib/server/libjvm.dylib")); - } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java index f81fb1c170c..0884b41dc55 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -25,6 +25,7 @@ package jdk.jpackage.test; import java.awt.Desktop; import java.awt.GraphicsEnvironment; import java.io.File; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; @@ -36,19 +37,32 @@ import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.jpackage.internal.AppImageFile; import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.test.Functional.ThrowingBiConsumer; +import static jdk.jpackage.test.Functional.ThrowingBiConsumer.toBiConsumer; import jdk.jpackage.test.Functional.ThrowingConsumer; +import static jdk.jpackage.test.Functional.ThrowingConsumer.toConsumer; import jdk.jpackage.test.Functional.ThrowingRunnable; - +import static jdk.jpackage.test.Functional.ThrowingSupplier.toSupplier; +import static jdk.jpackage.test.Functional.rethrowUnchecked; +import static jdk.jpackage.test.PackageType.LINUX; +import static jdk.jpackage.test.PackageType.LINUX_DEB; +import static jdk.jpackage.test.PackageType.LINUX_RPM; +import static jdk.jpackage.test.PackageType.MAC_DMG; +import static jdk.jpackage.test.PackageType.MAC_PKG; +import static jdk.jpackage.test.PackageType.NATIVE; +import static jdk.jpackage.test.PackageType.WINDOWS; +import static jdk.jpackage.test.PackageType.WIN_EXE; +import static jdk.jpackage.test.PackageType.WIN_MSI; /** @@ -82,7 +96,7 @@ public final class PackageTest extends RunnablePackageTest { public PackageTest forTypes(PackageType... types) { Collection newTypes; if (types == null || types.length == 0) { - newTypes = PackageType.NATIVE; + newTypes = NATIVE; } else { newTypes = Stream.of(types).collect(Collectors.toSet()); } @@ -122,7 +136,7 @@ public final class PackageTest extends RunnablePackageTest { namedInitializers.add(id); } currentTypes.forEach(type -> handlers.get(type).addInitializer( - ThrowingConsumer.toConsumer(v))); + toConsumer(v))); return this; } @@ -151,13 +165,12 @@ public final class PackageTest extends RunnablePackageTest { public PackageTest addBundleVerifier( ThrowingBiConsumer v) { currentTypes.forEach(type -> handlers.get(type).addBundleVerifier( - ThrowingBiConsumer.toBiConsumer(v))); + toBiConsumer(v))); return this; } public PackageTest addBundleVerifier(ThrowingConsumer v) { - return addBundleVerifier( - (cmd, unused) -> ThrowingConsumer.toConsumer(v).accept(cmd)); + return addBundleVerifier((cmd, unused) -> toConsumer(v).accept(cmd)); } public PackageTest addBundlePropertyVerifier(String propertyName, @@ -184,7 +197,7 @@ public final class PackageTest extends RunnablePackageTest { } public PackageTest addBundleDesktopIntegrationVerifier(boolean integrated) { - forTypes(PackageType.LINUX, () -> { + forTypes(LINUX, () -> { LinuxHelper.addBundleDesktopIntegrationVerifier(this, integrated); }); return this; @@ -192,31 +205,25 @@ public final class PackageTest extends RunnablePackageTest { public PackageTest addInstallVerifier(ThrowingConsumer v) { currentTypes.forEach(type -> handlers.get(type).addInstallVerifier( - ThrowingConsumer.toConsumer(v))); + toConsumer(v))); return this; } public PackageTest addUninstallVerifier(ThrowingConsumer v) { currentTypes.forEach(type -> handlers.get(type).addUninstallVerifier( - ThrowingConsumer.toConsumer(v))); + toConsumer(v))); return this; } - public PackageTest setPackageInstaller(Consumer v) { + public PackageTest disablePackageInstaller() { currentTypes.forEach( - type -> packageHandlers.get(type).installHandler = v); - return this; - } - - public PackageTest setPackageUnpacker( - BiFunction v) { - currentTypes.forEach(type -> packageHandlers.get(type).unpackHandler = v); + type -> packageHandlers.get(type).installHandler = cmd -> {}); return this; } - public PackageTest setPackageUninstaller(Consumer v) { + public PackageTest disablePackageUninstaller() { currentTypes.forEach( - type -> packageHandlers.get(type).uninstallHandler = v); + type -> packageHandlers.get(type).uninstallHandler = cmd -> {}); return this; } @@ -238,7 +245,7 @@ public final class PackageTest extends RunnablePackageTest { // running check of type of environment. addHelloAppInitializer(null); - forTypes(PackageType.LINUX, () -> { + forTypes(LINUX, () -> { LinuxHelper.addFileAssociationsVerifier(this, fa); }); @@ -317,11 +324,6 @@ public final class PackageTest extends RunnablePackageTest { return this; } - public PackageTest addLauncherName(String name) { - launcherNames.add(name); - return this; - } - public final static class Group extends RunnablePackageTest { public Group(PackageTest... tests) { handlers = Stream.of(tests) @@ -372,7 +374,7 @@ public final class PackageTest extends RunnablePackageTest { } private List> createPackageTypeHandlers() { - return PackageType.NATIVE.stream() + return NATIVE.stream() .map(type -> { Handler handler = handlers.entrySet().stream() .filter(entry -> !entry.getValue().isVoid()) @@ -393,29 +395,39 @@ public final class PackageTest extends RunnablePackageTest { private Consumer createPackageTypeHandler( PackageType type, Handler handler) { - return ThrowingConsumer.toConsumer(new ThrowingConsumer() { + return toConsumer(new ThrowingConsumer() { @Override public void accept(Action action) throws Throwable { + if (terminated) { + throw new IllegalStateException(); + } + if (action == Action.FINALIZE) { - if (unpackDir != null && Files.isDirectory(unpackDir) - && !unpackDir.startsWith(TKit.workDir())) { - TKit.deleteDirectoryRecursive(unpackDir); + if (unpackDir != null) { + if (Files.isDirectory(unpackDir) + && !unpackDir.startsWith(TKit.workDir())) { + TKit.deleteDirectoryRecursive(unpackDir); + } + unpackDir = null; } + terminated = true; } if (aborted) { return; } - final JPackageCommand curCmd; - if (Set.of(Action.INITIALIZE, Action.CREATE).contains(action)) { - curCmd = cmd; - } else { - curCmd = cmd.createImmutableCopy(); - } + final Supplier curCmd = () -> { + if (Set.of(Action.INITIALIZE, Action.CREATE).contains(action)) { + return cmd; + } else { + return cmd.createImmutableCopy(); + } + }; switch (action) { case UNPACK: { + cmd.setUnpackedPackageLocation(null); var handler = packageHandlers.get(type).unpackHandler; if (!(aborted = (handler == null))) { unpackDir = TKit.createTempDirectory( @@ -428,9 +440,10 @@ public final class PackageTest extends RunnablePackageTest { } case INSTALL: { + cmd.setUnpackedPackageLocation(null); var handler = packageHandlers.get(type).installHandler; if (!(aborted = (handler == null))) { - handler.accept(curCmd); + handler.accept(curCmd.get()); } break; } @@ -438,18 +451,19 @@ public final class PackageTest extends RunnablePackageTest { case UNINSTALL: { var handler = packageHandlers.get(type).uninstallHandler; if (!(aborted = (handler == null))) { - handler.accept(curCmd); + handler.accept(curCmd.get()); } break; } case CREATE: - handler.accept(action, curCmd); + cmd.setUnpackedPackageLocation(null); + handler.accept(action, curCmd.get()); aborted = (expectedJPackageExitCode != 0); return; default: - handler.accept(action, curCmd); + handler.accept(action, curCmd.get()); break; } @@ -462,6 +476,7 @@ public final class PackageTest extends RunnablePackageTest { private Path unpackDir; private boolean aborted; + private boolean terminated; private final JPackageCommand cmd = Functional.identity(() -> { JPackageCommand result = new JPackageCommand(); result.setDefaultInputOutput().setDefaultAppName(); @@ -535,13 +550,23 @@ public final class PackageTest extends RunnablePackageTest { verifyPackageUninstalled(cmd); } break; + + case PURGE: + if (expectedJPackageExitCode == 0) { + var bundle = cmd.outputBundle(); + if (toSupplier(() -> TKit.deleteIfExists(bundle)).get()) { + TKit.trace(String.format("Deleted [%s] package", + bundle)); + } + } + break; } } private void verifyPackageBundle(JPackageCommand cmd, Executor.Result result) { if (expectedJPackageExitCode == 0) { - if (PackageType.LINUX.contains(cmd.packageType())) { + if (LINUX.contains(cmd.packageType())) { LinuxHelper.verifyPackageBundleEssential(cmd); } } @@ -557,35 +582,85 @@ public final class PackageTest extends RunnablePackageTest { } TKit.trace(String.format(formatString, cmd.getPrintableCommandLine())); + Optional.ofNullable(cmd.unpackedPackageDirectory()).ifPresent( + unpackedDir -> { + verifyRootCountInUnpackedPackage(cmd, unpackedDir); + }); + if (!cmd.isRuntime()) { - if (PackageType.WINDOWS.contains(cmd.packageType()) + if (WINDOWS.contains(cmd.packageType()) && !cmd.isPackageUnpacked( "Not verifying desktop integration")) { // Check main launcher - new WindowsHelper.DesktopIntegrationVerifier(cmd, null); + WindowsHelper.verifyDesktopIntegration(cmd, null); // Check additional launchers - launcherNames.forEach(name -> { - new WindowsHelper.DesktopIntegrationVerifier(cmd, name); + cmd.addLauncherNames().forEach(name -> { + WindowsHelper.verifyDesktopIntegration(cmd, name); }); } } + cmd.assertAppLayout(); installVerifiers.forEach(v -> v.accept(cmd)); } + private void verifyRootCountInUnpackedPackage(JPackageCommand cmd, + Path unpackedDir) { + + final long expectedRootCount; + if (WINDOWS.contains(cmd.packageType())) { + // On Windows it is always two entries: + // installation home directory and MSI file + expectedRootCount = 2; + } else if (LINUX.contains(cmd.packageType())) { + Set roots = new HashSet<>(); + roots.add(Path.of("/").resolve(Path.of(cmd.getArgumentValue( + "--install-dir", () -> "/opt")).getName(0))); + if (cmd.hasArgument("--license-file")) { + switch (cmd.packageType()) { + case LINUX_RPM -> { + // License file is in /usr/share/licenses subtree + roots.add(Path.of("/usr")); + } + + case LINUX_DEB -> { + Path installDir = cmd.appInstallationDirectory(); + if (installDir.equals(Path.of("/")) + || installDir.startsWith("/usr")) { + // License file is in /usr/share/doc subtree + roots.add(Path.of("/usr")); + } + } + } + } + expectedRootCount = roots.size(); + } else { + expectedRootCount = 1; + } + + try ( var files = Files.list(unpackedDir)) { + TKit.assertEquals(expectedRootCount, files.count(), + String.format( + "Check the package has %d top installation directories", + expectedRootCount)); + } catch (IOException ex) { + rethrowUnchecked(ex); + } + } + private void verifyPackageUninstalled(JPackageCommand cmd) { TKit.trace(String.format("Verify uninstalled: %s", cmd.getPrintableCommandLine())); if (!cmd.isRuntime()) { TKit.assertPathExists(cmd.appLauncherPath(), false); - if (PackageType.WINDOWS.contains(cmd.packageType())) { + if (WINDOWS.contains(cmd.packageType())) { // Check main launcher - new WindowsHelper.DesktopIntegrationVerifier(cmd, null); + WindowsHelper.verifyDesktopIntegration(cmd, null); // Check additional launchers - launcherNames.forEach(name -> { - new WindowsHelper.DesktopIntegrationVerifier(cmd, name); + cmd.addLauncherNames().forEach(name -> { + WindowsHelper.verifyDesktopIntegration(cmd, name); }); } } @@ -610,18 +685,18 @@ public final class PackageTest extends RunnablePackageTest { private static Map createDefaultPackageHandlers() { HashMap handlers = new HashMap<>(); if (TKit.isLinux()) { - handlers.put(PackageType.LINUX_DEB, LinuxHelper.createDebPackageHandlers()); - handlers.put(PackageType.LINUX_RPM, LinuxHelper.createRpmPackageHandlers()); + handlers.put(LINUX_DEB, LinuxHelper.createDebPackageHandlers()); + handlers.put(LINUX_RPM, LinuxHelper.createRpmPackageHandlers()); } if (TKit.isWindows()) { - handlers.put(PackageType.WIN_MSI, WindowsHelper.createMsiPackageHandlers()); - handlers.put(PackageType.WIN_EXE, WindowsHelper.createExePackageHandlers()); + handlers.put(WIN_MSI, WindowsHelper.createMsiPackageHandlers()); + handlers.put(WIN_EXE, WindowsHelper.createExePackageHandlers()); } if (TKit.isOSX()) { - handlers.put(PackageType.MAC_DMG, MacHelper.createDmgPackageHandlers()); - handlers.put(PackageType.MAC_PKG, MacHelper.createPkgPackageHandlers()); + handlers.put(MAC_DMG, MacHelper.createDmgPackageHandlers()); + handlers.put(MAC_PKG, MacHelper.createPkgPackageHandlers()); } return handlers; @@ -633,7 +708,6 @@ public final class PackageTest extends RunnablePackageTest { private Map handlers; private Set namedInitializers; private Map packageHandlers; - private final List launcherNames = new ArrayList(); private final static File BUNDLE_OUTPUT_DIR; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/RunnablePackageTest.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/RunnablePackageTest.java index 6f98cfc234d..a5cedc5c34e 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/RunnablePackageTest.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/RunnablePackageTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -41,6 +41,12 @@ public abstract class RunnablePackageTest { .filter(Predicate.not(Action.INITIALIZE::equals)) .filter(Predicate.not(Action.FINALIZE::equals)) .collect(Collectors.toList())); + if (hasAction(Action.PURGE) && !actionList.contains(Action.PURGE)) { + // Default action list contains "purge" action meaning + // packages are not needed for further processing. + // Copy this behavior in custom action list. + actionList.add(Action.PURGE); + } } actionList.add(Action.FINALIZE); @@ -51,6 +57,10 @@ public abstract class RunnablePackageTest { runActions(actionGroups); } + public static boolean hasAction(Action a) { + return DEFAULT_ACTIONS.contains(a); + } + protected void runActions(List actions) { actions.forEach(this::runAction); } @@ -89,6 +99,10 @@ public abstract class RunnablePackageTest { * Uninstall package. */ UNINSTALL, + /** + * Purge package. + */ + PURGE, /** * Finalize test. */ diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java index fb88d4cd21d..1907c074504 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java index 528973bea22..a3f67e01d46 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -58,7 +58,7 @@ public class WindowsHelper { private static Path getInstallationSubDirectory(JPackageCommand cmd) { cmd.verifyIsOfType(PackageType.WINDOWS); - return Path.of(cmd.getArgumentValue("--install-dir", () -> cmd.name())); + return Path.of(cmd.getArgumentValue("--install-dir", cmd::name)); } private static void runMsiexecWithRetries(Executor misexec) { @@ -66,7 +66,13 @@ public class WindowsHelper { for (int attempt = 0; attempt < 8; ++attempt) { result = misexec.executeWithoutExitCodeCheck(); - // The given Executor may either be of an msiexe command or an + if (result.exitCode == 1605) { + // ERROR_UNKNOWN_PRODUCT, attempt to uninstall not installed + // package + return; + } + + // The given Executor may either be of an msiexec command or an // unpack.bat script containing the msiexec command. In the later // case, when misexec returns 1618, the unpack.bat may return 1603 if ((result.exitCode == 1618) || (result.exitCode == 1603)) { @@ -91,16 +97,25 @@ public class WindowsHelper { PackageHandlers msi = new PackageHandlers(); msi.installHandler = cmd -> installMsi.accept(cmd, true); - msi.uninstallHandler = cmd -> installMsi.accept(cmd, false); + msi.uninstallHandler = cmd -> { + if (Files.exists(cmd.outputBundle())) { + installMsi.accept(cmd, false); + } + }; msi.unpackHandler = (cmd, destinationDir) -> { cmd.verifyIsOfType(PackageType.WIN_MSI); final Path unpackBat = destinationDir.resolve("unpack.bat"); final Path unpackDir = destinationDir.resolve( TKit.removeRootFromAbsolutePath( getInstallationRootDirectory(cmd))); + // Put msiexec in .bat file because can't pass value of TARGETDIR // property containing spaces through ProcessBuilder properly. - TKit.createTextFile(unpackBat, List.of(String.join(" ", List.of( + // Set folder permissions to allow msiexec unpack msi bundle. + TKit.createTextFile(unpackBat, List.of( + String.format("icacls \"%s\" /inheritance:e /grant Users:M", + destinationDir), + String.join(" ", List.of( "msiexec", "/a", String.format("\"%s\"", cmd.outputBundle().normalize()), @@ -125,10 +140,19 @@ public class WindowsHelper { PackageHandlers exe = new PackageHandlers(); exe.installHandler = cmd -> installExe.accept(cmd, true); - exe.uninstallHandler = cmd -> installExe.accept(cmd, false); + exe.uninstallHandler = cmd -> { + if (Files.exists(cmd.outputBundle())) { + installExe.accept(cmd, false); + } + }; return exe; } + static void verifyDesktopIntegration(JPackageCommand cmd, + String launcherName) { + new DesktopIntegrationVerifier(cmd, launcherName); + } + public static String getMsiProperty(JPackageCommand cmd, String propertyName) { cmd.verifyIsOfType(PackageType.WIN_MSI); return Executor.of("cscript.exe", "//Nologo") @@ -143,21 +167,45 @@ public class WindowsHelper { return cmd.hasArgument("--win-per-user-install"); } - static class DesktopIntegrationVerifier { + private static class DesktopIntegrationVerifier { - DesktopIntegrationVerifier(JPackageCommand cmd, String name) { + DesktopIntegrationVerifier(JPackageCommand cmd, String launcherName) { cmd.verifyIsOfType(PackageType.WINDOWS); - this.cmd = cmd; - this.name = (name == null ? cmd.name() : name); + + name = Optional.ofNullable(launcherName).orElseGet(cmd::name); + + isUserLocalInstall = isUserLocalInstall(cmd); + + appInstalled = cmd.appLauncherPath(launcherName).toFile().exists(); + + desktopShortcutPath = Path.of(name + ".lnk"); + + startMenuShortcutPath = Path.of(cmd.getArgumentValue( + "--win-menu-group", () -> "Unknown"), name + ".lnk"); + + if (name.equals(cmd.name())) { + isWinMenu = cmd.hasArgument("--win-menu"); + isDesktop = cmd.hasArgument("--win-shortcut"); + } else { + var props = AdditionalLauncher.getAdditionalLauncherProperties(cmd, + launcherName); + isWinMenu = props.getPropertyBooleanValue("win-menu").orElseGet( + () -> cmd.hasArgument("--win-menu")); + isDesktop = props.getPropertyBooleanValue("win-shortcut").orElseGet( + () -> cmd.hasArgument("--win-shortcut")); + } + verifyStartMenuShortcut(); + verifyDesktopShortcut(); - verifyFileAssociationsRegistry(); + + Stream.of(cmd.getAllArgumentValues("--file-associations")).map( + Path::of).forEach(this::verifyFileAssociationsRegistry); } private void verifyDesktopShortcut() { - boolean appInstalled = cmd.appLauncherPath(name).toFile().exists(); - if (cmd.hasArgument("--win-shortcut")) { - if (isUserLocalInstall(cmd)) { + if (isDesktop) { + if (isUserLocalInstall) { verifyUserLocalDesktopShortcut(appInstalled); verifySystemDesktopShortcut(false); } else { @@ -170,10 +218,6 @@ public class WindowsHelper { } } - private Path desktopShortcutPath() { - return Path.of(name + ".lnk"); - } - private void verifyShortcut(Path path, boolean exists) { if (exists) { TKit.assertFileExists(path); @@ -185,19 +229,18 @@ public class WindowsHelper { private void verifySystemDesktopShortcut(boolean exists) { Path dir = Path.of(queryRegistryValueCache( SYSTEM_SHELL_FOLDERS_REGKEY, "Common Desktop")); - verifyShortcut(dir.resolve(desktopShortcutPath()), exists); + verifyShortcut(dir.resolve(desktopShortcutPath), exists); } private void verifyUserLocalDesktopShortcut(boolean exists) { Path dir = Path.of( queryRegistryValueCache(USER_SHELL_FOLDERS_REGKEY, "Desktop")); - verifyShortcut(dir.resolve(desktopShortcutPath()), exists); + verifyShortcut(dir.resolve(desktopShortcutPath), exists); } private void verifyStartMenuShortcut() { - boolean appInstalled = cmd.appLauncherPath(name).toFile().exists(); - if (cmd.hasArgument("--win-menu")) { - if (isUserLocalInstall(cmd)) { + if (isWinMenu) { + if (isUserLocalInstall) { verifyUserLocalStartMenuShortcut(appInstalled); verifySystemStartMenuShortcut(false); } else { @@ -210,13 +253,8 @@ public class WindowsHelper { } } - private Path startMenuShortcutPath() { - return Path.of(cmd.getArgumentValue("--win-menu-group", - () -> "Unknown"), name + ".lnk"); - } - private void verifyStartMenuShortcut(Path shortcutsRoot, boolean exists) { - Path shortcutPath = shortcutsRoot.resolve(startMenuShortcutPath()); + Path shortcutPath = shortcutsRoot.resolve(startMenuShortcutPath); verifyShortcut(shortcutPath, exists); if (!exists) { TKit.assertPathNotEmptyDirectory(shortcutPath.getParent()); @@ -234,13 +272,7 @@ public class WindowsHelper { USER_SHELL_FOLDERS_REGKEY, "Programs")), exists); } - private void verifyFileAssociationsRegistry() { - Stream.of(cmd.getAllArgumentValues("--file-associations")).map( - Path::of).forEach(this::verifyFileAssociationsRegistry); - } - private void verifyFileAssociationsRegistry(Path faFile) { - boolean appInstalled = cmd.appLauncherPath(name).toFile().exists(); try { TKit.trace(String.format( "Get file association properties from [%s] file", @@ -290,7 +322,12 @@ public class WindowsHelper { } } - private final JPackageCommand cmd; + private final Path desktopShortcutPath; + private final Path startMenuShortcutPath; + private final boolean isUserLocalInstall; + private final boolean appInstalled; + private final boolean isWinMenu; + private final boolean isDesktop; private final String name; } diff --git a/test/jdk/tools/jpackage/run_tests.sh b/test/jdk/tools/jpackage/run_tests.sh index a5cb03fc3aa..2639f38cd68 100644 --- a/test/jdk/tools/jpackage/run_tests.sh +++ b/test/jdk/tools/jpackage/run_tests.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 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 @@ -78,15 +78,25 @@ help_usage () echo " Optional, for jtreg tests debug purposes only." echo ' -l - value for `jpackage.test.logfile` property.' echo " Optional, for jtreg tests debug purposes only." - echo " -m - mode to run jtreg tests." - echo ' Should be one of `create`, `update` or `print-default-tests`.' - echo ' Optional, default mode is `update`.' + echo " -m - mode to run jtreg tests. Supported values:" echo ' - `create`' echo ' Remove all package bundles from the output directory before running jtreg tests.' echo ' - `update`' echo ' Run jtreg tests and overrite existing package bundles in the output directory.' echo ' - `print-default-tests`' echo ' Print default list of packaging tests and exit.' + echo ' - `create-small-runtime`' + echo ' Create small Java runtime using /bin/jlink command in the output directory.' + echo ' - `create-packages`' + echo ' Create packages.' + echo ' The script will set `jpackage.test.action` property.' + echo ' - `test-packages`' + echo ' Create and fully test packages. Will create, unpack, install, and uninstall packages.' + echo ' The script will set `jpackage.test.action` property.' + echo ' - `do-packages`' + echo " Create, unpack and verify packages." + echo ' The script will not set `jpackage.test.action` property.' + echo ' Optional, defaults are `update` and `create-packages`.' } error () @@ -133,8 +143,6 @@ exec_command () test_jdk= # Path to local copy of open jdk repo with jpackage jtreg tests -# hg clone http://hg.openjdk.java.net/jdk/sandbox -# cd sandbox; hg update -r JDK-8200758-branch open_jdk_with_jpackage_jtreg_tests=$(dirname $0)/../../../../ # Directory where to save artifacts for testing. @@ -152,12 +160,27 @@ mode=update # jtreg extra arguments declare -a jtreg_args -# Create packages only -jtreg_args+=("-Djpackage.test.action=create") - # run all tests run_all_tests= +test_actions= + +set_mode () +{ + case "$1" in + create-packages) test_actions='-Djpackage.test.action=create';; + test-packages) test_actions='-Djpackage.test.action=uninstall,create,unpack,verify-install,install,verify-install,uninstall,verify-uninstall,purge';; + do-packages) test_actions=;; + create-small-runtime) mode=$1;; + print-default-tests) mode=$1;; + create) mode=$1;; + update) mode=$1;; + *) fatal_with_help_usage 'Invalid value of -m option:' [$1];; + esac +} + +set_mode 'create-packages' + mapfile -t tests < <(find_all_packaging_tests) while getopts "vahdct:j:o:r:m:l:" argname; do @@ -171,7 +194,7 @@ while getopts "vahdct:j:o:r:m:l:" argname; do o) output_dir="$OPTARG";; r) runtime_dir="$OPTARG";; l) logfile="$OPTARG";; - m) mode="$OPTARG";; + m) set_mode "$OPTARG";; h) help_usage; exit 0;; ?) help_usage; exit 1;; esac @@ -201,6 +224,11 @@ if [ ! -e "$JAVA_HOME/bin/java" ]; then fatal JAVA_HOME variable is set to [$JAVA_HOME] value, but $JAVA_HOME/bin/java not found. fi +if [ "$mode" = "create-small-runtime" ]; then + exec_command "$test_jdk/bin/jlink" --add-modules java.base,java.datatransfer,java.xml,java.prefs,java.desktop --compress=2 --no-header-files --no-man-pages --strip-debug --output "$output_dir" + exit +fi + if [ -z "$JT_HOME" ]; then if [ -z "$JT_BUNDLE_URL" ]; then fatal 'JT_HOME or JT_BUNDLE_URL environment variable is not set. Link to JTREG bundle can be found at https://openjdk.java.net/jtreg/'. @@ -222,18 +250,12 @@ if [ -n "$logfile" ]; then jtreg_args+=("-Djpackage.test.logfile=$(to_native_path "$logfile")") fi -if [ "$mode" = create ]; then - true -elif [ "$mode" = update ]; then - true -else - fatal_with_help_usage 'Invalid value of -m option:' [$mode] -fi - if [ -z "$run_all_tests" ]; then jtreg_args+=(-Djpackage.test.SQETest=yes) fi +jtreg_args+=("$test_actions") + # Drop arguments separator [ "$1" != "--" ] || shift @@ -249,10 +271,10 @@ installJtreg () if [ ! -f "$jtreg_jar" ]; then exec_command mkdir -p "$workdir" if [[ ${jtreg_bundle: -7} == ".tar.gz" ]]; then - exec_command "(" cd "$workdir" "&&" wget "$jtreg_bundle" "&&" tar -xzf "$(basename $jtreg_bundle)" ";" rm -f "$(basename $jtreg_bundle)" ")" + exec_command "(" cd "$workdir" "&&" wget --no-check-certificate "$jtreg_bundle" "&&" tar -xzf "$(basename $jtreg_bundle)" ";" rm -f "$(basename $jtreg_bundle)" ")" else if [[ ${jtreg_bundle: -4} == ".zip" ]]; then - exec_command "(" cd "$workdir" "&&" wget "$jtreg_bundle" "&&" unzip "$(basename $jtreg_bundle)" ";" rm -f "$(basename $jtreg_bundle)" ")" + exec_command "(" cd "$workdir" "&&" wget --no-check-certificate "$jtreg_bundle" "&&" unzip "$(basename $jtreg_bundle)" ";" rm -f "$(basename $jtreg_bundle)" ")" else fatal 'Unsupported extension of JREG bundle ['$JT_BUNDLE_URL']. Only *.zip or *.tar.gz is supported.' fi diff --git a/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java b/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java index 5df3609e3ba..b048d6db335 100644 --- a/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java +++ b/test/jdk/tools/jpackage/share/MultiLauncherTwoPhaseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 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 @@ -69,8 +69,6 @@ public class MultiLauncherTwoPhaseTest { launcher2.applyTo(appImageCmd); PackageTest packageTest = new PackageTest() - .addLauncherName("bar") // Add launchers name for verification - .addLauncherName("foo") .addRunOnceInitializer(() -> appImageCmd.execute()) .addBundleDesktopIntegrationVerifier(true) .addInitializer(cmd -> { diff --git a/test/jdk/tools/jpackage/test_jpackage.sh b/test/jdk/tools/jpackage/test_jpackage.sh deleted file mode 100644 index c4b28020bc0..00000000000 --- a/test/jdk/tools/jpackage/test_jpackage.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# 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. - - -# -# Complete testing of jpackage platform-specific packaging. -# -# The script does the following: -# 1. Create packages. -# 2. Install created packages. -# 3. Verifies packages are installed. -# 4. Uninstall created packages. -# 5. Verifies packages are uninstalled. -# -# For the list of accepted command line arguments see `run_tests.sh` script. -# - -# Fail fast -set -e; set -o pipefail; - -# Script debug -dry_run=${JPACKAGE_TEST_DRY_RUN} - -# Default directory where jpackage should write bundle files -output_dir=~/jpackage_bundles - - -set_args () -{ - args=() - local arg_is_output_dir= - local arg_is_mode= - local output_dir_set= - local with_append_actions=yes - for arg in "$@"; do - if [ "$arg" == "-o" ]; then - arg_is_output_dir=yes - output_dir_set=yes - elif [ "$arg" == "-m" ]; then - arg_is_mode=yes - continue - elif [ "$arg" == '--' ]; then - append_actions - with_append_actions= - continue - elif ! case "$arg" in -Djpackage.test.action=*) false;; esac; then - continue - elif [ -n "$arg_is_output_dir" ]; then - arg_is_output_dir= - output_dir="$arg" - elif [ -n "$arg_is_mode" ]; then - arg_is_mode= - continue - fi - - args+=( "$arg" ) - done - [ -n "$output_dir_set" ] || args=( -o "$output_dir" "${args[@]}" ) - [ -z "$with_append_actions" ] || append_actions -} - - -append_actions () -{ - args+=( '--' '-Djpackage.test.action=create,install,verify-install,uninstall,verify-uninstall' ) -} - - -exec_command () -{ - if [ -n "$dry_run" ]; then - echo "$@" - else - eval "$@" - fi -} - -set_args "$@" -basedir="$(dirname $0)" -exec_command ${SHELL} "$basedir/run_tests.sh" -m create "${args[@]}" diff --git a/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java b/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java index 0c233b0e652..968ed94b345 100644 --- a/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java +++ b/test/jdk/tools/jpackage/windows/WinUpgradeUUIDTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 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 @@ -100,7 +100,7 @@ public class WinUpgradeUUIDTest { // It will be uninstalled automatically when the second // package will be installed. // However uninstall verification for the first package will be executed. - PackageTest test1 = init.get().setPackageUninstaller(cmd -> {}); + PackageTest test1 = init.get().disablePackageUninstaller(); PackageTest test2 = init.get().addInitializer(cmd -> { cmd.setArgumentValue("--app-version", "2.0"); -- GitLab From 1eec16b47be300e1462528bddf5d0686df3f042c Mon Sep 17 00:00:00 2001 From: Xiaohong Gong Date: Thu, 17 Feb 2022 05:44:12 +0000 Subject: [PATCH 280/400] 8281803: AArch64: Optimize masked vector NOT/AND_NOT for SVE Reviewed-by: aph, njian --- src/hotspot/cpu/aarch64/aarch64_sve.ad | 64 ++++++- src/hotspot/cpu/aarch64/aarch64_sve_ad.m4 | 56 ++++++- src/hotspot/cpu/aarch64/assembler_aarch64.hpp | 1 + test/hotspot/gtest/aarch64/aarch64-asmtest.py | 1 + test/hotspot/gtest/aarch64/asmtest.out.h | 158 +++++++++--------- 5 files changed, 198 insertions(+), 82 deletions(-) diff --git a/src/hotspot/cpu/aarch64/aarch64_sve.ad b/src/hotspot/cpu/aarch64/aarch64_sve.ad index bf00892b936..c048a463c1a 100644 --- a/src/hotspot/cpu/aarch64/aarch64_sve.ad +++ b/src/hotspot/cpu/aarch64/aarch64_sve.ad @@ -1,6 +1,6 @@ // -// Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2020, 2021, Arm Limited. All rights reserved. +// Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2020, 2022, Arm Limited. All rights reserved. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This code is free software; you can redistribute it and/or modify it @@ -1288,6 +1288,36 @@ instruct vnotL(vReg dst, vReg src, immL_M1 m1) %{ ins_pipe(pipe_slow); %} +// vector not - predicated + +instruct vnotI_masked(vReg dst, vReg src, immI_M1 m1, pRegGov pg) %{ + predicate(UseSVE > 0); + match(Set dst (XorV (Binary src (ReplicateB m1)) pg)); + match(Set dst (XorV (Binary src (ReplicateS m1)) pg)); + match(Set dst (XorV (Binary src (ReplicateI m1)) pg)); + ins_cost(SVE_COST); + format %{ "sve_not $dst, $pg, $src\t# vector (sve) B/H/S" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ sve_not(as_FloatRegister($dst$$reg), __ elemType_to_regVariant(bt), + as_PRegister($pg$$reg), as_FloatRegister($src$$reg)); + %} + ins_pipe(pipe_slow); +%} + +instruct vnotL_masked(vReg dst, vReg src, immL_M1 m1, pRegGov pg) %{ + predicate(UseSVE > 0); + match(Set dst (XorV (Binary src (ReplicateL m1)) pg)); + ins_cost(SVE_COST); + format %{ "sve_not $dst, $pg, $src\t# vector (sve) D" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ sve_not(as_FloatRegister($dst$$reg), __ elemType_to_regVariant(bt), + as_PRegister($pg$$reg), as_FloatRegister($src$$reg)); + %} + ins_pipe(pipe_slow); +%} + // vector and_not instruct vand_notI(vReg dst, vReg src1, vReg src2, immI_M1 m1) %{ @@ -1318,6 +1348,36 @@ instruct vand_notL(vReg dst, vReg src1, vReg src2, immL_M1 m1) %{ ins_pipe(pipe_slow); %} +// vector and_not - predicated + +instruct vand_notI_masked(vReg dst_src1, vReg src2, immI_M1 m1, pRegGov pg) %{ + predicate(UseSVE > 0); + match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (ReplicateB m1))) pg)); + match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (ReplicateS m1))) pg)); + match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (ReplicateI m1))) pg)); + ins_cost(SVE_COST); + format %{ "sve_bic $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) B/H/S" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ sve_bic(as_FloatRegister($dst_src1$$reg), __ elemType_to_regVariant(bt), + as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); + %} + ins_pipe(pipe_slow); +%} + +instruct vand_notL_masked(vReg dst_src1, vReg src2, immL_M1 m1, pRegGov pg) %{ + predicate(UseSVE > 0); + match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (ReplicateL m1))) pg)); + ins_cost(SVE_COST); + format %{ "sve_bic $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) D" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ sve_bic(as_FloatRegister($dst_src1$$reg), __ elemType_to_regVariant(bt), + as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); + %} + ins_pipe(pipe_slow); +%} + // vector float div instruct vdivF(vReg dst_src1, vReg src2) %{ diff --git a/src/hotspot/cpu/aarch64/aarch64_sve_ad.m4 b/src/hotspot/cpu/aarch64/aarch64_sve_ad.m4 index 7e0acdc52c2..874cdf6e4e0 100644 --- a/src/hotspot/cpu/aarch64/aarch64_sve_ad.m4 +++ b/src/hotspot/cpu/aarch64/aarch64_sve_ad.m4 @@ -1,6 +1,6 @@ // -// Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. -// Copyright (c) 2020, 2021, Arm Limited. All rights reserved. +// Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. +// Copyright (c) 2020, 2022, Arm Limited. All rights reserved. // 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,6 +745,32 @@ VECTOR_NOT(I, B/H/S) VECTOR_NOT(L, D) undefine(MATCH_RULE) dnl +// vector not - predicated +dnl +define(`MATCH_RULE', `ifelse($1, I, +`match(Set dst (XorV (Binary src (ReplicateB m1)) pg)); + match(Set dst (XorV (Binary src (ReplicateS m1)) pg)); + match(Set dst (XorV (Binary src (ReplicateI m1)) pg));', +`match(Set dst (XorV (Binary src (ReplicateL m1)) pg));')')dnl +dnl +define(`VECTOR_NOT_PREDICATE', ` +instruct vnot$1_masked`'(vReg dst, vReg src, imm$1_M1 m1, pRegGov pg) %{ + predicate(UseSVE > 0); + MATCH_RULE($1) + ins_cost(SVE_COST); + format %{ "sve_not $dst, $pg, $src\t# vector (sve) $2" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ sve_not(as_FloatRegister($dst$$reg), __ elemType_to_regVariant(bt), + as_PRegister($pg$$reg), as_FloatRegister($src$$reg)); + %} + ins_pipe(pipe_slow); +%}')dnl +dnl $1, $2 +VECTOR_NOT_PREDICATE(I, B/H/S) +VECTOR_NOT_PREDICATE(L, D) +undefine(MATCH_RULE) +dnl // vector and_not dnl define(`MATCH_RULE', `ifelse($1, I, @@ -771,6 +797,32 @@ VECTOR_AND_NOT(I, B/H/S) VECTOR_AND_NOT(L, D) undefine(MATCH_RULE) dnl +// vector and_not - predicated +dnl +define(`MATCH_RULE', `ifelse($1, I, +`match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (ReplicateB m1))) pg)); + match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (ReplicateS m1))) pg)); + match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (ReplicateI m1))) pg));', +`match(Set dst_src1 (AndV (Binary dst_src1 (XorV src2 (ReplicateL m1))) pg));')')dnl +dnl +define(`VECTOR_AND_NOT_PREDICATE', ` +instruct vand_not$1_masked`'(vReg dst_src1, vReg src2, imm$1_M1 m1, pRegGov pg) %{ + predicate(UseSVE > 0); + MATCH_RULE($1) + ins_cost(SVE_COST); + format %{ "sve_bic $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) $2" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + __ sve_bic(as_FloatRegister($dst_src1$$reg), __ elemType_to_regVariant(bt), + as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); + %} + ins_pipe(pipe_slow); +%}')dnl +dnl $1, $2 +VECTOR_AND_NOT_PREDICATE(I, B/H/S) +VECTOR_AND_NOT_PREDICATE(L, D) +undefine(MATCH_RULE) +dnl dnl VDIVF($1, $2 , $3 ) dnl VDIVF(name_suffix, size, min_vec_len) define(`VDIVF', ` diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp index 3717756d9d9..9482c3a65c2 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp @@ -3045,6 +3045,7 @@ public: INSN(sve_and, 0b00000100, 0b011010000); // vector and INSN(sve_andv, 0b00000100, 0b011010001); // bitwise and reduction to scalar INSN(sve_asr, 0b00000100, 0b010000100); // vector arithmetic shift right + INSN(sve_bic, 0b00000100, 0b011011000); // vector bitwise clear INSN(sve_cnt, 0b00000100, 0b011010101); // count non-zero bits INSN(sve_cpy, 0b00000101, 0b100000100); // copy scalar to each active vector element INSN(sve_eor, 0b00000100, 0b011001000); // vector eor diff --git a/test/hotspot/gtest/aarch64/aarch64-asmtest.py b/test/hotspot/gtest/aarch64/aarch64-asmtest.py index d43733535ae..1bbcdbb103a 100644 --- a/test/hotspot/gtest/aarch64/aarch64-asmtest.py +++ b/test/hotspot/gtest/aarch64/aarch64-asmtest.py @@ -1792,6 +1792,7 @@ generate(SVEVectorOp, [["add", "ZZZ"], ["add", "ZPZ", "m", "dn"], ["and", "ZPZ", "m", "dn"], ["asr", "ZPZ", "m", "dn"], + ["bic", "ZPZ", "m", "dn"], ["cnt", "ZPZ", "m"], ["eor", "ZPZ", "m", "dn"], ["lsl", "ZPZ", "m", "dn"], diff --git a/test/hotspot/gtest/aarch64/asmtest.out.h b/test/hotspot/gtest/aarch64/asmtest.out.h index 4975cce511d..2dbb48d3d01 100644 --- a/test/hotspot/gtest/aarch64/asmtest.out.h +++ b/test/hotspot/gtest/aarch64/asmtest.out.h @@ -1078,53 +1078,54 @@ __ sve_add(z8, __ D, p5, z16); // add z8.d, p5/m, z8.d, z16.d __ sve_and(z15, __ S, p1, z4); // and z15.s, p1/m, z15.s, z4.s __ sve_asr(z8, __ B, p1, z29); // asr z8.b, p1/m, z8.b, z29.b - __ sve_cnt(z28, __ D, p4, z29); // cnt z28.d, p4/m, z29.d - __ sve_eor(z9, __ H, p3, z2); // eor z9.h, p3/m, z9.h, z2.h - __ sve_lsl(z28, __ B, p0, z7); // lsl z28.b, p0/m, z28.b, z7.b - __ sve_lsr(z26, __ H, p5, z17); // lsr z26.h, p5/m, z26.h, z17.h - __ sve_mul(z8, __ D, p4, z21); // mul z8.d, p4/m, z8.d, z21.d - __ sve_neg(z5, __ S, p5, z21); // neg z5.s, p5/m, z21.s - __ sve_not(z22, __ S, p4, z29); // not z22.s, p4/m, z29.s - __ sve_orr(z19, __ S, p0, z4); // orr z19.s, p0/m, z19.s, z4.s - __ sve_smax(z23, __ B, p1, z19); // smax z23.b, p1/m, z23.b, z19.b - __ sve_smin(z23, __ B, p6, z19); // smin z23.b, p6/m, z23.b, z19.b - __ sve_sub(z8, __ D, p2, z14); // sub z8.d, p2/m, z8.d, z14.d - __ sve_fabs(z17, __ S, p7, z21); // fabs z17.s, p7/m, z21.s - __ sve_fadd(z30, __ D, p0, z10); // fadd z30.d, p0/m, z30.d, z10.d - __ sve_fdiv(z12, __ S, p0, z9); // fdiv z12.s, p0/m, z12.s, z9.s - __ sve_fmax(z24, __ D, p4, z4); // fmax z24.d, p4/m, z24.d, z4.d - __ sve_fmin(z6, __ D, p2, z27); // fmin z6.d, p2/m, z6.d, z27.d - __ sve_fmul(z13, __ D, p4, z30); // fmul z13.d, p4/m, z13.d, z30.d - __ sve_fneg(z22, __ D, p5, z30); // fneg z22.d, p5/m, z30.d - __ sve_frintm(z9, __ S, p3, z19); // frintm z9.s, p3/m, z19.s - __ sve_frintn(z20, __ S, p7, z9); // frintn z20.s, p7/m, z9.s - __ sve_frintp(z13, __ S, p3, z19); // frintp z13.s, p3/m, z19.s - __ sve_fsqrt(z24, __ S, p2, z19); // fsqrt z24.s, p2/m, z19.s - __ sve_fsub(z17, __ S, p4, z16); // fsub z17.s, p4/m, z17.s, z16.s - __ sve_fmad(z0, __ S, p0, z11, z7); // fmad z0.s, p0/m, z11.s, z7.s - __ sve_fmla(z14, __ D, p4, z4, z15); // fmla z14.d, p4/m, z4.d, z15.d - __ sve_fmls(z5, __ D, p0, z10, z21); // fmls z5.d, p0/m, z10.d, z21.d - __ sve_fnmla(z3, __ D, p0, z9, z19); // fnmla z3.d, p0/m, z9.d, z19.d - __ sve_fnmls(z10, __ S, p6, z3, z19); // fnmls z10.s, p6/m, z3.s, z19.s - __ sve_mla(z23, __ H, p7, z13, z21); // mla z23.h, p7/m, z13.h, z21.h - __ sve_mls(z26, __ S, p3, z17, z30); // mls z26.s, p3/m, z17.s, z30.s - __ sve_and(z14, z2, z29); // and z14.d, z2.d, z29.d - __ sve_eor(z21, z20, z7); // eor z21.d, z20.d, z7.d - __ sve_orr(z2, z1, z26); // orr z2.d, z1.d, z26.d - __ sve_bic(z9, z16, z17); // bic z9.d, z16.d, z17.d - __ sve_uzp1(z0, __ D, z4, z2); // uzp1 z0.d, z4.d, z2.d - __ sve_uzp2(z14, __ S, z6, z11); // uzp2 z14.s, z6.s, z11.s + __ sve_bic(z28, __ D, p4, z29); // bic z28.d, p4/m, z28.d, z29.d + __ sve_cnt(z9, __ H, p3, z2); // cnt z9.h, p3/m, z2.h + __ sve_eor(z28, __ B, p0, z7); // eor z28.b, p0/m, z28.b, z7.b + __ sve_lsl(z26, __ H, p5, z17); // lsl z26.h, p5/m, z26.h, z17.h + __ sve_lsr(z8, __ D, p4, z21); // lsr z8.d, p4/m, z8.d, z21.d + __ sve_mul(z5, __ S, p5, z21); // mul z5.s, p5/m, z5.s, z21.s + __ sve_neg(z22, __ S, p4, z29); // neg z22.s, p4/m, z29.s + __ sve_not(z19, __ S, p0, z4); // not z19.s, p0/m, z4.s + __ sve_orr(z23, __ B, p1, z19); // orr z23.b, p1/m, z23.b, z19.b + __ sve_smax(z23, __ B, p6, z19); // smax z23.b, p6/m, z23.b, z19.b + __ sve_smin(z8, __ D, p2, z14); // smin z8.d, p2/m, z8.d, z14.d + __ sve_sub(z17, __ B, p7, z21); // sub z17.b, p7/m, z17.b, z21.b + __ sve_fabs(z30, __ D, p0, z10); // fabs z30.d, p0/m, z10.d + __ sve_fadd(z12, __ S, p0, z9); // fadd z12.s, p0/m, z12.s, z9.s + __ sve_fdiv(z24, __ D, p4, z4); // fdiv z24.d, p4/m, z24.d, z4.d + __ sve_fmax(z6, __ D, p2, z27); // fmax z6.d, p2/m, z6.d, z27.d + __ sve_fmin(z13, __ D, p4, z30); // fmin z13.d, p4/m, z13.d, z30.d + __ sve_fmul(z22, __ D, p5, z30); // fmul z22.d, p5/m, z22.d, z30.d + __ sve_fneg(z9, __ S, p3, z19); // fneg z9.s, p3/m, z19.s + __ sve_frintm(z20, __ S, p7, z9); // frintm z20.s, p7/m, z9.s + __ sve_frintn(z13, __ S, p3, z19); // frintn z13.s, p3/m, z19.s + __ sve_frintp(z24, __ S, p2, z19); // frintp z24.s, p2/m, z19.s + __ sve_fsqrt(z17, __ S, p4, z16); // fsqrt z17.s, p4/m, z16.s + __ sve_fsub(z0, __ S, p0, z11); // fsub z0.s, p0/m, z0.s, z11.s + __ sve_fmad(z15, __ S, p3, z15, z4); // fmad z15.s, p3/m, z15.s, z4.s + __ sve_fmla(z29, __ D, p1, z0, z10); // fmla z29.d, p1/m, z0.d, z10.d + __ sve_fmls(z26, __ D, p0, z0, z9); // fmls z26.d, p0/m, z0.d, z9.d + __ sve_fnmla(z28, __ D, p2, z24, z3); // fnmla z28.d, p2/m, z24.d, z3.d + __ sve_fnmls(z7, __ D, p6, z28, z13); // fnmls z7.d, p6/m, z28.d, z13.d + __ sve_mla(z10, __ D, p6, z12, z17); // mla z10.d, p6/m, z12.d, z17.d + __ sve_mls(z17, __ S, p3, z2, z29); // mls z17.s, p3/m, z2.s, z29.s + __ sve_and(z21, z20, z7); // and z21.d, z20.d, z7.d + __ sve_eor(z2, z1, z26); // eor z2.d, z1.d, z26.d + __ sve_orr(z9, z16, z17); // orr z9.d, z16.d, z17.d + __ sve_bic(z0, z4, z2); // bic z0.d, z4.d, z2.d + __ sve_uzp1(z14, __ S, z6, z11); // uzp1 z14.s, z6.s, z11.s + __ sve_uzp2(z14, __ H, z16, z29); // uzp2 z14.h, z16.h, z29.h // SVEReductionOp - __ sve_andv(v14, __ H, p4, z29); // andv h14, p4, z29.h - __ sve_orv(v3, __ H, p0, z22); // orv h3, p0, z22.h - __ sve_eorv(v3, __ B, p6, z27); // eorv b3, p6, z27.b - __ sve_smaxv(v19, __ D, p5, z7); // smaxv d19, p5, z7.d - __ sve_sminv(v21, __ H, p3, z5); // sminv h21, p3, z5.h - __ sve_fminv(v25, __ D, p1, z21); // fminv d25, p1, z21.d - __ sve_fmaxv(v17, __ S, p0, z3); // fmaxv s17, p0, z3.s - __ sve_fadda(v19, __ S, p3, z7); // fadda s19, p3, s19, z7.s - __ sve_uaddv(v14, __ H, p4, z17); // uaddv d14, p4, z17.h + __ sve_andv(v3, __ H, p0, z22); // andv h3, p0, z22.h + __ sve_orv(v3, __ B, p6, z27); // orv b3, p6, z27.b + __ sve_eorv(v19, __ D, p5, z7); // eorv d19, p5, z7.d + __ sve_smaxv(v21, __ H, p3, z5); // smaxv h21, p3, z5.h + __ sve_sminv(v25, __ S, p1, z21); // sminv s25, p1, z21.s + __ sve_fminv(v17, __ S, p0, z3); // fminv s17, p0, z3.s + __ sve_fmaxv(v19, __ S, p3, z7); // fmaxv s19, p3, z7.s + __ sve_fadda(v14, __ S, p4, z17); // fadda s14, p4, s14, z17.s + __ sve_uaddv(v13, __ D, p6, z17); // uaddv d13, p6, z17.d __ bind(forth); @@ -1143,30 +1144,30 @@ 0x9101a1a0, 0xb10a5cc8, 0xd10810aa, 0xf10fd061, 0x120cb166, 0x321764bc, 0x52174681, 0x720c0227, 0x9241018e, 0xb25a2969, 0xd278b411, 0xf26aad01, - 0x14000000, 0x17ffffd7, 0x140003a5, 0x94000000, - 0x97ffffd4, 0x940003a2, 0x3400000a, 0x34fffa2a, - 0x340073ea, 0x35000008, 0x35fff9c8, 0x35007388, - 0xb400000b, 0xb4fff96b, 0xb400732b, 0xb500001d, - 0xb5fff91d, 0xb50072dd, 0x10000013, 0x10fff8b3, - 0x10007273, 0x90000013, 0x36300016, 0x3637f836, - 0x363071f6, 0x3758000c, 0x375ff7cc, 0x3758718c, + 0x14000000, 0x17ffffd7, 0x140003a6, 0x94000000, + 0x97ffffd4, 0x940003a3, 0x3400000a, 0x34fffa2a, + 0x3400740a, 0x35000008, 0x35fff9c8, 0x350073a8, + 0xb400000b, 0xb4fff96b, 0xb400734b, 0xb500001d, + 0xb5fff91d, 0xb50072fd, 0x10000013, 0x10fff8b3, + 0x10007293, 0x90000013, 0x36300016, 0x3637f836, + 0x36307216, 0x3758000c, 0x375ff7cc, 0x375871ac, 0x128313a0, 0x528a32c7, 0x7289173b, 0x92ab3acc, 0xd2a0bf94, 0xf2c285e8, 0x9358722f, 0x330e652f, 0x53067f3b, 0x93577c53, 0xb34a1aac, 0xd35a4016, 0x13946c63, 0x93c3dbc8, 0x54000000, 0x54fff5a0, - 0x54006f60, 0x54000001, 0x54fff541, 0x54006f01, - 0x54000002, 0x54fff4e2, 0x54006ea2, 0x54000002, - 0x54fff482, 0x54006e42, 0x54000003, 0x54fff423, - 0x54006de3, 0x54000003, 0x54fff3c3, 0x54006d83, - 0x54000004, 0x54fff364, 0x54006d24, 0x54000005, - 0x54fff305, 0x54006cc5, 0x54000006, 0x54fff2a6, - 0x54006c66, 0x54000007, 0x54fff247, 0x54006c07, - 0x54000008, 0x54fff1e8, 0x54006ba8, 0x54000009, - 0x54fff189, 0x54006b49, 0x5400000a, 0x54fff12a, - 0x54006aea, 0x5400000b, 0x54fff0cb, 0x54006a8b, - 0x5400000c, 0x54fff06c, 0x54006a2c, 0x5400000d, - 0x54fff00d, 0x540069cd, 0x5400000e, 0x54ffefae, - 0x5400696e, 0x5400000f, 0x54ffef4f, 0x5400690f, + 0x54006f80, 0x54000001, 0x54fff541, 0x54006f21, + 0x54000002, 0x54fff4e2, 0x54006ec2, 0x54000002, + 0x54fff482, 0x54006e62, 0x54000003, 0x54fff423, + 0x54006e03, 0x54000003, 0x54fff3c3, 0x54006da3, + 0x54000004, 0x54fff364, 0x54006d44, 0x54000005, + 0x54fff305, 0x54006ce5, 0x54000006, 0x54fff2a6, + 0x54006c86, 0x54000007, 0x54fff247, 0x54006c27, + 0x54000008, 0x54fff1e8, 0x54006bc8, 0x54000009, + 0x54fff189, 0x54006b69, 0x5400000a, 0x54fff12a, + 0x54006b0a, 0x5400000b, 0x54fff0cb, 0x54006aab, + 0x5400000c, 0x54fff06c, 0x54006a4c, 0x5400000d, + 0x54fff00d, 0x540069ed, 0x5400000e, 0x54ffefae, + 0x5400698e, 0x5400000f, 0x54ffef4f, 0x5400692f, 0xd40658e1, 0xd4014d22, 0xd4046543, 0xd4273f60, 0xd44cad80, 0xd503201f, 0xd69f03e0, 0xd6bf03e0, 0xd5033fdf, 0xd5033e9f, 0xd50332bf, 0xd61f0200, @@ -1198,7 +1199,7 @@ 0x791f226d, 0xf95aa2f3, 0xb9587bb7, 0x395f7176, 0x795d9143, 0x399e7e08, 0x799a2697, 0x79df3422, 0xb99c2624, 0xfd5c2374, 0xbd5fa1d9, 0xfd1d595a, - 0xbd1b1869, 0x5800595b, 0x1800000b, 0xf8945060, + 0xbd1b1869, 0x5800597b, 0x1800000b, 0xf8945060, 0xd8000000, 0xf8ae6ba0, 0xf99a0080, 0x1a070035, 0x3a0700a8, 0x5a0e0367, 0x7a11009b, 0x9a000380, 0xba1e030c, 0xda0f0320, 0xfa030301, 0x0b340b11, @@ -1365,17 +1366,18 @@ 0x25a0c6cd, 0x2521cf00, 0x0583c5b1, 0x05407336, 0x05001e62, 0x04e400f4, 0x04a80407, 0x65c402d3, 0x65cb0ac9, 0x659007c5, 0x0456ac36, 0x04c01608, - 0x049a048f, 0x041087a8, 0x04dab3bc, 0x04590c49, - 0x041380fc, 0x0451963a, 0x04d012a8, 0x0497b6a5, - 0x049eb3b6, 0x04980093, 0x04080677, 0x040a1a77, - 0x04c109c8, 0x049cbeb1, 0x65c0815e, 0x658d812c, - 0x65c69098, 0x65c78b66, 0x65c293cd, 0x04ddb7d6, - 0x6582ae69, 0x6580bd34, 0x6581ae6d, 0x658daa78, - 0x65819211, 0x65a78160, 0x65ef108e, 0x65f52145, - 0x65f34123, 0x65b3786a, 0x04555db7, 0x049e6e3a, - 0x043d304e, 0x04a73295, 0x047a3022, 0x04f13209, - 0x05e26880, 0x05ab6cce, 0x045a33ae, 0x045822c3, - 0x04193b63, 0x04c834f3, 0x044a2cb5, 0x65c726b9, - 0x65862071, 0x65982cf3, 0x0441322e, + 0x049a048f, 0x041087a8, 0x04db13bc, 0x045aac49, + 0x041900fc, 0x0453963a, 0x04d192a8, 0x049016a5, + 0x0497b3b6, 0x049ea093, 0x04180677, 0x04081a77, + 0x04ca09c8, 0x04011eb1, 0x04dca15e, 0x6580812c, + 0x65cd9098, 0x65c68b66, 0x65c793cd, 0x65c297d6, + 0x049dae69, 0x6582bd34, 0x6580ae6d, 0x6581aa78, + 0x658db211, 0x65818160, 0x65a48def, 0x65ea041d, + 0x65e9201a, 0x65e34b1c, 0x65ed7b87, 0x04d1598a, + 0x049d6c51, 0x04273295, 0x04ba3022, 0x04713209, + 0x04e23080, 0x05ab68ce, 0x057d6e0e, 0x045a22c3, + 0x04183b63, 0x04d934f3, 0x04482cb5, 0x048a26b9, + 0x65872071, 0x65862cf3, 0x6598322e, 0x04c13a2d, + }; // END Generated code -- do not edit -- GitLab From 1864481df10d2f616cbfdecebf3bebbae04de5e1 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Thu, 17 Feb 2022 06:40:46 +0000 Subject: [PATCH 281/400] 8279969: NULL return from map_bitmap_region() needs to be checked Reviewed-by: ccheung, coleenp --- src/hotspot/share/cds/filemap.cpp | 13 ++++++++++--- src/hotspot/share/cds/heapShared.cpp | 4 ++++ .../cds/appcds/SharedArchiveConsistency.java | 8 ++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 63ba7fb2893..69ab7430e16 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -2168,6 +2168,15 @@ void FileMapInfo::map_heap_regions_impl() { assert(is_aligned(relocated_closed_heap_region_bottom, HeapRegion::GrainBytes), "must be"); + if (_heap_pointers_need_patching) { + char* bitmap_base = map_bitmap_region(); + if (bitmap_base == NULL) { + log_info(cds)("CDS heap cannot be used because bitmap region cannot be mapped"); + _heap_pointers_need_patching = false; + return; + } + } + // Map the closed heap regions: GC does not write into these regions. if (map_heap_regions(MetaspaceShared::first_closed_heap_region, MetaspaceShared::max_num_closed_heap_regions, @@ -2297,9 +2306,7 @@ void FileMapInfo::patch_heap_embedded_pointers() { void FileMapInfo::patch_heap_embedded_pointers(MemRegion* regions, int num_regions, int first_region_idx) { char* bitmap_base = map_bitmap_region(); - if (bitmap_base == NULL) { - return; - } + assert(bitmap_base != NULL, "must have already been mapped"); for (int i=0; imap_bitmap_region(); + if (bitmap_base == 0) { + _loading_failed = true; + return false; // OOM or CRC error + } uintptr_t load_address = buffer; for (int i = 0; i < num_loaded_regions; i++) { LoadedArchiveHeapRegion* ri = &loaded_regions[i]; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java b/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java index fd0291f06e0..cec5b66a12f 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java @@ -80,6 +80,14 @@ public class SharedArchiveConsistency { OutputAnalyzer output = shareAuto ? TestCommon.execAuto(execArgs) : TestCommon.execCommon(execArgs); String stdtxt = output.getOutput(); System.out.println("Note: this test may fail in very rare occasions due to CRC32 checksum collision"); + for (String opt : execArgs) { + if (opt.equals("-XX:+VerifySharedSpaces")) { + // If VerifySharedSpaces is enabled, the VM should never crash even if the archive + // is corrupted (unless if we are so lucky that the corrupted archive ends up + // have the same checksum as recoreded in the header) + output.shouldNotContain("A fatal error has been detected by the Java Runtime Environment"); + } + } for (String message : matchMessages) { if (stdtxt.contains(message)) { // match any to return -- GitLab From c0275e18b7cb4a01385b79ced46560322aeacc97 Mon Sep 17 00:00:00 2001 From: Tyler Steele Date: Thu, 17 Feb 2022 08:49:22 +0000 Subject: [PATCH 282/400] 8203290: [AIX] Check functionality of JDK-8199712 (Flight Recorder) Implements JFR for AIX Reviewed-by: erikj, mdoerr, mgronlun, stuefe, ihse --- make/autoconf/jvm-features.m4 | 23 - src/hotspot/os/aix/libperfstat_aix.cpp | 61 +- src/hotspot/os/aix/libperfstat_aix.hpp | 153 ++- src/hotspot/os/aix/loadlib_aix.cpp | 178 ++-- src/hotspot/os/aix/loadlib_aix.hpp | 12 + src/hotspot/os/aix/os_aix.cpp | 8 +- src/hotspot/os/aix/os_perf_aix.cpp | 982 ++++++------------ src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp | 73 +- test/jdk/ProblemList.txt | 2 +- .../runtime/TestNativeLibrariesEvent.java | 5 +- 10 files changed, 728 insertions(+), 769 deletions(-) diff --git a/make/autoconf/jvm-features.m4 b/make/autoconf/jvm-features.m4 index 70457149edc..8dfc0d362b9 100644 --- a/make/autoconf/jvm-features.m4 +++ b/make/autoconf/jvm-features.m4 @@ -264,22 +264,6 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_DTRACE], ]) ]) -############################################################################### -# Check if the feature 'jfr' is available on this platform. -# -AC_DEFUN_ONCE([JVM_FEATURES_CHECK_JFR], -[ - JVM_FEATURES_CHECK_AVAILABILITY(jfr, [ - AC_MSG_CHECKING([if platform is supported by JFR]) - if test "x$OPENJDK_TARGET_OS" = xaix; then - AC_MSG_RESULT([no, $OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU]) - AVAILABLE=false - else - AC_MSG_RESULT([yes]) - fi - ]) -]) - ############################################################################### # Check if the feature 'jvmci' is available on this platform. # @@ -399,18 +383,11 @@ AC_DEFUN_ONCE([JVM_FEATURES_PREPARE_PLATFORM], JVM_FEATURES_CHECK_CDS JVM_FEATURES_CHECK_DTRACE - JVM_FEATURES_CHECK_JFR JVM_FEATURES_CHECK_JVMCI JVM_FEATURES_CHECK_SHENANDOAHGC JVM_FEATURES_CHECK_STATIC_BUILD JVM_FEATURES_CHECK_ZGC - # Filter out features by default for all variants on certain platforms. - # Make sure to just add to JVM_FEATURES_PLATFORM_FILTER, since it could - # have a value already from custom extensions. - if test "x$OPENJDK_TARGET_OS" = xaix; then - JVM_FEATURES_PLATFORM_FILTER="$JVM_FEATURES_PLATFORM_FILTER jfr" - fi ]) ############################################################################### diff --git a/src/hotspot/os/aix/libperfstat_aix.cpp b/src/hotspot/os/aix/libperfstat_aix.cpp index 65a937ef261..cec0ac1d287 100644 --- a/src/hotspot/os/aix/libperfstat_aix.cpp +++ b/src/hotspot/os/aix/libperfstat_aix.cpp @@ -1,5 +1,7 @@ /* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2018 SAP SE. All rights reserved. + * Copyright (c) 2022, IBM Corp. * 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 +32,22 @@ // Handle to the libperfstat. static void* g_libhandle = NULL; +typedef int (*fun_perfstat_cpu_t) (perfstat_id_t *name, PERFSTAT_CPU_T_LATEST* userbuff, + int sizeof_userbuff, int desired_number); + typedef int (*fun_perfstat_cpu_total_t) (perfstat_id_t *name, PERFSTAT_CPU_TOTAL_T_LATEST* userbuff, int sizeof_userbuff, int desired_number); typedef int (*fun_perfstat_memory_total_t) (perfstat_id_t *name, perfstat_memory_total_t* userbuff, int sizeof_userbuff, int desired_number); +typedef int (*fun_perfstat_netinterface_t) (perfstat_id_t *name, perfstat_netinterface_t* userbuff, + int sizeof_userbuff, int desired_number); + +typedef int (*fun_perfstat_process_t) (perfstat_id_t *name, + PERFSTAT_PROCESS_T_LATEST* userbuff, int sizeof_userbuff, + int desired_number); + typedef int (*fun_perfstat_partition_total_t) (perfstat_id_t *name, PERFSTAT_PARTITON_TOTAL_T_LATEST* userbuff, int sizeof_userbuff, int desired_number); @@ -48,12 +60,15 @@ typedef void (*fun_perfstat_reset_t) (); typedef cid_t (*fun_wpar_getcid_t) (); -static fun_perfstat_cpu_total_t g_fun_perfstat_cpu_total = NULL; -static fun_perfstat_memory_total_t g_fun_perfstat_memory_total = NULL; +static fun_perfstat_cpu_total_t g_fun_perfstat_cpu_total = NULL; +static fun_perfstat_cpu_t g_fun_perfstat_cpu = NULL; +static fun_perfstat_memory_total_t g_fun_perfstat_memory_total = NULL; +static fun_perfstat_netinterface_t g_fun_perfstat_netinterface = NULL; static fun_perfstat_partition_total_t g_fun_perfstat_partition_total = NULL; -static fun_perfstat_wpar_total_t g_fun_perfstat_wpar_total = NULL; -static fun_perfstat_reset_t g_fun_perfstat_reset = NULL; -static fun_wpar_getcid_t g_fun_wpar_getcid = NULL; +static fun_perfstat_process_t g_fun_perfstat_process = NULL; +static fun_perfstat_wpar_total_t g_fun_perfstat_wpar_total = NULL; +static fun_perfstat_reset_t g_fun_perfstat_reset = NULL; +static fun_wpar_getcid_t g_fun_wpar_getcid = NULL; bool libperfstat::init() { @@ -84,7 +99,10 @@ bool libperfstat::init() { // These functions are required for every release. RESOLVE_FUN(perfstat_cpu_total); + RESOLVE_FUN(perfstat_cpu); RESOLVE_FUN(perfstat_memory_total); + RESOLVE_FUN(perfstat_netinterface); + RESOLVE_FUN(perfstat_process); RESOLVE_FUN(perfstat_reset); trcVerbose("libperfstat loaded."); @@ -108,6 +126,22 @@ void libperfstat::cleanup() { } +int libperfstat::perfstat_cpu_total(perfstat_id_t *name, PERFSTAT_CPU_TOTAL_T_LATEST* userbuff, + int sizeof_userbuff, int desired_number) { + if (g_fun_perfstat_cpu_total == NULL) { + return -1; + } + return g_fun_perfstat_cpu_total(name, userbuff, sizeof_userbuff, desired_number); +} + +int libperfstat::perfstat_cpu(perfstat_id_t *name, PERFSTAT_CPU_T_LATEST* userbuff, + int sizeof_userbuff, int desired_number) { + if (g_fun_perfstat_cpu == NULL) { + return -1; + } + return g_fun_perfstat_cpu(name, userbuff, sizeof_userbuff, desired_number); +} + int libperfstat::perfstat_memory_total(perfstat_id_t *name, perfstat_memory_total_t* userbuff, int sizeof_userbuff, int desired_number) { @@ -117,12 +151,13 @@ int libperfstat::perfstat_memory_total(perfstat_id_t *name, return g_fun_perfstat_memory_total(name, userbuff, sizeof_userbuff, desired_number); } -int libperfstat::perfstat_cpu_total(perfstat_id_t *name, PERFSTAT_CPU_TOTAL_T_LATEST* userbuff, - int sizeof_userbuff, int desired_number) { - if (g_fun_perfstat_cpu_total == NULL) { +int libperfstat::perfstat_netinterface(perfstat_id_t *name, + perfstat_netinterface_t* userbuff, + int sizeof_userbuff, int desired_number) { + if (g_fun_perfstat_netinterface == NULL) { return -1; } - return g_fun_perfstat_cpu_total(name, userbuff, sizeof_userbuff, desired_number); + return g_fun_perfstat_netinterface(name, userbuff, sizeof_userbuff, desired_number); } int libperfstat::perfstat_partition_total(perfstat_id_t *name, PERFSTAT_PARTITON_TOTAL_T_LATEST* userbuff, @@ -133,6 +168,14 @@ int libperfstat::perfstat_partition_total(perfstat_id_t *name, PERFSTAT_PARTITON return g_fun_perfstat_partition_total(name, userbuff, sizeof_userbuff, desired_number); } +int libperfstat::perfstat_process(perfstat_id_t *name, perfstat_process_t* userbuff, + int sizeof_userbuff, int desired_number) { + if (g_fun_perfstat_process == NULL) { + return -1; + } + return g_fun_perfstat_process(name, userbuff, sizeof_userbuff, desired_number); +} + int libperfstat::perfstat_wpar_total(perfstat_id_wpar_t *name, PERFSTAT_WPAR_TOTAL_T_LATEST* userbuff, int sizeof_userbuff, int desired_number) { if (g_fun_perfstat_wpar_total == NULL) { diff --git a/src/hotspot/os/aix/libperfstat_aix.hpp b/src/hotspot/os/aix/libperfstat_aix.hpp index d323b8e8bbc..30f08c57a03 100644 --- a/src/hotspot/os/aix/libperfstat_aix.hpp +++ b/src/hotspot/os/aix/libperfstat_aix.hpp @@ -1,5 +1,7 @@ /* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2018 SAP SE. All rights reserved. + * Copyright (c) 2022, IBM Corp. * 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 +49,9 @@ // work without recompilation on all newer AIX versions. // -#define IDENTIFIER_LENGTH 64 /* length of strings included in the structures */ +#define IDENTIFIER_LENGTH 64 /* length of strings included in the structures */ +#define FIRST_CPU "" /* pseudo-name for fist CPU */ +#define FIRST_NETINTERFACE "" /* pseudo-name for first NETINTERFACE */ typedef struct { /* structure element identifier */ @@ -439,6 +443,102 @@ typedef struct { /* global cpu information AIX 7.2 / 6.1 TL6 (see oslevel -r) * * of perfstat_cpu_total_t data structure */ } perfstat_cpu_total_t_72; +typedef struct { /* component perfstat_cpu_t from AIX 7.2 documentation */ + char name [IDENTIFIER_LENGTH]; /* Logical processor name (processor0, processor1,.). */ + ulong_t state; /* Specifies whether the CPU is offline or online. + * (NOTE: The type of 'state' is not specified in the documentation, but + * ulong_t is the correct length) */ + u_longlong_t user; /* Raw number of clock ticks spent in user mode. */ + u_longlong_t sys; /* Raw number of clock ticks spent in system mode. */ + u_longlong_t idle; /* Raw number of clock ticks spent idle. */ + u_longlong_t wait; /* Raw number of clock ticks spent waiting for I/O. */ + u_longlong_t pswitch; /* Number of context switches (changes of currently running process). */ + u_longlong_t syscall; /* Number of system calls executed. */ + u_longlong_t sysread; /* Number of read system calls executed. */ + u_longlong_t syswrite; /* Number of write system calls executed. */ + u_longlong_t sysfork; /* Number of fork system call executed. */ + u_longlong_t sysexec; /* Number of exec system call executed. */ + u_longlong_t readch; /* Number of characters transferred with read system call. */ + u_longlong_t writech; /* Number of characters transferred with write system call. */ + u_longlong_t bread; /* Number of block reads. */ + u_longlong_t bwrite; /* Number of block writes. */ + u_longlong_t lread; /* Number of logical read requests. */ + u_longlong_t lwrite; /* Number of logical write requests. */ + u_longlong_t phread; /* Number of physical reads (reads on raw device). */ + u_longlong_t phwrite; /* Number of physical writes (writes on raw device). */ + u_longlong_t iget; /* Number of inode lookups. */ + u_longlong_t namei; /* Number of vnode lookup from a path name. */ + u_longlong_t dirblk; /* Number of 512-byte blocks reads by the directory search routine to locate an entry for a file. */ + u_longlong_t msg; /* Number of interprocess communication (IPC) message operations. */ + u_longlong_t sema; /* Number of IPC semaphore operations. */ + u_longlong_t minfaults; /* Number of page faults with no I/O. */ + u_longlong_t majfaults; /* Number of page faults with disk I/O. */ + u_longlong_t puser; /* Raw number of physical processor ticks in user mode. */ + u_longlong_t psys; /* Raw number of physical processor ticks in system mode. */ + u_longlong_t pidle; /* Raw number of physical processor ticks idle. */ + u_longlong_t pwait; /* Raw number of physical processor ticks waiting for I/O. */ + u_longlong_t redisp_sd0; /* Number of thread redispatches within the scheduler affinity domain 0. */ + u_longlong_t redisp_sd1; /* Number of thread redispatches within the scheduler affinity domain 1. */ + u_longlong_t redisp_sd2; /* Number of thread redispatches within the scheduler affinity domain 2. */ + u_longlong_t redisp_sd3; /* Number of thread redispatches within the scheduler affinity domain 3. */ + u_longlong_t redisp_sd4; /* Number of thread redispatches within the scheduler affinity domain 4. */ + u_longlong_t redisp_sd5; /* Number of thread redispatches within the scheduler affinity domain 5. */ + u_longlong_t migration_push; /* Number of thread migrations from the local runque to another queue due to starvation load balancing. */ + u_longlong_t migration_S3grq; /* Number of thread migrations from the global runque to the local runque resulting in a move across scheduling domain 3. */ + u_longlong_t migration_S3pull; /* Number of thread migrations from another processor's runque resulting in a move across scheduling domain 3. */ + u_longlong_t invol_cswitch; /* Number of involuntary thread context switches. */ + u_longlong_t vol_cswitch; /* Number of voluntary thread context switches. */ + u_longlong_t runque; /* Number of threads on the runque. */ + u_longlong_t bound; /* Number of bound threads. */ + u_longlong_t decrintrs; /* Number of decrementer interrupts. */ + u_longlong_t mpcrintrs; /* Number of received interrupts for MPC. */ + u_longlong_t mpcsintrs; /* Number of sent interrupts for MPC. */ + u_longlong_t devintrs; /* Number of device interrupts. */ + u_longlong_t softintrs; /* Number of offlevel handlers called. */ + u_longlong_t phantintrs; /* Number of phantom interrupts. */ + u_longlong_t idle_donated_purr; /* Number of idle cycles donated by a dedicated partition enabled for donation. */ + u_longlong_t idle_donated_spurr; /* Number of idle spurr cycles donated by a dedicated partition enabled for donation. */ + u_longlong_t busy_donated_purr; /* Number of busy cycles donated by a dedicated partition enabled for donation. */ + u_longlong_t busy_donated_spurr; /* Number of busy spurr cycles donated by a dedicated partition enabled for donation. */ + u_longlong_t idle_stolen_purr; /* Number of idle cycles stolen by the hypervisor from a dedicated partition. */ + u_longlong_t idle_stolen_spurr; /* Number of idle spurr cycles stolen by the hypervisor from a dedicated partition. */ + u_longlong_t busy_stolen_purr; /* Number of busy cycles stolen by the hypervisor from a dedicated partition. */ + u_longlong_t busy_stolen_spurr; /* Number of busy spurr cycles stolen by the hypervisor from a dedicated partition.*/ + u_longlong_t shcpus_in_sys; /* Number of physical processors allocated for shared processor use, across all shared processors pools. */ + u_longlong_t entitled_pool_capacity; /* Entitled processor capacity of partition’s pool. */ + u_longlong_t pool_max_time; /* Summation of maximum time that can be consumed by the pool (nanoseconds). */ + u_longlong_t pool_busy_time; /* Summation of busy (nonidle) time accumulated across all partitions in the pool (nanoseconds). */ + u_longlong_t pool_scaled_busy_time; /* Scaled summation of busy (nonidle) time accumulated across all partitions in the pool (nanoseconds). */ + u_longlong_t shcpu_tot_time; /* Summation of total time across all physical processors allocated for shared processor use (nanoseconds). */ + u_longlong_t shcpu_busy_time; /* Summation of busy (nonidle) time accumulated across all shared processor partitions (nanoseconds). */ + u_longlong_t shcpu_scaled_busy_time; /* Scaled summation of busy time accumulated across all shared processor partitions (nanoseconds). */ + int ams_pool_id; /* AMS pool ID of the pool the LPAR belongs to. */ + int var_mem_weight; /* Variable memory capacity weight. */ + u_longlong_t iome; /* I/O memory entitlement of the partition in bytes. */ + u_longlong_t pmem; /* Physical memory currently backing the partition's logical memory in bytes. */ + u_longlong_t hpi; /* Number of hypervisor page-ins. */ + u_longlong_t hpit; /* Time spent in hypervisor page-ins (in nanoseconds). */ + u_longlong_t hypv_pagesize; /* Hypervisor page size in KB. */ + uint online_lcpus; /* Number of online logical processors. */ + uint smt_thrds; /* Number of SMT threads. */ +} perfstat_cpu_t; + +typedef struct { + char name[IDENTIFIER_LENGTH]; /* Name of the interface. */ + char description[IDENTIFIER_LENGTH]; /* Interface description (from ODM, similar to lscfg output). */ + uchar type; /* Ethernet, token ring, and so on. Interpretation can be done using the /usr/include/net/if_types.h file. */ + u_longlong_t mtu; /* Network frame size. */ + u_longlong_t ipacets; /* Number of packets received on interface. */ + u_longlong_t ibytes; /* Number of bytes received on interface. */ + u_longlong_t ierrors; /* Number of input errors on interface. */ + u_longlong_t opackets; /* Number of packets sent on interface. */ + u_longlong_t obytes; /* Number of bytes sent on interface. */ + u_longlong_t oerrors; /* Number of output errors on interface. */ + u_longlong_t collisions; /* Number of collisions on csma interface. */ + u_longlong_t bitrate; /* Adapter rating in bit per second. */ + u_longlong_t if_iqdrops; /* Dropped on input, this interface. */ + u_longlong_t if_arpdrops; /* Dropped because no arp response. */ +} perfstat_netinterface_t; typedef union { uint w; @@ -797,6 +897,38 @@ typedef struct { /* partition total information AIX 7.1 >= TL1*/ * of perfstat_partition_total_t data structure */ } perfstat_partition_total_t_71_1; +typedef struct { + u_longlong_t version; /* Version number of the data structure. */ + u_longlong_t pid; /* Process ID. */ + char proc_name[64]; /* Name of the process. */ + int proc_priority; /* Process priority. */ + u_longlong_t num_threads; /* Thread count. */ + u_longlong_t proc_uid; /* Owner information. */ + u_longlong_t proc_classid; /* WLM class name. */ + u_longlong_t proc_size; /* Virtual size of the process (exclusive usage, leaving all shared library text & shared file pages, shared memory, and memory mapped). */ + u_longlong_t proc_real_mem_data; /* Real memory used for data in KB. */ + u_longlong_t proc_real_mem_text; /* Real memory used for text in KB. */ + u_longlong_t proc_virt_mem_data; /* Virtual memory used for data in KB. */ + u_longlong_t proc_virt_mem_text; /* Virtual memory used for text in KB. */ + u_longlong_t shared_lib_data_size; /* Data size from shared library in KB. */ + u_longlong_t heap_size; /* Heap size in KB. */ + u_longlong_t real_inuse; /* The Real memory (in KB) in use by the process including all kind of segments (excluding system segments). This includes text, data, shared library text, shared library data, file pages, shared memory, and memory mapped. */ + u_longlong_t virt_inuse; /* The virtual memory (in KB) in use by the process including all kind of segments (excluding system segments). This includes text, data, shared library text, shared library data, file pages, shared memory, and memory mapped. */ + u_longlong_t pinned; /* Pinned memory (in KB) for this process inclusive of all segments. */ + u_longlong_t pgsp_inuse; /* Paging space used (in KB) inclusive of all segments. */ + u_longlong_t filepages; /* File pages used (in KB) including shared pages. */ + u_longlong_t real_inuse_map; /* Real memory used (in KB) for shared memory and memory mapped regions */ + u_longlong_t virt_inuse_map; /* Virtual memory used (in KB) for shared memory and memory mapped regions. */ + u_longlong_t pinned_inuse_map; /* Pinned memory used (in KB) for shared memory and memory mapped regions. */ + double ucpu_time; /* User mode CPU time is in percentage or milliseconds, which is based on, whether it is filled by perfstat_process_util or perfstat_process respectively. */ + double scpu_time; /* System mode CPU time is in percentage or milliseconds, which is based on whether it is filled by perfstat_process_util or perfstat_process respectively. */ + u_longlong_t last_timebase; /* Timebase counter. */ + u_longlong_t inBytes; /* Bytes written to disk. */ + u_longlong_t outBytes; /* Bytes read from disk. */ + u_longlong_t inOps; /* In operations from disk. */ + u_longlong_t outOps; /* Out operations from disk */ +} perfstat_process_t; + typedef union { /* WPAR Type & Flags */ uint w; struct { @@ -854,9 +986,14 @@ typedef struct { /* WPAR identifier */ // end: libperfstat.h (AIX 5.2, 5.3, 6.1, 7.1) ////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#define PERFSTAT_PARTITON_TOTAL_T_LATEST perfstat_partition_total_t_71_1/* latest perfstat_partition_total_t structure */ -#define PERFSTAT_CPU_TOTAL_T_LATEST perfstat_cpu_total_t_72 /* latest perfstat_cpu_total_t structure */ -#define PERFSTAT_WPAR_TOTAL_T_LATEST perfstat_wpar_total_t_71 /* latest perfstat_wpar_total_t structure */ +#define PERFSTAT_PARTITON_TOTAL_T_LATEST perfstat_partition_total_t_71_1 /* latest perfstat_partition_total_t structure */ +#define PERFSTAT_PROCESS_T_LATEST perfstat_process_t /* latest perfstat_process_t structure */ +#define PERFSTAT_CPU_TOTAL_T_LATEST perfstat_cpu_total_t_72 /* latest perfstat_cpu_total_t structure */ +#define PERFSTAT_CPU_T_LATEST perfstat_cpu_t /* latest perfstat_cpu_t structure */ +#define PERFSTAT_NETINTERFACE_T_LATEST perfstat_netinterface_t /* latest perfstat_netinterface_t structure */ +#define PERFSTAT_WPAR_TOTAL_T_LATEST perfstat_wpar_total_t_71 /* latest perfstat_wpar_total_t structure */ + +typedef PERFSTAT_CPU_TOTAL_T_LATEST perfstat_cpu_total_t; class libperfstat { @@ -886,6 +1023,14 @@ public: static cid_t wpar_getcid(); + static int perfstat_cpu(perfstat_id_t *name, PERFSTAT_CPU_T_LATEST* userbuff, + int sizeof_userbuff, int desired_number); + + static int perfstat_process(perfstat_id_t *name, PERFSTAT_PROCESS_T_LATEST* userbuff, + int sizeof_userbuff, int desired_number); + + static int perfstat_netinterface(perfstat_id_t *name, PERFSTAT_NETINTERFACE_T_LATEST* userbuff, + int sizeof_userbuff, int desired_number); //////////////////////////////////////////////////////////////// // The convenience functions get_partitioninfo(), get_cpuinfo(), get_wparinfo() return diff --git a/src/hotspot/os/aix/loadlib_aix.cpp b/src/hotspot/os/aix/loadlib_aix.cpp index 9ac761f6212..a111e0199fa 100644 --- a/src/hotspot/os/aix/loadlib_aix.cpp +++ b/src/hotspot/os/aix/loadlib_aix.cpp @@ -1,6 +1,7 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2019 SAP SE. All rights reserved. + * Copyright (c) 2022, IBM Corp. * 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,13 +111,7 @@ static StringList g_stringlist; // eternal - this list is rebuilt on every reload. // Note that we do not hand out those entries, but copies of them. -struct entry_t { - entry_t* next; - loaded_module_t info; -}; - -static void print_entry(const entry_t* e, outputStream* os) { - const loaded_module_t* const lm = &(e->info); +static void print_entry(const loaded_module_t* lm, outputStream* os) { os->print(" %c text: " INTPTR_FORMAT " - " INTPTR_FORMAT ", data: " INTPTR_FORMAT " - " INTPTR_FORMAT " " "%s", @@ -129,50 +124,50 @@ static void print_entry(const entry_t* e, outputStream* os) { } } -static entry_t* g_first = NULL; +static loaded_module_t* g_first = NULL; -static entry_t* find_entry_for_text_address(const void* p) { - for (entry_t* e = g_first; e; e = e->next) { - if ((uintptr_t)p >= (uintptr_t)e->info.text && - (uintptr_t)p < ((uintptr_t)e->info.text + e->info.text_len)) { - return e; +static loaded_module_t* find_entry_for_text_address(const void* p) { + for (loaded_module_t* lm = g_first; lm; lm = lm->next) { + if ((uintptr_t)p >= (uintptr_t)lm->text && + (uintptr_t)p < ((uintptr_t)lm->text + lm->text_len)) { + return lm; } } return NULL; } -static entry_t* find_entry_for_data_address(const void* p) { - for (entry_t* e = g_first; e; e = e->next) { - if ((uintptr_t)p >= (uintptr_t)e->info.data && - (uintptr_t)p < ((uintptr_t)e->info.data + e->info.data_len)) { - return e; +static loaded_module_t* find_entry_for_data_address(const void* p) { + for (loaded_module_t* lm = g_first; lm; lm = lm->next) { + if ((uintptr_t)p >= (uintptr_t)lm->data && + (uintptr_t)p < ((uintptr_t)lm->data + lm->data_len)) { + return lm; } } return NULL; } // Adds a new entry to the list (ordered by text address ascending). -static void add_entry_to_list(entry_t* e, entry_t** start) { - entry_t* last = NULL; - entry_t* e2 = *start; - while (e2 && e2->info.text < e->info.text) { - last = e2; - e2 = e2->next; +static void add_entry_to_list(loaded_module_t* lm, loaded_module_t** start) { + loaded_module_t* last = NULL; + loaded_module_t* lm2 = *start; + while (lm2 && lm2->text < lm->text) { + last = lm2; + lm2 = lm2->next; } if (last) { - last->next = e; + last->next = lm; } else { - *start = e; + *start = lm; } - e->next = e2; + lm->next = lm2; } -static void free_entry_list(entry_t** start) { - entry_t* e = *start; - while (e) { - entry_t* const e2 = e->next; - ::free(e); - e = e2; +static void free_entry_list(loaded_module_t** start) { + loaded_module_t* lm = *start; + while (lm) { + loaded_module_t* const lm2 = lm->next; + ::free(lm); + lm = lm2; } *start = NULL; } @@ -186,7 +181,7 @@ static bool reload_table() { trcVerbose("reload module table..."); - entry_t* new_list = NULL; + loaded_module_t* new_list = NULL; const struct ld_info* ldi = NULL; // Call loadquery(L_GETINFO..) to get a list of all loaded Dlls from AIX. loadquery @@ -214,33 +209,33 @@ static bool reload_table() { for (;;) { - entry_t* e = (entry_t*) ::malloc(sizeof(entry_t)); - if (!e) { + loaded_module_t* lm = (loaded_module_t*) ::malloc(sizeof(loaded_module_t)); + if (!lm) { trcVerbose("OOM."); goto cleanup; } - memset(e, 0, sizeof(entry_t)); + memset(lm, 0, sizeof(loaded_module_t)); - e->info.text = ldi->ldinfo_textorg; - e->info.text_len = ldi->ldinfo_textsize; - e->info.data = ldi->ldinfo_dataorg; - e->info.data_len = ldi->ldinfo_datasize; + lm->text = ldi->ldinfo_textorg; + lm->text_len = ldi->ldinfo_textsize; + lm->data = ldi->ldinfo_dataorg; + lm->data_len = ldi->ldinfo_datasize; - e->info.path = g_stringlist.add(ldi->ldinfo_filename); - if (!e->info.path) { + lm->path = g_stringlist.add(ldi->ldinfo_filename); + if (!lm->path) { trcVerbose("OOM."); goto cleanup; } // Extract short name { - const char* p = strrchr(e->info.path, '/'); + const char* p = strrchr(lm->path, '/'); if (p) { p ++; - e->info.shortname = p; + lm->shortname = p; } else { - e->info.shortname = e->info.path; + lm->shortname = lm->path; } } @@ -248,32 +243,32 @@ static bool reload_table() { const char* p_mbr_name = ldi->ldinfo_filename + strlen(ldi->ldinfo_filename) + 1; if (*p_mbr_name) { - e->info.member = g_stringlist.add(p_mbr_name); - if (!e->info.member) { + lm->member = g_stringlist.add(p_mbr_name); + if (!lm->member) { trcVerbose("OOM."); goto cleanup; } } else { - e->info.member = NULL; + lm->member = NULL; } - if (strcmp(e->info.shortname, "libjvm.so") == 0) { + if (strcmp(lm->shortname, "libjvm.so") == 0) { // Note that this, theoretically, is fuzzy. We may accidentally contain // more than one libjvm.so. But that is improbable, so lets go with this // solution. - e->info.is_in_vm = true; + lm->is_in_vm = true; } trcVerbose("entry: %p " SIZE_FORMAT ", %p " SIZE_FORMAT ", %s %s %s, %d", - e->info.text, e->info.text_len, - e->info.data, e->info.data_len, - e->info.path, e->info.shortname, - (e->info.member ? e->info.member : "NULL"), - e->info.is_in_vm + lm->text, lm->text_len, + lm->data, lm->data_len, + lm->path, lm->shortname, + (lm->member ? lm->member : "NULL"), + lm->is_in_vm ); // Add to list. - add_entry_to_list(e, &new_list); + add_entry_to_list(lm, &new_list); // Next entry... if (ldi->ldinfo_next) { @@ -304,6 +299,23 @@ cleanup: } // end LoadedLibraries::reload() +// Callback for loaded module information (from os.hpp) +// Input parameters: +// char* module_file_name, +// address module_base_addr, +// address module_top_addr, +// void* param +static bool for_each_internal(os::LoadedModulesCallbackFunc cb, void* param) { + + for (const loaded_module_t* lm = g_first; lm; lm = lm->next) { + (*cb)(lm->shortname, + (address) lm->text, + (address) lm->text + lm->text_len, + param); + } + + return true; +} /////////////////////////////////////////////////////////////////////////////// // Externals @@ -322,8 +334,8 @@ void LoadedLibraries::print(outputStream* os) { if (!g_first) { reload_table(); } - for (entry_t* e = g_first; e; e = e->next) { - print_entry(e, os); + for (loaded_module_t* lm = g_first; lm; lm = lm->next) { + print_entry(lm, os); os->cr(); } } @@ -334,14 +346,17 @@ bool LoadedLibraries::find_for_text_address(const void* p, if (!g_first) { reload_table(); } - const entry_t* const e = find_entry_for_text_address(p); - if (e) { - if (info) { - *info = e->info; - } - return true; + + const loaded_module_t* const lm = find_entry_for_text_address(p); + if (!lm) { + return false; } - return false; + + if (info) { + memcpy(info, lm, sizeof(loaded_module_t)); + info->next = nullptr; + } + return true; } @@ -353,13 +368,30 @@ bool LoadedLibraries::find_for_data_address ( if (!g_first) { reload_table(); } - const entry_t* const e = find_entry_for_data_address(p); - if (e) { - if (info) { - *info = e->info; + + const loaded_module_t* const lm = find_entry_for_data_address(p); + if (!lm) { + return false; + } + + if (info) { + memcpy(info, lm, sizeof(loaded_module_t)); + info->next = nullptr; + } + return true; +} + +bool LoadedLibraries::for_each(os::LoadedModulesCallbackFunc cb, void* param) { + MiscUtils::AutoCritSect lck(&g_cs); + + if (!g_first) { + if (!reload_table()) { + // If the table is not loaded and cannot be initialized, + // then we must quit. + return false; } - return true; } - return false; + + return for_each_internal(cb, param); } diff --git a/src/hotspot/os/aix/loadlib_aix.hpp b/src/hotspot/os/aix/loadlib_aix.hpp index 354dccf4c7b..18cd6e59864 100644 --- a/src/hotspot/os/aix/loadlib_aix.hpp +++ b/src/hotspot/os/aix/loadlib_aix.hpp @@ -1,4 +1,5 @@ /* + * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2013 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -32,6 +33,9 @@ #ifndef OS_AIX_LOADLIB_AIX_HPP #define OS_AIX_LOADLIB_AIX_HPP +#include "misc_aix.hpp" +#include "runtime/os.hpp" + #include class outputStream; @@ -66,6 +70,9 @@ struct loaded_module_t { // True if this module is part of the vm. bool is_in_vm; + // Next item in the list, or NULL if no such item exits + loaded_module_t* next; + }; // This class is a singleton holding a map of all loaded binaries @@ -99,6 +106,11 @@ class LoadedLibraries // Output debug info static void print(outputStream* os); + // Apply the callback to each loaded_module_t in the list + // Return false if module table is empty and cannot be loaded. + static bool for_each(os::LoadedModulesCallbackFunc cb, void* param); + }; + #endif // OS_AIX_LOADLIB_AIX_HPP diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp index 419e2ce92fd..b586da9a78d 100644 --- a/src/hotspot/os/aix/os_aix.cpp +++ b/src/hotspot/os/aix/os_aix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2021 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -1131,7 +1131,11 @@ void os::get_summary_os_info(char* buf, size_t buflen) { } int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) { - // Not yet implemented. + + if (!LoadedLibraries::for_each(callback, param)) { + return -1; + } + return 0; } diff --git a/src/hotspot/os/aix/os_perf_aix.cpp b/src/hotspot/os/aix/os_perf_aix.cpp index bdccca0c1c5..ad031de3cdc 100644 --- a/src/hotspot/os/aix/os_perf_aix.cpp +++ b/src/hotspot/os/aix/os_perf_aix.cpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, IBM Corp. * 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,197 +25,42 @@ #include "precompiled.hpp" #include "jvm.h" +#include "libperfstat_aix.hpp" #include "memory/allocation.inline.hpp" +#include "memory/resourceArea.hpp" #include "os_aix.inline.hpp" #include "runtime/os.hpp" #include "runtime/os_perf.hpp" #include "runtime/vm_version.hpp" +#include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" -#include -#include -#include +#include +#include #include +#include +#include +#include +#include #include +#include #include -#include #include -#include +#include #include -#include -#include -#include - -/** - /proc/[number]/stat - Status information about the process. This is used by ps(1). It is defined in /usr/src/linux/fs/proc/array.c. - - The fields, in order, with their proper scanf(3) format specifiers, are: - - 1. pid %d The process id. - - 2. comm %s - The filename of the executable, in parentheses. This is visible whether or not the executable is swapped out. - - 3. state %c - One character from the string "RSDZTW" where R is running, S is sleeping in an interruptible wait, D is waiting in uninterruptible disk - sleep, Z is zombie, T is traced or stopped (on a signal), and W is paging. - - 4. ppid %d - The PID of the parent. - - 5. pgrp %d - The process group ID of the process. - - 6. session %d - The session ID of the process. - - 7. tty_nr %d - The tty the process uses. - - 8. tpgid %d - The process group ID of the process which currently owns the tty that the process is connected to. - - 9. flags %lu - The flags of the process. The math bit is decimal 4, and the traced bit is decimal 10. - - 10. minflt %lu - The number of minor faults the process has made which have not required loading a memory page from disk. - - 11. cminflt %lu - The number of minor faults that the process's waited-for children have made. - - 12. majflt %lu - The number of major faults the process has made which have required loading a memory page from disk. - - 13. cmajflt %lu - The number of major faults that the process's waited-for children have made. - - 14. utime %lu - The number of jiffies that this process has been scheduled in user mode. - - 15. stime %lu - The number of jiffies that this process has been scheduled in kernel mode. - - 16. cutime %ld - The number of jiffies that this process's waited-for children have been scheduled in user mode. (See also times(2).) - - 17. cstime %ld - The number of jiffies that this process' waited-for children have been scheduled in kernel mode. - - 18. priority %ld - The standard nice value, plus fifteen. The value is never negative in the kernel. - - 19. nice %ld - The nice value ranges from 19 (nicest) to -19 (not nice to others). - - 20. 0 %ld This value is hard coded to 0 as a placeholder for a removed field. - - 21. itrealvalue %ld - The time in jiffies before the next SIGALRM is sent to the process due to an interval timer. - - 22. starttime %lu - The time in jiffies the process started after system boot. - - 23. vsize %lu - Virtual memory size in bytes. - - 24. rss %ld - Resident Set Size: number of pages the process has in real memory, minus 3 for administrative purposes. This is just the pages which count - towards text, data, or stack space. This does not include pages which have not been demand-loaded in, or which are swapped out. - - 25. rlim %lu - Current limit in bytes on the rss of the process (usually 4294967295 on i386). - - 26. startcode %lu - The address above which program text can run. - - 27. endcode %lu - The address below which program text can run. - - 28. startstack %lu - The address of the start of the stack. - - 29. kstkesp %lu - The current value of esp (stack pointer), as found in the kernel stack page for the process. - - 30. kstkeip %lu - The current EIP (instruction pointer). - - 31. signal %lu - The bitmap of pending signals (usually 0). - - 32. blocked %lu - The bitmap of blocked signals (usually 0, 2 for shells). - - 33. sigignore %lu - The bitmap of ignored signals. - - 34. sigcatch %lu - The bitmap of catched signals. - - 35. wchan %lu - This is the "channel" in which the process is waiting. It is the address of a system call, and can be looked up in a namelist if you need - a textual name. (If you have an up-to-date /etc/psdatabase, then try ps -l to see the WCHAN field in action.) - - 36. nswap %lu - Number of pages swapped - not maintained. - - 37. cnswap %lu - Cumulative nswap for child processes. - - 38. exit_signal %d - Signal to be sent to parent when we die. - - 39. processor %d - CPU number last executed on. - - - - ///// SSCANF FORMAT STRING. Copy and use. - -field: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 -format: %d %s %c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d - - -*/ - -/** - * For platforms that have them, when declaring - * a printf-style function, - * formatSpec is the parameter number (starting at 1) - * that is the format argument ("%d pid %s") - * params is the parameter number where the actual args to - * the format starts. If the args are in a va_list, this - * should be 0. - */ -#ifndef PRINTF_ARGS -# define PRINTF_ARGS(formatSpec, params) ATTRIBUTE_PRINTF(formatSpec, params) -#endif - -#ifndef SCANF_ARGS -# define SCANF_ARGS(formatSpec, params) ATTRIBUTE_SCANF(formatSpec, params) -#endif - -#ifndef _PRINTFMT_ -# define _PRINTFMT_ -#endif - -#ifndef _SCANFMT_ -# define _SCANFMT_ -#endif - +#include -struct CPUPerfTicks { - uint64_t used; - uint64_t usedKernel; - uint64_t total; -}; +typedef struct { + u_longlong_t user; + u_longlong_t sys; + u_longlong_t idle; + u_longlong_t wait; +} cpu_tick_store_t; -typedef enum { - CPU_LOAD_VM_ONLY, - CPU_LOAD_GLOBAL, -} CpuLoadTarget; +typedef struct { + double utime; + double stime; +} jvm_time_store_t; enum { UNDETECTED, @@ -223,318 +69,299 @@ enum { BAREMETAL }; -struct CPUPerfCounters { - int nProcs; - CPUPerfTicks jvmTicks; - CPUPerfTicks* cpus; -}; - -static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target); - -/** reads /proc//stat data, with some checks and some skips. - * Ensure that 'fmt' does _NOT_ contain the first two "%d %s" +/** + * Get info for requested PID from /proc//psinfo file */ -static int SCANF_ARGS(2, 0) vread_statdata(const char* procfile, _SCANFMT_ const char* fmt, va_list args) { - FILE*f; - int n; - char buf[2048]; - - if ((f = os::fopen(procfile, "r")) == NULL) { - return -1; - } - - if ((n = fread(buf, 1, sizeof(buf), f)) != -1) { - char *tmp; - - buf[n-1] = '\0'; - /** skip through pid and exec name. */ - if ((tmp = strrchr(buf, ')')) != NULL) { - // skip the ')' and the following space - // but check that buffer is long enough - tmp += 2; - if (tmp < buf + n) { - n = vsscanf(tmp, fmt, args); - } - } - } +static bool read_psinfo(const u_longlong_t& pid, psinfo_t& psinfo) { + static size_t BUF_LENGTH = 32 + sizeof(u_longlong_t); - fclose(f); + FILE* fp; + char buf[BUF_LENGTH]; + int len; - return n; -} + jio_snprintf(buf, BUF_LENGTH, "/proc/%llu/psinfo", pid); + fp = fopen(buf, "r"); -static int SCANF_ARGS(2, 3) read_statdata(const char* procfile, _SCANFMT_ const char* fmt, ...) { - int n; - va_list args; + if (!fp) { + return false; + } - va_start(args, fmt); - n = vread_statdata(procfile, fmt, args); - va_end(args); - return n; + len = fread(&psinfo, 1, sizeof(psinfo_t), fp); + return len == sizeof(psinfo_t); } /** - * on Linux we got the ticks related information from /proc/stat - * this does not work on AIX, libperfstat might be an alternative + * Get and set ticks for the specified lcpu */ -static OSReturn get_total_ticks(int which_logical_cpu, CPUPerfTicks* pticks) { - return OS_ERR; -} +static OSReturn get_lcpu_ticks(perfstat_id_t* lcpu_name, cpu_tick_store_t* pticks) { + perfstat_cpu_t lcpu_stats; -/** read user and system ticks from a named procfile, assumed to be in 'stat' format then. */ -static int read_ticks(const char* procfile, uint64_t* userTicks, uint64_t* systemTicks) { - return read_statdata(procfile, "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u " UINT64_FORMAT " " UINT64_FORMAT, - userTicks, systemTicks); -} + if (!pticks) { + return OS_ERR; + } -/** - * Return the number of ticks spent in any of the processes belonging - * to the JVM on any CPU. - */ -static OSReturn get_jvm_ticks(CPUPerfTicks* pticks) { - return OS_ERR; + // populate cpu_stats + if (libperfstat::perfstat_cpu(lcpu_name, &lcpu_stats, sizeof(perfstat_cpu_t), 1) < 1) { + memset(pticks, 0, sizeof(cpu_tick_store_t)); + return OS_ERR; + } + + pticks->user = lcpu_stats.user; + pticks->sys = lcpu_stats.sys; + pticks->idle = lcpu_stats.idle; + pticks->wait = lcpu_stats.wait; + + return OS_OK; } /** - * Return the load of the CPU as a double. 1.0 means the CPU process uses all - * available time for user or system processes, 0.0 means the CPU uses all time - * being idle. - * - * Returns a negative value if there is a problem in determining the CPU load. + * Return CPU load caused by the currently executing process (the jvm). */ -static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, double* pkernelLoad, CpuLoadTarget target) { - uint64_t udiff, kdiff, tdiff; - CPUPerfTicks* pticks; - CPUPerfTicks tmp; - double user_load; +static OSReturn get_jvm_load(double* jvm_uload, double* jvm_sload) { + static clock_t ticks_per_sec = sysconf(_SC_CLK_TCK); + static u_longlong_t last_timebase = 0; - *pkernelLoad = 0.0; + perfstat_process_t jvm_stats; + perfstat_id_t name_holder; + u_longlong_t timebase_diff; - if (target == CPU_LOAD_VM_ONLY) { - pticks = &counters->jvmTicks; - } else if (-1 == which_logical_cpu) { - pticks = &counters->cpus[counters->nProcs]; - } else { - pticks = &counters->cpus[which_logical_cpu]; + jio_snprintf(name_holder.name, IDENTIFIER_LENGTH, "%d", getpid()); + if (libperfstat::perfstat_process(&name_holder, &jvm_stats, sizeof(perfstat_process_t), 1) < 1) { + return OS_ERR; } - tmp = *pticks; + // Update timebase + timebase_diff = jvm_stats.last_timebase - last_timebase; + last_timebase = jvm_stats.last_timebase; - if (target == CPU_LOAD_VM_ONLY) { - if (get_jvm_ticks(pticks) != OS_OK) { - return -1.0; - } - } else if (get_total_ticks(which_logical_cpu, pticks) != OS_OK) { - return -1.0; + if (jvm_uload) { + *jvm_uload = jvm_stats.ucpu_time / timebase_diff; + } + if (jvm_sload) { + *jvm_sload = jvm_stats.scpu_time / timebase_diff; } - // seems like we sometimes end up with less kernel ticks when - // reading /proc/self/stat a second time, timing issue between cpus? - if (pticks->usedKernel < tmp.usedKernel) { - kdiff = 0; - } else { - kdiff = pticks->usedKernel - tmp.usedKernel; + return OS_OK; +} + +static void update_prev_time(jvm_time_store_t* from, jvm_time_store_t* to) { + if (from && to) { + memcpy(to, from, sizeof(jvm_time_store_t)); } - tdiff = pticks->total - tmp.total; - udiff = pticks->used - tmp.used; +} - if (tdiff == 0) { - return 0.0; - } else if (tdiff < (udiff + kdiff)) { - tdiff = udiff + kdiff; +static void update_prev_ticks(cpu_tick_store_t* from, cpu_tick_store_t* to) { + if (from && to) { + memcpy(to, from, sizeof(cpu_tick_store_t)); } - *pkernelLoad = (kdiff / (double)tdiff); - // BUG9044876, normalize return values to sane values - *pkernelLoad = MAX2(*pkernelLoad, 0.0); - *pkernelLoad = MIN2(*pkernelLoad, 1.0); +} - user_load = (udiff / (double)tdiff); - user_load = MAX2(user_load, 0.0); - user_load = MIN2(user_load, 1.0); +/** + * Calculate the current system load from current ticks using previous ticks as a starting point. + */ +static void calculate_updated_load(cpu_tick_store_t* update, cpu_tick_store_t* prev, double* load) { + cpu_tick_store_t diff; - return user_load; -} + if (update && prev && load) { + diff.user = update->user - prev->user; + diff.sys = update->sys - prev->sys; + diff.idle = update->idle - prev->idle; + diff.wait = update->wait - prev->wait; -static int SCANF_ARGS(1, 2) parse_stat(_SCANFMT_ const char* fmt, ...) { - return OS_ERR; + *load = 1.0 - diff.idle/(diff.sys + diff.user + diff.idle + diff.wait); + } } -static int get_noof_context_switches(uint64_t* switches) { - return parse_stat("ctxt " UINT64_FORMAT "\n", switches); -} +/** + * Look up lcpu names for later re-use. + */ +static bool populate_lcpu_names(int ncpus, perfstat_id_t* lcpu_names) { + ResourceMark rm; + perfstat_cpu_t* all_lcpu_stats; + perfstat_cpu_t* lcpu_stats; + perfstat_id_t name_holder; -/** returns boot time in _seconds_ since epoch */ -static int get_boot_time(uint64_t* time) { - return parse_stat("btime " UINT64_FORMAT "\n", time); -} + assert(lcpu_names, "Names pointer NULL"); -static int perf_context_switch_rate(double* rate) { - static pthread_mutex_t contextSwitchLock = PTHREAD_MUTEX_INITIALIZER; - static uint64_t bootTime; - static uint64_t lastTimeNanos; - static uint64_t lastSwitches; - static double lastRate; + strncpy(name_holder.name, FIRST_CPU, IDENTIFIER_LENGTH); - uint64_t bt = 0; - int res = 0; + all_lcpu_stats = NEW_RESOURCE_ARRAY(perfstat_cpu_t, ncpus); - // First time through bootTime will be zero. - if (bootTime == 0) { - uint64_t tmp; - if (get_boot_time(&tmp) < 0) { - return OS_ERR; - } - bt = tmp * 1000; + // If perfstat_cpu does not return the expected number of names, signal error to caller + if (ncpus != libperfstat::perfstat_cpu(&name_holder, all_lcpu_stats, sizeof(perfstat_cpu_t), ncpus)) { + return false; } - res = OS_OK; + for (int n = 0; n < ncpus; n++) { + strncpy(lcpu_names[n].name, all_lcpu_stats[n].name, IDENTIFIER_LENGTH); + } - pthread_mutex_lock(&contextSwitchLock); - { + return true; +} - uint64_t sw; - s8 t, d; +/** + * Calculates the context switch rate. + * (Context Switches / Tick) * (Tick / s) = Context Switches per second + */ +static OSReturn perf_context_switch_rate(double* rate) { + static clock_t ticks_per_sec = sysconf(_SC_CLK_TCK); - if (bootTime == 0) { - // First interval is measured from boot time which is - // seconds since the epoch. Thereafter we measure the - // elapsed time using javaTimeNanos as it is monotonic- - // non-decreasing. - lastTimeNanos = os::javaTimeNanos(); - t = os::javaTimeMillis(); - d = t - bt; - // keep bootTime zero for now to use as a first-time-through flag - } else { - t = os::javaTimeNanos(); - d = nanos_to_millis(t - lastTimeNanos); - } + u_longlong_t ticks; + perfstat_cpu_total_t cpu_stats; - if (d == 0) { - *rate = lastRate; - } else if (get_noof_context_switches(&sw) == 0) { - *rate = ( (double)(sw - lastSwitches) / d ) * 1000; - lastRate = *rate; - lastSwitches = sw; - if (bootTime != 0) { - lastTimeNanos = t; - } - } else { - *rate = 0; - res = OS_ERR; - } - if (*rate <= 0) { - *rate = 0; - lastRate = 0; - } + if (libperfstat::perfstat_cpu_total(NULL, &cpu_stats, sizeof(perfstat_cpu_total_t), 1) < 0) { + return OS_ERR; + } - if (bootTime == 0) { - bootTime = bt; - } - } - pthread_mutex_unlock(&contextSwitchLock); + ticks = cpu_stats.user + cpu_stats.sys + cpu_stats.idle + cpu_stats.wait; + *rate = (cpu_stats.pswitch / ticks) * ticks_per_sec; - return res; + return OS_OK; } class CPUPerformanceInterface::CPUPerformance : public CHeapObj { - friend class CPUPerformanceInterface; private: - CPUPerfCounters _counters; - - int cpu_load(int which_logical_cpu, double* cpu_load); - int context_switch_rate(double* rate); - int cpu_load_total_process(double* cpu_load); - int cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad); + int _ncpus; + perfstat_id_t* _lcpu_names; + cpu_tick_store_t* _prev_ticks; public: CPUPerformance(); bool initialize(); ~CPUPerformance(); + + int cpu_load(int which_logical_cpu, double* cpu_load); + int context_switch_rate(double* rate); + int cpu_load_total_process(double* cpu_load); + int cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad); }; -CPUPerformanceInterface::CPUPerformance::CPUPerformance() { - _counters.nProcs = os::active_processor_count(); - _counters.cpus = NULL; -} +CPUPerformanceInterface::CPUPerformance::CPUPerformance(): + _ncpus(0), + _lcpu_names(NULL), + _prev_ticks(NULL) {} bool CPUPerformanceInterface::CPUPerformance::initialize() { - size_t array_entry_count = _counters.nProcs + 1; - _counters.cpus = NEW_C_HEAP_ARRAY(CPUPerfTicks, array_entry_count, mtInternal); - memset(_counters.cpus, 0, array_entry_count * sizeof(*_counters.cpus)); + perfstat_cpu_total_t cpu_stats; - // For the CPU load total - get_total_ticks(-1, &_counters.cpus[_counters.nProcs]); - - // For each CPU - for (int i = 0; i < _counters.nProcs; i++) { - get_total_ticks(i, &_counters.cpus[i]); + if (libperfstat::perfstat_cpu_total(NULL, &cpu_stats, sizeof(perfstat_cpu_total_t), 1) < 0) { + return false; + } + if (cpu_stats.ncpus <= 0) { + return false; } - // For JVM load - get_jvm_ticks(&_counters.jvmTicks); - // initialize context switch system - // the double is only for init - double init_ctx_switch_rate; - perf_context_switch_rate(&init_ctx_switch_rate); + _ncpus = cpu_stats.ncpus; + _lcpu_names = NEW_C_HEAP_ARRAY(perfstat_id_t, _ncpus, mtInternal); + + _prev_ticks = NEW_C_HEAP_ARRAY(cpu_tick_store_t, _ncpus, mtInternal); + // Set all prev-tick values to 0 + memset(_prev_ticks, 0, _ncpus*sizeof(cpu_tick_store_t)); + + if (!populate_lcpu_names(_ncpus, _lcpu_names)) { + return false; + } return true; } CPUPerformanceInterface::CPUPerformance::~CPUPerformance() { - if (_counters.cpus != NULL) { - FREE_C_HEAP_ARRAY(char, _counters.cpus); + if (_lcpu_names) { + FREE_C_HEAP_ARRAY(perfstat_id_t, _lcpu_names); + } + if (_prev_ticks) { + FREE_C_HEAP_ARRAY(cpu_tick_store_t, _prev_ticks); } } -int CPUPerformanceInterface::CPUPerformance::cpu_load(int which_logical_cpu, double* cpu_load) { - double u, s; - u = get_cpu_load(which_logical_cpu, &_counters, &s, CPU_LOAD_GLOBAL); - if (u < 0) { - *cpu_load = 0.0; +/** + * Get CPU load for all processes on specified logical CPU. + */ +int CPUPerformanceInterface::CPUPerformance::cpu_load(int lcpu_number, double* lcpu_load) { + cpu_tick_store_t ticks; + + assert(lcpu_load != NULL, "NULL pointer passed to cpu_load"); + assert(lcpu_number < _ncpus, "Invalid lcpu passed to cpu_load"); + + if (get_lcpu_ticks(&_lcpu_names[lcpu_number], &ticks) == OS_ERR) { + *lcpu_load = -1.0; return OS_ERR; } - // Cap total systemload to 1.0 - *cpu_load = MIN2((u + s), 1.0); + + calculate_updated_load(&ticks, &_prev_ticks[lcpu_number], lcpu_load); + update_prev_ticks(&ticks, &_prev_ticks[lcpu_number]); + return OS_OK; } -int CPUPerformanceInterface::CPUPerformance::cpu_load_total_process(double* cpu_load) { - double u, s; - u = get_cpu_load(-1, &_counters, &s, CPU_LOAD_VM_ONLY); - if (u < 0) { - *cpu_load = 0.0; - return OS_ERR; +/** + * Get CPU load for all processes on all CPUs. + */ +int CPUPerformanceInterface::CPUPerformance::cpu_load_total_process(double* total_load) { + cpu_tick_store_t total_ticks; + cpu_tick_store_t prev_total_ticks; + + assert(total_load != NULL, "NULL pointer passed to cpu_load_total_process"); + + memset(&total_ticks, 0, sizeof(cpu_tick_store_t)); + memset(&prev_total_ticks, 0, sizeof(cpu_tick_store_t)); + + for (int lcpu = 0; lcpu < _ncpus; lcpu++) { + cpu_tick_store_t lcpu_ticks; + + if (get_lcpu_ticks(&_lcpu_names[lcpu], &lcpu_ticks) == OS_ERR) { + *total_load = -1.0; + return OS_ERR; + } + + total_ticks.user = lcpu_ticks.user; + total_ticks.sys = lcpu_ticks.sys; + total_ticks.idle = lcpu_ticks.idle; + total_ticks.wait = lcpu_ticks.wait; + + prev_total_ticks.user += _prev_ticks[lcpu].user; + prev_total_ticks.sys += _prev_ticks[lcpu].sys; + prev_total_ticks.idle += _prev_ticks[lcpu].idle; + prev_total_ticks.wait += _prev_ticks[lcpu].wait; + + update_prev_ticks(&lcpu_ticks, &_prev_ticks[lcpu]); } - *cpu_load = u + s; + + calculate_updated_load(&total_ticks, &prev_total_ticks, total_load); + return OS_OK; } +/** + * Get CPU load for all CPUs. + * + * Set values for: + * - pjvmUserLoad: CPU load due to jvm process in user mode. Jvm process assumed to be self process + * - pjvmKernelLoad: CPU load due to jvm process in kernel mode. Jvm process assumed to be self process + * - psystemTotalLoad: Total CPU load from all process on all logical CPUs + * + * Note: If any of the above loads cannot be calculated, this procedure returns OS_ERR and any load that could not be calculated is set to -1 + * + */ int CPUPerformanceInterface::CPUPerformance::cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad) { - double u, s, t; + double u, k, t; - assert(pjvmUserLoad != NULL, "pjvmUserLoad not inited"); - assert(pjvmKernelLoad != NULL, "pjvmKernelLoad not inited"); - assert(psystemTotalLoad != NULL, "psystemTotalLoad not inited"); - - u = get_cpu_load(-1, &_counters, &s, CPU_LOAD_VM_ONLY); - if (u < 0) { - *pjvmUserLoad = 0.0; - *pjvmKernelLoad = 0.0; - *psystemTotalLoad = 0.0; - return OS_ERR; + int retval = OS_OK; + if (get_jvm_load(&u, &k) == OS_ERR || cpu_load_total_process(&t) == OS_ERR) { + retval = OS_ERR; } - cpu_load(-1, &t); - // clamp at user+system and 1.0 - if (u + s > t) { - t = MIN2(u + s, 1.0); + if (pjvmUserLoad) { + *pjvmUserLoad = u; + } + if (pjvmKernelLoad) { + *pjvmKernelLoad = k; + } + if (psystemTotalLoad) { + *psystemTotalLoad = t; } - *pjvmUserLoad = u; - *pjvmKernelLoad = s; - *psystemTotalLoad = t; - - return OS_OK; + return retval; } int CPUPerformanceInterface::CPUPerformance::context_switch_rate(double* rate) { @@ -573,267 +400,85 @@ int CPUPerformanceInterface::context_switch_rate(double* rate) const { } class SystemProcessInterface::SystemProcesses : public CHeapObj { - friend class SystemProcessInterface; - private: - class ProcessIterator : public CHeapObj { - friend class SystemProcessInterface::SystemProcesses; - private: - DIR* _dir; - struct dirent* _entry; - bool _valid; - char _exeName[PATH_MAX]; - char _exePath[PATH_MAX]; - - ProcessIterator(); - ~ProcessIterator(); - bool initialize(); - - bool is_valid() const { return _valid; } - bool is_valid_entry(struct dirent* entry) const; - bool is_dir(const char* name) const; - int fsize(const char* name, uint64_t& size) const; - - char* allocate_string(const char* str) const; - void get_exe_name(); - char* get_exe_path(); - char* get_cmdline(); - - int current(SystemProcess* process_info); - int next_process(); - }; - - ProcessIterator* _iterator; + private: + char* allocate_string(const char* str) const; + + public: SystemProcesses(); bool initialize(); ~SystemProcesses(); - - //information about system processes int system_processes(SystemProcess** system_processes, int* no_of_sys_processes) const; }; -bool SystemProcessInterface::SystemProcesses::ProcessIterator::is_dir(const char* name) const { - struct stat mystat; - int ret_val = 0; - - ret_val = stat(name, &mystat); - if (ret_val < 0) { - return false; - } - ret_val = S_ISDIR(mystat.st_mode); - return ret_val > 0; -} - -int SystemProcessInterface::SystemProcesses::ProcessIterator::fsize(const char* name, uint64_t& size) const { - assert(name != NULL, "name pointer is NULL!"); - size = 0; - struct stat fbuf; - - if (stat(name, &fbuf) < 0) { - return OS_ERR; - } - size = fbuf.st_size; - return OS_OK; -} - -// if it has a numeric name, is a directory and has a 'stat' file in it -bool SystemProcessInterface::SystemProcesses::ProcessIterator::is_valid_entry(struct dirent* entry) const { - char buffer[PATH_MAX]; - uint64_t size = 0; - - if (atoi(entry->d_name) != 0) { - jio_snprintf(buffer, PATH_MAX, "/proc/%s", entry->d_name); - buffer[PATH_MAX - 1] = '\0'; - - if (is_dir(buffer)) { - jio_snprintf(buffer, PATH_MAX, "/proc/%s/stat", entry->d_name); - buffer[PATH_MAX - 1] = '\0'; - if (fsize(buffer, size) != OS_ERR) { - return true; - } - } - } - return false; -} - -// get exe-name from /proc//stat -void SystemProcessInterface::SystemProcesses::ProcessIterator::get_exe_name() { - FILE* fp; - char buffer[PATH_MAX]; - - jio_snprintf(buffer, PATH_MAX, "/proc/%s/stat", _entry->d_name); - buffer[PATH_MAX - 1] = '\0'; - if ((fp = os::fopen(buffer, "r")) != NULL) { - if (fgets(buffer, PATH_MAX, fp) != NULL) { - char* start, *end; - // exe-name is between the first pair of ( and ) - start = strchr(buffer, '('); - if (start != NULL && start[1] != '\0') { - start++; - end = strrchr(start, ')'); - if (end != NULL) { - size_t len; - len = MIN2(end - start, sizeof(_exeName) - 1); - memcpy(_exeName, start, len); - _exeName[len] = '\0'; - } - } - } - fclose(fp); - } +SystemProcessInterface::SystemProcesses::SystemProcesses() { } -// get command line from /proc//cmdline -char* SystemProcessInterface::SystemProcesses::ProcessIterator::get_cmdline() { - FILE* fp; - char buffer[PATH_MAX]; - char* cmdline = NULL; - - jio_snprintf(buffer, PATH_MAX, "/proc/%s/cmdline", _entry->d_name); - buffer[PATH_MAX - 1] = '\0'; - if ((fp = os::fopen(buffer, "r")) != NULL) { - size_t size = 0; - char dummy; - - // find out how long the file is (stat always returns 0) - while (fread(&dummy, 1, 1, fp) == 1) { - size++; - } - if (size > 0) { - cmdline = NEW_C_HEAP_ARRAY(char, size + 1, mtInternal); - cmdline[0] = '\0'; - if (fseek(fp, 0, SEEK_SET) == 0) { - if (fread(cmdline, 1, size, fp) == size) { - // the file has the arguments separated by '\0', - // so we translate '\0' to ' ' - for (size_t i = 0; i < size; i++) { - if (cmdline[i] == '\0') { - cmdline[i] = ' '; - } - } - cmdline[size] = '\0'; - } - } - } - fclose(fp); - } - return cmdline; +bool SystemProcessInterface::SystemProcesses::initialize() { + return true; } -// get full path to exe from /proc//exe symlink -char* SystemProcessInterface::SystemProcesses::ProcessIterator::get_exe_path() { - char buffer[PATH_MAX]; - - jio_snprintf(buffer, PATH_MAX, "/proc/%s/exe", _entry->d_name); - buffer[PATH_MAX - 1] = '\0'; - return realpath(buffer, _exePath); +SystemProcessInterface::SystemProcesses::~SystemProcesses() { } -char* SystemProcessInterface::SystemProcesses::ProcessIterator::allocate_string(const char* str) const { +char* SystemProcessInterface::SystemProcesses::allocate_string(const char* str) const { if (str != NULL) { return os::strdup_check_oom(str, mtInternal); } return NULL; } -int SystemProcessInterface::SystemProcesses::ProcessIterator::current(SystemProcess* process_info) { - if (!is_valid()) { - return OS_ERR; - } - - process_info->set_pid(atoi(_entry->d_name)); - - get_exe_name(); - process_info->set_name(allocate_string(_exeName)); +int SystemProcessInterface::SystemProcesses::system_processes(SystemProcess** system_processes, int* nprocs) const { + ResourceMark rm; + perfstat_process_t* proc_stats; + SystemProcess* head; + perfstat_id_t name_holder; + int records_allocated = 0; - if (get_exe_path() != NULL) { - process_info->set_path(allocate_string(_exePath)); - } - - char* cmdline = NULL; - cmdline = get_cmdline(); - if (cmdline != NULL) { - process_info->set_command_line(allocate_string(cmdline)); - FREE_C_HEAP_ARRAY(char, cmdline); - } + assert(nprocs != NULL, "system_processes counter pointers is NULL!"); - return OS_OK; -} + head = NULL; + *nprocs = 0; + strncpy(name_holder.name, "", IDENTIFIER_LENGTH); -int SystemProcessInterface::SystemProcesses::ProcessIterator::next_process() { - if (!is_valid()) { + // calling perfstat_(NULL, NULL, _, 0) returns number of available records + *nprocs = libperfstat::perfstat_process(NULL, NULL, sizeof(perfstat_process_t), 0); + if(*nprocs < 1) { + // expect at least 1 process return OS_ERR; } - do { - _entry = os::readdir(_dir); - if (_entry == NULL) { - // Error or reached end. Could use errno to distinguish those cases. - _valid = false; - return OS_ERR; - } - } while(!is_valid_entry(_entry)); - - _valid = true; - return OS_OK; -} - -SystemProcessInterface::SystemProcesses::ProcessIterator::ProcessIterator() { - _dir = NULL; - _entry = NULL; - _valid = false; -} + records_allocated = *nprocs; + proc_stats = NEW_RESOURCE_ARRAY(perfstat_process_t, records_allocated); -bool SystemProcessInterface::SystemProcesses::ProcessIterator::initialize() { - // Not yet implemented. - return false; -} + // populate stats && set the actual number of procs that have been populated + // should never be higher than requested, but may be lower due to process death + *nprocs = libperfstat::perfstat_process(&name_holder, proc_stats, sizeof(perfstat_process_t), records_allocated); -SystemProcessInterface::SystemProcesses::ProcessIterator::~ProcessIterator() { - if (_dir != NULL) { - os::closedir(_dir); - } -} + for (int n = 0; n < *nprocs; n++) { + psinfo_t psinfo; + // Note: SystemProcess with free these in its dtor. + char* name = NEW_C_HEAP_ARRAY(char, IDENTIFIER_LENGTH, mtInternal); + char* exe_name = NEW_C_HEAP_ARRAY(char, PRFNSZ, mtInternal); + char* cmd_line = NEW_C_HEAP_ARRAY(char, PRARGSZ, mtInternal); -SystemProcessInterface::SystemProcesses::SystemProcesses() { - _iterator = NULL; -} + strncpy(name, proc_stats[n].proc_name, IDENTIFIER_LENGTH); -bool SystemProcessInterface::SystemProcesses::initialize() { - _iterator = new SystemProcessInterface::SystemProcesses::ProcessIterator(); - return _iterator->initialize(); -} + if (read_psinfo(proc_stats[n].pid, psinfo)) { + strncpy(exe_name, psinfo.pr_fname, PRFNSZ); + strncpy(cmd_line, psinfo.pr_psargs, PRARGSZ); + } -SystemProcessInterface::SystemProcesses::~SystemProcesses() { - if (_iterator != NULL) { - delete _iterator; + // create a new SystemProcess with next pointing to current head. + SystemProcess* sp = new SystemProcess(proc_stats[n].pid, + name, + exe_name, + cmd_line, + head); + // update head. + head = sp; } -} - -int SystemProcessInterface::SystemProcesses::system_processes(SystemProcess** system_processes, int* no_of_sys_processes) const { - assert(system_processes != NULL, "system_processes pointer is NULL!"); - assert(no_of_sys_processes != NULL, "system_processes counter pointers is NULL!"); - assert(_iterator != NULL, "iterator is NULL!"); - - // initialize pointers - *no_of_sys_processes = 0; - *system_processes = NULL; - while (_iterator->is_valid()) { - SystemProcess* tmp = new SystemProcess(); - _iterator->current(tmp); - - //if already existing head - if (*system_processes != NULL) { - //move "first to second" - tmp->set_next(*system_processes); - } - // new head - *system_processes = tmp; - // increment - (*no_of_sys_processes)++; - // step forward - _iterator->next_process(); - } + *system_processes = head; return OS_OK; } @@ -897,29 +542,68 @@ int CPUInformationInterface::cpu_information(CPUInformation& cpu_info) { } class NetworkPerformanceInterface::NetworkPerformance : public CHeapObj { - friend class NetworkPerformanceInterface; + NONCOPYABLE(NetworkPerformance); + private: + char* allocate_string(const char* str) const; + + public: NetworkPerformance(); - NONCOPYABLE(NetworkPerformance); bool initialize(); ~NetworkPerformance(); int network_utilization(NetworkInterface** network_interfaces) const; }; -NetworkPerformanceInterface::NetworkPerformance::NetworkPerformance() { - -} +NetworkPerformanceInterface::NetworkPerformance::NetworkPerformance() {} bool NetworkPerformanceInterface::NetworkPerformance::initialize() { return true; } -NetworkPerformanceInterface::NetworkPerformance::~NetworkPerformance() { -} +NetworkPerformanceInterface::NetworkPerformance::~NetworkPerformance() {} + +int NetworkPerformanceInterface::NetworkPerformance::network_utilization(NetworkInterface** network_interfaces) const { + int n_records = 0; + perfstat_netinterface_t* net_stats; + perfstat_id_t name_holder; + int records_allocated = 0; + + assert(network_interfaces != NULL, "network_interfaces is NULL"); + + *network_interfaces = NULL; + strncpy(name_holder.name , FIRST_NETINTERFACE, IDENTIFIER_LENGTH); + + // calling perfstat_(NULL, NULL, _, 0) returns number of available records + if ((n_records = libperfstat::perfstat_netinterface(NULL, NULL, sizeof(perfstat_netinterface_t), 0)) < 0) { + return OS_ERR; + } -int NetworkPerformanceInterface::NetworkPerformance::network_utilization(NetworkInterface** network_interfaces) const -{ - return FUNCTIONALITY_NOT_IMPLEMENTED; + records_allocated = n_records; + net_stats = NEW_C_HEAP_ARRAY(perfstat_netinterface_t, records_allocated, mtInternal); + + n_records = libperfstat::perfstat_netinterface(&name_holder, net_stats, sizeof(perfstat_netinterface_t), n_records); + + // check for error + if (n_records < 0) { + FREE_C_HEAP_ARRAY(perfstat_netinterface_t, net_stats); + return OS_ERR; + } + + for (int i = 0; i < n_records; i++) { + // Create new Network interface *with current head as next node* + // Note: NetworkInterface makes copies of these string values into RA memory + // this means: + // (1) we are free to clean our values upon exiting this proc + // (2) we avoid using RA-alloced memory here (ie. do not use NEW_RESOURCE_ARRAY) + NetworkInterface* new_interface = new NetworkInterface(net_stats[i].name, + net_stats[i].ibytes, + net_stats[i].obytes, + *network_interfaces); + *network_interfaces = new_interface; + } + + FREE_C_HEAP_ARRAY(perfstat_netinterface_t, net_stats); + return OS_OK; } NetworkPerformanceInterface::NetworkPerformanceInterface() { diff --git a/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp b/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp index 6b810bd3918..44c7baebd79 100644 --- a/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp +++ b/src/hotspot/os_cpu/aix_ppc/thread_aix_ppc.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014 SAP SE. All rights reserved. + * Copyright (c) 2022, IBM Corp. * 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,6 +25,7 @@ */ #include "precompiled.hpp" +#include "memory/metaspace.hpp" #include "runtime/frame.inline.hpp" #include "runtime/thread.hpp" @@ -34,6 +36,8 @@ frame JavaThread::pd_last_frame() { address pc = _anchor.last_Java_pc(); // Last_Java_pc ist not set, if we come here from compiled code. + // Assume spill slot for link register contains a suitable pc. + // Should have been filled by method entry code. if (pc == NULL) pc = (address) *(sp + 2); @@ -41,16 +45,71 @@ frame JavaThread::pd_last_frame() { } bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) { - ucontext_t* uc = (ucontext_t*) ucontext; - *fr_addr = frame((intptr_t*)uc->uc_mcontext.jmp_context.gpr[1/*REG_SP*/], - (address)uc->uc_mcontext.jmp_context.iar); - return true; + + // If we have a last_Java_frame, then we should use it even if + // isInJava == true. It should be more reliable than ucontext info. + if (has_last_Java_frame() && frame_anchor()->walkable()) { + *fr_addr = pd_last_frame(); + return true; + } + + // At this point, we don't have a last_Java_frame, so + // we try to glean some information out of the ucontext + // if we were running Java code when SIGPROF came in. + if (isInJava) { + ucontext_t* uc = (ucontext_t*) ucontext; + address pc = (address)uc->uc_mcontext.jmp_context.iar; + + if (pc == NULL) { + // ucontext wasn't useful + return false; + } + + frame ret_frame((intptr_t*)uc->uc_mcontext.jmp_context.gpr[1/*REG_SP*/], pc); + + if (ret_frame.fp() == NULL) { + // The found frame does not have a valid frame pointer. + // Bail out because this will create big trouble later on, either + // - when using istate, calculated as (NULL - ijava_state_size) or + // - when using fp() directly in safe_for_sender() + // + // There is no conclusive description (yet) how this could happen, but it does. + // For more details on what was observed, see thread_linux_s390.cpp + return false; + } + + if (ret_frame.is_interpreted_frame()) { + frame::ijava_state *istate = ret_frame.get_ijava_state(); + const Method *m = (const Method*)(istate->method); + if (!Method::is_valid_method(m)) return false; + if (!Metaspace::contains(m->constMethod())) return false; + + uint64_t reg_bcp = uc->uc_mcontext.jmp_context.gpr[14/*R14_bcp*/]; + uint64_t istate_bcp = istate->bcp; + uint64_t code_start = (uint64_t)(m->code_base()); + uint64_t code_end = (uint64_t)(m->code_base() + m->code_size()); + if (istate_bcp >= code_start && istate_bcp < code_end) { + // we have a valid bcp, don't touch it, do nothing + } else if (reg_bcp >= code_start && reg_bcp < code_end) { + istate->bcp = reg_bcp; + } else { + return false; + } + } + if (!ret_frame.safe_for_sender(this)) { + // nothing else to try if the frame isn't good + return false; + } + *fr_addr = ret_frame; + return true; + } + // nothing else to try + return false; } -// Forte Analyzer AsyncGetCallTrace profiling support is not implemented on Aix/PPC. +// Forte Analyzer AsyncGetCallTrace profiling support. bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, bool isInJava) { - Unimplemented(); - return false; + return pd_get_top_frame_for_profiling(fr_addr, ucontext, isInJava); } void JavaThread::cache_global_variables() { } diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 8e00e12f1ba..81c2dffe2d1 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -821,7 +821,7 @@ javax/script/Test7.java 8239361 generic- # jdk_jfr -jdk/jfr/event/runtime/TestNetworkUtilizationEvent.java 8228990 generic-all +jdk/jfr/event/runtime/TestNetworkUtilizationEvent.java 8228990 macosx-all,linux-all,windows-all jdk/jfr/event/compiler/TestCodeSweeper.java 8225209 generic-all jdk/jfr/event/os/TestThreadContextSwitches.java 8247776 windows-all jdk/jfr/startupargs/TestStartName.java 8214685 windows-x64 diff --git a/test/jdk/jdk/jfr/event/runtime/TestNativeLibrariesEvent.java b/test/jdk/jdk/jfr/event/runtime/TestNativeLibrariesEvent.java index f3299820925..77eb0362841 100644 --- a/test/jdk/jdk/jfr/event/runtime/TestNativeLibrariesEvent.java +++ b/test/jdk/jdk/jfr/event/runtime/TestNativeLibrariesEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -77,7 +77,10 @@ public class TestNativeLibrariesEvent { libTemplate = "lib%s.dylib"; } else if (Platform.isLinux()) { libTemplate = "lib%s.so"; + } else if (Platform.isAix()) { + libTemplate = "lib%s.so"; } + if (libTemplate == null) { throw new Exception("Unsupported OS"); } -- GitLab From b4900b1298e536c0ceaa77bc0ac0e8e6ccba6400 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Thu, 17 Feb 2022 09:36:05 +0000 Subject: [PATCH 283/400] 8264743: Add forRemoval for deprecated classes and method in javax/swing/plaf/basic Reviewed-by: trebari, prr --- .../javax/swing/plaf/basic/BasicDirectoryModel.java | 6 +++--- .../classes/javax/swing/plaf/basic/BasicMenuItemUI.java | 2 +- .../classes/javax/swing/plaf/basic/BasicScrollPaneUI.java | 8 ++++---- .../classes/javax/swing/plaf/basic/BasicToolBarUI.java | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java index 34c53ca915f..63e8309fda2 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java @@ -228,7 +228,7 @@ public class BasicDirectoryModel extends AbstractListModel implements Pr * @param e list data event * @deprecated Obsolete method, not used anymore. */ - @Deprecated(since = "17") + @Deprecated(since = "17", forRemoval = true) public void intervalAdded(ListDataEvent e) { } @@ -237,7 +237,7 @@ public class BasicDirectoryModel extends AbstractListModel implements Pr * @param e list data event * @deprecated Obsolete method, not used anymore. */ - @Deprecated(since = "17") + @Deprecated(since = "17", forRemoval = true) public void intervalRemoved(ListDataEvent e) { } @@ -257,7 +257,7 @@ public class BasicDirectoryModel extends AbstractListModel implements Pr * @param b another file * @deprecated Obsolete method, not used anymore. */ - @Deprecated(since = "17") + @Deprecated(since = "17", forRemoval = true) protected boolean lt(File a, File b) { // First ignore case when comparing int diff = a.getName().toLowerCase().compareTo(b.getName().toLowerCase()); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java index db9eee52f1f..cbe840c1ad6 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java @@ -928,7 +928,7 @@ public class BasicMenuItemUI extends MenuItemUI * All its functionality has been moved into Handler. * @deprecated */ - @Deprecated(since = "17") + @Deprecated(since = "17", forRemoval = true) protected class MouseInputHandler implements MouseInputListener { // NOTE: This class exists only for backward compatibility. All // its functionality has been moved into Handler. If you need to add diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java index 714199af15b..e017ac6722b 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollPaneUI.java @@ -500,7 +500,7 @@ public class BasicScrollPaneUI * All its functionality has been moved into Handler. * @deprecated */ - @Deprecated(since = "17") + @Deprecated(since = "17", forRemoval = true) public class ViewportChangeHandler implements ChangeListener { /** @@ -534,7 +534,7 @@ public class BasicScrollPaneUI * All its functionality has been moved into Handler. * @deprecated */ - @Deprecated(since = "17") + @Deprecated(since = "17", forRemoval = true) public class HSBChangeListener implements ChangeListener { /** @@ -577,7 +577,7 @@ public class BasicScrollPaneUI * All its functionality has been moved into Handler. * @deprecated */ - @Deprecated(since = "17") + @Deprecated(since = "17", forRemoval = true) public class VSBChangeListener implements ChangeListener { /** @@ -786,7 +786,7 @@ public class BasicScrollPaneUI * All its functionality has been moved into Handler. * @deprecated */ - @Deprecated(since = "17") + @Deprecated(since = "17", forRemoval = true) public class PropertyChangeHandler implements PropertyChangeListener { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java index 8a13bf119a5..975272a03b7 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java @@ -551,7 +551,7 @@ public class BasicToolBarUI extends ToolBarUI implements SwingConstants * @deprecated It is recommended that {@link BasicToolBarUI#createFloatingWindow(JToolBar)} * be used instead */ - @Deprecated(since = "17") + @Deprecated(since = "17", forRemoval = true) protected JFrame createFloatingFrame(JToolBar toolbar) { Window window = SwingUtilities.getWindowAncestor(toolbar); @SuppressWarnings("serial") // anonymous class -- GitLab From 9ca435b4c03f9741709bbfab22fb006de8c8c9d3 Mon Sep 17 00:00:00 2001 From: Julia Boes Date: Thu, 17 Feb 2022 10:35:05 +0000 Subject: [PATCH 284/400] 8281305: Test com/sun/net/httpserver/simpleserver/MapToPathTest.java fails on Windows 11 Reviewed-by: dfuchs --- .../simpleserver/FileServerHandler.java | 5 +- .../simpleserver/URIPathSegment.java | 44 +++++++++++++++ .../simpleserver/URIPathSegment.java | 53 +++++++++++++++++++ .../simpleserver/MapToPathTest.java | 43 ++++++++++++--- 4 files changed, 138 insertions(+), 7 deletions(-) create mode 100644 src/jdk.httpserver/unix/classes/sun/net/httpserver/simpleserver/URIPathSegment.java create mode 100644 src/jdk.httpserver/windows/classes/sun/net/httpserver/simpleserver/URIPathSegment.java diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/FileServerHandler.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/FileServerHandler.java index e0e9736cad4..b3dc1ff5f4a 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/FileServerHandler.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/simpleserver/FileServerHandler.java @@ -227,9 +227,12 @@ public final class FileServerHandler implements HttpHandler { // resolve each path segment against the root Path path = root; for (var segment : pathSegment) { + if (!URIPathSegment.isSupported(segment)) { + return null; // stop resolution, null results in 404 response + } path = path.resolve(segment); if (!Files.isReadable(path) || isHiddenOrSymLink(path)) { - return null; // stop resolution, null results in 404 response + return null; // stop resolution } } path = path.normalize(); diff --git a/src/jdk.httpserver/unix/classes/sun/net/httpserver/simpleserver/URIPathSegment.java b/src/jdk.httpserver/unix/classes/sun/net/httpserver/simpleserver/URIPathSegment.java new file mode 100644 index 00000000000..497ccd7a850 --- /dev/null +++ b/src/jdk.httpserver/unix/classes/sun/net/httpserver/simpleserver/URIPathSegment.java @@ -0,0 +1,44 @@ +/* + * 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 sun.net.httpserver.simpleserver; + +/** + * A class that represents a URI path segment. + */ +final class URIPathSegment { + + private URIPathSegment() { throw new AssertionError(); } + + /** + * Checks if the segment of a URI path is supported. + * + * @param segment the segment string + * @return true + */ + static boolean isSupported(String segment) { + return true; + } +} diff --git a/src/jdk.httpserver/windows/classes/sun/net/httpserver/simpleserver/URIPathSegment.java b/src/jdk.httpserver/windows/classes/sun/net/httpserver/simpleserver/URIPathSegment.java new file mode 100644 index 00000000000..0de28f188dc --- /dev/null +++ b/src/jdk.httpserver/windows/classes/sun/net/httpserver/simpleserver/URIPathSegment.java @@ -0,0 +1,53 @@ +/* + * 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 sun.net.httpserver.simpleserver; + +/** + * A class that represents a URI path segment. + */ +final class URIPathSegment { + + private URIPathSegment() { throw new AssertionError(); } + + /** + * Checks if the segment of a URI path is supported. For example, + * "C:" is supported as a drive on Windows only. + * + * @param segment the segment string + * @return true if the segment is supported + */ + static boolean isSupported(String segment) { + // apply same logic as WindowsPathParser + if (segment.length() >= 2 && isLetter(segment.charAt(0)) && segment.charAt(1) == ':') { + return false; + } + return true; + } + + private static boolean isLetter(char c) { + return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')); + } +} diff --git a/test/jdk/com/sun/net/httpserver/simpleserver/MapToPathTest.java b/test/jdk/com/sun/net/httpserver/simpleserver/MapToPathTest.java index d6e61da4073..aa8f37acc1b 100644 --- a/test/jdk/com/sun/net/httpserver/simpleserver/MapToPathTest.java +++ b/test/jdk/com/sun/net/httpserver/simpleserver/MapToPathTest.java @@ -137,19 +137,27 @@ public class MapToPathTest { var res3 = client.send(req3, BodyHandlers.ofString()); assertEquals(res3.statusCode(), 404); // not found - var req4 = HttpRequest.newBuilder(uri(server, "/foo/file:" + TEST_DIR.getParent())).build(); + var req4 = HttpRequest.newBuilder(uri(server, "/foo/bar/baz/c:.//")).build(); var res4 = client.send(req4, BodyHandlers.ofString()); assertEquals(res4.statusCode(), 404); // not found - var req5 = HttpRequest.newBuilder(uri(server, "/foo/bar/\\..\\../")).build(); + var req5 = HttpRequest.newBuilder(uri(server, "/foo/bar/baz/c:..//")).build(); var res5 = client.send(req5, BodyHandlers.ofString()); assertEquals(res5.statusCode(), 404); // not found - var req6 = HttpRequest.newBuilder(uri(server, "/foo")).build(); + var req6 = HttpRequest.newBuilder(uri(server, "/foo/file:" + TEST_DIR.getParent())).build(); var res6 = client.send(req6, BodyHandlers.ofString()); - assertEquals(res6.statusCode(), 301); // redirect - assertEquals(res6.headers().firstValue("content-length").get(), "0"); - assertEquals(res6.headers().firstValue("location").get(), "/foo/"); + assertEquals(res6.statusCode(), 404); // not found + + var req7 = HttpRequest.newBuilder(uri(server, "/foo/bar/\\..\\../")).build(); + var res7 = client.send(req7, BodyHandlers.ofString()); + assertEquals(res7.statusCode(), 404); // not found + + var req8 = HttpRequest.newBuilder(uri(server, "/foo")).build(); + var res8 = client.send(req8, BodyHandlers.ofString()); + assertEquals(res8.statusCode(), 301); // redirect + assertEquals(res8.headers().firstValue("content-length").get(), "0"); + assertEquals(res8.headers().firstValue("location").get(), "/foo/"); } finally { server.stop(0); } @@ -250,6 +258,29 @@ public class MapToPathTest { server.stop(0); } } + { + // Test that a request path segment that is a Windows root drive + // does not circumvent access restrictions. + // + // For example, given the test directory tree: + // + // |-- TEST_DIR + // |-- foo + // |-- bar ----->>> if hidden, itself and any of its subdirectories are not accessible + // |-- baz + // |-- file.txt + // ... + var handler = SimpleFileServer.createFileHandler(TEST_DIR); + var server = HttpServer.create(LOOPBACK_ADDR, 10, "/", handler, OUTPUT_FILTER); + server.start(); + try { + var req1 = HttpRequest.newBuilder(uri(server, "/foo/bar/c:/baz/")).build(); + var res1 = client.send(req1, BodyHandlers.ofString()); + assertEquals(res1.statusCode(), 404); // not found + } finally { + server.stop(0); + } + } } // Tests with a mixture of in-memory and file handlers. -- GitLab From 3b7a3cfce345cc900e042c5378d35d1237bdcd78 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang Date: Thu, 17 Feb 2022 11:40:43 +0000 Subject: [PATCH 285/400] 8281971: Remove unimplemented InstanceRefKlass::do_next Reviewed-by: dholmes --- src/hotspot/share/oops/instanceRefKlass.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hotspot/share/oops/instanceRefKlass.hpp b/src/hotspot/share/oops/instanceRefKlass.hpp index 4156559df05..16a9bb53c3a 100644 --- a/src/hotspot/share/oops/instanceRefKlass.hpp +++ b/src/hotspot/share/oops/instanceRefKlass.hpp @@ -97,9 +97,6 @@ class InstanceRefKlass: public InstanceKlass { template static void do_referent(oop obj, OopClosureType* closure, Contains& contains); - template - static void do_next(oop obj, OopClosureType* closure, Contains& contains); - template static void do_discovered(oop obj, OopClosureType* closure, Contains& contains); -- GitLab From d0e11808fd688d96e5cfeb586d1de277f26da5ad Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Thu, 17 Feb 2022 12:31:37 +0000 Subject: [PATCH 286/400] 8282019: Unused static fields DEGREES_TO_RADIANS, RADIANS_TO_DEGREES in StrictMath Reviewed-by: bpb, darcy --- .../share/classes/java/lang/StrictMath.java | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/java.base/share/classes/java/lang/StrictMath.java b/src/java.base/share/classes/java/lang/StrictMath.java index b5e3541c85c..53b25fedebb 100644 --- a/src/java.base/share/classes/java/lang/StrictMath.java +++ b/src/java.base/share/classes/java/lang/StrictMath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -101,19 +101,6 @@ public final class StrictMath { */ public static final double PI = 3.14159265358979323846; - /** - * Constant by which to multiply an angular value in degrees to obtain an - * angular value in radians. - */ - private static final double DEGREES_TO_RADIANS = 0.017453292519943295; - - /** - * Constant by which to multiply an angular value in radians to obtain an - * angular value in degrees. - */ - - private static final double RADIANS_TO_DEGREES = 57.29577951308232; - /** * Returns the trigonometric sine of an angle. Special cases: *
    • If the argument is NaN or an infinity, then the @@ -397,7 +384,7 @@ public final class StrictMath { * @param a the value to be floored or ceiled * @param negativeBoundary result for values in (-1, 0) * @param positiveBoundary result for values in (0, 1) - * @param increment value to add when the argument is non-integral + * @param sign the sign of the result */ private static double floorOrCeil(double a, double negativeBoundary, @@ -408,8 +395,8 @@ public final class StrictMath { if (exponent < 0) { /* * Absolute value of argument is less than 1. - * floorOrceil(-0.0) => -0.0 - * floorOrceil(+0.0) => +0.0 + * floorOrCeil(-0.0) => -0.0 + * floorOrCeil(+0.0) => +0.0 */ return ((a == 0.0) ? a : ( (a < 0.0) ? negativeBoundary : positiveBoundary) ); -- GitLab From 4c7f8b49a4845acf58272c42327328d6d2837cea Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 17 Feb 2022 17:12:40 +0000 Subject: [PATCH 287/400] 8268250: Class.arrayType() for a 255-d array throws undocumented IllegalArgumentException Reviewed-by: sundar, alanb --- .../share/classes/java/lang/Class.java | 11 ++++- test/jdk/java/lang/Class/ArrayType.java | 49 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 test/jdk/java/lang/Class/ArrayType.java diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index fce7793fbcf..840abc63aaf 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -4485,12 +4485,21 @@ public final class Class implements java.io.Serializable, * Returns a {@code Class} for an array type whose component type * is described by this {@linkplain Class}. * + * @throws UnsupportedOperationException if this component type is {@linkplain + * Void#TYPE void} or if the number of dimensions of the resulting array + * type would exceed 255. * @return a {@code Class} describing the array type + * @jvms 4.3.2 Field Descriptors + * @jvms 4.4.1 The {@code CONSTANT_Class_info} Structure * @since 12 */ @Override public Class arrayType() { - return Array.newInstance(this, 0).getClass(); + try { + return Array.newInstance(this, 0).getClass(); + } catch (IllegalArgumentException iae) { + throw new UnsupportedOperationException(iae); + } } /** diff --git a/test/jdk/java/lang/Class/ArrayType.java b/test/jdk/java/lang/Class/ArrayType.java new file mode 100644 index 00000000000..9764dd0b366 --- /dev/null +++ b/test/jdk/java/lang/Class/ArrayType.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021, 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. + * + * 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 8268250 + * @summary Check exceptional behavior of Class.arrayType + */ + +import java.lang.reflect.*; +import java.util.function.*; + +public class ArrayType { + public static void main(String... args) { + expectException(() -> Void.TYPE); + expectException(() -> Array.newInstance(int.class, new int[255]) + .getClass()); + } + + private static void expectException(Supplier> arrayTypeArg) { + try { + Class arrayClazz = arrayTypeArg.get().arrayType(); + throw new RuntimeException("Expected exception not thrown: " + + arrayClazz); + } catch (UnsupportedOperationException uoe) { + ; // Expected + } + } +} -- GitLab From a6f8a386efa7af162f4b815951287f0a9bc1f396 Mon Sep 17 00:00:00 2001 From: Tim Prinzing Date: Thu, 17 Feb 2022 17:34:39 +0000 Subject: [PATCH 288/400] 8281000: ClassLoader::registerAsParallelCapable throws NPE if caller is null Reviewed-by: erikj, ihse, mchung, bchristi --- make/test/JtregNativeJdk.gmk | 2 + .../share/classes/java/lang/ClassLoader.java | 10 +++ .../BadRegisterAsParallelCapableCaller.java | 57 ++++++++++++++ .../NullCallerClassLoaderTest.java | 71 +++++++++++++++++ .../exeNullCallerClassLoaderTest.c | 76 +++++++++++++++++++ 5 files changed, 216 insertions(+) create mode 100644 test/jdk/java/lang/ClassLoader/BadRegisterAsParallelCapableCaller.java create mode 100644 test/jdk/java/lang/ClassLoader/exeNullCallerClassLoaderTest/NullCallerClassLoaderTest.java create mode 100644 test/jdk/java/lang/ClassLoader/exeNullCallerClassLoaderTest/exeNullCallerClassLoaderTest.c diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk index 974ab77cb7b..6797952bc05 100644 --- a/make/test/JtregNativeJdk.gmk +++ b/make/test/JtregNativeJdk.gmk @@ -62,6 +62,7 @@ ifeq ($(call isTargetOs, windows), true) WIN_LIB_JLI := $(SUPPORT_OUTPUTDIR)/native/java.base/libjli/jli.lib BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := $(WIN_LIB_JLI) BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := jvm.lib + BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerClassLoaderTest := jvm.lib BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerLookupTest := jvm.lib BUILD_JDK_JTREG_EXECUTABLES_LIBS_exerevokeall := advapi32.lib BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libAsyncStackWalk := /EHsc @@ -81,6 +82,7 @@ else endif BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := -ljli BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := -ljvm + BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerClassLoaderTest := -ljvm BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeNullCallerLookupTest := -ljvm endif diff --git a/src/java.base/share/classes/java/lang/ClassLoader.java b/src/java.base/share/classes/java/lang/ClassLoader.java index ed5ad09da44..0aeb7620189 100644 --- a/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/src/java.base/share/classes/java/lang/ClassLoader.java @@ -1606,9 +1606,16 @@ public abstract class ClassLoader { * *

      Note that once a class loader is registered as parallel capable, there * is no way to change it back.

      + *

      + * In cases where this method is called from a context where the caller is + * not a subclass of {@code ClassLoader} or there is no caller frame on the + * stack (e.g. when called directly from a JNI attached thread), + * {@code IllegalCallerException} is thrown. + *

      * * @return {@code true} if the caller is successfully registered as * parallel capable and {@code false} if otherwise. + * @throws IllegalCallerException if the caller is not a subclass of {@code ClassLoader} * * @see #isRegisteredAsParallelCapable() * @@ -1622,6 +1629,9 @@ public abstract class ClassLoader { // Caller-sensitive adapter method for reflective invocation @CallerSensitiveAdapter private static boolean registerAsParallelCapable(Class caller) { + if ((caller == null) || !ClassLoader.class.isAssignableFrom(caller)) { + throw new IllegalCallerException(caller + " not a subclass of ClassLoader"); + } return ParallelLoaders.register(caller.asSubclass(ClassLoader.class)); } diff --git a/test/jdk/java/lang/ClassLoader/BadRegisterAsParallelCapableCaller.java b/test/jdk/java/lang/ClassLoader/BadRegisterAsParallelCapableCaller.java new file mode 100644 index 00000000000..8b1c8d24d5e --- /dev/null +++ b/test/jdk/java/lang/ClassLoader/BadRegisterAsParallelCapableCaller.java @@ -0,0 +1,57 @@ +/* + * 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. + * + * 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 8281000 + * @summary Test ClassLoader.isRegisteredAsParallelCapable() method with an + * invalid caller (non-JNI cases). This test uses reflection and opens + * the java.base module so it runs separate from behavior tests of + * isRegisteredParallelCapable to avoid side effects. + * @modules java.base/java.lang:open + * @run main/othervm BadRegisterAsParallelCapableCaller + */ + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class BadRegisterAsParallelCapableCaller { + + public static void main(String[] args) throws Exception { + + Throwable thrown = null; + final Method m = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable"); + m.setAccessible(true); + try { + m.invoke(null); + } catch (InvocationTargetException ite) { + thrown = ite.getCause(); + } + if (! (thrown instanceof IllegalCallerException)) { + throw new RuntimeException("Didn't get expected IllegalCallerException, got "+ thrown); + } else { + System.out.println("Invalid caller threw IllegalCallerException as expected"); + } + } + +} diff --git a/test/jdk/java/lang/ClassLoader/exeNullCallerClassLoaderTest/NullCallerClassLoaderTest.java b/test/jdk/java/lang/ClassLoader/exeNullCallerClassLoaderTest/NullCallerClassLoaderTest.java new file mode 100644 index 00000000000..52427f01e6e --- /dev/null +++ b/test/jdk/java/lang/ClassLoader/exeNullCallerClassLoaderTest/NullCallerClassLoaderTest.java @@ -0,0 +1,71 @@ +/* + * 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. + * + * 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 8281000 + * @summary Test uses custom launcher that starts VM using JNI that verifies + * ClassLoader.registerAsParallelCapable with null caller class + * throws an IllegalCallerException. + * @library /test/lib + * @requires os.family != "aix" + * @run main/native NullCallerClassLoaderTest + */ + +// Test disabled on AIX since we cannot invoke the JVM on the primordial thread. + +import java.io.File; +import java.util.Map; +import jdk.test.lib.Platform; +import jdk.test.lib.process.OutputAnalyzer; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class NullCallerClassLoaderTest { + public static void main(String[] args) throws IOException { + Path launcher = Path.of(System.getProperty("test.nativepath"), "NullCallerClassLoaderTest"); + ProcessBuilder pb = new ProcessBuilder(launcher.toString()); + Map env = pb.environment(); + + String libDir = Platform.libDir().toString(); + String vmDir = Platform.jvmLibDir().toString(); + + // set up shared library path + String sharedLibraryPathEnvName = Platform.sharedLibraryPathVariableName(); + env.compute(sharedLibraryPathEnvName, + (k, v) -> (v == null) ? libDir : v + File.pathSeparator + libDir); + env.compute(sharedLibraryPathEnvName, + (k, v) -> (v == null) ? vmDir : v + File.pathSeparator + vmDir); + + System.out.println("Launching: " + launcher + " shared library path: " + + env.get(sharedLibraryPathEnvName)); + new OutputAnalyzer(pb.start()) + .outputTo(System.out) + .errorTo(System.err) + .shouldHaveExitValue(0); + } +} + diff --git a/test/jdk/java/lang/ClassLoader/exeNullCallerClassLoaderTest/exeNullCallerClassLoaderTest.c b/test/jdk/java/lang/ClassLoader/exeNullCallerClassLoaderTest/exeNullCallerClassLoaderTest.c new file mode 100644 index 00000000000..d488c74bf6c --- /dev/null +++ b/test/jdk/java/lang/ClassLoader/exeNullCallerClassLoaderTest/exeNullCallerClassLoaderTest.c @@ -0,0 +1,76 @@ +/* + * 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. + * + * 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 +#include + +#include "jni.h" +#include "assert.h" + +static jclass class_IllegalCallerException; + +int checkAndClearIllegalCallerExceptionThrown(JNIEnv *env) { + jthrowable t = (*env)->ExceptionOccurred(env); + if ((*env)->IsInstanceOf(env, t, class_IllegalCallerException) == JNI_TRUE) { + (*env)->ExceptionClear(env); + return JNI_TRUE; + } + return JNI_FALSE; +} + +int main(int argc, char** args) { + JavaVM *jvm; + JNIEnv *env; + JavaVMInitArgs vm_args; + JavaVMOption options[1]; + jint rc; + + + vm_args.version = JNI_VERSION_1_2; + vm_args.nOptions = 0; + vm_args.options = options; + + if ((rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)) != JNI_OK) { + printf("ERROR: cannot create VM.\n"); + exit(-1); + } + class_IllegalCallerException = (*env)->FindClass(env, "java/lang/IllegalCallerException"); + assert (class_IllegalCallerException != NULL); + + // call ClassLoader.registerAsParallelCapable() + jclass class_ClassLoader = (*env)->FindClass(env, "java/lang/ClassLoader"); + assert(class_ClassLoader != NULL); + jmethodID mid_ClassLoader_registerAsParallelCapable = (*env)->GetStaticMethodID(env, class_ClassLoader, "registerAsParallelCapable", "()Z" ); + assert(mid_ClassLoader_registerAsParallelCapable != NULL); + jboolean b = (*env)->CallStaticBooleanMethod(env, class_ClassLoader, mid_ClassLoader_registerAsParallelCapable ); + if ((rc = checkAndClearIllegalCallerExceptionThrown(env)) != JNI_TRUE) { + printf("ERROR: Didn't get the expected IllegalCallerException.\n"); + exit(-1); + } + + printf("Expected IllegalCallerException was thrown\n"); + + (*jvm)->DestroyJavaVM(jvm); + return 0; +} + -- GitLab From cd9a3cf05b2c200709103e2e8596414a62a1c441 Mon Sep 17 00:00:00 2001 From: Mahendra Chhipa Date: Thu, 17 Feb 2022 17:45:06 +0000 Subject: [PATCH 289/400] 8282017: sun/net/www/protocol/https/HttpsURLConnection/B6216082.java fails with "SocketException: Unexpected end of file from server" Reviewed-by: dfuchs --- test/jdk/ProblemList.txt | 2 -- .../www/protocol/https/HttpsURLConnection/TunnelProxy.java | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 81c2dffe2d1..7e19b4bd713 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -597,8 +597,6 @@ java/net/MulticastSocket/SetGetNetworkInterfaceTest.java 8219083 windows- java/net/ServerSocket/AcceptInheritHandle.java 8211854 aix-ppc64 -sun/net/www/protocol/https/HttpsURLConnection/B6216082.java 8282017 generic-all - ############################################################################ # jdk_nio diff --git a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/TunnelProxy.java b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/TunnelProxy.java index 979e8be9acd..9cec3987d9e 100644 --- a/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/TunnelProxy.java +++ b/test/jdk/sun/net/www/protocol/https/HttpsURLConnection/TunnelProxy.java @@ -261,9 +261,9 @@ public class TunnelProxy { boolean res; try { InputStream is = new BufferedInputStream (new NioInputStream (chan)); - String requestline = readLine (is); - HttpHeaderParser mhead = new HttpHeaderParser (is); - String[] req = requestline.split (" "); + HttpHeaderParser mHead = new HttpHeaderParser (is); + String requestLine = mHead.getRequestDetails(); + String[] req = requestLine.split (" "); if (req.length < 2) { /* invalid request line */ return false; -- GitLab From 129277653e51e9b1387ecee279a6ccee9199c8ff Mon Sep 17 00:00:00 2001 From: Naoto Sato Date: Thu, 17 Feb 2022 19:03:08 +0000 Subject: [PATCH 290/400] 8281317: CompactNumberFormat displays 4-digit values when rounding to a new range Reviewed-by: joehw --- .../java/text/CompactNumberFormat.java | 41 ++++++++++++++++--- .../TestCompactPatternsValidity.java | 12 +++--- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/java.base/share/classes/java/text/CompactNumberFormat.java b/src/java.base/share/classes/java/text/CompactNumberFormat.java index 0449133d5b8..551945cc832 100644 --- a/src/java.base/share/classes/java/text/CompactNumberFormat.java +++ b/src/java.base/share/classes/java/text/CompactNumberFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -589,6 +589,10 @@ public final class CompactNumberFormat extends NumberFormat { if (compactDataIndex != -1) { long divisor = (Long) divisors.get(compactDataIndex); int iPart = getIntegerPart(number, divisor); + if (checkIncrement(iPart, compactDataIndex, divisor)) { + divisor = (Long) divisors.get(++compactDataIndex); + iPart = getIntegerPart(number, divisor); + } String prefix = getAffix(false, true, isNegative, compactDataIndex, iPart); String suffix = getAffix(false, false, isNegative, compactDataIndex, iPart); @@ -658,6 +662,10 @@ public final class CompactNumberFormat extends NumberFormat { if (compactDataIndex != -1) { long divisor = (Long) divisors.get(compactDataIndex); int iPart = getIntegerPart(number, divisor); + if (checkIncrement(iPart, compactDataIndex, divisor)) { + divisor = (Long) divisors.get(++compactDataIndex); + iPart = getIntegerPart(number, divisor); + } String prefix = getAffix(false, true, isNegative, compactDataIndex, iPart); String suffix = getAffix(false, false, isNegative, compactDataIndex, iPart); if (!prefix.isEmpty() || !suffix.isEmpty()) { @@ -753,6 +761,10 @@ public final class CompactNumberFormat extends NumberFormat { if (compactDataIndex != -1) { Number divisor = divisors.get(compactDataIndex); int iPart = getIntegerPart(number.doubleValue(), divisor.doubleValue()); + if (checkIncrement(iPart, compactDataIndex, divisor.doubleValue())) { + divisor = divisors.get(++compactDataIndex); + iPart = getIntegerPart(number.doubleValue(), divisor.doubleValue()); + } String prefix = getAffix(false, true, isNegative, compactDataIndex, iPart); String suffix = getAffix(false, false, isNegative, compactDataIndex, iPart); if (!prefix.isEmpty() || !suffix.isEmpty()) { @@ -820,6 +832,10 @@ public final class CompactNumberFormat extends NumberFormat { if (compactDataIndex != -1) { Number divisor = divisors.get(compactDataIndex); int iPart = getIntegerPart(number.doubleValue(), divisor.doubleValue()); + if (checkIncrement(iPart, compactDataIndex, divisor.doubleValue())) { + divisor = divisors.get(++compactDataIndex); + iPart = getIntegerPart(number.doubleValue(), divisor.doubleValue()); + } String prefix = getAffix(false, true, isNegative, compactDataIndex, iPart); String suffix = getAffix(false, false, isNegative, compactDataIndex, iPart); if (!prefix.isEmpty() || !suffix.isEmpty()) { @@ -875,7 +891,7 @@ public final class CompactNumberFormat extends NumberFormat { * Appends the {@code prefix} to the {@code result} and also set the * {@code NumberFormat.Field.SIGN} and {@code NumberFormat.Field.PREFIX} * field positions. - * @param result the resulting string, where the pefix is to be appended + * @param result the resulting string, where the prefix is to be appended * @param prefix prefix to append * @param delegate notified of the locations of * {@code NumberFormat.Field.SIGN} and @@ -910,7 +926,7 @@ public final class CompactNumberFormat extends NumberFormat { * @param result the resulting string, where the text is to be appended * @param string the text to append * @param delegate notified of the locations of sub fields - * @param positions a list of {@code FieldPostion} in the given + * @param positions a list of {@code FieldPosition} in the given * string */ private void append(StringBuffer result, String string, @@ -956,10 +972,10 @@ public final class CompactNumberFormat extends NumberFormat { } /** - * Returns a list of {@code FieldPostion} in the given {@code pattern}. + * Returns a list of {@code FieldPosition} in the given {@code pattern}. * @param pattern the pattern to be parsed for {@code FieldPosition} * @param field whether a PREFIX or SUFFIX field - * @return a list of {@code FieldPostion} + * @return a list of {@code FieldPosition} */ private List getFieldPositions(String pattern, Field field) { List positions = new ArrayList<>(); @@ -1769,7 +1785,7 @@ public final class CompactNumberFormat extends NumberFormat { if (cnfMultiplier.longValue() != 1L) { double doubleResult = number.doubleValue() * cnfMultiplier.doubleValue(); doubleResult = (double) convertIfNegative(doubleResult, status, gotLongMin); - // Check if a double can be represeneted as a long + // Check if a double can be represented as a long long longResult = (long) doubleResult; gotDouble = ((doubleResult != (double) longResult) || (doubleResult == 0.0 && 1 / doubleResult < 0.0)); @@ -2396,6 +2412,19 @@ public final class CompactNumberFormat extends NumberFormat { .divide(BigDecimal.valueOf(divisor), roundingMode).intValue(); } + // Checks whether the iPart is incremented by the BigDecimal division in + // getIntegerPart(), and affects the compact number index. + private boolean checkIncrement(int iPart, int index, double divisor) { + if (index < compactPatterns.length - 1 && + !"".equals(compactPatterns[index])) { // ignore empty pattern + var nextDiv = divisors.get(index + 1).doubleValue(); + if (divisor != nextDiv) { + return Math.log10(iPart) == Math.log10(nextDiv) - Math.log10(divisor); + } + } + return false; + } + /** * Returns LDML's tag from the plurals rules * diff --git a/test/jdk/java/text/Format/CompactNumberFormat/TestCompactPatternsValidity.java b/test/jdk/java/text/Format/CompactNumberFormat/TestCompactPatternsValidity.java index 6ca1f25ea90..8476b568ba0 100644 --- a/test/jdk/java/text/Format/CompactNumberFormat/TestCompactPatternsValidity.java +++ b/test/jdk/java/text/Format/CompactNumberFormat/TestCompactPatternsValidity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -22,7 +22,7 @@ */ /* * @test - * @bug 8177552 8217254 8251499 + * @bug 8177552 8217254 8251499 8281317 * @summary Checks the validity of compact number patterns specified through * CompactNumberFormat constructor * @run testng/othervm TestCompactPatternsValidity @@ -101,8 +101,9 @@ public class TestCompactPatternsValidity { {COMPACT_PATTERN5, List.of(100, 1000, 30000), List.of("100", "1K", "K3")}, {COMPACT_PATTERN6, List.of(20.99, 1000, 30000), List.of("21", ".1K", ".30K")}, {COMPACT_PATTERN7, List.of(100, 1000, new BigInteger("12345678987654321")), List.of("100", "1K,", "12345678987654K,")}, - {COMPACT_PATTERN8, List.of(new BigInteger("223565686837667632"), new BigDecimal("12322456774334.89766"), 30000, 3456.78), - List.of("223566T", "12T", "30K", "3K")}, + {COMPACT_PATTERN8, List.of(new BigInteger("223565686837667632"), new BigDecimal("12322456774334.89766"), 30000, 3456.78, + new BigInteger("999999999999"), new BigDecimal("999999999999.0"), 999_999, 999_999_999), + List.of("223566T", "12T", "30K", "3K", "1T", "1T", "1M", "1B")}, {COMPACT_PATTERN9, List.of(new BigInteger("223566000000000000"), new BigDecimal("12345678987654567"), 30000, 3000), List.of("223,566,000,000,000,000", "12,345,678,987,654,567", "30,000", "3,000")}, {COMPACT_PATTERN10, List.of(new BigInteger("100000000000000000"), new BigInteger("10000000000000000000"), new BigDecimal("555555555555555555555.89766"), 30000), @@ -110,7 +111,8 @@ public class TestCompactPatternsValidity { {COMPACT_PATTERN11, List.of(20.99, -20.99, 1000, -1000, 30000, -30000, new BigInteger("12345678987654321"), new BigInteger("-12345678987654321")), List.of("21", "-21", "elfu 1", "elfu -1", "elfu 30", "elfu -30", "milioni 12345678988", "milioni -12345678988")}, {COMPACT_PATTERN12, List.of(0, 500, -500, 30000, -3000, 5000000), List.of("0", "H5H", "H-5H", "30K", "3K-", "H50G")}, - {COMPACT_PATTERN13, List.of(1000, new BigInteger("10000000000000000000")), List.of("Thousand", "BeyondLong")}, + {COMPACT_PATTERN13, List.of(1000, new BigInteger("10000000000000000000"), new BigDecimal("9999999999999999999.9")), + List.of("Thousand", "BeyondLong", "BeyondLong")}, }; } -- GitLab From 69fc273f202352f74a313c37db0198be2be08616 Mon Sep 17 00:00:00 2001 From: "Daniel D. Daugherty" Date: Thu, 17 Feb 2022 20:56:46 +0000 Subject: [PATCH 291/400] 8282075: ProblemList 3 compiler/whitebox tests on macosx-x64 Reviewed-by: mikael, bpb --- test/hotspot/jtreg/ProblemList.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index a09185a4b19..9c9b1b0b3c5 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -67,9 +67,9 @@ compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java 8183263 generic-x64 compiler/c2/Test8004741.java 8235801 generic-all -compiler/whitebox/ClearMethodStateTest.java 8265360 macosx-aarch64 -compiler/whitebox/EnqueueMethodForCompilationTest.java 8265360 macosx-aarch64 -compiler/whitebox/MakeMethodNotCompilableTest.java 8265360 macosx-aarch64 +compiler/whitebox/ClearMethodStateTest.java 8265360 macosx-generic +compiler/whitebox/EnqueueMethodForCompilationTest.java 8265360 macosx-generic +compiler/whitebox/MakeMethodNotCompilableTest.java 8265360 macosx-generic compiler/codecache/jmx/PoolsIndependenceTest.java 8264632 macosx-generic compiler/codecache/TestStressCodeBuffers.java 8272094 generic-aarch64 -- GitLab From f830cbec909b91ad0f00f46a3496d83ecb5912ed Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Thu, 17 Feb 2022 21:18:15 +0000 Subject: [PATCH 292/400] 8188073: Add Capstone as backend for hsdis Co-authored-by: Magnus Ihse Bursie Co-authored-by: Jorn Vernee Reviewed-by: erikj --- make/Hsdis.gmk | 151 +++++++++++------- make/autoconf/help.m4 | 4 + make/autoconf/jdk-options.m4 | 42 ++++- make/autoconf/spec.gmk.in | 3 +- src/utils/hsdis/README | 102 ------------ src/utils/hsdis/README.md | 133 +++++++++++++++ .../{hsdis.c => binutils/hsdis-binutils.c} | 0 src/utils/hsdis/capstone/hsdis-capstone.c | 97 +++++++++++ src/utils/hsdis/hsdis.h | 20 ++- 9 files changed, 381 insertions(+), 171 deletions(-) delete mode 100644 src/utils/hsdis/README create mode 100644 src/utils/hsdis/README.md rename src/utils/hsdis/{hsdis.c => binutils/hsdis-binutils.c} (100%) create mode 100644 src/utils/hsdis/capstone/hsdis-capstone.c diff --git a/make/Hsdis.gmk b/make/Hsdis.gmk index 02f09b320f0..fa5238c80f6 100644 --- a/make/Hsdis.gmk +++ b/make/Hsdis.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2020, 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 @@ -36,89 +36,111 @@ include JdkNativeCompilation.gmk HSDIS_OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/hsdis +HSDIS_TOOLCHAIN := TOOLCHAIN_DEFAULT +HSDIS_TOOLCHAIN_CFLAGS := $(CFLAGS_JDKLIB) +HSDIS_TOOLCHAIN_LDFLAGS := $(LDFLAGS_JDKLIB) + ifeq ($(call isTargetOs, windows), true) INSTALLED_HSDIS_DIR := $(JDK_OUTPUTDIR)/bin + IMAGE_HSDIS_DIR := $(JDK_IMAGE_DIR)/bin +else + INSTALLED_HSDIS_DIR := $(JDK_OUTPUTDIR)/lib + IMAGE_HSDIS_DIR := $(JDK_IMAGE_DIR)/lib +endif - # On windows, we need to "fake" a completely different toolchain using gcc - # instead of the normal microsoft toolchain. This is quite hacky... +ifeq ($(HSDIS_BACKEND), capstone) + ifeq ($(call isTargetCpuArch, x86), true) + CAPSTONE_ARCH := CS_ARCH_X86 + CAPSTONE_MODE := CS_MODE_$(OPENJDK_TARGET_CPU_BITS) + else ifeq ($(call isTargetCpuArch, aarch64), true) + CAPSTONE_ARCH := CS_ARCH_ARM64 + CAPSTONE_MODE := CS_MODE_ARM + else + $(error No support for Capstone on this platform) + endif - MINGW_BASE := x86_64-w64-mingw32 + HSDIS_CFLAGS += -DCAPSTONE_ARCH=$(CAPSTONE_ARCH) \ + -DCAPSTONE_MODE=$(CAPSTONE_MODE) +endif + +ifeq ($(HSDIS_BACKEND), binutils) + ifeq ($(call isTargetOs, windows), true) + # On windows, we need to "fake" a completely different toolchain using gcc + # instead of the normal microsoft toolchain. This is quite hacky... - MINGW_SYSROOT = $(shell $(MINGW_BASE)-gcc -print-sysroot) - ifeq ($(wildcard $(MINGW_SYSROOT)), ) - # Use fallback path - MINGW_SYSROOT := /usr/$(MINGW_BASE) + MINGW_BASE := x86_64-w64-mingw32 + + MINGW_SYSROOT = $(shell $(MINGW_BASE)-gcc -print-sysroot) ifeq ($(wildcard $(MINGW_SYSROOT)), ) - $(error mingw sysroot not found) + # Use fallback path + MINGW_SYSROOT := /usr/$(MINGW_BASE) + ifeq ($(wildcard $(MINGW_SYSROOT)), ) + $(error mingw sysroot not found) + endif endif - endif - $(eval $(call DefineNativeToolchain, TOOLCHAIN_MINGW, \ - CC := $(MINGW_BASE)-gcc, \ - LD := $(MINGW_BASE)-ld, \ - OBJCOPY := $(MINGW_BASE)-objcopy, \ - RC := $(RC), \ - SYSROOT_CFLAGS := --sysroot=$(MINGW_SYSROOT), \ - SYSROOT_LDFLAGS := --sysroot=$(MINGW_SYSROOT), \ - )) - - MINGW_SYSROOT_LIB_PATH := $(MINGW_SYSROOT)/mingw/lib - ifeq ($(wildcard $(MINGW_SYSROOT_LIB_PATH)), ) - # Try without mingw - MINGW_SYSROOT_LIB_PATH := $(MINGW_SYSROOT)/lib + $(eval $(call DefineNativeToolchain, TOOLCHAIN_MINGW, \ + CC := $(MINGW_BASE)-gcc, \ + LD := $(MINGW_BASE)-ld, \ + OBJCOPY := $(MINGW_BASE)-objcopy, \ + RC := $(RC), \ + SYSROOT_CFLAGS := --sysroot=$(MINGW_SYSROOT), \ + SYSROOT_LDFLAGS := --sysroot=$(MINGW_SYSROOT), \ + )) + + MINGW_SYSROOT_LIB_PATH := $(MINGW_SYSROOT)/mingw/lib ifeq ($(wildcard $(MINGW_SYSROOT_LIB_PATH)), ) - $(error mingw sysroot lib path not found) + # Try without mingw + MINGW_SYSROOT_LIB_PATH := $(MINGW_SYSROOT)/lib + ifeq ($(wildcard $(MINGW_SYSROOT_LIB_PATH)), ) + $(error mingw sysroot lib path not found) + endif endif - endif - MINGW_VERSION = $(shell $(MINGW_BASE)-gcc -v 2>&1 | $(GREP) "gcc version" | $(CUT) -d " " -f 3) - MINGW_GCC_LIB_PATH := /usr/lib/gcc/$(MINGW_BASE)/$(MINGW_VERSION) - ifeq ($(wildcard $(MINGW_GCC_LIB_PATH)), ) - # Try using only major version number - MINGW_VERSION_MAJOR := $(firstword $(subst ., , $(MINGW_VERSION))) - MINGW_GCC_LIB_PATH := /usr/lib/gcc/$(MINGW_BASE)/$(MINGW_VERSION_MAJOR) + MINGW_VERSION = $(shell $(MINGW_BASE)-gcc -v 2>&1 | $(GREP) "gcc version" | $(CUT) -d " " -f 3) + MINGW_GCC_LIB_PATH := /usr/lib/gcc/$(MINGW_BASE)/$(MINGW_VERSION) ifeq ($(wildcard $(MINGW_GCC_LIB_PATH)), ) - $(error mingw gcc lib path not found) + # Try using only major version number + MINGW_VERSION_MAJOR := $(firstword $(subst ., , $(MINGW_VERSION))) + MINGW_GCC_LIB_PATH := /usr/lib/gcc/$(MINGW_BASE)/$(MINGW_VERSION_MAJOR) + ifeq ($(wildcard $(MINGW_GCC_LIB_PATH)), ) + $(error mingw gcc lib path not found) + endif endif - endif - TOOLCHAIN_TYPE := gcc - OPENJDK_TARGET_OS := linux - CC_OUT_OPTION := -o$(SPACE) - LD_OUT_OPTION := -o$(SPACE) - GENDEPS_FLAGS := -MMD -MF - CFLAGS_DEBUG_SYMBOLS := -g - DISABLED_WARNINGS := - DISABLE_WARNING_PREFIX := -Wno- - CFLAGS_WARNINGS_ARE_ERRORS := -Werror - SHARED_LIBRARY_FLAGS := -shared - - HSDIS_TOOLCHAIN := TOOLCHAIN_MINGW - HSDIS_TOOLCHAIN_CFLAGS := - HSDIS_TOOLCHAIN_LDFLAGS := -L$(MINGW_GCC_LIB_PATH) -L$(MINGW_SYSROOT_LIB_PATH) - MINGW_DLLCRT := $(MINGW_SYSROOT_LIB_PATH)/dllcrt2.o - HSDIS_TOOLCHAIN_LIBS := $(MINGW_DLLCRT) -lmingw32 -lgcc -lgcc_eh -lmoldname \ - -lmingwex -lmsvcrt -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 -else - INSTALLED_HSDIS_DIR := $(JDK_OUTPUTDIR)/lib - - HSDIS_TOOLCHAIN := TOOLCHAIN_DEFAULT - HSDIS_TOOLCHAIN_CFLAGS := $(CFLAGS_JDKLIB) - HSDIS_TOOLCHAIN_LDFLAGS := $(LDFLAGS_JDKLIB) - HSDIS_TOOLCHAIN_LIBS := -ldl + TOOLCHAIN_TYPE := gcc + OPENJDK_TARGET_OS := linux + CC_OUT_OPTION := -o$(SPACE) + LD_OUT_OPTION := -o$(SPACE) + GENDEPS_FLAGS := -MMD -MF + CFLAGS_DEBUG_SYMBOLS := -g + DISABLED_WARNINGS := + DISABLE_WARNING_PREFIX := -Wno- + CFLAGS_WARNINGS_ARE_ERRORS := -Werror + SHARED_LIBRARY_FLAGS := -shared + + HSDIS_TOOLCHAIN := TOOLCHAIN_MINGW + HSDIS_TOOLCHAIN_CFLAGS := + HSDIS_TOOLCHAIN_LDFLAGS := -L$(MINGW_GCC_LIB_PATH) -L$(MINGW_SYSROOT_LIB_PATH) + MINGW_DLLCRT := $(MINGW_SYSROOT_LIB_PATH)/dllcrt2.o + HSDIS_TOOLCHAIN_LIBS := $(MINGW_DLLCRT) -lmingw32 -lgcc -lgcc_eh -lmoldname \ + -lmingwex -lmsvcrt -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 + else + HSDIS_TOOLCHAIN_LIBS := -ldl + endif endif - $(eval $(call SetupJdkLibrary, BUILD_HSDIS, \ NAME := hsdis, \ - SRC := $(TOPDIR)/src/utils/hsdis, \ + SRC := $(TOPDIR)/src/utils/hsdis/$(HSDIS_BACKEND), \ + EXTRA_HEADER_DIRS := $(TOPDIR)/src/utils/hsdis, \ TOOLCHAIN := $(HSDIS_TOOLCHAIN), \ OUTPUT_DIR := $(HSDIS_OUTPUT_DIR), \ OBJECT_DIR := $(HSDIS_OUTPUT_DIR), \ DISABLED_WARNINGS_gcc := undef format-nonliteral sign-compare, \ DISABLED_WARNINGS_clang := undef format-nonliteral, \ CFLAGS := $(HSDIS_TOOLCHAIN_CFLAGS) $(HSDIS_CFLAGS), \ - LDFLAGS := $(HSDIS_TOOLCHAIN_LDFLAGS) $(SHARED_LIBRARY_FLAGS), \ + LDFLAGS := $(HSDIS_TOOLCHAIN_LDFLAGS) $(HSDIS_LDFLAGS) $(SHARED_LIBRARY_FLAGS), \ LIBS := $(HSDIS_LIBS) $(HSDIS_TOOLCHAIN_LIBS), \ )) @@ -129,13 +151,18 @@ TARGETS += build INSTALLED_HSDIS_NAME := hsdis-$(OPENJDK_TARGET_CPU_LEGACY_LIB)$(SHARED_LIBRARY_SUFFIX) INSTALLED_HSDIS := $(INSTALLED_HSDIS_DIR)/$(INSTALLED_HSDIS_NAME) +INSTALLED_HSDIS_IMAGE := $(IMAGE_HSDIS_DIR)/$(INSTALLED_HSDIS_NAME) $(INSTALLED_HSDIS): $(BUILD_HSDIS_TARGET) - $(call LogWarn, NOTE: The resulting build might not be redistributable. Seek legal advice before distibuting.) + ifeq ($(HSDIS_BACKEND), binutils) + $(call LogWarn, NOTE: The resulting build might not be redistributable. Seek legal advice before distributing.) + endif $(install-file) +$(INSTALLED_HSDIS_IMAGE): $(INSTALLED_HSDIS) + $(install-file) -install: $(INSTALLED_HSDIS) +install: $(INSTALLED_HSDIS_IMAGE) TARGETS += install diff --git a/make/autoconf/help.m4 b/make/autoconf/help.m4 index 09e82e36c94..486e78d4fcf 100644 --- a/make/autoconf/help.m4 +++ b/make/autoconf/help.m4 @@ -117,6 +117,8 @@ apt_help() { PKGHANDLER_COMMAND="sudo apt-get install ccache" ;; dtrace) PKGHANDLER_COMMAND="sudo apt-get install systemtap-sdt-dev" ;; + capstone) + PKGHANDLER_COMMAND="sudo apt-get install libcapstone-dev" ;; esac } @@ -168,6 +170,8 @@ brew_help() { PKGHANDLER_COMMAND="brew install freetype" ;; ccache) PKGHANDLER_COMMAND="brew install ccache" ;; + capstone) + PKGHANDLER_COMMAND="brew install capstone" ;; esac } diff --git a/make/autoconf/jdk-options.m4 b/make/autoconf/jdk-options.m4 index 0a7145c9116..7692407316a 100644 --- a/make/autoconf/jdk-options.m4 +++ b/make/autoconf/jdk-options.m4 @@ -811,7 +811,10 @@ AC_DEFUN([JDKOPT_BUILD_BINUTILS], AC_DEFUN_ONCE([JDKOPT_SETUP_HSDIS], [ AC_ARG_WITH([hsdis], [AS_HELP_STRING([--with-hsdis], - [what hsdis backend to use ('none', 'binutils') @<:@none@:>@])]) + [what hsdis backend to use ('none', 'capstone', 'binutils') @<:@none@:>@])]) + + AC_ARG_WITH(capstone, [AS_HELP_STRING([--with-capstone], + [where to find the Capstone files needed for hsdis/capstone])]) AC_ARG_WITH([binutils], [AS_HELP_STRING([--with-binutils], [where to find the binutils files needed for hsdis/binutils])]) @@ -826,6 +829,41 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_HSDIS], elif test "x$with_hsdis" = xnone || test "x$with_hsdis" = xno || test "x$with_hsdis" = x; then HSDIS_BACKEND=none AC_MSG_RESULT(['none', hsdis will not be built]) + elif test "x$with_hsdis" = xcapstone; then + HSDIS_BACKEND=capstone + AC_MSG_RESULT(['capstone']) + + if test "x$with_capstone" != x; then + AC_MSG_CHECKING([for capstone]) + CAPSTONE="$with_capstone" + AC_MSG_RESULT([$CAPSTONE]) + + HSDIS_CFLAGS="-I${CAPSTONE}/include/capstone" + if test "x$OPENJDK_TARGET_OS" != xwindows; then + HSDIS_LDFLAGS="-L${CAPSTONE}/lib" + HSDIS_LIBS="-lcapstone" + else + HSDIS_LDFLAGS="-nodefaultlib:libcmt.lib" + HSDIS_LIBS="${CAPSTONE}/capstone.lib" + fi + else + if test "x$OPENJDK_TARGET_OS" = xwindows; then + # There is no way to auto-detect capstone on Windowos + AC_MSG_NOTICE([You must specify capstone location using --with-capstone=]) + AC_MSG_ERROR([Cannot continue]) + fi + + PKG_CHECK_MODULES(CAPSTONE, capstone, [CAPSTONE_FOUND=yes], [CAPSTONE_FOUND=no]) + if test "x$CAPSTONE_FOUND" = xyes; then + HSDIS_CFLAGS="$CAPSTONE_CFLAGS" + HSDIS_LDFLAGS="$CAPSTONE_LDFLAGS" + HSDIS_LIBS="$CAPSTONE_LIBS" + else + HELP_MSG_MISSING_DEPENDENCY([capstone]) + AC_MSG_NOTICE([Cannot locate capstone which is needed for hsdis/capstone. Try using --with-capstone=. $HELP_MSG]) + AC_MSG_ERROR([Cannot continue]) + fi + fi elif test "x$with_hsdis" = xbinutils; then HSDIS_BACKEND=binutils AC_MSG_RESULT(['binutils']) @@ -853,6 +891,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_HSDIS], test -e $BINUTILS_DIR/opcodes/libopcodes.a && \ test -e $BINUTILS_DIR/libiberty/libiberty.a; then HSDIS_CFLAGS="-I$BINUTILS_DIR/include -I$BINUTILS_DIR/bfd -DLIBARCH_$OPENJDK_TARGET_CPU_LEGACY_LIB" + HSDIS_LDFLAGS="" HSDIS_LIBS="$BINUTILS_DIR/bfd/libbfd.a $BINUTILS_DIR/opcodes/libopcodes.a $BINUTILS_DIR/libiberty/libiberty.a $BINUTILS_DIR/zlib/libz.a" fi fi @@ -895,5 +934,6 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_HSDIS], AC_SUBST(HSDIS_BACKEND) AC_SUBST(HSDIS_CFLAGS) + AC_SUBST(HSDIS_LDFLAGS) AC_SUBST(HSDIS_LIBS) ]) diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in index 3dce730970e..d286d5cc2cc 100644 --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 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 @@ -361,6 +361,7 @@ ALLOW_ABSOLUTE_PATHS_IN_OUTPUT := @ALLOW_ABSOLUTE_PATHS_IN_OUTPUT@ HSDIS_BACKEND := @HSDIS_BACKEND@ HSDIS_CFLAGS := @HSDIS_CFLAGS@ +HSDIS_LDFLAGS := @HSDIS_LDFLAGS@ HSDIS_LIBS := @HSDIS_LIBS@ # The boot jdk to use. This is overridden in bootcycle-spec.gmk. Make sure to keep diff --git a/src/utils/hsdis/README b/src/utils/hsdis/README deleted file mode 100644 index 64a8ab61a7c..00000000000 --- a/src/utils/hsdis/README +++ /dev/null @@ -1,102 +0,0 @@ -Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. -DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - -The Universal Permissive License (UPL), Version 1.0 - -Subject to the condition set forth below, permission is hereby granted to -any person obtaining a copy of this software, associated documentation -and/or data (collectively the "Software"), free of charge and under any -and all copyright rights in the Software, and any and all patent rights -owned or freely licensable by each licensor hereunder covering either (i) -the unmodified Software as contributed to or provided by such licensor, -or (ii) the Larger Works (as defined below), to deal in both - -(a) the Software, and - -(b) any piece of software and/or hardware listed in the lrgrwrks.txt file -if one is included with the Software (each a "Larger Work" to which the -Software is contributed by such licensors), - -without restriction, including without limitation the rights to copy, -create derivative works of, display, perform, and distribute the Software -and make, use, sell, offer for sale, import, export, have made, and have -sold the Software and the Larger Work(s), and to sublicense the foregoing -rights on either these or other terms. - -This license is subject to the following condition: - -The above copyright notice and either this complete permission notice or -at a minimum a reference to the UPL must be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - -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. - -________________________________________________________________________ - -'hsdis': A HotSpot plugin for disassembling dynamically generated code. - -The files in this directory are built independently of the HotSpot JVM. - -* Building - -To build this project you need a copy of GNU binutils to build against. It is -known to work with binutils 2.37. Building against versions older than 2.29 is -not supported. Download a copy of the software from -http://directory.fsf.org/project/binutils or one of its mirrors. - -To build this library, you must enable building in configure by "bash configure ---with-hsdis=binutils". - -You must also specify where binutils is located. To facilitate building, you can -point to a place where the (unpacked) binutils sources are located using -"--with-binutils-src=", and configure will build binutils for you. On -repeated runs, you can keep this command line option, since configure will -figure out that the binutils binaries are already present and skip building, or -you can replace it with "--with-binutils=". - -If you have pre-built binutils binaries, you can point to them directly using -"--with-binutils=". - -If you want to build hsdis with binutils provided by system -(e.g. binutils-devel from Fedora, binutils-dev from Ubuntu), you can pass -"--with-binutils=system". "system" is available on Linux only. - -When you have created a proper configuration, you can then build the hsdis -library using "make build-hsdis". - -* Building on Windows - -On Windows, the normal Microsoft Visual Studio toolchain cannot build binutils. -Instead we need to use the mingw compiler. This is available as a cygwin -package. You need to install the "gcc-core" and "mingw64-x86_64-gcc-core" -packages (or "mingw64-i686-gcc-core", if you want the 32-bit version) and -"mingw64-x86_64-glib2.0". - -* Installing - -To build the hsdis library, run "make build-hsdis". This will build the library -in a separate directory, but not make it available to the JDK in the -configuration. To actually install it in the JDK, run "make install-hsdis". - -Note: The resulting build may not be distributable. Please get legal advice if -you intend to distribute the result of your build. - -* Using the library - -The hsdis library will be automatically loaded by Hotspot when you use the -diagnostic option "-XX:+PrintAssembly". Note that since this is a diagnostic -option, you need to unlock these first, so in practice you activate it using -"-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly". - -More information is available at the wiki -[https://wiki.openjdk.java.net/display/HotSpot/PrintAssembly]. diff --git a/src/utils/hsdis/README.md b/src/utils/hsdis/README.md new file mode 100644 index 00000000000..bc8bdb767b7 --- /dev/null +++ b/src/utils/hsdis/README.md @@ -0,0 +1,133 @@ +``` +Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. +DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + +The Universal Permissive License (UPL), Version 1.0 + +Subject to the condition set forth below, permission is hereby granted to +any person obtaining a copy of this software, associated documentation +and/or data (collectively the "Software"), free of charge and under any +and all copyright rights in the Software, and any and all patent rights +owned or freely licensable by each licensor hereunder covering either (i) +the unmodified Software as contributed to or provided by such licensor, +or (ii) the Larger Works (as defined below), to deal in both + +(a) the Software, and + +(b) any piece of software and/or hardware listed in the lrgrwrks.txt file +if one is included with the Software (each a "Larger Work" to which the +Software is contributed by such licensors), + +without restriction, including without limitation the rights to copy, +create derivative works of, display, perform, and distribute the Software +and make, use, sell, offer for sale, import, export, have made, and have +sold the Software and the Larger Work(s), and to sublicense the foregoing +rights on either these or other terms. + +This license is subject to the following condition: + +The above copyright notice and either this complete permission notice or +at a minimum a reference to the UPL must be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +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. +``` + +--- + +# hsdis - a HotSpot plugin for disassembling dynamically generated code + +The files in this directory are built independently of the HotSpot JVM. + +hsdis is an interface exposed by Hotspot. There are several backends that +implement this interface, using different disassembly engines. Included in the +JDK is support for building hsdis with Capstone or GNU binutils. The interface +is fairly straightforward and easy to implement using other backends. + +## Building and installing + +To compile hsdis, you need to activate hsdis support, and select the proper +backend to use. This is done with the configure switch `--with-hsdis=`, +where `` is either `capstone` or `binutils`. For details, see the +sections on the respective backends below. + +To build the hsdis library, run `make build-hsdis`. This will build the library +in a separate directory, but not make it available to the JDK in the +configuration. To actually install it in the JDK, run `make install-hsdis`. + +**NOTE:** If you do this using the binutils backend, the resulting build may not +be distributable. Please get legal advice if you intend to distribute the result +of your build. + +## Using the library + +The hsdis library will be automatically loaded by Hotspot when you use the +diagnostic option `-XX:+PrintAssembly`. Note that since this is a diagnostic +option, you need to unlock these first, so in practice you activate it using +`-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly`. + +More information is available at the [HotSpot +wiki](https://wiki.openjdk.java.net/display/HotSpot/PrintAssembly). + +## Building with Capstone + +To build this project using Capstone you need to have Capstone installed. +Typical ways of installation can be `sudo apt install libcapstone-dev` (on +Debian and derivatives), or `brew install capstone` (on macOS with Homebrew). +For Windows, you need to download the "Core Engine", and unzip it. See the +[Capstone Download +page](https://www.capstone-engine.org/download.html#windows---core-engine-) for +up-to-date download links. + +This has been tested with Capstone v4.0.2, but earlier (and later) versions are +also likely to work. + +To build hsdis using Capstone, you must enable it in configure by `bash +configure --with-hsdis=capstone`. + +On Linux and macOS, the location Capstone can most often be auto-detected. If +this fails, or if you are building on Windows, you need to specify where +Capstone is located using `--with-capstone=`. This path should point to +where you have extracted the Core Engine zip file. + +## Building with binutils + +To build this project using binutils you need a copy of GNU binutils to build +against. It is known to work with binutils 2.37. Building against versions older +than 2.29 is not supported. Download a copy of the software from [FSF binutils +page](http://directory.fsf.org/project/binutils) or one of its mirrors. + +To build this library, you must enable building in configure by `bash configure +--with-hsdis=binutils`. + +You must also specify where binutils is located. To facilitate building, you can +point to a place where the (unpacked) binutils sources are located using +`--with-binutils-src=`, and configure will build binutils for you. On +repeated runs, you can keep this command line option, since configure will +figure out that the binutils binaries are already present and skip building, or +you can replace it with `--with-binutils=`. + +If you have pre-built binutils binaries, you can point to them directly using +`--with-binutils=`. + +If you want to build hsdis with binutils provided by system (e.g. binutils-devel +from Fedora, binutils-dev from Ubuntu), you can pass `--with-binutils=system`. +`system` is available on Linux only. + +### Building with binutils on Windows + +On Windows, the normal Microsoft Visual Studio toolchain cannot build binutils. +Instead we need to use the mingw compiler. This is available as a cygwin +package. You need to install the `gcc-core` and `mingw64-x86_64-gcc-core` +packages (or `mingw64-i686-gcc-core`, if you want the 32-bit version) and +`mingw64-x86_64-glib2.0`. diff --git a/src/utils/hsdis/hsdis.c b/src/utils/hsdis/binutils/hsdis-binutils.c similarity index 100% rename from src/utils/hsdis/hsdis.c rename to src/utils/hsdis/binutils/hsdis-binutils.c diff --git a/src/utils/hsdis/capstone/hsdis-capstone.c b/src/utils/hsdis/capstone/hsdis-capstone.c new file mode 100644 index 00000000000..d71330ee6a7 --- /dev/null +++ b/src/utils/hsdis/capstone/hsdis-capstone.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to + * any person obtaining a copy of this software, associated documentation + * and/or data (collectively the "Software"), free of charge and under any + * and all copyright rights in the Software, and any and all patent rights + * owned or freely licensable by each licensor hereunder covering either (i) + * the unmodified Software as contributed to or provided by such licensor, + * or (ii) the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file + * if one is included with the Software (each a "Larger Work" to which the + * Software is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, + * create derivative works of, display, perform, and distribute the Software + * and make, use, sell, offer for sale, import, export, have made, and have + * sold the Software and the Larger Work(s), and to sublicense the foregoing + * rights on either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or + * at a minimum a reference to the UPL must be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * 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. + * + */ + +/* hsdis.c -- dump a range of addresses as native instructions + This implements the plugin protocol required by the + HotSpot PrintAssembly option. +*/ + +#include + +#include + +#include "hsdis.h" + +/* short names for stuff in hsdis.h */ +typedef decode_instructions_event_callback_ftype event_callback_t; +typedef decode_instructions_printf_callback_ftype printf_callback_t; + +#define print(...) (*printf_callback) (printf_stream, __VA_ARGS__) + +#ifdef _WIN32 +__declspec(dllexport) +#endif +void* decode_instructions_virtual(uintptr_t start_va, uintptr_t end_va, + unsigned char* buffer, uintptr_t length, + void* (*event_callback)(void*, const char*, void*), + void* event_stream, + int (*printf_callback)(void*, const char*, ...), + void* printf_stream, + const char* options, + int newline /* bool value for nice new line */) { + csh cs_handle; + + if (cs_open(CAPSTONE_ARCH, CAPSTONE_MODE, &cs_handle) != CS_ERR_OK) { + print("Could not open cs_handle"); + return NULL; + } + + // TODO: Support intel syntax + cs_option(cs_handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); + + cs_insn *insn; + size_t count = cs_disasm(cs_handle, buffer, length, (uintptr_t) buffer, 0 , &insn); + if (count) { + for (unsigned int j = 0; j < count; j++) { + print(" 0x%" PRIx64 ":\t%s\t\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + } + cs_free(insn, count); + } + + cs_close(&cs_handle); + + return NULL; +} diff --git a/src/utils/hsdis/hsdis.h b/src/utils/hsdis/hsdis.h index a6b45a57ba8..7e3b8e397af 100644 --- a/src/utils/hsdis/hsdis.h +++ b/src/utils/hsdis/hsdis.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -72,9 +72,14 @@ #ifndef SHARED_TOOLS_HSDIS_H #define SHARED_TOOLS_HSDIS_H +#ifdef __cplusplus +extern "C" +{ +#endif + extern -#ifdef DLL_EXPORT - DLL_EXPORT +#ifdef _WIN32 +__declspec(dllexport) #endif void* decode_instructions_virtual(uintptr_t start_va, uintptr_t end_va, unsigned char* buffer, uintptr_t length, @@ -87,8 +92,8 @@ void* decode_instructions_virtual(uintptr_t start_va, uintptr_t end_va, /* This is the compatability interface for older versions of hotspot */ extern -#ifdef DLL_ENTRY - DLL_ENTRY +#ifdef _WIN32 +__declspec(dllexport) #endif void* decode_instructions(void* start_pv, void* end_pv, void* (*event_callback)(void*, const char*, void*), @@ -115,4 +120,9 @@ typedef void* (*decode_func_stype) (void* start_pv, void* end_pv, decode_instructions_printf_callback_ftype printf_callback, void* printf_stream, const char* options); + +#ifdef __cplusplus +} +#endif + #endif /* SHARED_TOOLS_HSDIS_H */ -- GitLab From fdce35f3a1c12a64238d0c76c02451a25b0b4abb Mon Sep 17 00:00:00 2001 From: Jie Fu Date: Thu, 17 Feb 2022 22:53:53 +0000 Subject: [PATCH 293/400] 8282025: assert(ctrl != __null) failed: control out is assumed to be unique after JDK-8281732 Reviewed-by: kvn, thartmann, chagedorn --- src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp index f46d9436316..849b40f3d79 100644 --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2015, 2021, Red Hat, Inc. All rights reserved. + * Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -706,7 +707,7 @@ Node* ShenandoahBarrierC2Support::no_branches(Node* c, Node* dom, bool allow_one Node* iffproj = NULL; while (c != dom) { Node* next = phase->idom(c); - assert(next->unique_ctrl_out() == c || c->is_Proj() || c->is_Region(), "multiple control flow out but no proj or region?"); + assert(next->unique_ctrl_out_or_null() == c || c->is_Proj() || c->is_Region(), "multiple control flow out but no proj or region?"); if (c->is_Region()) { ResourceMark rm; Unique_Node_List wq; -- GitLab From a22f422b7f18dc134e48c6193bf690004635bf7d Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Fri, 18 Feb 2022 04:56:05 +0000 Subject: [PATCH 294/400] 8037573: Typo in DefaultTreeModel docs: askAllowsChildren instead of asksAllowsChildren Reviewed-by: prr, jdv, azvegint --- .../share/classes/javax/swing/tree/DefaultTreeModel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.desktop/share/classes/javax/swing/tree/DefaultTreeModel.java b/src/java.desktop/share/classes/javax/swing/tree/DefaultTreeModel.java index 6d2a692c043..4cdec3f6b38 100644 --- a/src/java.desktop/share/classes/javax/swing/tree/DefaultTreeModel.java +++ b/src/java.desktop/share/classes/javax/swing/tree/DefaultTreeModel.java @@ -204,7 +204,7 @@ public class DefaultTreeModel implements Serializable, TreeModel { /** * Returns whether the specified node is a leaf node. * The way the test is performed depends on the - * askAllowsChildren setting. + * asksAllowsChildren setting. * * @param node the node to check * @return true if the node is a leaf node -- GitLab From c9289583eb6919ced3b4115cf981180f6a957fbf Mon Sep 17 00:00:00 2001 From: Jie Fu Date: Fri, 18 Feb 2022 05:02:19 +0000 Subject: [PATCH 295/400] 8281936: compiler/arguments/TestCodeEntryAlignment.java fails on AVX512 machines Reviewed-by: shade, kvn --- src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp index 6597c91bb42..8bfbe3303da 100644 --- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp +++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp @@ -3002,7 +3002,7 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha // allocate space for the code ResourceMark rm; - CodeBuffer buffer(name, 1000, 512); + CodeBuffer buffer(name, 1200, 512); MacroAssembler* masm = new MacroAssembler(&buffer); int frame_size_in_words; -- GitLab From 7bcca7692b62a37f70c757694f6acff0295371cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Fri, 18 Feb 2022 08:35:52 +0000 Subject: [PATCH 296/400] 8279068: IGV: Update to work with JDK 16 and 17 Reviewed-by: kvn, neliasso, chagedorn --- .../IdealGraphVisualizer/Bytecodes/pom.xml | 6 ++++- .../IdealGraphVisualizer/ControlFlow/pom.xml | 6 ++++- .../IdealGraphVisualizer/Coordinator/pom.xml | 6 ++++- src/utils/IdealGraphVisualizer/Data/pom.xml | 6 ++++- .../IdealGraphVisualizer/Difference/pom.xml | 6 ++++- src/utils/IdealGraphVisualizer/Filter/pom.xml | 8 +++++-- .../IdealGraphVisualizer/FilterWindow/pom.xml | 6 ++++- src/utils/IdealGraphVisualizer/Graal/pom.xml | 6 ++++- src/utils/IdealGraphVisualizer/Graph/pom.xml | 6 ++++- .../HierarchicalLayout/pom.xml | 6 ++++- src/utils/IdealGraphVisualizer/Layout/pom.xml | 6 ++++- .../NetworkConnection/pom.xml | 6 ++++- src/utils/IdealGraphVisualizer/README.md | 2 +- .../SelectionCoordinator/pom.xml | 6 ++++- .../ServerCompiler/pom.xml | 4 ++++ .../IdealGraphVisualizer/Settings/pom.xml | 6 ++++- src/utils/IdealGraphVisualizer/Util/pom.xml | 6 ++++- src/utils/IdealGraphVisualizer/View/pom.xml | 6 ++++- .../IdealGraphVisualizer/application/pom.xml | 5 +++- .../main/resources/idealgraphvisualizer.conf | 24 +++++++++++++++++++ .../IdealGraphVisualizer/branding/pom.xml | 6 ++++- src/utils/IdealGraphVisualizer/pom.xml | 24 ++++++++++++++++++- 22 files changed, 142 insertions(+), 21 deletions(-) create mode 100644 src/utils/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf diff --git a/src/utils/IdealGraphVisualizer/Bytecodes/pom.xml b/src/utils/IdealGraphVisualizer/Bytecodes/pom.xml index 188537f81d6..e87ad7fb509 100644 --- a/src/utils/IdealGraphVisualizer/Bytecodes/pom.xml +++ b/src/utils/IdealGraphVisualizer/Bytecodes/pom.xml @@ -1,6 +1,6 @@ diff --git a/src/utils/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf b/src/utils/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf new file mode 100644 index 00000000000..500ed32f280 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/application/src/main/resources/idealgraphvisualizer.conf @@ -0,0 +1,24 @@ +# 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. +# +# 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. + +# Open/export modules still accessed by the NetBeans Platform. +# All options must be passed in a single line for multi-platform support. +default_options="-J--add-opens=java.base/java.net=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing.plaf.synth=ALL-UNNAMED -J--add-opens=java.desktop/com.sun.java.swing.plaf.gtk=ALL-UNNAMED -J--add-opens=java.desktop/javax.swing=ALL-UNNAMED -J--add-exports=java.desktop/sun.awt=ALL-UNNAMED" \ No newline at end of file diff --git a/src/utils/IdealGraphVisualizer/branding/pom.xml b/src/utils/IdealGraphVisualizer/branding/pom.xml index 67821ff4621..ed33298d3e4 100644 --- a/src/utils/IdealGraphVisualizer/branding/pom.xml +++ b/src/utils/IdealGraphVisualizer/branding/pom.xml @@ -1,6 +1,6 @@